设备管理,设备组管理
diff --git a/build.gradle b/build.gradle
index 464e7cf..a747702 100644
--- a/build.gradle
+++ b/build.gradle
@@ -25,6 +25,13 @@
 
 dependencies {
     implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
+    compile group: 'org.apache.poi', name: 'poi', version: '3.10.1'
+    compile group: 'org.apache.poi', name: 'poi-examples', version: '3.10.1'
+    compile group: 'org.apache.poi', name: 'poi-excelant', version: '3.10.1'
+    compile group: 'org.apache.poi',name: 'poi-ooxml', version:'3.10.1'
+    compile group: 'org.apache.poi',name: 'poi-ooxml-schemas', version:'3.10.1'
+    compile group: 'org.apache.poi',name: 'poi-scratchpad', version:'3.10.1'
+
     implementation 'org.springframework.boot:spring-boot-starter-tomcat'
     implementation 'org.springframework.boot:spring-boot-starter-data-redis'
     implementation 'org.springframework.boot:spring-boot-starter-web'
diff --git a/src/main/java/com/supwisdom/dlpay/device/bean/DeviceSearchBean.java b/src/main/java/com/supwisdom/dlpay/device/bean/DeviceSearchBean.java
index a4e6bfa..7b03fa2 100644
--- a/src/main/java/com/supwisdom/dlpay/device/bean/DeviceSearchBean.java
+++ b/src/main/java/com/supwisdom/dlpay/device/bean/DeviceSearchBean.java
@@ -6,7 +6,24 @@
     private Integer id;
     private String devicename;
     private String factoryid;
+    private Integer devgroupid;
+    private String devphyid;
 
+    public String getDevphyid() {
+        return devphyid;
+    }
+
+    public void setDevphyid(String devphyid) {
+        this.devphyid = devphyid;
+    }
+
+    public Integer getDevgroupid() {
+        return devgroupid;
+    }
+
+    public void setDevgroupid(Integer devgroupid) {
+        this.devgroupid = devgroupid;
+    }
 
     public Integer getId() {
         return id;
diff --git a/src/main/java/com/supwisdom/dlpay/device/controller/DeviceController.java b/src/main/java/com/supwisdom/dlpay/device/controller/DeviceController.java
index 1128e8b..61d958d 100644
--- a/src/main/java/com/supwisdom/dlpay/device/controller/DeviceController.java
+++ b/src/main/java/com/supwisdom/dlpay/device/controller/DeviceController.java
@@ -2,6 +2,7 @@
 
 
 import com.google.gson.Gson;
+import com.supwisdom.dlpay.api.bean.BaseResp;
 import com.supwisdom.dlpay.api.bean.JsonResult;
 import com.supwisdom.dlpay.area.bean.AreaSearchBean;
 import com.supwisdom.dlpay.area.domain.TArea;
@@ -9,6 +10,7 @@
 import com.supwisdom.dlpay.device.bean.DeviceSearchBean;
 import com.supwisdom.dlpay.device.domain.TDevice;
 import com.supwisdom.dlpay.device.service.DeviceService;
+import com.supwisdom.dlpay.framework.util.ExportExcel;
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.framework.util.WebConstant;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -17,7 +19,10 @@
 import org.springframework.ui.Model;
 import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -83,4 +88,40 @@
             return JsonResult.error("操作失败");
         }
     }
+
+    @GetMapping("/loadimport")
+   /* @PreAuthorize("hasPermission('/device/loadimport','')")*/
+    public String loadimport(Model model) {
+        return "device/import";
+    }
+
+
+    @RequestMapping("/download")
+    @PreAuthorize("hasPermission('/device/download','')")
+    @ResponseBody
+    public JsonResult downloadfile(HttpServletRequest request, HttpServletResponse response) throws Exception{
+        String[] titles0 = {"设备物理ID",	"设备厂商",	"所属商户ID"
+        }; //表头
+        String[][] info0 = {{"30F32B1C",	"XKP",	"3000000"
+        }}; // 示例内容
+        String fileName0 = "设备导入模板";// 保存数据
+
+        try {
+            ExportExcel.queryexcel(fileName0, titles0,info0,request, response);
+            return JsonResult.ok("操作成功");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return JsonResult.error("操作失败");
+    }
+
+    @PostMapping("/import")
+    @PreAuthorize("hasPermission('/device/import','')")
+    @ResponseBody
+    public JsonResult importFile(@RequestParam(value = "file",required = false) MultipartFile file, HttpServletRequest request) throws Exception{
+//    System.out.println("---------under the upload file:"+file);
+        return deviceService.importFile(file,request);
+    }
+
+
 }
diff --git a/src/main/java/com/supwisdom/dlpay/device/controller/DeviceGroupController.java b/src/main/java/com/supwisdom/dlpay/device/controller/DeviceGroupController.java
index cecb0f7..1b1923c 100644
--- a/src/main/java/com/supwisdom/dlpay/device/controller/DeviceGroupController.java
+++ b/src/main/java/com/supwisdom/dlpay/device/controller/DeviceGroupController.java
@@ -4,9 +4,12 @@
 import com.supwisdom.dlpay.api.bean.JsonResult;
 import com.supwisdom.dlpay.device.bean.DeviceSearchBean;
 import com.supwisdom.dlpay.device.domain.TDevice;
+import com.supwisdom.dlpay.device.domain.TDeviceGroup;
+import com.supwisdom.dlpay.device.service.DeviceGroupService;
 import com.supwisdom.dlpay.device.service.DeviceService;
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.framework.util.WebConstant;
+import com.supwisdom.dlpay.system.bean.ZTreeNode;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.stereotype.Controller;
@@ -14,12 +17,16 @@
 import org.springframework.ui.ModelMap;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.List;
+
 @Controller
 @RequestMapping("/devicegroup")
 public class DeviceGroupController {
 
     @Autowired
     private DeviceService deviceService;
+    @Autowired
+    private DeviceGroupService groupService;
 
     @RequestMapping("/index")
     public String indexView(ModelMap model) {
@@ -27,8 +34,8 @@
         return "devicegroup/index";
     }
 
-    @RequestMapping("/list")
-    @PreAuthorize("hasPermission('/devicegroup/index','')")
+    @RequestMapping("/listDevice")
+    @PreAuthorize("hasPermission('/devicegroup/listDevice','')")
     @ResponseBody
     public PageResult<TDevice> getDataList(@RequestParam("page") Integer pageNo,
                                          @RequestParam("limit") Integer pageSize,
@@ -38,9 +45,22 @@
             if (null == pageSize || pageSize < 1) pageSize = WebConstant.PAGESIZE_DEFAULT;
             DeviceSearchBean searchBean = new DeviceSearchBean();
             searchBean.setPageNo(pageNo);
-            searchBean.setId(searchKey);
+            searchBean.setDevgroupid(searchKey);
             searchBean.setPageSize(pageSize);
-            return deviceService.getDeviceByKey(searchBean);
+            System.out.println(searchKey+"&&&&");
+            return deviceService.getDeviceByGroupId(searchBean);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new PageResult<>(99, "系统查询错误");
+        }
+    }
+
+    @RequestMapping("/listTree")
+    @PreAuthorize("hasPermission('/devicegroup/listTree','')")
+    @ResponseBody
+    public PageResult<ZTreeNode> listTree()  {
+        try {
+            return groupService.getDeviceGroupTree();
         } catch (Exception e) {
             e.printStackTrace();
             return new PageResult<>(99, "系统查询错误");
@@ -51,19 +71,28 @@
     @GetMapping("/loadadd")
     @PreAuthorize("hasPermission('/devicegroup/loadadd','')")
     public String loadadd(Model model) {
+        List<TDeviceGroup> list=groupService.findAll();
+        model.addAttribute("grouplist",list);
+
         return "devicegroup/form";
     }
 
     @PostMapping("/add")
     @PreAuthorize("hasPermission('/devicegroup/add','')")
     @ResponseBody
-    public JsonResult add(@RequestBody TDevice device) {
-        if (device != null) {
-            return deviceService.saveDevice(device);
+    public JsonResult add(@RequestBody TDeviceGroup group) {
+        if (group != null) {
+            return groupService.saveGroup(group);
         } else {
-            return JsonResult.error("添加失败");
+            return JsonResult.error("失败");
         }
     }
 
+    @PostMapping("/delete")
+    @PreAuthorize("hasPermission('/devicegroup/delete','')")
+    @ResponseBody
+    public JsonResult delete(@RequestParam("id") Integer id) {
+        return groupService.delete(id);
+    }
 
 }
diff --git a/src/main/java/com/supwisdom/dlpay/device/controller/DeviceManageController.java b/src/main/java/com/supwisdom/dlpay/device/controller/DeviceManageController.java
new file mode 100644
index 0000000..d166494
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/device/controller/DeviceManageController.java
@@ -0,0 +1,76 @@
+package com.supwisdom.dlpay.device.controller;
+
+
+import com.supwisdom.dlpay.api.bean.JsonResult;
+import com.supwisdom.dlpay.device.bean.DeviceSearchBean;
+import com.supwisdom.dlpay.device.domain.TDevice;
+import com.supwisdom.dlpay.device.service.DeviceService;
+import com.supwisdom.dlpay.framework.util.ExportExcel;
+import com.supwisdom.dlpay.framework.util.PageResult;
+import com.supwisdom.dlpay.framework.util.WebConstant;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Controller
+@RequestMapping("/devicemanage")
+public class DeviceManageController {
+
+    @Autowired
+    private DeviceService deviceService;
+
+    @RequestMapping("/index")
+    public String indexView(ModelMap model) {
+
+        return "devicemanage/index";
+    }
+
+    @RequestMapping("/list")
+    @PreAuthorize("hasPermission('/devicemanage/index','')")
+    @ResponseBody
+    public PageResult<TDevice> getDataList(@RequestParam("page") Integer pageNo,
+                                         @RequestParam("limit") Integer pageSize,
+                                         @RequestParam(value = "searchkey", required = false) Integer searchKey) {
+        try {
+            if (null == pageNo || pageNo < 1) pageNo = WebConstant.PAGENO_DEFAULT;
+            if (null == pageSize || pageSize < 1) pageSize = WebConstant.PAGESIZE_DEFAULT;
+            DeviceSearchBean searchBean = new DeviceSearchBean();
+            searchBean.setPageNo(pageNo);
+            searchBean.setId(searchKey);
+            searchBean.setPageSize(pageSize);
+            return deviceService.getDeviceByKey(searchBean);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new PageResult<>(99, "系统查询错误");
+        }
+    }
+
+
+    @GetMapping("/loadupdate")
+    @PreAuthorize("hasPermission('/devicemanage/loadupdate','')")
+    public String loadadd(Model model) {
+        return "device/form";
+    }
+
+
+
+    @PostMapping("/update")
+    @PreAuthorize("hasPermission('/devicemanage/update','')")
+    @ResponseBody
+    public JsonResult updatestate(@RequestBody TDevice device) {
+        if (device != null) {
+            return deviceService.saveDevice(device);
+        } else {
+            return JsonResult.error("失败");
+        }
+    }
+
+
+}
diff --git a/src/main/java/com/supwisdom/dlpay/device/dao/DeviceDao.java b/src/main/java/com/supwisdom/dlpay/device/dao/DeviceDao.java
index 4765033..5af40fb 100644
--- a/src/main/java/com/supwisdom/dlpay/device/dao/DeviceDao.java
+++ b/src/main/java/com/supwisdom/dlpay/device/dao/DeviceDao.java
@@ -6,6 +6,7 @@
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Query;
 import org.springframework.stereotype.Repository;
 
 @Repository
@@ -13,7 +14,13 @@
 
     Page<TDevice> findAllByIdContaining(Integer id, Pageable pageable);
 
+    Page<TDevice> findAllByDevgroupid(Integer devgroupid, Pageable pageable);
 
 
+    @Query("select count(*) from TDevice t where t.devgroupid =:id and t.state=0")
+    Integer countByDevgroupid(Integer Devgroupid);
+
+    Integer countByDevphyid(String devphyid);
+
     TDevice findByDevicename(String devicename);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/device/dao/DeviceGroupDao.java b/src/main/java/com/supwisdom/dlpay/device/dao/DeviceGroupDao.java
index 2171bbd..446deda 100644
--- a/src/main/java/com/supwisdom/dlpay/device/dao/DeviceGroupDao.java
+++ b/src/main/java/com/supwisdom/dlpay/device/dao/DeviceGroupDao.java
@@ -2,6 +2,21 @@
 
 import com.supwisdom.dlpay.device.domain.TDeviceGroup;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.transaction.annotation.Transactional;
+
 
 public interface DeviceGroupDao  extends  JpaRepository<TDeviceGroup, Integer> {
+
+/*    @Modifying
+    @Transactional
+    @Query("delete from TDeviceGroup where devgroupid =:id or pid=:id")
+    int deleteByQuery(@Param("id") Integer id);*/
+
+    int deleteByDevgroupid(Integer Devgroupid);
+
+
+    Integer countByPid(Integer Devgroupid);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/device/dao/impl/DeviceDaoImpl.java b/src/main/java/com/supwisdom/dlpay/device/dao/impl/DeviceDaoImpl.java
new file mode 100644
index 0000000..9dea9d7
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/device/dao/impl/DeviceDaoImpl.java
@@ -0,0 +1,12 @@
+package com.supwisdom.dlpay.device.dao.impl;
+
+import com.supwisdom.dlpay.device.dao.DeviceDao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+public class DeviceDaoImpl {
+    @PersistenceContext
+    EntityManager manager;
+
+}
diff --git a/src/main/java/com/supwisdom/dlpay/device/domain/TDevice.java b/src/main/java/com/supwisdom/dlpay/device/domain/TDevice.java
index 4f74f73..fd23fcb 100644
--- a/src/main/java/com/supwisdom/dlpay/device/domain/TDevice.java
+++ b/src/main/java/com/supwisdom/dlpay/device/domain/TDevice.java
@@ -9,12 +9,11 @@
     private Integer id;
     private String devicename;
     private String devphyid;
-   // private String termid;
     private Integer shopid;
     private String factoryid;
     private Integer state;
     private String operid;
-    private String devgroupid;
+    private Integer devgroupid;
     private String lastsaved;
 
     @Id
@@ -89,11 +88,11 @@
     }
 
     @Column(name = "devgroupid", length = 30)
-    public String getDevgroupid() {
+    public Integer getDevgroupid() {
         return devgroupid;
     }
 
-    public void setDevgroupid(String devgroupid) {
+    public void setDevgroupid(Integer devgroupid) {
         this.devgroupid = devgroupid;
     }
     @Column(name = "lastsaved", length = 14)
diff --git a/src/main/java/com/supwisdom/dlpay/device/domain/TDeviceGroup.java b/src/main/java/com/supwisdom/dlpay/device/domain/TDeviceGroup.java
index 172ca1f..4218ffd 100644
--- a/src/main/java/com/supwisdom/dlpay/device/domain/TDeviceGroup.java
+++ b/src/main/java/com/supwisdom/dlpay/device/domain/TDeviceGroup.java
@@ -5,13 +5,14 @@
 
 @Entity
 @Table(name = "TB_DEVICEGROUP")
-@SequenceGenerator(name="SEQ_DEVGROUP",sequenceName="SEQ_DEVGROUP",allocationSize=1)
+@SequenceGenerator(name = "SEQ_DEVGROUP", sequenceName = "SEQ_DEVGROUP", allocationSize = 1)
 public class TDeviceGroup {
     private Integer devgroupid;
     private String groupname;
+    private Integer pid;
 
     @Id
-    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_DEVGROUP")
+    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_DEVGROUP")
     @Column(name = "devgroupid", unique = true, nullable = false, length = 8)
     public Integer getDevgroupid() {
         return devgroupid;
@@ -20,6 +21,7 @@
     public void setDevgroupid(Integer devgroupid) {
         this.devgroupid = devgroupid;
     }
+
     @Column(name = "groupname", length = 60)
     public String getGroupname() {
         return groupname;
@@ -28,4 +30,13 @@
     public void setGroupname(String groupname) {
         this.groupname = groupname;
     }
+
+    @Column(name = "pid", length = 8)
+    public Integer getPid() {
+        return pid;
+    }
+
+    public void setPid(Integer pid) {
+        this.pid = pid;
+    }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/device/service/DeviceGroupService.java b/src/main/java/com/supwisdom/dlpay/device/service/DeviceGroupService.java
new file mode 100644
index 0000000..5d914eb
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/device/service/DeviceGroupService.java
@@ -0,0 +1,26 @@
+package com.supwisdom.dlpay.device.service;
+
+import com.supwisdom.dlpay.api.bean.JsonResult;
+import com.supwisdom.dlpay.device.domain.TDeviceGroup;
+import com.supwisdom.dlpay.framework.util.PageResult;
+import com.supwisdom.dlpay.system.bean.ZTreeNode;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+public interface DeviceGroupService {
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
+    PageResult<ZTreeNode> getDeviceGroupTree( );
+
+    List<TDeviceGroup> findAll();
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+    JsonResult saveGroup(TDeviceGroup device);
+
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+    JsonResult delete(Integer id);
+
+
+}
diff --git a/src/main/java/com/supwisdom/dlpay/device/service/DeviceService.java b/src/main/java/com/supwisdom/dlpay/device/service/DeviceService.java
index 7673b73..5a15d0a 100644
--- a/src/main/java/com/supwisdom/dlpay/device/service/DeviceService.java
+++ b/src/main/java/com/supwisdom/dlpay/device/service/DeviceService.java
@@ -7,7 +7,9 @@
 import com.supwisdom.dlpay.framework.util.PageResult;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 public interface DeviceService {
@@ -15,6 +17,14 @@
     PageResult<TDevice> getDeviceByKey(DeviceSearchBean param);
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
+    PageResult<TDevice> getDeviceByParam(DeviceSearchBean param);
+
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
+    PageResult<TDevice> getDeviceByGroupId(DeviceSearchBean param);
+
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
     List<TDevice> findAll();
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
@@ -22,4 +32,8 @@
 
     @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
     boolean updateState(Integer id,Integer state);
+
+
+    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+    JsonResult importFile(MultipartFile file, HttpServletRequest request) throws Exception;
 }
diff --git a/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceGroupServiceImpl.java b/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceGroupServiceImpl.java
new file mode 100644
index 0000000..b8770b7
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceGroupServiceImpl.java
@@ -0,0 +1,71 @@
+package com.supwisdom.dlpay.device.service.impl;
+
+import com.supwisdom.dlpay.api.bean.JsonResult;
+import com.supwisdom.dlpay.device.dao.DeviceDao;
+import com.supwisdom.dlpay.device.dao.DeviceGroupDao;
+import com.supwisdom.dlpay.device.domain.TDeviceGroup;
+import com.supwisdom.dlpay.device.service.DeviceGroupService;
+import com.supwisdom.dlpay.framework.util.PageResult;
+import com.supwisdom.dlpay.system.bean.ZTreeNode;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class DeviceGroupServiceImpl implements DeviceGroupService {
+    @Autowired
+    private DeviceGroupDao groupDao;
+    @Autowired
+    private DeviceDao deviceDao;
+
+    @Override
+    public PageResult<ZTreeNode> getDeviceGroupTree() {
+        List<TDeviceGroup> groups=groupDao.findAll();
+        List<ZTreeNode> zlist=new ArrayList<>();
+        for(TDeviceGroup g:groups){
+            ZTreeNode z=new ZTreeNode();
+            z.setId(g.getDevgroupid().toString());
+            z.setName(g.getGroupname());
+            if(g.getPid()==null){
+                z.setpId("0");
+            }else{
+                z.setpId(g.getPid().toString());
+            }
+
+            z.setChecked(false);
+            z.setOpen(true);
+            zlist.add(z);
+        }
+        PageResult<ZTreeNode> p=new PageResult<>(zlist);
+        p.setCode(0);
+        return p;
+    }
+
+    @Override
+    public List<TDeviceGroup> findAll(){
+        return groupDao.findAll();
+    }
+
+    @Override
+    public JsonResult saveGroup(TDeviceGroup device){
+        groupDao.save(device);
+        return JsonResult.ok("成功");
+    }
+
+    @Override
+    public JsonResult delete(Integer id) {
+        if(deviceDao.countByDevgroupid(id)>0){
+            return JsonResult.error("不能删除有正常设备的设备组");
+        }
+        if(groupDao.countByPid(id)>0){
+            return JsonResult.error("不能删除含有子节点的设备组");
+        }
+        if(groupDao.deleteByDevgroupid(id)<=0){
+            return  JsonResult.error("删除失败");
+        }
+        return  JsonResult.ok("删除成功");
+    }
+
+}
diff --git a/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceServiceImpl.java b/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceServiceImpl.java
index efef7b0..b2104a6 100644
--- a/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/device/service/impl/DeviceServiceImpl.java
@@ -7,17 +7,25 @@
 import com.supwisdom.dlpay.device.domain.TDevice;
 import com.supwisdom.dlpay.device.domain.TShopDevice;
 import com.supwisdom.dlpay.device.service.DeviceService;
-import com.supwisdom.dlpay.framework.domain.TOperator;
+import com.supwisdom.dlpay.framework.dao.ShopSettlementDao;
 import com.supwisdom.dlpay.framework.security.OperUtil;
+import com.supwisdom.dlpay.framework.util.ImportExcelUtil;
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.framework.util.StringUtil;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.persistence.criteria.*;
+import javax.servlet.http.HttpServletRequest;
+import java.io.InputStream;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Optional;
 
 @Service
@@ -26,9 +34,11 @@
     private DeviceDao deviceDao;
     @Autowired
     private ShopDeviceDao shopDeviceDao;
+    @Autowired
+    private ShopSettlementDao shopSettlementDao;
 
-    /*    @Override
-        public PageResult<TDevice> getDeviceByKey(DeviceSearchBean param) {
+        @Override
+        public PageResult<TDevice> getDeviceByParam(DeviceSearchBean param) {
             Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
                     , Sort.by("id"));
 
@@ -40,29 +50,42 @@
                     if (!StringUtil.isEmpty(param.getDevicename())) {
                         list.add(cb.like(root.get("devicename").as(String.class), "%" + param.getDevicename() + "%"));
                     }
-
+                    if (!StringUtil.isEmpty(param.getDevphyid())) {
+                        list.add(cb.like(root.get("devphyid").as(String.class), "%" + param.getDevphyid() + "%"));
+                    }
                     if (!StringUtil.isEmpty(param.getFactoryid())) {
                         list.add(cb.equal(root.get("factoryid").as(String.class), param.getFactoryid()));
                     }
-                    if (!StringUtil.isEmpty(param.getTermid())) {
-                        list.add(cb.like(root.get("termid").as(String.class), param.getTermid()));
+                    if (null!=param.getId()) {
+                        list.add(cb.like(root.get("id").as(String.class), param.getId().toString()));
                     }
+
                     return cb.and(list.toArray(new Predicate[list.size()]));
                 }
             };
 
             return new PageResult<>(deviceDao.findAll(spec, pageable));
-        }*/
+        }
     @Override
     public PageResult<TDevice> getDeviceByKey(DeviceSearchBean param) {
         Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
                 , Sort.by("id"));
-        if (null !=param.getId()) {
+        if (null != param.getId()) {
             return new PageResult<>(deviceDao.findAllByIdContaining(param.getId(), pageable));
         }
         return new PageResult<>(deviceDao.findAll(pageable));
     }
 
+    @Override
+    public PageResult<TDevice> getDeviceByGroupId(DeviceSearchBean param) {
+        Pageable pageable = PageRequest.of(param.getPageNo() - 1, param.getPageSize()
+                , Sort.by("id"));
+        if (null != param.getDevgroupid()) {
+            return new PageResult<>(deviceDao.findAllByDevgroupid(param.getDevgroupid(), pageable));
+        }
+        return new PageResult<>(deviceDao.findAll(pageable));
+    }
+
 
     @Override
     public List<TDevice> findAll() {
@@ -71,11 +94,15 @@
 
     @Override
     public JsonResult saveDevice(TDevice device) {
-        if(null==device.getState()){
+        if(shopSettlementDao.countByShopid(device.getShopid())==0){
+            return JsonResult.error("商户不存在");
+        }
+        if (null == device.getState()) {
             device.setState(1);
         }
-        TDevice d=deviceDao.save(device);
-        TShopDevice shopDevice=new TShopDevice();
+
+        TDevice d = deviceDao.save(device);
+        TShopDevice shopDevice = new TShopDevice();
         shopDevice.setDeviceid(d.getId());
         shopDevice.setShopid(d.getShopid());
         shopDevice.setOperid(OperUtil.getCurrentOperid());
@@ -97,4 +124,58 @@
     }
 
 
+    @Override
+    public JsonResult importFile(MultipartFile file, HttpServletRequest request) throws Exception {
+        String fname = file.getOriginalFilename();
+        if (!fname.endsWith(".xls") && !fname.endsWith(".xlsx")) {
+
+            return JsonResult.error("文件格式错误,请选择excel文件格式(.xls/.xlsx)");
+        }
+
+        List<TDevice> sList = new ArrayList<>();
+//    InputStream excelstream = new FileInputStream(savePath+"/"+fname);
+        InputStream excelstream = file.getInputStream();
+        List<Object[][]> oList = null;
+        if (fname.endsWith(".xls")) {
+            oList = ImportExcelUtil.getIntegralData(excelstream);//2003版本
+        } else {
+            oList = ImportExcelUtil.getIntegralData07(excelstream);//2007版本以上
+        }
+
+        String msg = "";
+        for (Object[][] data : oList) {
+            for (int i = 1; i < data.length; i++) {
+
+                if (StringUtil.isEmpty((String) data[i][0]) || StringUtil.isEmpty((String) data[i][1]) || StringUtil.isEmpty((String) data[i][2])) {
+                    msg = msg + "第" + i + "行,关键字段缺失。<br/>";
+                } else if (deviceDao.countByDevphyid((String) data[i][0]) >0) {
+                    msg = msg + "第" + i + "行,设备已存在。<br/>";
+                } else if (shopSettlementDao.countByShopid(Integer.parseInt((String) data[i][2]))==0){
+                    msg = msg + "第" + i + "行,商户不存在。<br/>";
+                }
+                else{
+                    TDevice d=new TDevice();
+                    d.setDevicename((String) data[i][0]);
+                    d.setDevphyid((String) data[i][0]);
+                    d.setFactoryid((String) data[i][1]);
+                    d.setShopid(Integer.parseInt((String) data[i][2]));
+                    sList.add(d);
+                }
+            }
+        }
+        /*resp.setCode(Code.SUCCESS);
+        // resp.setMsg("成功导入了"+sList.size()+"条信息");
+        resp.setMsg(String.format(Locale.CHINESE, msg));
+        return resp;*/
+        if(StringUtil.isEmpty(msg)){
+            for(TDevice d:sList){
+                saveDevice(d);
+            }
+
+            return JsonResult.ok("成功导入"+sList.size()+"条信息");
+        }
+        return JsonResult.error(String.format(Locale.CHINESE, msg));
+    }
+
+
 }
diff --git a/src/main/java/com/supwisdom/dlpay/framework/dao/ShopSettlementDao.java b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopSettlementDao.java
new file mode 100644
index 0000000..aa132f1
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/dao/ShopSettlementDao.java
@@ -0,0 +1,11 @@
+package com.supwisdom.dlpay.framework.dao;
+
+import com.supwisdom.dlpay.framework.domain.TShopSettlement;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+
+@Repository
+public interface ShopSettlementDao extends JpaRepository<TShopSettlement, String> {
+    int countByShopid(Integer shopid);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/domain/TShopSettlement.java b/src/main/java/com/supwisdom/dlpay/framework/domain/TShopSettlement.java
new file mode 100644
index 0000000..03a0faf
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/domain/TShopSettlement.java
@@ -0,0 +1,54 @@
+package com.supwisdom.dlpay.framework.domain;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "TB_SHOPSettlement")
+public class TShopSettlement {
+  @Id
+  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_SETTLEMENT")
+  @Column(name="SHOPSettlementno",unique = true, nullable = false, length = 9)
+  private String SHOPSettlementno;
+
+  @Column(name="SHOPID", precision = 9)
+  private Integer shopid;
+
+  @Column(name="SHOPNAME", length = 200)
+  private String shopname;
+
+  @Column(name="operno", length = 40)
+  private String operno;
+
+
+  public String getSHOPSettlementno() {
+    return SHOPSettlementno;
+  }
+
+  public void setSHOPSettlementno(String SHOPSettlementno) {
+    this.SHOPSettlementno = SHOPSettlementno;
+  }
+
+  public Integer getShopid() {
+    return shopid;
+  }
+
+  public void setShopid(Integer shopid) {
+    this.shopid = shopid;
+  }
+
+  public String getShopname() {
+    return shopname;
+  }
+
+  public void setShopname(String shopname) {
+    this.shopname = shopname;
+  }
+
+  public String getOperno() {
+    return operno;
+  }
+
+  public void setOperno(String operno) {
+    this.operno = operno;
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/ExportExcel.java b/src/main/java/com/supwisdom/dlpay/framework/util/ExportExcel.java
new file mode 100644
index 0000000..02a1604
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/ExportExcel.java
@@ -0,0 +1,216 @@
+package com.supwisdom.dlpay.framework.util;
+
+import org.apache.poi.hssf.usermodel.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.OutputStream;
+
+public class ExportExcel {
+
+	/**
+	 * Excel导出数据
+	 */
+	public static void queryexcel(String filename, String[] titles, String[][] info, HttpServletRequest request, HttpServletResponse response)
+			throws Exception {
+//		String path = KSConfiguration.getInstance().getClass().getResource("/").getPath();
+		String path= Thread.currentThread().getContextClassLoader().getResource("").getPath();
+		path=path+"download/";
+//		System.out.println("----excel path:"+path);
+		File inFile=new File(path+filename+".xls");
+		if(inFile.exists()){
+//			System.out.println("---file exist---");
+			try {
+				response.setContentType("application/x-msdownload");
+				response.setHeader("Content-Disposition", "attachment;" + " filename="
+						+ new String(filename.getBytes(), "ISO-8859-1") + ".xls");
+				OutputStream out = response.getOutputStream();
+				FileInputStream inStream = new FileInputStream(inFile);
+				byte[] inOutb = new byte[inStream.available()];
+				inStream.read(inOutb);
+				out.write(inOutb);
+				out.flush();
+				inStream.close();
+				out.close();
+//				System.out.println("---before return---");
+				return;
+			} catch (Exception e) {
+//				System.out.println("---输出失败---");
+				e.printStackTrace();
+			}
+		}
+//		System.out.println("---file not exist---");
+		
+		HSSFWorkbook workbook = null;
+		// 读取表头(表字段名)
+//		String[] titles = (String[]) request.getAttribute("titles");
+//		// 读取数据库数据
+//		String[][] info = (String[][]) request.getAttribute("info");
+		// 创建工作簿实例
+		workbook = new HSSFWorkbook();
+		HSSFSheet sheet = workbook.createSheet("sheet1");
+		workbook.getSheet(null);
+
+		HSSFFont font = workbook.createFont();
+		font.setFontName(HSSFFont.FONT_ARIAL);
+		font.setFontHeightInPoints((short) 11);
+		//font.setBold(true);
+		HSSFCellStyle style = workbook.createCellStyle();
+		style.setFont(font);
+		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 居中
+//		style.setWrapText(true);
+		// 加载表头数据
+		
+		HSSFRow titleRow = sheet.createRow(0);
+		for (int i = 0; i < titles.length; i++) {
+			HSSFCell cell = titleRow.createCell(i);
+			cell.setCellType(HSSFCell.CELL_TYPE_STRING);
+			cell.setCellValue(titles[i]);
+			cell.setCellStyle(style);
+		}
+		if (info != null) {
+			for (int i = 0; i < info.length; i++) {
+				HSSFRow dataRow = sheet.createRow(i + 1);
+				for (int j = 0; j < info[i].length; j++) {
+					HSSFCell cell = dataRow.createCell(j);
+					sheet.setColumnWidth(j, 3500);
+					if(j==7){
+						sheet.setColumnWidth(j, 10000);
+					}
+					cell.setCellType(HSSFCell.CELL_TYPE_STRING);
+					cell.setCellValue(info[i][j]);
+				}
+			}
+		}
+//		System.out.println("---下载之前---");
+		// 通过数据流下载工作簿
+		try {
+			response.setContentType("application/x-msdownload");
+			response.setHeader("Content-Disposition", "attachment;" + " filename="
+					+ new String(filename.getBytes(), "ISO-8859-1") + ".xls");
+			OutputStream out = response.getOutputStream();
+			workbook.write(out);
+			out.flush();
+			out.close();
+//			System.out.println("---下载成功---");
+		} catch (Exception e) {
+//			System.out.println("---下载失败---");
+			e.printStackTrace();
+		}
+	}
+
+	// 中文名
+	public static String toUtf8String(String s) {
+		StringBuffer sb = new StringBuffer();
+		for (int i = 0; i < s.length(); i++) {
+			char c = s.charAt(i);
+			if (c >= 0 && c <= 255) {
+				sb.append(c);
+			} else {
+				byte[] b;
+				try {
+					b = Character.toString(c).getBytes("UTF-8");
+				} catch (Exception ex) {
+					System.out.println(ex);
+					b = new byte[0];
+				}
+				for (int j = 0; j < b.length; j++) {
+					int k = b[j];
+					if (k < 0)
+						k += 256;
+					sb.append("%" + Integer.toHexString(k).toUpperCase());
+				}
+			}
+		}
+		return sb.toString();
+	}
+
+//	public static void writeDBF(String filename, HttpServletRequest request, HttpServletResponse response)
+//			throws Exception {
+//
+//		// 读取表头(表字段名)
+//		String[] dbf_titles = (String[]) request.getAttribute("dbf_titles");
+//
+//		// 读取数据库数据
+//		String[][] info = (String[][]) request.getAttribute("info");
+//		// 创建工作簿实例
+//		DBFField[] fields = new DBFField[dbf_titles.length];
+//
+//		for (int i = 0; i < dbf_titles.length; i++) {
+//			fields[i] = new DBFField();
+//			fields[i].setName(dbf_titles[i]);
+//			fields[i].setDataType(DBFField.FIELD_TYPE_C);
+//			fields[i].setFieldLength(255);
+//		}
+//
+//		// 定义DBFWriter实例用来写DBF文件
+//		DBFWriter writer = new DBFWriter();
+//		writer.setCharactersetName("GBK");
+//		// 把字段信息写入DBFWriter实例,即定义表结构
+//		writer.setFields(fields);
+//
+//		if (info != null) {
+//			for (int i = 0; i < info.length; i++) {
+//				Object[] rowData = new Object[dbf_titles.length];
+//				for (int j = 0; j < info[i].length; j++) {
+//					rowData[j] = info[i][j];
+//				}
+//				writer.addRecord(rowData);
+//
+//			}
+//		}
+//
+//
+//		OutputStream out = response.getOutputStream();
+//		try {
+//			response.setContentType("applicationnd.ms-excel");
+//			response.setHeader("Content-Disposition", "attachment;" + " filename="
+//					+ new String(filename.getBytes(), "ISO-8859-1") + ".dbf");
+//
+//			writer.write(out);
+//
+//		} catch (Exception e) {
+//			e.printStackTrace();
+//		}finally{
+//			out.flush();
+//			out.close();
+//
+//		}
+//
+//	}
+
+	
+	 /**
+   * 检验结果Excel导出数据
+   */
+  public static void queryCheckExcel(String filename, String path, HttpServletRequest request,
+                                     HttpServletResponse response) throws Exception {
+    if (StringUtil.isEmpty(filename)) {
+      throw new Exception("Excel file name is null!");
+    }
+
+    File inFile = new File(path, filename + ".xls");
+    if (inFile.exists()) {
+      try {
+        response.setContentType("application/x-msdownload");
+        response.setHeader("Content-Disposition", "attachment;" + " filename="
+            + new String(filename.getBytes(), "ISO-8859-1") + ".xls");
+        OutputStream out = response.getOutputStream();
+        FileInputStream inStream = new FileInputStream(inFile);
+        byte[] inOutb = new byte[inStream.available()];
+        inStream.read(inOutb);
+        out.write(inOutb);
+        out.flush();
+        inStream.close();
+        out.close();
+        return;
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    } else {
+      throw new Exception("Excel file not exist!");
+    }
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java
new file mode 100644
index 0000000..eb601d2
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java
@@ -0,0 +1,376 @@
+/**
+ * 
+ */
+package com.supwisdom.dlpay.framework.util;
+
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.hssf.usermodel.*;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.OPCPackage;
+import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFCell;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class ImportExcelUtil {
+    static SimpleDateFormat sFormat = new SimpleDateFormat("yyyyMMdd");
+    /**
+     * @param excelFile
+     * @return
+     * @throws IOException
+     * @throws InvalidFormatException
+     */
+    public static Workbook createCommonWb(InputStream excelFile) throws Exception {
+
+        if (excelFile.markSupported()) {
+            excelFile = new PushbackInputStream(excelFile, 8);
+        }
+        if (POIFSFileSystem.hasPOIFSHeader(excelFile)) {//2003
+            return (Workbook) new HSSFWorkbook(excelFile);
+        }
+        else
+        	if (POIXMLDocument.hasOOXMLHeader(excelFile)) {//2007
+            return new XSSFWorkbook(OPCPackage.open(excelFile));
+        }
+        	else {
+        	System.out.println("其他版本");
+            return null;
+        }
+
+    }
+
+    /**
+     *
+     * @param inp
+     * @return
+     * @throws InvalidFormatException
+     * @throws IOException
+     */
+    public static Object[][] getBackWbData(InputStream inp)
+            throws Exception, IOException {
+
+        Workbook wb = createCommonWb(inp);
+        return getBackWbData(wb);
+
+    }
+
+    /**
+     * ͨ��sheetName
+     *
+     * @param wb
+     * @param column
+     * @param sheetName
+     * @return
+     */
+
+    public static Object[][] getBackWbData(Workbook wb, int column,
+                                           String sheetName) {
+
+        Sheet sheet = wb.getSheet(sheetName);
+        return getData(column, sheet);
+    }
+
+    /**
+     *
+     * @param wb
+     * @param column
+     * @param sheetNum
+     * @return
+     */
+    public static Object[][] getBackWbData(Workbook wb, int column, int sheetNum) {
+
+        Sheet sheet = wb.getSheetAt(sheetNum);
+        return getData(column, sheet);
+    }
+
+    /**
+     * sheet
+     *
+     * @param wb
+     * @param column
+     * @return
+     */
+
+    public static Object[][] getBackWbData(Workbook wb, int column) {
+
+        return getBackWbData(wb, column, 0);
+    }
+
+    /**
+     * sheet
+     *
+     * @param wb
+     * @return
+     */
+    public static Object[][] getBackWbData(Workbook wb) {
+
+        return getBackWbData(wb, wb.getSheetAt(0).getRow(0).getLastCellNum());
+
+    }
+
+    /**
+     * @param column
+     * @param sheet
+     * @return
+     */
+    private static Object[][] getData(int column, Sheet sheet) {
+        Object data[][] = new String[sheet.getLastRowNum()][column];
+        for (int i = 0; i < sheet.getLastRowNum(); i++) {
+            Row row = sheet.getRow(i);
+            for (int j = 0; j < row.getLastCellNum(); j++) {
+                data[i][j] = getCellFormatValue(row.getCell(j));
+            }
+        }
+        return data;
+    }
+
+    /**
+     * Cell
+     *
+     * @param cell
+     * @return
+     */
+    private static String getCellFormatValue(Cell cell) {
+        String cellvalue = "";
+        if (cell != null) {
+            switch (cell.getCellType()) {
+            case Cell.CELL_TYPE_NUMERIC:
+            case Cell.CELL_TYPE_FORMULA: {
+
+                if ( cell instanceof Date) {
+                    // cellvalue = cell.getDateCellValue().toLocaleString();
+                    Date date = cell.getDateCellValue();
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
+                    cellvalue = sdf.format(date);
+                }
+                else {
+                    cellvalue = String.valueOf(cell.getNumericCellValue());
+                }
+                break;
+            }
+            case Cell.CELL_TYPE_STRING:
+                cellvalue = cell.getRichStringCellValue().getString();
+                break;
+            default:
+                cellvalue = " ";
+            }
+        } else {
+            cellvalue = "";
+        }
+        return cellvalue;
+
+    }
+
+    /**
+     *
+     * @param inp
+     * @return
+     * @throws InvalidFormatException
+     * @throws IOException
+     */
+    //@SuppressWarnings("deprecation")
+    public static Object[][] getWbData(InputStream inp)
+            throws Exception, IOException {
+        POIFSFileSystem fs = new POIFSFileSystem(inp);
+        HSSFWorkbook wb = new HSSFWorkbook(fs);
+        HSSFSheet sheet = wb.getSheetAt(0);
+        Iterator<Row> rows = sheet.rowIterator();
+        int coloumNum = sheet.getRow(0).getPhysicalNumberOfCells();// ���������
+        Object data[][] = new Object[sheet.getLastRowNum() + 1][coloumNum];
+        while (rows.hasNext()) {
+            HSSFRow row = (HSSFRow) rows.next();
+            Iterator<Cell> cells = row.cellIterator();
+            while (cells.hasNext()) {
+                HSSFCell cell = (HSSFCell) cells.next();
+                switch (cell.getCellType()) {
+                case HSSFCell.CELL_TYPE_NUMERIC:
+                    DecimalFormat df = new DecimalFormat("0");
+                    String numberCode = df.format(cell.getNumericCellValue());
+                    data[row.getRowNum()][cell.getCellNum()] = numberCode;
+                    break;
+                case HSSFCell.CELL_TYPE_STRING:
+                    data[row.getRowNum()][cell.getCellNum()] = cell
+                            .getStringCellValue();
+                    break;
+                case HSSFCell.CELL_TYPE_BOOLEAN:
+                    data[row.getRowNum()][cell.getCellNum()] = cell
+                            .getBooleanCellValue();
+                    break;
+                case HSSFCell.CELL_TYPE_FORMULA:
+                    data[row.getRowNum()][cell.getCellNum()] = cell
+                            .getCellFormula();
+                    break;
+                default:
+                    data[row.getRowNum()][cell.getCellNum()] = "";
+                    break;
+                }
+            }
+        }
+        return data;
+    }
+
+    /**
+     * @return��List<Object[][]>  oList
+     * @param��InputStream excelFile
+     * @Description:check Input Stream
+     */
+    public static List<Object[][]> checkInputStream(InputStream excelFile) {
+
+    	try{
+    		if (!excelFile.markSupported()) {//������Ĵ�
+        	excelFile = new PushbackInputStream(excelFile, 8);
+        }
+//        if (POIFSFileSystem.hasPOIFSHeader(excelFile)) {
+//        	List<Object[][]> oList= ImportExcelUtil.getIntegralData(excelFile);
+//        	return oList;
+//        } else
+        	if (POIXMLDocument.hasOOXMLHeader(excelFile)) {
+        	List<Object[][]> oList=ImportExcelUtil.getIntegralData07(excelFile);
+        	return oList;
+        }
+        	}catch(IOException e){
+//        		System.out.print("999999999 The error is::::");
+        		e.printStackTrace();
+        	} catch (Exception e) {
+				// TODO Auto-generated catch block
+        		System.out.print("999999999 The error is::::");
+				e.printStackTrace();
+			}
+
+		return null;
+    }
+
+    /**
+     * @return�� List<Object[][]> oList
+     * @param��InputStream excelFile
+     * @Description:excel03 import
+     */
+    @SuppressWarnings({ "rawtypes", "deprecation" })
+	public static List<Object[][]> getIntegralData(InputStream excelFile)throws Exception {
+
+		POIFSFileSystem fs = new POIFSFileSystem(excelFile);
+        HSSFWorkbook wb = new HSSFWorkbook(fs);
+        List<Object[][]> oList = new ArrayList<Object[][]>();
+
+        HSSFSheet sheet = wb.getSheetAt(0);
+	        Iterator rows = sheet.rowIterator();
+	        int coloumNum = sheet.getRow(0).getPhysicalNumberOfCells();
+//	        System.out.println("66666 coloumNum:::"+coloumNum);
+	        Object data[][] = new Object[sheet.getLastRowNum() + 1][coloumNum];
+	        while (rows.hasNext()) {
+	            HSSFRow row = (HSSFRow) rows.next();
+	            Iterator cells = row.cellIterator();
+
+	            while (cells.hasNext()) {
+	                HSSFCell cell = (HSSFCell) cells.next();
+
+                    //默认设置前三个字段为string类型
+	                for(int i=0;i<=2;i++){
+	                HSSFCell cell1 = row.getCell(i);
+	                cell1.setCellType(HSSFCell.CELL_TYPE_STRING);
+	                }
+
+	                switch (cell.getCellType()) {
+	                case HSSFCell.CELL_TYPE_NUMERIC:
+	                        data[row.getRowNum()][cell.getCellNum()] = (long)cell.
+	                        getNumericCellValue();
+	                    break;
+	                case HSSFCell.CELL_TYPE_STRING:
+	                    data[row.getRowNum()][cell.getCellNum()] = cell
+	                            .getStringCellValue();
+	                    break;
+	                case HSSFCell.CELL_TYPE_BOOLEAN:
+	                    data[row.getRowNum()][cell.getCellNum()] = cell
+	                            .getBooleanCellValue();
+	                    break;
+	                case HSSFCell.CELL_TYPE_FORMULA:
+	                    data[row.getRowNum()][cell.getCellNum()] = cell
+	                            .getCellFormula();
+	                    break;
+	                }
+	            }
+	        }
+
+	       oList.add(data);
+
+        return oList;
+    }
+
+
+    /**
+     * 2007-xlsx格式
+     * @return�� List<Object[][]> oList
+     * @param��InputStream excelFile
+     * @Description:excel07 import
+     */
+    public static List<Object[][]> getIntegralData07(InputStream excelFile)throws Exception, IOException {
+        OPCPackage op=OPCPackage.open(excelFile);
+        XSSFWorkbook xwb = new XSSFWorkbook(op);
+        List<Object[][]> oList = new ArrayList<Object[][]>();
+        for (int k = 0; k < xwb.getNumberOfSheets(); k++){
+	        XSSFSheet sheet = xwb.getSheetAt(k);
+	        Iterator<Row> rows = sheet.rowIterator();
+	        int coloumNum = sheet.getRow(0).getPhysicalNumberOfCells();// get number of columns
+	        Object data[][] = new Object[sheet.getLastRowNum() + 1][coloumNum];
+	        while (rows.hasNext()) {
+	            XSSFRow row = (XSSFRow) rows.next();
+	            Iterator<Cell> cells = row.cellIterator();
+	            while (cells.hasNext()) {
+	                XSSFCell cell = (XSSFCell) cells.next();
+                    for (int i=0;i<3;i++){
+                        cell.setCellType(XSSFCell.CELL_TYPE_STRING);
+                    }
+	                switch (cell.getCellType()) {
+	                case XSSFCell.CELL_TYPE_NUMERIC:
+	                    if (100000000 < cell.getNumericCellValue()) {
+	                        double d = cell.getNumericCellValue();
+	                        Date date = HSSFDateUtil.getJavaDate(d);
+	                        data[row.getRowNum()][cell.getColumnIndex()] = sFormat
+	                                .format(date);
+	                    } else {
+	                        DecimalFormat df = new DecimalFormat("0");
+	                        String numberCode = df.format(cell
+	                                .getNumericCellValue());
+	                        data[row.getRowNum()][cell.getColumnIndex()] = numberCode;
+	                    }
+	                    break;
+	                case XSSFCell.CELL_TYPE_STRING:
+	                    data[row.getRowNum()][cell.getColumnIndex()] = cell
+	                            .getStringCellValue();
+	                    break;
+	                case XSSFCell.CELL_TYPE_BOOLEAN:
+	                    data[row.getRowNum()][cell.getColumnIndex()] = cell
+	                            .getBooleanCellValue();
+	                    break;
+	                case XSSFCell.CELL_TYPE_FORMULA:
+	                    data[row.getRowNum()][cell.getColumnIndex()] = cell
+	                            .getCellFormula();
+	                    break;
+	                default:
+	                    data[row.getRowNum()][cell.getColumnIndex()] = "";
+	                    break;
+	                }
+	            }
+	        }
+	       oList.add(data);
+        }
+        return oList;
+    }
+    
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt b/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt
index cc262cb..fe3d1a6 100644
--- a/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt
+++ b/src/main/kotlin/com/supwisdom/dlpay/api/controller/notify_api_controller.kt
@@ -51,10 +51,10 @@
             // 得到根元素的所有子节点
             val elementList = root.elements()
             // 遍历所有子节点
-            for (e in elementList) {
+         /*   for (e in elementList) {
                 map[e.name] = e.text
                 logger.error("*************" + e.name + "=" + e.text + "************************")
-            }
+            }*/
             // 释放资源
             inputStream.close()
 
diff --git a/src/main/resources/templates/area/form.html b/src/main/resources/templates/area/form.html
index 2bcc90d..22308ab 100644
--- a/src/main/resources/templates/area/form.html
+++ b/src/main/resources/templates/area/form.html
@@ -81,7 +81,6 @@
         form.on('submit(form-submit)', function (data) {
             layer.load(2);
             let token = $("meta[name='_csrf_token']").attr("value");
-            debugger
             $.ajax({
                 type: "POST",
                 dataType: "json",
diff --git a/src/main/resources/templates/device/form.html b/src/main/resources/templates/device/form.html
index 6b5265d..5540300 100644
--- a/src/main/resources/templates/device/form.html
+++ b/src/main/resources/templates/device/form.html
@@ -75,7 +75,6 @@
         form.on('submit(form-submit)', function (data) {
             layer.load(2);
             let token = $("meta[name='_csrf_token']").attr("value");
-            debugger
             $.ajax({
                 type: "POST",
                 dataType: "json",
diff --git a/src/main/resources/templates/device/import.html b/src/main/resources/templates/device/import.html
new file mode 100644
index 0000000..c5a3bd0
--- /dev/null
+++ b/src/main/resources/templates/device/import.html
@@ -0,0 +1,92 @@
+<div style="color: #0c91e5" align="right">
+    <a th:href="@{/device/download}">点击此处下载导入模板</a>
+</div>
+<form lay-filter="form" class="layui-form model-form" >
+    <!-- row -->
+    <div class="layui-form-item">
+        <label class="control-label">请选择导入文件<span class="required"> * </span></label>
+        <input type="file" name="file" id="file" placeholder="请选择xls格式文件">
+    </div>
+
+    <!-- /row -->
+    <!-- row -->
+    <div class="layui-form-item" align="center">
+        <div id="importError" style="color:red">
+        </div>
+        <div id="importInfo" >
+        </div>
+    </div>
+
+    <!--    <div class="form-actions right">
+            <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>
+            <button type="submit" class="btn btn-success" >保存</button>
+        </div>-->
+    <div class="layui-form-item model-form-footer">
+        <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
+        <button class="layui-btn" lay-filter="form-import" lay-submit id="importbtn">保存</button>
+    </div>
+</form>
+
+<script>
+    layui.use(['layer', 'admin', 'form', 'formSelects'], function () {
+        var layer = layui.layer;
+        var admin = layui.admin;
+        var form = layui.form;
+
+        var url = '/device/import';
+        // 回显user数据
+
+        /* let fid = admin.getTempData("fid");
+         if (fid) {
+             form.val('form', {"fid": fid});
+         }*/
+        // 表单提交事件
+        form.on('submit(form-import)', function (data) {
+            $("#importError").html("");
+            var files = $('#file').prop('files');
+            var formData = new FormData();
+            $.each(files, function (i, file) {
+
+                formData.append('file', file);
+            });
+            console.log(formData);
+            layer.load(2);
+            let token = $("meta[name='_csrf_token']").attr("value");
+            debugger
+            $.ajax({
+                type: "POST",
+                url: url,
+                dataType: 'json',
+                processData:false,
+                contentType: false,
+                data: formData,
+                headers: {
+                    'Accept': 'application/json',
+                    'X-CSRF-TOKEN': token,
+                },
+                success: function (result) {
+                    layer.closeAll('loading');
+                    if (result.code == 200) {
+                        layer.msg(result.msg, {icon: 1});
+                        admin.finishPopupCenter();
+                    } else if (result.code == 401) {
+                        layer.msg(result.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else {
+                        $("#importError").html("导入结束,导入失败信息:<br/>" + result.msg);
+
+                        console.log('err:' + result.code);
+                      /*  layer.msg(result.msg, {icon: 2});*/
+                    }
+                },
+                error: function () {
+                    layer.closeAll('loading');
+                    layer.msg("请求服务器失败!", {icon: 2});
+                }
+            });
+            return false;
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/device/index.html b/src/main/resources/templates/device/index.html
index 59fe5f8..45c1d12 100644
--- a/src/main/resources/templates/device/index.html
+++ b/src/main/resources/templates/device/index.html
@@ -9,10 +9,12 @@
     <div class="layui-card-body">
         <div class="layui-form toolbar">
             搜索:
-            <input id="search-value" class="layui-input search-input" type="text" placeholder="输入功能名称"/>&emsp;
+            <input id="search-value" class="layui-input search-input" type="text" placeholder="输入终端编号"/>&emsp;
             <button id="btn-search" class="layui-btn icon-btn" data-type="search"><i class="layui-icon">&#xe615;</i>搜索
             </button>
             <button id="btn-add" class="layui-btn icon-btn" data-type="add"><i class="layui-icon"></i>添加设备</button>
+            <button id="btn-import" class="layui-btn icon-btn" ><i class="layui-icon"></i>批量导入</button>
+
         </div>
         <table class="layui-table" id="table" lay-filter="table"></table>
     </div>
@@ -39,9 +41,9 @@
             cols: [
                 [
                     {field: 'id', title: '终端编号', sort: true},
-                    {field: 'devphyid', sort: true, width: 300, title: '设备物理id'},
-                    {field: 'shopid', sort: true, width: 300, title: '商户id'},
-                    {field: 'factoryid', sort: true, width: 300, title: '设备厂商'},
+                    {field: 'devphyid', sort: true, width: 200, title: '设备物理id'},
+                    {field: 'shopid', sort: true, width: 200, title: '商户id'},
+                    {field: 'factoryid', sort: true, width: 200, title: '设备厂商'},
                     {field: 'state', title: '状态', sort: true, width: 100, templet: '#dev-tpl-state'},
                     {
                         field: 'id', align: 'center', title: '操作', fixed: 'right', templet: function (item) {
@@ -59,6 +61,18 @@
         $('#btn-add').click(function () {
             showModel();
         });
+        $('#btn-import').click(function () {
+            showDownload();
+        });
+        let showDownload = function () {
+            let title ='导入';
+            admin.popupCenter({
+                title: title,
+                path: '/device/loadimport',
+                finish: function () {
+                }
+            });
+        };
         let showModel = function (data) {
             let title = data ? '修改设备' : '添加设备';
             admin.putTempData('t_dev', data);
diff --git a/src/main/resources/templates/devicegroup/form.html b/src/main/resources/templates/devicegroup/form.html
new file mode 100644
index 0000000..974c2e8
--- /dev/null
+++ b/src/main/resources/templates/devicegroup/form.html
@@ -0,0 +1,79 @@
+<!-- operator表单弹窗 -->
+<form id="form" lay-filter="form" class="layui-form model-form">
+    <input name="devgroupid" id="devgroupid" type="hidden"/>
+    <div class="layui-form-item">
+        <label class="layui-form-label">设备组名称</label>
+        <div class="layui-input-block">
+            <input name="groupname"  type="text" class="layui-input" maxlength="20"
+                   lay-verify="required|groupname" required/>
+        </div>
+    </div>
+    <div class="layui-form-item">
+        <label class="layui-form-label">上级设备组</label>
+        <div class="layui-input-block">
+            <select name="pid" id="pid" lay-verify="required">
+                <option value="0">根设备</option>
+                <option th:each="group : ${grouplist}" th:value="${group.devgroupid}">[[${group.groupname}]]</option>
+            </select>
+        </div>
+    </div>
+
+    <div class="layui-form-item model-form-footer">
+        <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
+        <button class="layui-btn" lay-filter="form-submit" lay-submit id="submitbtn">保存</button>
+    </div>
+</form>
+
+<script>
+    layui.use(['layer', 'admin', 'form', 'formSelects'], function () {
+        var layer = layui.layer;
+        var admin = layui.admin;
+        var form = layui.form;
+        form.render('select');
+
+        var url = '/devicegroup/add';
+
+      /*  var group = admin.getTempData('t_devgroup');
+        if (group) {
+            $('input[name="devgroupid"]').attr('readonly', 'readonly');
+            form.val('form', group);
+        }*/
+
+        // 表单提交事件
+        form.on('submit(form-submit)', function (data) {
+            layer.load(2);
+            let token = $("meta[name='_csrf_token']").attr("value");
+            $.ajax({
+                type: "POST",
+                dataType: "json",
+                url: url,
+                headers: {
+                    'Accept': 'application/json',
+                    'Content-Type': 'application/json',
+                    'X-CSRF-TOKEN': token,
+                },
+                data: JSON.stringify(data.field),
+                success: function (result) {
+                    layer.closeAll('loading');
+                    if (result.code == 200) {
+                        layer.msg(result.msg, {icon: 1});
+                        admin.finishPopupCenter();
+                    } else if (result.code == 401) {
+                        layer.msg(result.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else {
+                        console.log('err:' + result.code);
+                        layer.msg(result.msg, {icon: 2});
+                    }
+                },
+                error: function () {
+                    layer.closeAll('loading');
+                    layer.msg("请求服务器失败!", {icon: 2});
+                }
+            });
+            return false;
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/devicegroup/index.html b/src/main/resources/templates/devicegroup/index.html
new file mode 100644
index 0000000..c716fea
--- /dev/null
+++ b/src/main/resources/templates/devicegroup/index.html
@@ -0,0 +1,301 @@
+<div class="layui-card layui-col-xs3" style="padding-bottom: 40%">
+    <div class="layui-card-header">
+        <h2 class="header-title">设备组</h2>
+
+    </div>
+    <div class="layui-card-body">
+        <div class="layui-form toolbar">
+            <button id="btn-add" class="layui-btn icon-btn" data-type="add"><i class="layui-icon"></i>添加设备组</button>
+        </div>
+        <div id="menuContent" class="menuContent " style="position: absolute;">
+            <ul id="ztree-menu" class="ztree" style="margin-top:0;"></ul>
+        </div>
+    </div>
+</div>
+
+
+<div class="layui-card layui-col-xs8" style="margin-left:3% ">
+    <div class="layui-card-header">
+        <h2 class="header-title">设备</h2>
+        <span class="layui-breadcrumb pull-right">
+          <a href="#">设备</a>
+          <a><cite>设备</cite></a>
+        </span>
+    </div>
+
+    <div class="layui-card-body ">
+        <div class="layui-form toolbar">
+            <input id="search-value" class="layui-input search-input" type="hidden"/>&emsp;
+            <!--    <button id="btn-search" class="layui-btn icon-btn" data-type="search"><i class="layui-icon">&#xe615;</i>搜索
+                </button>-->
+
+        </div>
+        <table class="layui-table" id="table" lay-filter="table"></table>
+    </div>
+</div>
+
+<script type="text/html" id="dev-tpl-state">
+    <input type="checkbox" lay-filter="dev-tpl-state" value="{{d.id}}" lay-skin="switch" lay-text="正常|注销" disabled
+           {{d.state=='1'?'checked':''}} />
+</script>
+<script>
+
+    layui.use(['form', 'table', 'layer', 'admin', 'element'], function () {
+        let form = layui.form;
+        let table = layui.table;
+        let admin = layui.admin;
+
+        form.render('select');
+
+        // 渲染表格
+        table.render({
+            elem: '#table',
+            url: '/devicegroup/listDevice',
+            page: true,
+            cols: [
+                [
+                    {field: 'id', title: '终端编号', sort: true},
+                    {field: 'devphyid', sort: true, width: 200, title: '设备物理id'},
+                    {field: 'shopid', sort: true, width: 200, title: '商户id'},
+                    {field: 'factoryid', sort: true, width: 200, title: '设备厂商'},
+                    {field: 'state', title: '状态', sort: true, width: 100, templet: '#dev-tpl-state'},
+                ]
+            ]
+        });
+        // 搜索按钮点击事件
+        $('#btn-search').click(function () {
+            let key = $('#search-value').val();
+            table.reload('table', {where: {searchkey: key}, page: {curr: 1}});
+        });
+        $('#btn-add').click(function () {
+            showModel();
+        });
+
+        let showModel = function (data) {
+            let title = data ? '修改设备组' : '添加设备组';
+            admin.putTempData('t_devgroup', data);
+            admin.popupCenter({
+                title: title,
+                path: '/devicegroup/loadadd',
+                finish: function () {
+                    loadTree();
+                }
+            });
+        };
+
+
+        // 工具条点击事件
+        table.on('tool(table)', function (obj) {
+            let data = obj.data;
+            let layEvent = obj.event;
+            console.log(data);
+            if (layEvent === 'edit') {
+                showModel(data);
+            } else if (layEvent === 'del') {
+                showDelete(data);
+            }
+        });
+        let showDelete = function (data) {
+            layer.confirm('确定要删除吗?', function (i) {
+                layer.close(i);
+                layer.load(2);
+                let token = $("meta[name='_csrf_token']").attr("value");
+                admin.go('/device/delete', {
+                    id: data.id,
+                    _csrf: token
+                }, function (data) {
+                    layer.closeAll('loading');
+                    if (data.code == 200) {
+                        layer.msg(data.msg, {icon: 1});
+                    } else if (data.code == 401) {
+                        layer.msg(data.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else {
+                        layer.msg(data.msg, {icon: 2});
+                    }
+                    table.reload('table', {});
+                }, function (ret) {
+                    console.log(ret);
+                    layer.closeAll('loading');
+                    layer.msg('请求失败了,请稍后再试', {icon: 2});
+                });
+            });
+        };
+
+        form.on('switch(dev-tpl-state)', function (obj) {
+            layer.load(2);
+            let token = $("meta[name='_csrf_token']").attr("value");
+            admin.go('/device/updatestate', {
+                id: obj.elem.value,
+                _csrf: token,
+                state: obj.elem.checked ? 1 : 0
+            }, function (data) {
+                layer.closeAll('loading');
+                if (data.code == 200) {
+                    layer.msg(data.msg, {icon: 1});
+                    //table.reload('table-user', {});
+                } else if (data.code == 401) {
+                    layer.msg(data.msg, {icon: 2, time: 1500}, function () {
+                        location.replace('/login');
+                    }, 1000);
+                    return;
+                } else {
+                    layer.msg(data.msg, {icon: 2});
+                    $(obj.elem).prop('checked', !obj.elem.checked);
+                    form.render('checkbox');
+                }
+            }, function () {
+                layer.closeAll('loading');
+                layer.msg('请求失败了,请稍后再试', {icon: 2});
+            });
+        });
+
+
+        function OnGrpClick(e, treeId, treeNode) {
+            console.log(treeNode.id);
+            table.reload('table', {where: {searchkey: treeNode.id}, page: {curr: 1}});
+
+        }
+
+        function loadZTree(eNodes) {
+            var menuSetting = {
+                view: {
+                    dblClickExpand: true,
+                    selectedMulti: false,
+                    showLine: true,
+                    showIcon: false
+                },
+                edit: {
+                    enable: true,
+                    drag: {
+                        isMove: true,
+                        prev: true,
+                        autoOpenTime: 0
+                    },
+                    editNameSelectAll: true,
+                    showRemoveBtn: true,
+                    removeTitle: "删除节点",
+                    renameTitle: "编辑节点名称",
+                    showRenameBtn: true,
+                },
+                data: {
+                    simpleData: {
+                        enable: true
+                    }
+                },
+                callback: {
+                    onClick: OnGrpClick,
+                    onRename: onRename,
+                    beforeRemove: beforeRemove
+                }
+            };
+            $.fn.zTree.init($("#ztree-menu"), menuSetting, eNodes);
+        }
+
+        $(document).ready(function () {
+            loadTree();
+        })
+
+        function loadTree() {
+            let token = $("meta[name='_csrf_token']").attr("value");
+            $.ajax({
+                type: "POST",
+                dataType: "json",
+                url: "/devicegroup/listTree",
+                headers: {
+                    'Accept': 'application/json',
+                    'X-CSRF-TOKEN': token,
+                },
+                data: {},
+                success: function (result) {
+                    console.log("获取返回", result.data);
+                    if (result.code == 0) {
+                        loadZTree(result.data);
+                    } else {
+                        layer.msg('请求失败了,请稍后再试', {icon: 2});
+                    }
+                },
+                error: function (data) {
+                    layer.msg('请求失败了,请稍后再试', {icon: 2});
+                }
+            })
+        }
+
+        function beforeRemove(treeId, treeNode) {
+            var flag = false;
+            layer.confirm("确认要删除当前节点(" + treeNode.name + ")吗?", {title: "删除确认"}, function (i) {
+                layer.close(i);
+                layer.load(2);
+                let token = $("meta[name='_csrf_token']").attr("value");
+                admin.go('/devicegroup/delete', {
+                    id: treeNode.id,
+                    _csrf: token
+                }, function (data) {
+                    layer.closeAll('loading');
+                    if (data.code == 200) {
+                        flag = true;
+                        loadTree();
+                        layer.msg(data.msg, {icon: 1});
+                    } else if (data.code == 401) {
+                        layer.msg(data.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else {
+                        layer.msg(data.msg, {icon: 2});
+                    }
+                }, function (ret) {
+                    console.log(ret);
+                    layer.closeAll('loading');
+                    layer.msg('请求失败了,请稍后再试', {icon: 2});
+                });
+            });
+
+            return flag;
+        }
+
+        function onRename(e, treeId, treeNode) {
+            var data = {
+                'devgroupid': treeNode.id,
+                'pid': treeNode.pId,
+                'groupname': treeNode.name
+            };
+            let token = $("meta[name='_csrf_token']").attr("value");
+            var url = 'devicegroup/add';
+            $.ajax({
+                type: "POST",
+                dataType: "json",
+                url: url,
+                headers: {
+                    'Accept': 'application/json',
+                    'Content-Type': 'application/json',
+                    'X-CSRF-TOKEN': token,
+                },
+                data: JSON.stringify(data),
+                success: function (result) {
+                    layer.closeAll('loading');
+                    if (result.code == 200) {
+                        layer.msg(result.msg, {icon: 1});
+                    } else if (result.code == 401) {
+                        layer.msg(result.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else {
+                        console.log('err:' + result.code);
+                        layer.msg(result.msg, {icon: 2});
+                    }
+                },
+                error: function () {
+                    layer.closeAll('loading');
+                    layer.msg("请求服务器失败!", {icon: 2});
+                }
+            });
+        }
+
+    });
+
+
+</script>
diff --git a/src/main/resources/templates/devicemanage/index.html b/src/main/resources/templates/devicemanage/index.html
new file mode 100644
index 0000000..1948862
--- /dev/null
+++ b/src/main/resources/templates/devicemanage/index.html
@@ -0,0 +1,156 @@
+<div class="layui-card">
+    <div class="layui-card-header">
+        <h2 class="header-title">设备注册</h2>
+        <span class="layui-breadcrumb pull-right">
+          <a href="#">设备注册</a>
+          <a><cite>设备注册</cite></a>
+        </span>
+    </div>
+    <div class="layui-card-body">
+        <div class="layui-form toolbar">
+            搜索:
+            <input id="search-value" class="layui-input search-input" type="text" placeholder="输入终端编号"/>&emsp;
+            <button id="btn-search" class="layui-btn icon-btn" data-type="search"><i class="layui-icon">&#xe615;</i>搜索
+            </button>
+
+        </div>
+        <table class="layui-table" id="table" lay-filter="table"></table>
+    </div>
+</div>
+
+<script type="text/html" id="dev-tpl-state">
+    <input type="checkbox" lay-filter="dev-tpl-state" value="{{d.id}}" lay-skin="switch" lay-text="正常|注销"
+           {{d.state=='1'?'checked':''}} />
+</script>
+<script>
+
+    layui.use(['form', 'table', 'layer', 'admin', 'element'], function () {
+        let form = layui.form;
+        let table = layui.table;
+        let admin = layui.admin;
+
+        form.render('select');
+
+        // 渲染表格
+        table.render({
+            elem: '#table',
+            url: '/device/list',
+            page: true,
+            cols: [
+                [
+                    {field: 'id', title: '终端编号', sort: true},
+                    {field: 'devphyid', sort: true, width: 200, title: '设备物理id'},
+                    {field: 'shopid', sort: true, width: 200, title: '商户id'},
+                    {field: 'factoryid', sort: true, width: 200, title: '设备厂商'},
+                    {field: 'state', title: '状态', sort: true, width: 100, templet: '#dev-tpl-state'},
+                    {
+                        field: 'id', align: 'center', title: '操作', fixed: 'right', templet: function (item) {
+                            return ' <a class="layui-btn  layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a> ';
+                        }
+                    }
+                ]
+            ]
+        });
+        // 搜索按钮点击事件
+        $('#btn-search').click(function () {
+            let key = $('#search-value').val();
+            table.reload('table', {where: {searchkey: key}, page: {curr: 1}});
+        });
+        $('#btn-add').click(function () {
+            showModel();
+        });
+        $('#btn-import').click(function () {
+            showDownload();
+        });
+        let showDownload = function () {
+            let title ='导入';
+            admin.popupCenter({
+                title: title,
+                path: '/device/loadimport',
+                finish: function () {
+                }
+            });
+        };
+        let showModel = function (data) {
+            let title = data ? '修改设备' : '添加设备';
+            admin.putTempData('t_dev', data);
+            admin.popupCenter({
+                title: title,
+                path: '/device/loadadd',
+                finish: function () {
+                    table.reload('table', {});
+                }
+            });
+        };
+
+
+        // 工具条点击事件
+        table.on('tool(table)', function (obj) {
+            let data = obj.data;
+            let layEvent = obj.event;
+            console.log(data);
+            if (layEvent === 'edit') {
+                showModel(data);
+            } else if (layEvent === 'del') {
+                showDelete(data);
+            }
+        });
+        let showDelete = function (data) {
+            layer.confirm('确定要删除吗?', function (i) {
+                layer.close(i);
+                layer.load(2);
+                let token = $("meta[name='_csrf_token']").attr("value");
+                admin.go('/device/delete', {
+                    id: data.id,
+                    _csrf: token
+                }, function (data) {
+                    console.log(data.code);
+                    layer.closeAll('loading');
+                    if (data.code == 200) {
+                        layer.msg(data.msg, {icon: 1});
+                    } else if (data.code == 401) {
+                        layer.msg(data.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('/login');
+                        }, 1000);
+                        return;
+                    } else {
+                        layer.msg(data.msg, {icon: 2});
+                    }
+                    table.reload('table', {});
+                }, function (ret) {
+                    console.log(ret);
+                    layer.closeAll('loading');
+                    layer.msg('请求失败了,请稍后再试', {icon: 2});
+                });
+            });
+        };
+
+        form.on('switch(dev-tpl-state)', function (obj) {
+            layer.load(2);
+            let token = $("meta[name='_csrf_token']").attr("value");
+            admin.go('/device/updatestate', {
+                id: obj.elem.value,
+                _csrf: token,
+                state: obj.elem.checked ? 1 : 0
+            }, function (data) {
+                layer.closeAll('loading');
+                if (data.code == 200) {
+                    layer.msg(data.msg, {icon: 1});
+                    //table.reload('table-user', {});
+                } else if (data.code == 401) {
+                    layer.msg(data.msg, {icon: 2, time: 1500}, function () {
+                        location.replace('/login');
+                    }, 1000);
+                    return;
+                } else {
+                    layer.msg(data.msg, {icon: 2});
+                    $(obj.elem).prop('checked', !obj.elem.checked);
+                    form.render('checkbox');
+                }
+            },function () {
+                layer.closeAll('loading');
+                layer.msg('请求失败了,请稍后再试', {icon: 2});
+            });
+        });
+    });
+</script>