餐补规则审核和设备绑定
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java
index eb601d2..c14a1a6 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/ImportExcelUtil.java
@@ -281,10 +281,10 @@
 	                HSSFCell cell = (HSSFCell) cells.next();
 
                     //默认设置前三个字段为string类型
-	                for(int i=0;i<=2;i++){
-	                HSSFCell cell1 = row.getCell(i);
-	                cell1.setCellType(HSSFCell.CELL_TYPE_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:
@@ -333,9 +333,9 @@
 	            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);
-                    }
+//                    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()) {
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleBindShowBean.java b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleBindShowBean.java
new file mode 100644
index 0000000..82b6d2c
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleBindShowBean.java
@@ -0,0 +1,76 @@
+package com.supwisdom.dlpay.restaurant.bean;
+
+public class DiscountRuleBindShowBean {
+  private String id;
+  private Integer deviceid;
+  private String devicename;
+  private String devphyid;
+  private Integer ruleid;
+  private String rulename;
+  private String rulestatus;
+  private String createtime;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public Integer getDeviceid() {
+    return deviceid;
+  }
+
+  public void setDeviceid(Integer deviceid) {
+    this.deviceid = deviceid;
+  }
+
+  public String getDevicename() {
+    return devicename;
+  }
+
+  public void setDevicename(String devicename) {
+    this.devicename = devicename;
+  }
+
+  public String getDevphyid() {
+    return devphyid;
+  }
+
+  public void setDevphyid(String devphyid) {
+    this.devphyid = devphyid;
+  }
+
+  public Integer getRuleid() {
+    return ruleid;
+  }
+
+  public void setRuleid(Integer ruleid) {
+    this.ruleid = ruleid;
+  }
+
+  public String getRulename() {
+    return rulename;
+  }
+
+  public void setRulename(String rulename) {
+    this.rulename = rulename;
+  }
+
+  public String getRulestatus() {
+    return rulestatus;
+  }
+
+  public void setRulestatus(String rulestatus) {
+    this.rulestatus = rulestatus;
+  }
+
+  public String getCreatetime() {
+    return createtime;
+  }
+
+  public void setCreatetime(String createtime) {
+    this.createtime = createtime;
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleSelectBean.java b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleSelectBean.java
new file mode 100644
index 0000000..a9229f0
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleSelectBean.java
@@ -0,0 +1,31 @@
+package com.supwisdom.dlpay.restaurant.bean;
+
+public class DiscountRuleSelectBean {
+  private Integer ruleid;
+  private String rulename;
+  private String timeperiod;
+
+  public Integer getRuleid() {
+    return ruleid;
+  }
+
+  public void setRuleid(Integer ruleid) {
+    this.ruleid = ruleid;
+  }
+
+  public String getRulename() {
+    return rulename;
+  }
+
+  public void setRulename(String rulename) {
+    this.rulename = rulename;
+  }
+
+  public String getTimeperiod() {
+    return timeperiod;
+  }
+
+  public void setTimeperiod(String timeperiod) {
+    this.timeperiod = timeperiod;
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleShowBean.java b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleShowBean.java
index 4cac7ff..bcdd42e 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleShowBean.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountRuleShowBean.java
@@ -8,7 +8,10 @@
   private Integer limitcnt;
   private Double amount;
   private String status;
+  private Integer detailStatus;
   private String remark;
+  private String starttime;
+  private String endtime;
 
   public Integer getRuleid() {
     return ruleid;
@@ -66,6 +69,14 @@
     this.status = status;
   }
 
+  public Integer getDetailStatus() {
+    return detailStatus;
+  }
+
+  public void setDetailStatus(Integer detailStatus) {
+    this.detailStatus = detailStatus;
+  }
+
   public String getRemark() {
     return remark;
   }
@@ -73,4 +84,20 @@
   public void setRemark(String remark) {
     this.remark = remark;
   }
+
+  public String getStarttime() {
+    return starttime;
+  }
+
+  public void setStarttime(String starttime) {
+    this.starttime = starttime;
+  }
+
+  public String getEndtime() {
+    return endtime;
+  }
+
+  public void setEndtime(String endtime) {
+    this.endtime = endtime;
+  }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java b/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
index f9026f1..ef1b587 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
@@ -1,20 +1,37 @@
 package com.supwisdom.dlpay.restaurant.controller;
 
 import com.supwisdom.dlpay.api.bean.JsonResult;
-import com.supwisdom.dlpay.framework.util.PageResult;
-import com.supwisdom.dlpay.framework.util.StringUtil;
-import com.supwisdom.dlpay.framework.util.WebConstant;
+import com.supwisdom.dlpay.exception.WebCheckException;
+import com.supwisdom.dlpay.framework.domain.TOperator;
+import com.supwisdom.dlpay.framework.util.*;
+import com.supwisdom.dlpay.restaurant.bean.DevparaBinddevShowBean;
+import com.supwisdom.dlpay.restaurant.bean.DiscountRuleBindShowBean;
 import com.supwisdom.dlpay.restaurant.bean.DiscountRuleShowBean;
+import com.supwisdom.dlpay.restaurant.domain.TDiscountDetail;
+import com.supwisdom.dlpay.restaurant.domain.TDiscountDevbind;
 import com.supwisdom.dlpay.restaurant.service.DeviceDiscountRuleService;
+import com.supwisdom.dlpay.restaurant.service.DeviceParamService;
+import com.supwisdom.dlpay.restaurant.util.RestaurantConstant;
+import com.supwisdom.dlpay.system.bean.TreeSelectNode;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.security.core.userdetails.UserDetails;
 import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
 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.List;
 
 @Controller
 public class DeviceDiscountRuleController {
   @Autowired
   private DeviceDiscountRuleService deviceDiscountRuleService;
+  @Autowired
+  private DeviceParamService deviceParamService;
 
   @GetMapping("/discountrule/index")
   public String DiscountRuleView() {
@@ -51,12 +68,37 @@
       } else {
         return JsonResult.error("删除失败!");
       }
+    }catch (WebCheckException ex){
+      return JsonResult.error(ex.getMessage());
+    }catch (Exception e) {
+      e.printStackTrace();
+      return JsonResult.error("系统处理异常").put("exception", e);
+    }
+  }
+
+  @PostMapping("/discountrule/closerule")
+  @PreAuthorize("hasPermission('/discountrule/closerule','')")
+  @ResponseBody
+  public JsonResult closeDiscountRule(@RequestParam("ruleid") Integer ruleid) {
+    try {
+      if (null == ruleid) {
+        return JsonResult.error("参数传递错误");
+      }
+      if (deviceDiscountRuleService.closeDiscountRule(ruleid)) {
+        return JsonResult.ok("关闭成功!");
+      } else {
+        return JsonResult.error("关闭失败!");
+      }
+    } catch (WebCheckException ex) {
+      return JsonResult.error(ex.getMessage());
     } catch (Exception e) {
       e.printStackTrace();
       return JsonResult.error("系统处理异常").put("exception", e);
     }
   }
 
+
+
   @GetMapping("/discountrule/load4addrule")
   @PreAuthorize("hasPermission('/discountrule/load4addrule','')")
   public String load4addDiscountRule() {
@@ -86,16 +128,87 @@
   @PostMapping("/discountrule/addrule")
   @PreAuthorize("hasPermission('/discountrule/addrule','')")
   @ResponseBody
-  public JsonResult addDiscountRule() {
+  public JsonResult editDiscountRule(@RequestParam("rulename") String rulename,
+                                     @RequestParam("ruletype") String ruletype,
+                                     @RequestParam("starttime") String starttime,
+                                     @RequestParam("endtime") String endtime,
+                                     @RequestParam("amount") String amount,
+                                     @RequestParam("limitcnt") Integer limitcnt,
+                                     @RequestParam(value = "file", required = false) MultipartFile file,
+                                     @AuthenticationPrincipal UserDetails operUser) {
     try {
+      if (StringUtil.isEmpty(rulename)
+          || (!RestaurantConstant.RULETYPE_QUOTA.equals(ruletype) && !RestaurantConstant.RULETYPE_REDUCTION.equals(ruletype))
+          || !DateUtil.checkDatetimeValid(starttime, "HH:mm")
+          || !DateUtil.checkDatetimeValid(endtime, "HH:mm")
+          || !NumberUtil.isAmount(amount) || null == limitcnt) {
+        return JsonResult.error("参数传递错误");
+      } else if (DateUtil.compareDatetime(endtime, starttime, "HH:mm") <= 0) {
+        return JsonResult.error("时间范围错误,结束时间必须必起始时间大");
+      } else if (Double.valueOf(amount) < 0) {
+        return JsonResult.error("金额不能为负");
+      } else if (limitcnt < 1) {
+        return JsonResult.error("使用次数必须大于零");
+      } else if(null == file){
+        return JsonResult.error("请选择餐补名单");
+      }
 
-      return JsonResult.error("系统处理异常").put("exception", "");
+      TOperator oper = (TOperator) operUser;
+      if (null == oper || StringUtil.isEmpty(oper.getOperid())) {
+        return JsonResult.error("登录过期,请重新登录");
+      }
+
+      if (deviceDiscountRuleService.saveNewDiscountRule(rulename.trim(), ruletype, DateUtil.unParseToDateFormat(starttime), DateUtil.unParseToDateFormat(endtime), Double.parseDouble(amount), limitcnt, file, oper)) {
+        return JsonResult.ok("新增成功");
+      } else {
+        return JsonResult.error("新增失败");
+      }
+    } catch (WebCheckException ex) {
+      return JsonResult.ok(599, ex.getMessage());
     } catch (Exception e) {
       e.printStackTrace();
       return JsonResult.error("系统处理异常").put("exception", e);
     }
   }
 
+
+  @GetMapping("/discountrule/downloadexcel")
+  @PreAuthorize("hasPermission('/discountrule/load4addrule','')")
+  @ResponseBody
+  public void downloadDiscountRuleExcel(HttpServletRequest request, HttpServletResponse response) {
+    try {
+      String[] title = {"市民卡号", "姓名"}; //表头
+      String[][] infos = {{"19045632", "张三"}}; // 示例内容
+      ExportExcel.queryexcel("餐补名单模板", title, infos, request, response);
+    } catch (Exception e) {
+      e.printStackTrace();
+    }
+  }
+
+  @GetMapping("/discountrule/load4detail")
+  public String load4DiscountRuleDetails(@RequestParam("ruleid") Integer ruleid, Model model) {
+    model.addAttribute("detailRuleid", ruleid);
+    return "restaurant/discountrule/ruledetail";
+  }
+
+  @GetMapping("/discountrule/load4detaillist")
+  @PreAuthorize("hasPermission('/discountrule/load4detail','')")
+  @ResponseBody
+  public PageResult<TDiscountDetail> searchDiscountRules(@RequestParam("page") Integer pageNo,
+                                                         @RequestParam("limit") Integer pageSize,
+                                                         @RequestParam("ruleid") Integer ruleid,
+                                                         @RequestParam(value = "searchkey", required = false) String searchkey) {
+    try {
+      if (null == pageNo || pageNo < 1) pageNo = WebConstant.PAGENO_DEFAULT;
+      if (null == pageSize || pageSize < 1) pageSize = WebConstant.PAGESIZE_DEFAULT;
+      return deviceDiscountRuleService.getDiscountRuleDetails(searchkey, ruleid, pageNo, pageSize);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return new PageResult<>(99, "系统查询错误");
+    }
+  }
+
+
   /**
    * ====================================================
    * 餐补规则审核
@@ -122,6 +235,63 @@
     }
   }
 
+  @GetMapping("/discountrule/load4checkdetail")
+  @PreAuthorize("hasPermission('/discountrule/load4checkdetail','')")
+  public String load4DiscountRuleCheckDetails(@RequestParam("ruleid") Integer ruleid, Model model) {
+    model.addAttribute("checkDetailRuleid", ruleid);
+    return "restaurant/discountrule/checkdetail";
+  }
+
+  @GetMapping("/discountrule/load4checkdetaillist")
+  @PreAuthorize("hasPermission('/discountrule/load4checkdetail','')")
+  @ResponseBody
+  public PageResult<TDiscountDetail> searchDiscountRulesCheckDetails(@RequestParam("page") Integer pageNo,
+                                                         @RequestParam("limit") Integer pageSize,
+                                                         @RequestParam("ruleid") Integer ruleid,
+                                                         @RequestParam(value = "searchkey", required = false) String searchkey) {
+    try {
+      if (null == pageNo || pageNo < 1) pageNo = WebConstant.PAGENO_DEFAULT;
+      if (null == pageSize || pageSize < 1) pageSize = WebConstant.PAGESIZE_DEFAULT;
+      return deviceDiscountRuleService.getDiscountRuleDetails(searchkey, ruleid, pageNo, pageSize);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return new PageResult<>(99, "系统查询错误");
+    }
+  }
+
+  @PostMapping("/discountrule/checkruledetail")
+  @PreAuthorize("hasPermission('/discountrule/checkruledetail','')")
+  @ResponseBody
+  public JsonResult editDiscountRule(@RequestParam("ruleid") Integer ruleid,
+                                     @RequestParam("checktype") String checktype,
+                                     @RequestParam("reason") String reason,
+                                     @AuthenticationPrincipal UserDetails operUser) {
+    try {
+      if (null == ruleid || (!"pass".equals(checktype) && !"reject".equals(checktype))) {
+        return JsonResult.error("参数传递错误");
+      } else if ("reject".equals(checktype) && StringUtil.isEmpty(reason)) {
+        return JsonResult.error("请填写驳回原因");
+      }
+
+      TOperator oper = (TOperator) operUser;
+      if (null == oper || StringUtil.isEmpty(oper.getOperid())) {
+        return JsonResult.error("登录过期,请重新登录");
+      }
+
+      if (deviceDiscountRuleService.doCheckDiscountRule(ruleid, "pass".equals(checktype), reason, oper)) {
+        return JsonResult.ok("pass".equals(checktype) ? "审核通过" : "驳回成功");
+      } else {
+        return JsonResult.error("操作失败");
+      }
+
+    } catch (WebCheckException ex) {
+      return JsonResult.error(ex.getMessage());
+    } catch (Exception e) {
+      e.printStackTrace();
+      return JsonResult.error("系统处理异常").put("exception", e);
+    }
+
+  }
 
   /**
    * ====================================================
@@ -133,5 +303,106 @@
     return "restaurant/discountrule/ruledevbind";
   }
 
+  @GetMapping("/discountrule/devbindlist")
+  @PreAuthorize("hasPermission('/discountrule/devbind','')")
+  @ResponseBody
+  public PageResult<DiscountRuleBindShowBean> searchDiscountDevbindInfo(@RequestParam("page") Integer pageNo,
+                                                                        @RequestParam("limit") Integer pageSize,
+                                                                        @RequestParam(value = "searchkey", required = false) String searchkey) {
+    try {
+      if (null == pageNo || pageNo < 1) pageNo = WebConstant.PAGENO_DEFAULT;
+      if (null == pageSize || pageSize < 1) pageSize = WebConstant.PAGESIZE_DEFAULT;
+      return deviceDiscountRuleService.getDiscountRuleDevBindInfo(searchkey, pageNo, pageSize);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return new PageResult<>(99, "系统查询错误");
+    }
+  }
+
+  @PostMapping("/discountrule/deletedevbind")
+  @PreAuthorize("hasPermission('/discountrule/deletedevbind','')")
+  @ResponseBody
+  public JsonResult deleteDiscountDevbind(@RequestParam("id") String id) {
+    try {
+      TDiscountDevbind bind = deviceDiscountRuleService.getDiscountDevbindById(id);
+      if (null == bind) {
+        return JsonResult.error("绑定关系不存在!");
+      }
+
+      if (deviceDiscountRuleService.deleteDiscountDevbind(bind)) {
+        return JsonResult.ok("删除成功");
+      } else {
+        return JsonResult.error("删除失败");
+      }
+    } catch (Exception e) {
+      e.printStackTrace();
+      return JsonResult.error("系统处理异常").put("exception", e);
+    }
+  }
+
+  @GetMapping("/discountrule/load4binddev")
+  @PreAuthorize("hasPermission('/discountrule/load4binddev','')")
+  public String load4RuleBindDevice(Model model) {
+    model.addAttribute("rulelist", deviceDiscountRuleService.getNormalDiscountRules());
+    return "restaurant/discountrule/rulebind";
+  }
+
+  @GetMapping("/discountrule/devsearch")
+  @PreAuthorize("hasPermission('/discountrule/load4binddev','')")
+  @ResponseBody
+  public PageResult<DevparaBinddevShowBean> searchRuleBindDevices(@RequestParam(value = "devgroupid", required = false) Integer devgroupid,
+                                                                  @RequestParam(value = "searchkey", required = false) String searchkey,
+                                                                  @RequestParam(value = "ruleid", required = false) Integer ruleid){
+    try {
+      if (null == ruleid && null == devgroupid && StringUtil.isEmpty(searchkey)) {
+        return new PageResult<>(99, "请填写条件查询设备");
+      }else if(null==ruleid){
+        return new PageResult<>(99, "请选择餐补规则");
+      }
+
+      return deviceDiscountRuleService.searchRuleBindDevices(devgroupid, searchkey, ruleid);
+    } catch (Exception e) {
+      e.printStackTrace();
+      return new PageResult<>(99, "系统查询错误");
+    }
+  }
+
+  @GetMapping("/discountrule/devgrouptree")
+  @PreAuthorize("hasPermission('/discountrule/load4binddev','')")
+  @ResponseBody
+  public List<TreeSelectNode> searchDevgroupTree() {
+    List<TreeSelectNode> tree = deviceParamService.getDeviceGroupSelectTree();
+    return tree;
+  }
+
+  @PostMapping("/discountrule/dorulebinddev")
+  @PreAuthorize("hasPermission('/discountrule/dorulebinddev','')")
+  @ResponseBody
+  public JsonResult doBindRuleDevices(@RequestParam("ruleid") Integer ruleid,
+                                      @RequestParam("deviceid[]") List<Integer> deviceIds,
+                                      @AuthenticationPrincipal UserDetails operUser) {
+    try {
+      if (null == ruleid || StringUtil.isEmpty(deviceIds)) {
+        return JsonResult.error("参数传递错误");
+      }
+
+      TOperator oper = (TOperator) operUser;
+      if (null == oper || StringUtil.isEmpty(oper.getOperid())) {
+        return JsonResult.error("登录过期,请重新登录");
+      }
+
+      if (deviceDiscountRuleService.saveRuleBindDevices(ruleid, deviceIds, oper)) {
+        return JsonResult.ok("绑定成功");
+      } else {
+        return JsonResult.error("绑定失败");
+      }
+    } catch (WebCheckException ex) {
+      return JsonResult.error(ex.getMessage());
+    } catch (Exception e) {
+      e.printStackTrace();
+      return JsonResult.error("系统处理异常").put("exception", e);
+    }
+  }
+
 
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/dao/CustomerDao.java b/src/main/java/com/supwisdom/dlpay/restaurant/dao/CustomerDao.java
index b18d3ff..d5f8378 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/dao/CustomerDao.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/dao/CustomerDao.java
@@ -7,6 +7,8 @@
 import org.springframework.data.jpa.repository.JpaRepository;
 import org.springframework.stereotype.Repository;
 
+import java.util.List;
+
 @Repository
 public interface CustomerDao extends JpaRepository<TCustomer, Integer> {
 
@@ -17,4 +19,6 @@
     Integer countByCardno(String cardno);
 
     Integer countByBankcardno(String bankcardno);
+
+    List<TCustomer> findAllByCardno(String cardno);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java
new file mode 100644
index 0000000..2b40245
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java
@@ -0,0 +1,20 @@
+package com.supwisdom.dlpay.restaurant.dao;
+
+import com.supwisdom.dlpay.restaurant.domain.TDiscountDetail;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface DiscountDetailDao extends JpaRepository<TDiscountDetail, String>, JpaSpecificationExecutor<TDiscountDetail> {
+
+  @Modifying
+  @Query("delete from TDiscountDetail where ruleid=?1  ")
+  void deleteRuleDetailsByRuleid(int ruleid);
+
+  @Modifying
+  @Query("update TDiscountDetail t set t.status=?1 where t.ruleid=?2 ")
+  void updateRuleDetailStatusByRuleid(String status, int ruleid);
+}
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDevbindDao.java b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDevbindDao.java
index f200457..15f3f02 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDevbindDao.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDevbindDao.java
@@ -2,10 +2,21 @@
 
 import com.supwisdom.dlpay.restaurant.domain.TDiscountDevbind;
 import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
 
+@Repository
 public interface DiscountDevbindDao extends JpaRepository<TDiscountDevbind, String> {
 
   @Query("select count(t.id) from TDiscountDevbind t where t.ruleid=?1 ")
   long getBindcntByRuleid(int ruleid);
+
+
+  @Modifying
+  @Query("delete from TDiscountDevbind where ruleid=?1  ")
+  void deleteBindByRuleid(int ruleid);
+
+  @Query("from TDiscountDevbind where id=?1")
+  TDiscountDevbind getDiscountDevbindById(String id);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountRuleDao.java b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountRuleDao.java
index 9e2150e..6583740 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountRuleDao.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountRuleDao.java
@@ -5,6 +5,8 @@
 import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Query;
 
+import java.util.List;
+
 public interface DiscountRuleDao extends JpaRepository<TDiscountRule, Integer>, JpaSpecificationExecutor<TDiscountRule> {
   TDiscountRule findByRuleid(int ruleid);
 
@@ -13,4 +15,7 @@
 
   @Query("select count(t.ruleid) from TDiscountRule t where t.rulename=?1 and t.ruleid<>?2 ")
   long checkRulenameExists(String rulename, int ruleid);
+
+  @Query("from TDiscountRule where status=?1 order by ruleid ")
+  List<TDiscountRule> getDiscountRuleByStatus(String status);
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java
new file mode 100644
index 0000000..2e580ff
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java
@@ -0,0 +1,89 @@
+package com.supwisdom.dlpay.restaurant.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "TB_DISCOUNT_DETAIL")
+public class TDiscountDetail {
+  @Id
+  @GenericGenerator(name = "idGenerator", strategy = "uuid")
+  @GeneratedValue(generator = "idGenerator")
+  @Column(name = "ID", nullable = false, length = 32)
+  private String id;
+
+  @Column(name="RULEID", length = 20)
+  private Integer ruleid;
+
+  @Column(name="CARDNO", length = 20)
+  private String cardno;
+
+  @Column(name="USERNAME", length = 60)
+  private String username;
+
+  @Column(name="USERID", length = 32)
+  private String userid;
+
+  @Column(name="STATUS", nullable = false, length = 10)
+  private String status;
+
+  @Column(name="LASTSAVED", length = 14)
+  private String lastsaved;
+
+  public String getId() {
+    return id;
+  }
+
+  public void setId(String id) {
+    this.id = id;
+  }
+
+  public Integer getRuleid() {
+    return ruleid;
+  }
+
+  public void setRuleid(Integer ruleid) {
+    this.ruleid = ruleid;
+  }
+
+  public String getCardno() {
+    return cardno;
+  }
+
+  public void setCardno(String cardno) {
+    this.cardno = cardno;
+  }
+
+  public String getUsername() {
+    return username;
+  }
+
+  public void setUsername(String username) {
+    this.username = username;
+  }
+
+  public String getUserid() {
+    return userid;
+  }
+
+  public void setUserid(String userid) {
+    this.userid = userid;
+  }
+
+  public String getStatus() {
+    return status;
+  }
+
+  public void setStatus(String status) {
+    this.status = status;
+  }
+
+  public String getLastsaved() {
+    return lastsaved;
+  }
+
+  public void setLastsaved(String lastsaved) {
+    this.lastsaved = lastsaved;
+  }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountRule.java b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountRule.java
index 9cdd8b9..7ada260 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountRule.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountRule.java
@@ -32,6 +32,9 @@
   @Column(name = "STATUS", nullable = false, length = 10)
   private String status;
 
+  @Column(name = "DETAIL_STATUS", nullable = false, length = 1)
+  private Integer detailStatus; //名单状态 1-已上传;0-未上传
+
   @Version
   @GeneratedValue(strategy = GenerationType.AUTO)
   @Column(name="VERNO", nullable = false, precision = 9)
@@ -163,4 +166,12 @@
   public void setRemark(String remark) {
     this.remark = remark;
   }
+
+  public Integer getDetailStatus() {
+    return detailStatus;
+  }
+
+  public void setDetailStatus(Integer detailStatus) {
+    this.detailStatus = detailStatus;
+  }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
index 363f1a6..e40f5d6 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
@@ -1,9 +1,18 @@
 package com.supwisdom.dlpay.restaurant.service;
 
 import com.supwisdom.dlpay.exception.WebCheckException;
+import com.supwisdom.dlpay.framework.domain.TOperator;
 import com.supwisdom.dlpay.framework.util.PageResult;
+import com.supwisdom.dlpay.restaurant.bean.DevparaBinddevShowBean;
+import com.supwisdom.dlpay.restaurant.bean.DiscountRuleBindShowBean;
+import com.supwisdom.dlpay.restaurant.bean.DiscountRuleSelectBean;
 import com.supwisdom.dlpay.restaurant.bean.DiscountRuleShowBean;
+import com.supwisdom.dlpay.restaurant.domain.TDiscountDetail;
+import com.supwisdom.dlpay.restaurant.domain.TDiscountDevbind;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
 
 public interface DeviceDiscountRuleService {
   @Transactional(rollbackFor = Exception.class, readOnly = true)
@@ -12,11 +21,40 @@
   @Transactional(rollbackFor = Exception.class)
   boolean deleteDiscountRule(int ruleid)throws WebCheckException;
 
+  @Transactional(rollbackFor = Exception.class)
+  boolean closeDiscountRule(int ruleid)throws WebCheckException;
+
   @Transactional(rollbackFor = Exception.class, readOnly = true)
   boolean checkDiscountRulenameExist(String rulename,Integer ruleid);
 
+  @Transactional(rollbackFor = Exception.class)
+  boolean saveNewDiscountRule(String rulename, String ruletype, String starttime,
+                                   String endtime, Double amount, Integer limitcnt, MultipartFile file, TOperator oper) throws Exception;
 
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  PageResult<TDiscountDetail> getDiscountRuleDetails(String searchkey, int ruleid, int pageNo, int pageSize);
 
   @Transactional(rollbackFor = Exception.class, readOnly = true)
   PageResult<DiscountRuleShowBean> getCheckDiscountRuleInfos(String status, int pageNo, int pageSize);
+
+  @Transactional(rollbackFor = Exception.class)
+  boolean doCheckDiscountRule(int ruleid, boolean passflag, String reason, TOperator oper) throws Exception;
+
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  List<DiscountRuleSelectBean> getNormalDiscountRules();
+
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  PageResult<DiscountRuleBindShowBean> getDiscountRuleDevBindInfo(String searchkey, int pageNo, int pageSize);
+
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  TDiscountDevbind getDiscountDevbindById(String id);
+
+  @Transactional(rollbackFor = Exception.class)
+  boolean deleteDiscountDevbind(TDiscountDevbind bind);
+
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  PageResult<DevparaBinddevShowBean> searchRuleBindDevices(Integer devgroupid, String searchkey, int ruleid);
+
+  @Transactional(rollbackFor = Exception.class)
+  boolean saveRuleBindDevices(int ruleid, List<Integer> deviceIds, TOperator oper) throws WebCheckException;
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/DeviceDiscountRuleServiceImpl.java b/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/DeviceDiscountRuleServiceImpl.java
index 78321dd..6eedce3 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/DeviceDiscountRuleServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/DeviceDiscountRuleServiceImpl.java
@@ -1,15 +1,22 @@
 package com.supwisdom.dlpay.restaurant.service.impl;
 
 import com.supwisdom.dlpay.exception.WebCheckException;
+import com.supwisdom.dlpay.framework.domain.TOperator;
 import com.supwisdom.dlpay.framework.service.SystemUtilService;
+import com.supwisdom.dlpay.framework.util.ImportExcelUtil;
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.framework.util.StringUtil;
+import com.supwisdom.dlpay.restaurant.bean.DevparaBinddevShowBean;
+import com.supwisdom.dlpay.restaurant.bean.DiscountRuleBindShowBean;
+import com.supwisdom.dlpay.restaurant.bean.DiscountRuleSelectBean;
 import com.supwisdom.dlpay.restaurant.bean.DiscountRuleShowBean;
-import com.supwisdom.dlpay.restaurant.dao.DiscountDevbindDao;
-import com.supwisdom.dlpay.restaurant.dao.DiscountRuleDao;
-import com.supwisdom.dlpay.restaurant.domain.TDiscountRule;
+import com.supwisdom.dlpay.restaurant.dao.*;
+import com.supwisdom.dlpay.restaurant.domain.*;
 import com.supwisdom.dlpay.restaurant.service.DeviceDiscountRuleService;
 import com.supwisdom.dlpay.restaurant.util.RestaurantConstant;
+import org.apache.commons.lang3.StringUtils;
+import org.hibernate.query.internal.NativeQueryImpl;
+import org.hibernate.transform.Transformers;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
@@ -17,14 +24,16 @@
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.domain.Specification;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
 import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Predicate;
 import javax.persistence.criteria.Root;
+import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -35,8 +44,13 @@
   @Autowired
   private DiscountDevbindDao discountDevbindDao;
   @Autowired
+  private DiscountDetailDao discountDetailDao;
+  @Autowired
   private SystemUtilService systemUtilService;
-
+  @Autowired
+  private CustomerDao customerDao;
+  @Autowired
+  private DeviceDao deviceDao;
 
   @PersistenceContext
   private EntityManager entityManager;
@@ -68,10 +82,12 @@
         bean.setRuletype(rule.getRuletype());
         bean.setAmount(rule.getAmount());
         bean.setStatus(rule.getStatus());
+        bean.setDetailStatus(rule.getDetailStatus());
         bean.setLimitcnt(rule.getLimitcnt());
         bean.setRemark(rule.getRemark());
-        String period = rule.getStarttime().substring(0, 2) + ":" + rule.getStarttime().substring(2) + "~" + rule.getEndtime().substring(0, 2) + ":" + rule.getEndtime().substring(2);
-        bean.setTimeperiod(period);
+        bean.setStarttime(rule.getStarttime().substring(0, 2) + ":" + rule.getStarttime().substring(2));
+        bean.setEndtime(rule.getEndtime().substring(0, 2) + ":" + rule.getEndtime().substring(2));
+        bean.setTimeperiod(bean.getStarttime() + " ~ " + bean.getEndtime());
         result.add(bean);
       }
     }
@@ -89,12 +105,30 @@
     TDiscountRule rule = discountRuleDao.findByRuleid(ruleid);
     if (null == rule) {
       throw new WebCheckException("餐补规则不存在!");
+    } else if (!RestaurantConstant.STATUS_DISCOUNTRULE_UNCHECK.equals(rule.getStatus()) && !RestaurantConstant.STATUS_DISCOUNTRULE_REJECT.equals(rule.getStatus())) {
+      throw new WebCheckException("待审核或驳回的餐补规则才能删除!");
+    }
+
+    discountDetailDao.deleteRuleDetailsByRuleid(ruleid); //名单
+    discountDevbindDao.deleteBindByRuleid(ruleid); //绑定设备
+    discountRuleDao.delete(rule);
+    return true;
+  }
+
+  @Override
+  public boolean closeDiscountRule(int ruleid) throws WebCheckException {
+    TDiscountRule rule = discountRuleDao.findByRuleid(ruleid);
+    if (null == rule) {
+      throw new WebCheckException("餐补规则不存在!");
     } else if (RestaurantConstant.STATUS_DISCOUNTRULE_CLOSED.equals(rule.getStatus())) {
       throw new WebCheckException("餐补规则已经失效!");
+    } else if (!RestaurantConstant.STATUS_DISCOUNTRULE_NORMAL.equals(rule.getStatus())) {
+      throw new WebCheckException("餐补规则未审核通过,不能关闭");
     }
-    if (discountDevbindDao.getBindcntByRuleid(ruleid) > 0) {
-      throw new WebCheckException("有设备正在使用该餐补规则,请先解绑设备");
-    }
+
+//    if (discountDevbindDao.getBindcntByRuleid(ruleid) > 0) {
+//      throw new WebCheckException("有设备正在使用该餐补规则,请先解绑设备");
+//    }
 
     rule.setStatus(RestaurantConstant.STATUS_DISCOUNTRULE_CLOSED);
     rule.setLastsaved(systemUtilService.getSysdatetime().getHostdatetime());
@@ -116,9 +150,310 @@
     return false;
   }
 
+  private TCustomer getCustomerByCardno(String cardno) {
+    if (!StringUtil.isEmpty(cardno)) {
+      List<TCustomer> list = customerDao.findAllByCardno(cardno.trim());
+      if (!StringUtil.isEmpty(list)) {
+        return list.get(0);
+      }
+    }
+    return null;
+  }
+
+  private boolean checkRuleTimeError(String starttime, String endtime, String cardno, Integer custid) {
+    Query query = entityManager.createNativeQuery("select count(a.id) from tb_discount_detail a, tb_discount_rule b where a.ruleid=b.ruleid and (b.status='uncheck' or b.status='normal') " +
+        "and a.cardno=:cardno and ((b.starttime<:starttime and b.endtime>:starttime) or (b.starttime<:endtime and b.endtime>:endtime)) ");
+    query.setParameter("cardno", cardno);
+    query.setParameter("starttime", starttime);
+    query.setParameter("endtime", endtime);
+    BigInteger cnt = (BigInteger) query.getSingleResult();
+    if (null != cnt && cnt.longValue() > 0) {
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public boolean saveNewDiscountRule(String rulename, String ruletype, String starttime,
+                                     String endtime, Double amount, Integer limitcnt, MultipartFile file, TOperator oper) throws Exception {
+    TDiscountRule rule = new TDiscountRule();
+    if (discountRuleDao.checkRulenameExists(rulename) > 0) {
+      throw new WebCheckException("餐补名称已经存在!");
+    }
+    rule.setRulename(rulename);
+    rule.setRuletype(ruletype);
+    rule.setStarttime(starttime);
+    rule.setEndtime(endtime);
+    rule.setAmount(amount);
+    rule.setLimitcnt(limitcnt);
+    rule.setStatus(RestaurantConstant.STATUS_DISCOUNTRULE_UNCHECK);
+    rule.setDetailStatus(1);
+    rule.setCreateOperid(oper.getOperid());
+    String systime = systemUtilService.getSysdatetime().getHostdatetime();
+    rule.setCreatetime(systime);
+    rule.setLastsaved(systime);
+    rule.setVerno(1);
+    rule = discountRuleDao.save(rule);
+
+    String filename = file.getOriginalFilename();
+    if (!filename.endsWith(".xls") && !filename.endsWith(".xlsx")) {
+      throw new WebCheckException("文件格式错误,请选择excel文件");
+    }
+    List<Object[][]> excelData = null;
+    if (filename.endsWith(".xls")) {
+      excelData = ImportExcelUtil.getIntegralData(file.getInputStream());//2003版本
+    } else {
+      excelData = ImportExcelUtil.getIntegralData07(file.getInputStream());//2007版本以上
+    }
+    if (null == excelData || excelData.size() < 1) {
+      throw new WebCheckException("excel文件解析错误");
+    }
+
+    int index_cardno = -1;
+    int index_name = -1;
+    Object[] titleRow = excelData.get(0)[0]; //sheet1表头
+    for (int i = 0; i < titleRow.length; i++) {
+      if ("市民卡号".equals(titleRow[i])) {
+        index_cardno = i;
+        continue;
+      } else if ("姓名".equals(titleRow[i])) {
+        index_name = i;
+        continue;
+      }
+    }
+    if (index_cardno == -1 || index_name == -1 || excelData.get(0).length < 2) {
+      throw new WebCheckException("名单模板表头不能修改,且必须包含数据!");
+    }
+
+    List<String> successCardnos = new ArrayList<>(0);
+    List<String> errmsgList = new ArrayList<>(0);
+    for (int n = 1; n < excelData.get(0).length; n++) {
+      String msg = "";
+      Object[] row = excelData.get(0)[n];
+      String cardno = row[index_cardno] == null ? null : row[index_cardno].toString().trim();
+      String name = row[index_name] == null ? null : row[index_name].toString().trim();
+      if (StringUtil.isEmpty(cardno)) {
+        msg += ",市民卡号为空";
+      }
+      if (StringUtil.isEmpty(name)) {
+        msg += ",姓名为空";
+      }
+      TCustomer customer = getCustomerByCardno(cardno);
+      if (!StringUtil.isEmpty(cardno)) {
+        if (null == customer) {
+          msg += ",市民卡用户不存在";
+        } else if (!customer.getCustname().equals(name)) {
+          msg += ",市民卡号与姓名不匹配!";
+        }
+      }
+      if (!StringUtil.isEmpty(cardno) && successCardnos.contains(cardno)) {
+        msg += ",市民卡号重复!";
+      } else if (null != customer && checkRuleTimeError(starttime, endtime, cardno, customer.getCustid())) {
+        msg += ",市民卡号[" + cardno + "]存在规则时间段冲突!";
+      }
+
+
+      if (!StringUtil.isEmpty(msg)) {
+        errmsgList.add("第" + (n+1) + "行数据错误" + msg);
+      } else {
+        TDiscountDetail detail = new TDiscountDetail();
+        detail.setRuleid(rule.getRuleid());
+        detail.setCardno(cardno);
+        detail.setUsername(name);
+        detail.setUserid(customer.getCustid() + "");
+        detail.setStatus("uncheck");
+        detail.setLastsaved(systime);
+        discountDetailDao.save(detail); //保存明细
+
+        successCardnos.add(cardno);
+      }
+    }
+
+    if (!StringUtil.isEmpty(errmsgList)) {
+      StringBuffer errmsg = new StringBuffer("导入失败,名单存在错误!");
+      for (int j = 0; j < errmsgList.size(); j++) {
+        errmsg.append("<br/>" + errmsgList.get(j));
+        if (j > 10) {
+          errmsg.append("<br/>错误太多,请仔细核对名单后再上传!");
+        }
+      }
+      throw new WebCheckException(errmsg.toString());
+    }
+    return true;
+  }
+
+  @Override
+  public PageResult<TDiscountDetail> getDiscountRuleDetails(String searchkey, int ruleid, int pageNo, int pageSize) {
+    StringBuffer querySql = new StringBuffer("from TDiscountDetail t where t.ruleid=:rlid ");
+    StringBuffer countSql = new StringBuffer("select count(t.id) as cnt from TDiscountDetail t where t.ruleid=:rlid ");
+    if (!StringUtil.isEmpty(searchkey)) {
+      querySql.append(" and (t.cardno like :str or t.username like :str) ");
+      countSql.append(" and (t.cardno like :str or t.username like :str) ");
+    }
+    querySql.append(" order by t.cardno ");
+    Query query = entityManager.createQuery(querySql.toString());
+    Query countQuery = entityManager.createQuery(countSql.toString());
+    query.setParameter("rlid", ruleid);
+    countQuery.setParameter("rlid", ruleid);
+    if (!StringUtil.isEmpty(searchkey)) {
+      query.setParameter("str", "%" + searchkey.trim() + "%");
+      countQuery.setParameter("str", "%" + searchkey.trim() + "%");
+    }
+    query.setFirstResult((pageNo - 1) * pageSize);
+    query.setMaxResults(pageSize); //分页显示
+    List<TDiscountDetail> list = query.getResultList();
+    Long count = (Long) countQuery.getSingleResult();
+    return new PageResult<>(count.longValue(), list);
+  }
+
+
   @Override
   public PageResult<DiscountRuleShowBean> getCheckDiscountRuleInfos(String status, int pageNo, int pageSize) {
     Pageable pageable = PageRequest.of(pageNo - 1, pageSize, Sort.by(Sort.Direction.DESC, "createtime"));
     return getDiscountRuleBySearch(null, null, status, pageable);
   }
+
+  @Override
+  public boolean doCheckDiscountRule(int ruleid, boolean passflag, String reason, TOperator oper) throws Exception {
+    TDiscountRule rule = discountRuleDao.findByRuleid(ruleid);
+    if (null == rule) {
+      throw new WebCheckException("餐补规则不存在!");
+    } else if (!RestaurantConstant.STATUS_DISCOUNTRULE_UNCHECK.equals(rule.getStatus())) {
+      throw new WebCheckException("餐补规则非待审核状态");
+    }
+
+    rule.setCheckOperid(oper.getOperid());
+    rule.setLastsaved(systemUtilService.getSysdatetime().getHostdatetime());
+    if (passflag) {
+      rule.setStatus(RestaurantConstant.STATUS_DISCOUNTRULE_NORMAL);
+      rule.setRemark(null);
+    } else {
+      rule.setStatus(RestaurantConstant.STATUS_DISCOUNTRULE_REJECT);
+      rule.setRemark(reason);
+    }
+    discountRuleDao.save(rule);
+    discountDetailDao.updateRuleDetailStatusByRuleid(rule.getStatus(), rule.getRuleid());
+    return true;
+  }
+
+  @Override
+  public List<DiscountRuleSelectBean> getNormalDiscountRules() {
+    List<TDiscountRule> list = discountRuleDao.getDiscountRuleByStatus(RestaurantConstant.STATUS_DISCOUNTRULE_NORMAL);
+    if (!StringUtil.isEmpty(list)) {
+      List<DiscountRuleSelectBean> result = new ArrayList<>(0);
+      for (TDiscountRule rule : list) {
+        DiscountRuleSelectBean bean = new DiscountRuleSelectBean();
+        bean.setRuleid(rule.getRuleid());
+        String period = rule.getStarttime().substring(0, 2) + ":" + rule.getStarttime().substring(2) + " ~ " + rule.getEndtime().substring(0, 2) + ":" + rule.getEndtime().substring(2);
+        bean.setRulename(rule.getRulename()+"("+period+")");
+        bean.setTimeperiod(period);
+        result.add(bean);
+      }
+      return result;
+    }
+    return new ArrayList<>(0);
+  }
+
+  @Override
+  public PageResult<DiscountRuleBindShowBean> getDiscountRuleDevBindInfo(String searchkey, int pageNo, int pageSize) {
+    StringBuffer querySql = new StringBuffer("select t.id,t.deviceid,b.devicename,b.devphyid,t.ruleid,a.rulename,a.status as rulestatus,t.createtime " +
+        " from TB_DISCOUNT_DEVBIND t left join TB_DISCOUNT_RULE a on t.ruleid=a.ruleid left join TB_DEVICE b on t.deviceid=b.id where 1=1 ");
+    StringBuffer countSql = new StringBuffer("select count(t.id) as cnt " +
+        " from TB_DISCOUNT_DEVBIND t left join TB_DISCOUNT_RULE a on t.ruleid=a.ruleid left join TB_DEVICE b on t.deviceid=b.id where 1=1 ");
+    if (!StringUtil.isEmpty(searchkey)) {
+      querySql.append(" and (a.rulename like :str or b.devicename like :str or b.devphyid like :str) ");
+      countSql.append(" and (a.rulename like :str or b.devicename like :str or b.devphyid like :str) ");
+    }
+    querySql.append(" order by t.createtime desc ");
+    Query query = entityManager.createNativeQuery(querySql.toString());
+    Query countQuery = entityManager.createNativeQuery(countSql.toString());
+    if (!StringUtil.isEmpty(searchkey)) {
+      query.setParameter("str", "%" + searchkey.trim() + "%");
+      countQuery.setParameter("str", "%" + searchkey.trim() + "%");
+    }
+    query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(DiscountRuleBindShowBean.class));
+    query.setFirstResult((pageNo - 1) * pageSize);
+    query.setMaxResults(pageSize); //分页显示
+    List<DiscountRuleBindShowBean> list = query.getResultList();
+    BigInteger count = (BigInteger) countQuery.getSingleResult();
+    return new PageResult<>(count.longValue(), list);
+  }
+
+  @Override
+  public TDiscountDevbind getDiscountDevbindById(String id) {
+    if (!StringUtil.isEmpty(id)) {
+      return discountDevbindDao.getDiscountDevbindById(id.trim());
+    }
+    return null;
+  }
+
+  @Override
+  public boolean deleteDiscountDevbind(TDiscountDevbind bind) {
+    if (null != bind) {
+      discountDevbindDao.delete(bind);
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public PageResult<DevparaBinddevShowBean> searchRuleBindDevices(Integer devgroupid, String searchkey, int ruleid) {
+    List<Integer> chirdGroupids = null;
+    if (null != devgroupid) {
+      Query chirdGroupQuery = entityManager.createNativeQuery(" WITH  RECURSIVE  r  AS ( " +
+          " SELECT * FROM tb_devicegroup WHERE devgroupid = :gid " +
+          " union ALL " +
+          " SELECT a.* FROM tb_devicegroup a, r WHERE a.pid = r.devgroupid ) " +
+          " SELECT devgroupid FROM r ORDER BY devgroupid ");
+      chirdGroupQuery.setParameter("gid", devgroupid.intValue());
+      chirdGroupids = chirdGroupQuery.getResultList(); //递归查询所有的子节点
+    }
+
+    StringBuffer sql = new StringBuffer("select t.id as deviceid,t.devicename,t.devphyid,t.devgroupid,a.groupname as devgroupname " +
+        " from TB_DEVICE t left join TB_DEVICEGROUP a on t.devgroupid=a.devgroupid " +
+        " left join TB_DISCOUNT_DEVBIND b on t.id=b.deviceid and b.ruleid=:rlid where b.id is null and t.state=1 ");
+    if (!StringUtil.isEmpty(chirdGroupids)) {
+      sql.append(" and t.devgroupid in (" + StringUtils.join(chirdGroupids.toArray(), ",") + ") ");
+    }
+    if (!StringUtil.isEmpty(searchkey)) {
+      sql.append(" and (t.devicename like :str or t.devphyid like :str) ");
+    }
+    sql.append(" order by t.id ");
+    Query query = entityManager.createNativeQuery(sql.toString());
+    if (!StringUtil.isEmpty(searchkey)) {
+      query.setParameter("str", "%" + searchkey.trim() + "%");
+    }
+    query.setParameter("rlid", ruleid);
+    query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(DevparaBinddevShowBean.class));
+    List<DevparaBinddevShowBean> list = query.getResultList();
+    return new PageResult<>(list);
+  }
+
+  @Override
+  public boolean saveRuleBindDevices(int ruleid, List<Integer> deviceIds, TOperator oper) throws WebCheckException {
+    TDiscountRule rule = discountRuleDao.findByRuleid(ruleid);
+    if (null == rule) {
+      throw new WebCheckException("所选餐补规则不存在");
+    } else if (!RestaurantConstant.STATUS_DISCOUNTRULE_NORMAL.equals(rule.getStatus())) {
+      throw new WebCheckException("所选餐补规则状态异常");
+    }
+
+    for (Integer id : deviceIds) {
+      TDevice device = deviceDao.findTDeviceById(id);
+      if (null == device) {
+        throw new WebCheckException("终端编号为[" + id + "]的设备不存在");
+      } else if (1 != device.getState()) {
+        throw new WebCheckException("终端编号为[" + id + "]的设备状态异常");
+      }
+
+      TDiscountDevbind bind = new TDiscountDevbind();
+      bind.setRuleid(rule.getRuleid());
+      bind.setDeviceid(device.getId());
+      bind.setCreateOperid(oper == null ? null : oper.getOperid());
+      bind.setCreatetime(systemUtilService.getSysdatetime().getHostdatetime());
+      discountDevbindDao.save(bind);
+    }
+    return true;
+  }
+
 }
diff --git a/src/main/resources/static/custom/css/custom.css b/src/main/resources/static/custom/css/custom.css
new file mode 100644
index 0000000..726abe7
--- /dev/null
+++ b/src/main/resources/static/custom/css/custom.css
@@ -0,0 +1,10 @@
+/*自定义式样*/
+.upoadfile-btn input {
+    position: absolute;
+    font-size: 100px;
+    right: 0;
+    top: 0;
+    opacity: 0;
+    width: 113px;
+    height: 34px;
+}
\ No newline at end of file
diff --git a/src/main/resources/templates/index.html b/src/main/resources/templates/index.html
index 1fb326d..9122669 100755
--- a/src/main/resources/templates/index.html
+++ b/src/main/resources/templates/index.html
@@ -12,6 +12,7 @@
     <link rel="stylesheet" th:href="@{/static/libs/zTree/css/zTreeStyle/zTreeStyle.css}"/>

     <link rel="stylesheet" th:href="@{/static/custom/module/formSelects/formSelects-v4.css}"/>

     <link rel="stylesheet" th:href="@{/static/custom/css/admin.css}"/>

+    <link rel="stylesheet" th:href="@{/static/custom/css/custom.css}"/>

     <link th:if="${session.theme != null}" rel="stylesheet" th:href="@{/static/custom/css/theme-blue.css}"/>

 </head>

 

diff --git a/src/main/resources/templates/restaurant/devpara/devparabindform.html b/src/main/resources/templates/restaurant/devpara/devparabindform.html
index 6863470..cbe9913 100644
--- a/src/main/resources/templates/restaurant/devpara/devparabindform.html
+++ b/src/main/resources/templates/restaurant/devpara/devparabindform.html
@@ -1,4 +1,4 @@
-<form id="devparabind-form" lay-filter="devparabind-form-filter" class="layui-form model-form"
+<div id="devparabind-form" lay-filter="devparabind-form-filter" class="layui-form model-form"
       style="padding: 30px 25px 10px 25px;">
     <div class="layui-form-item">
         <div class="layui-input-inline" style="width: 300px;">
@@ -42,7 +42,7 @@
         <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>
+</div>
 
 <style type="text/css" id="devparabind-form-css">
     .layui-form-item .layui-form-checkbox[lay-skin=primary] {
@@ -117,7 +117,7 @@
             treeSelect.revokeNode('search-devparabind-form-devgroupid-filter');
         });
 
-        form.on('submit(form-submit)', function (data) {
+        form.on('submit(form-submit)', function (el) {
             var groupid = $("#devparabind-form-select-groupid").val();
             var checkStatus = table.checkStatus('devparabindformTable');
             var data = checkStatus.data;
@@ -150,6 +150,7 @@
                     layer.closeAll('loading');
                     if (result.code == 200) {
                         layer.msg(result.msg, {icon: 1});
+                        table.reload('devparabindformTable');
                         admin.finishPopupCenter();
                     } else if (result.code == 401) {
                         layer.msg(result.msg, {icon: 2, time: 1500}, function () {
diff --git a/src/main/resources/templates/restaurant/discountrule/checkdetail.html b/src/main/resources/templates/restaurant/discountrule/checkdetail.html
new file mode 100644
index 0000000..71bc2e1
--- /dev/null
+++ b/src/main/resources/templates/restaurant/discountrule/checkdetail.html
@@ -0,0 +1,94 @@
+<div id="discountrule-checkdetail-form" lay-filter="discountrule-checkdetail-form-filter" class="layui-form model-form" style="padding: 10px 25px;">
+    <input type="hidden" name="ruleid" id="search-form-discountrule-checkdetail-ruleid" th:value="${checkDetailRuleid}" />
+    <div class="layui-form-item">
+        <label class="layui-form-label" style="color: red;">审核意见</label>
+        <div class="layui-input-block">
+            <input type="radio" name="checktype" id="form-discountrule-checkdetail-pass" lay-filter="discountrule-checkdetail-filter" value="pass" title="通过" checked/>
+            <input type="radio" name="checktype" id="form-discountrule-checkdetail-reject" lay-filter="discountrule-checkdetail-filter" value="reject" title="驳回"/>
+        </div>
+    </div>
+
+    <div class="layui-form-item" id="form-discountrule-checkdetail-reason-div" style="display: none;">
+        <label class="layui-form-label">驳回原因</label>
+        <div class="layui-input-block">
+            <textarea name="reason" id="form-discountrule-checkdetail-reason" placeholder="请输入内容" class="layui-textarea"></textarea>
+        </div>
+    </div>
+
+    <div class="layui-form-item">
+        <table class="layui-table" id="discountruleCheckdetailTable" lay-filter="discountruleCheckdetailTable-filter"></table>
+    </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="discountrule-checkdetail-form-submit" lay-submit>确认</button>
+    </div>
+</div>
+
+<script>
+    layui.use(['layer', 'admin', 'form', 'table'], function () {
+        var layer = layui.layer;
+        var admin = layui.admin;
+        var form = layui.form;
+        var table = layui.table;
+
+        // 表单提交事件
+        form.render("radio");
+        form.on('radio(discountrule-checkdetail-filter)', function (data) {
+            if ('pass' == data.value) {
+                $("#form-discountrule-checkdetail-reason-div").hide();
+            } else {
+                $("#form-discountrule-checkdetail-reason").val('');
+                $("#form-discountrule-checkdetail-reason-div").show();
+            }
+        });
+
+        // 渲染表格
+        var renderDetailTable = function (obj) {
+            table.render({
+                elem: '#discountruleCheckdetailTable',
+                url: '[[@{/discountrule/load4checkdetaillist}]]',
+                where: obj,
+                page: true,
+                size: 'sm',
+                height: 384,
+                cols: [
+                    [
+                        {field: 'cardno', title: '市民卡号', align: 'center'},
+                        {field: 'username', title: '姓名', align: 'center'}
+                    ]
+                ]
+            });
+        }
+        renderDetailTable({ruleid: $("#search-form-discountrule-checkdetail-ruleid").val()});
+
+        form.on('submit(discountrule-checkdetail-form-submit)', function (data) {
+            var vdata = data.field;
+            console.log(vdata);
+            if ('reject' == vdata.checktype) {
+                if (undefined == vdata.reason || "" == vdata.reason || "" == $.trim(vdata.reason)) {
+                    layer.msg("请填写驳回原因", {icon: 2, time: 1500});
+                    return;
+                }
+            }
+            vdata["_csrf"] = $("meta[name='_csrf_token']").attr("value");
+            admin.go('[[@{/discountrule/checkruledetail}]]', vdata, 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});
+                }
+            }, function (err) {
+                admin.errorBack(err);
+            })
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/restaurant/discountrule/rule.html b/src/main/resources/templates/restaurant/discountrule/rule.html
index 1cf7a9a..7921d16 100644
--- a/src/main/resources/templates/restaurant/discountrule/rule.html
+++ b/src/main/resources/templates/restaurant/discountrule/rule.html
@@ -26,7 +26,12 @@
 
 <!-- 表格操作列 -->
 <script type="text/html" id="discountrule-table-bar">
-    <a class="layui-btn layui-btn layui-btn-xs" lay-event="edit">修改</a>
+    <a class="layui-btn layui-btn layui-btn-xs" lay-event="detail">查看名单</a>
+    {{# if(d.status=='uncheck' || d.status=='reject'){ }}
+        <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
+    {{# } else if(d.status=='normal'){ }}
+        <a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="closed">关闭</a>
+    {{# } }}
 </script>
 
 <script>
@@ -34,6 +39,7 @@
         var form = layui.form;
         var table = layui.table;
         var admin = layui.admin;
+        var element = layui.element;
 
         form.render("select");
         // 渲染表格
@@ -77,6 +83,7 @@
                             }
                         }
                     },
+                    {field: 'remark', title: '备注',  align: 'center'},
                     {align: 'center', title: '操作', width: 250, toolbar: '#discountrule-table-bar',  fixed: 'right'}
                 ]
             ]
@@ -103,15 +110,13 @@
         //监听单元格
         table.on('tool(discountruleTable-filter)', function (obj) {
             var data = obj.data;
-
             if('del' == obj.event){
-                layer.confirm('确定要删除设备参数组【'+data.groupname+'】?', {
+                layer.confirm('确定直接删除餐补规则【'+data.rulename+'】吗?', {
                     btn: ['确定', '取消']
                 },function(){
-                    layer.closeAll('dialog');
                     layer.load(2);
-                    admin.go('[[@{/device/deletedevpara}]]', {
-                        groupid: data.groupid,
+                    admin.go('[[@{/discountrule/deleterule}]]', {
+                        ruleid: data.ruleid,
                         _csrf: $("meta[name='_csrf_token']").attr("value")
                     }, function (data) {
                         console.log(data.code);
@@ -126,18 +131,46 @@
                         } else {
                             layer.msg(data.msg, {icon: 2});
                         }
-                        table.reload('devparagroupTable');
+                        table.reload('discountruleTable');
                     }, function (err) {
                         admin.errorBack(err)
                     });
                 });
-            }else if('edit' == obj.event){
+
+            }else if('closed' == obj.event){
+                layer.confirm('确定关闭餐补规则【'+data.rulename+'】吗?', {
+                    btn: ['确定', '取消']
+                },function(){
+                    layer.load(2);
+                    admin.go('[[@{/discountrule/closerule}]]', {
+                        ruleid: data.ruleid,
+                        _csrf: $("meta[name='_csrf_token']").attr("value")
+                    }, 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('discountruleTable');
+                    }, function (err) {
+                        admin.errorBack(err)
+                    });
+                });
+
+            }else if('detail' == obj.event){
                 admin.popupCenter({
-                    title: "修改参数组【" + data.groupid + "_" + data.groupname + "】",
-                    path: '[[@{/device/load4editdevpara}]]?groupid=' + data.groupid,
-                    area: '1200px',
+                    title: "查看名单",
+                    path: '[[@{/discountrule/load4detail}]]?ruleid=' + data.ruleid,
+                    area: '600px',
                     finish: function () {
-                        table.reload('devparagroupTable');
+                        table.reload('discountruleTable');
                     }
                 });
             }
diff --git a/src/main/resources/templates/restaurant/discountrule/rulebind.html b/src/main/resources/templates/restaurant/discountrule/rulebind.html
new file mode 100644
index 0000000..15b3d4e
--- /dev/null
+++ b/src/main/resources/templates/restaurant/discountrule/rulebind.html
@@ -0,0 +1,178 @@
+<div id="discountrule-devbind-form" lay-filter="discountrule-devbind-filter" class="layui-form model-form"
+     style="padding: 30px 25px 10px 25px;">
+    <div class="layui-form-item">
+        <div class="layui-input-inline" style="width: 450px;">
+            <label class="layui-form-label">餐补规则</label>
+            <div class="layui-input-block">
+                <select lay-verify="required" class="layui-select" id="discountrule-devbind-form-select-ruleid">
+                    <option th:each="rl:${rulelist}" th:value="${rl.ruleid}"
+                            th:text="${rl.rulename}"></option>
+                </select>&emsp;
+            </div>
+        </div>
+    </div>
+
+    <div class="layui-form-item">
+        <label class="layui-form-label">选择设备</label>
+        <div class="layui-input-block" style="border: 1px solid #ddd;border-radius: 4px;padding: 10px;">
+            <div class="layui-card-body">
+                <div class="layui-form toolbar">
+                    <div class="layui-input-inline">
+                        <input id="search-discountrule-devbind-form-devgroupid" type="text"
+                               lay-filter="search-discountrule-devbind-form-devgroupid-filter" autocomplete="off"
+                               class="layui-input"/>
+                    </div>
+                    设备:
+                    <input id="search-discountrule-devbind-form-searchkey" type="text" class="layui-input search-input"
+                           maxlength="20" style="width: 200px;" placeholder="输入设备名称或设备物理ID"/>&emsp;
+                    <button id="btn-search-discountrule-devbind-form" class="layui-btn icon-btn"><i
+                            class="layui-icon">&#xe615;</i>搜索
+                    </button>
+                    <button id="btn-reset-discountrule-devbind-form" class="layui-btn layui-btn-primary"><i
+                            class="layui-icon"></i>清空
+                    </button>
+
+                    <table class="layui-table" id="discountrule-devbind-form-table"
+                           lay-filter="discountrule-devbind-form-table-filter"></table>
+                </div>
+            </div>
+        </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="discountrule-devbind-form-submit" lay-submit id="submitbtn">保存</button>
+    </div>
+</div>
+
+<style type="text/css" id="discountrule-devbind-form-css">
+    .layui-form-item .layui-form-checkbox[lay-skin=primary] {
+        margin-top: 0;
+    }
+</style>
+
+<script>
+    layui.use(['layer', 'table', 'admin', 'form', 'treeSelect'], function () {
+        var layer = layui.layer;
+        var admin = layui.admin;
+        var form = layui.form;
+        var table = layui.table;
+        var treeSelect = layui.treeSelect;
+        var $ = layui.$
+
+        form.render("select");
+        treeSelect.render({
+            elem: '#search-discountrule-devbind-form-devgroupid',
+            data: '[[@{/discountrule/devgrouptree}]]',
+            type: 'get',
+            placeholder: '选择设备组',
+            search: false,
+            style: {
+                folder: {
+                    enable: false
+                },
+                line: {
+                    enable: true
+                }
+            },
+            // 点击回调
+            click: function (d) {
+                var treeNode = d.current;
+                console.log(treeNode);
+                return true;
+            },
+            success: function (d) {
+                console.log(d); // 加载完成后的回调函数
+            }
+        });
+
+        // 渲染表格
+        table.render({
+            elem: '#discountrule-devbind-form-table',
+            url: '[[@{/discountrule/devsearch}]]',
+            size: 'sm',
+            height: 350,
+            page: false,
+            cols: [
+                [
+                    {type: 'checkbox', style: "#discountrule-devbind-form-css", fixed: 'left'},
+                    {field: 'deviceid', title: '设备编号', align: 'center'},
+                    {field: 'devicename', title: '设备名称', align: 'center'},
+                    {field: 'devphyid', title: '设备物理ID', align: 'center'},
+                    {field: 'devgroupname', title: '设备组', align: 'center'}
+                ]
+            ]
+        });
+
+        // 搜索按钮点击事件
+        $('#btn-search-discountrule-devbind-form').click(function () {
+            var ruleid = $("#discountrule-devbind-form-select-ruleid").val();
+            var devgroupid = $("#search-discountrule-devbind-form-devgroupid").val();
+            var searchkey = $("#search-discountrule-devbind-form-searchkey").val();
+            table.reload('discountrule-devbind-form-table', {
+                where: {
+                    devgroupid: devgroupid,
+                    searchkey: searchkey,
+                    ruleid: ruleid
+                }
+            });
+        });
+
+        $("#btn-reset-discountrule-devbind-form").click(function () {
+            $("#search-discountrule-devbind-form-devgroupid").val("");
+            $("#search-discountrule-devbind-form-searchkey").val("");
+            treeSelect.revokeNode('search-discountrule-devbind-form-devgroupid-filter');
+        });
+
+        form.on('submit(discountrule-devbind-form-submit)', function (el) {
+            var ruleid = $("#discountrule-devbind-form-select-ruleid").val();
+            var checkStatus = table.checkStatus('discountrule-devbind-form-table');
+            var data = checkStatus.data;
+            var deviceids = [];
+            if ("" == ruleid) {
+                layer.msg("请选择餐补规则", {icon: 2, time: 1500});
+                return;
+            }
+            for (var i = 0; i < data.length; i++) {
+                deviceids.push(data[i].deviceid);
+            }
+            if (deviceids.length < 1) {
+                layer.msg("请选择设备", {icon: 2, time: 1500});
+                return;
+            }
+            debugger
+            console.log(ruleid, deviceids);
+            layer.load(2);
+            var token = $("meta[name='_csrf_token']").attr("value");
+            $.ajax({
+                type: "POST",
+                dataType: "json",
+                url: '[[@{/discountrule/dorulebinddev}]]',
+                data: {
+                    "ruleid": ruleid,
+                    "deviceid[]": deviceids,
+                    "_csrf": token
+                },
+                success: function (result) {
+                    layer.closeAll('loading');
+                    if (result.code == 200) {
+                        layer.msg(result.msg, {icon: 1});
+                        table.reload('discountrule-devbind-form-table'); //刷新表格
+                        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 (err) {
+                    admin.errorBack(err);
+                }
+            });
+        });
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/restaurant/discountrule/rulecheck.html b/src/main/resources/templates/restaurant/discountrule/rulecheck.html
index 71121d2..8449f57 100644
--- a/src/main/resources/templates/restaurant/discountrule/rulecheck.html
+++ b/src/main/resources/templates/restaurant/discountrule/rulecheck.html
@@ -27,7 +27,11 @@
 
 <!-- 表格操作列 -->
 <script type="text/html" id="discountrule-check-table-bar">
-    <a class="layui-btn layui-btn layui-btn-xs" lay-event="edit">修改</a>
+    {{# if(d.status =='uncheck'){ }}
+        <a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="check">审核</a>
+    {{# } else { }}
+        <a class="layui-btn layui-btn-disabled layui-btn-xs">审核</a>
+    {{# } }}
 </script>
 
 <script>
@@ -37,56 +41,71 @@
         var admin = layui.admin;
 
         form.render("select");
-        // 渲染表格
-        table.render({
-            elem: '#discountrulecheckTable',
-            url: '[[@{/discountrule/checklist}]]',
-            page: true,
-            cols: [
-                [
-                    {field: 'rulename', title: '餐补名称', align: 'center', fixed: 'left'},
-                    {field: 'timeperiod', title: '优惠时间段', align: 'center'},
-                    {
-                        field: 'ruletype',
-                        title: '餐补类型',
-                        align: 'center',
-                        width: 120,
-                        sort: true,
-                        templet: function (d) {
-                            if ('quota' == d.ruletype) {
-                                return '定额';
-                            } else if ('reduction' == d.ruletype) {
-                                return '减免';
-                            } else {
-                                return d.ruletype;
+
+        var renderCheckRuleTable = function(obj){
+            table.render({
+                elem: '#discountrulecheckTable',
+                url: '[[@{/discountrule/checklist}]]',
+                where: obj,
+                page: true,
+                cols: [
+                    [
+                        {field: 'rulename', title: '餐补名称', align: 'center', fixed: 'left'},
+                        {field: 'timeperiod', title: '优惠时间段', align: 'center'},
+                        {
+                            field: 'ruletype',
+                            title: '餐补类型',
+                            align: 'center',
+                            width: 120,
+                            sort: true,
+                            templet: function (d) {
+                                if ('quota' == d.ruletype) {
+                                    return '定额';
+                                } else if ('reduction' == d.ruletype) {
+                                    return '减免';
+                                } else {
+                                    return d.ruletype;
+                                }
                             }
-                        }
-                    },
-                    {
-                        field: 'amount', title: '金额(元)', align: 'center', sort: true, templet: function (d) {
-                            return parseFloat(d.amount).toFixed(2);
-                        }
-                    },
-                    {field: 'limitcnt', title: '可使用次数/人', align: 'center'},
-                    {
-                        field: 'status', title: '状态', align: 'center', width: 120, sort: true, templet: function (d) {
-                            if ('uncheck' == d.status) {
-                                return '<span class="layui-badge layui-bg-orange">待审核</span>'
-                            } else if ('normal' == d.status) {
-                                return '<span class="layui-badge layui-bg-green">有效</span>';
-                            } else if ('closed' == d.status) {
-                                return '<span class="layui-badge layui-bg-gray">无效</span>';
-                            } else if ('reject' == d.status) {
-                                return '<span class="layui-badge">驳回</span>';
-                            } else {
-                                return d.status;
+                        },
+                        {
+                            field: 'amount', title: '金额(元)', align: 'center', sort: true, templet: function (d) {
+                                return parseFloat(d.amount).toFixed(2);
                             }
+                        },
+                        {field: 'limitcnt', title: '可使用次数/人', align: 'center'},
+                        {
+                            field: 'status',
+                            title: '状态',
+                            align: 'center',
+                            width: 120,
+                            sort: true,
+                            templet: function (d) {
+                                if ('uncheck' == d.status) {
+                                    return '<span class="layui-badge layui-bg-orange">待审核</span>'
+                                } else if ('normal' == d.status) {
+                                    return '<span class="layui-badge layui-bg-green">有效</span>';
+                                } else if ('closed' == d.status) {
+                                    return '<span class="layui-badge layui-bg-gray">无效</span>';
+                                } else if ('reject' == d.status) {
+                                    return '<span class="layui-badge">驳回</span>';
+                                } else {
+                                    return d.status;
+                                }
+                            }
+                        },
+                        {
+                            align: 'center',
+                            title: '操作',
+                            width: 250,
+                            toolbar: '#discountrule-check-table-bar',
+                            fixed: 'right'
                         }
-                    },
-                    {align: 'center', title: '操作', width: 250, toolbar: '#discountrule-check-table-bar', fixed: 'right'}
+                    ]
                 ]
-            ]
-        });
+            });
+        }
+        renderCheckRuleTable({status: "uncheck"});
 
         // 搜索按钮点击事件
         $('#btn-search-discountrule-check').click(function () {
@@ -98,6 +117,17 @@
         table.on('tool(discountrulecheckTable-filter)', function (obj) {
             var data = obj.data;
 
+            if('check' == obj.event){
+                admin.popupCenter({
+                    title: "查看名单",
+                    path: '[[@{/discountrule/load4checkdetail}]]?ruleid=' + data.ruleid,
+                    area: '600px',
+                    finish: function () {
+                        table.reload('discountrulecheckTable', {where: {status: ""}, page: {curr: 1}});
+                    }
+                });
+
+            }
         });
 
     });
diff --git a/src/main/resources/templates/restaurant/discountrule/ruledetail.html b/src/main/resources/templates/restaurant/discountrule/ruledetail.html
new file mode 100644
index 0000000..01928ae
--- /dev/null
+++ b/src/main/resources/templates/restaurant/discountrule/ruledetail.html
@@ -0,0 +1,48 @@
+<div class="layui-card">
+    <div class="layui-card-body">
+        <div class="layui-form toolbar">
+            搜索:
+            <input type="hidden" id="search-discountrule-detail-ruleid" th:value="${detailRuleid}" />
+            <input id="search-discountrule-detail-searchkey" class="layui-input search-input" maxlength="20" type="text" style="width: 200px;"
+                   placeholder="输入市民卡号或姓名查询"/>&emsp;
+            <button id="btn-search-discountrule-detail" class="layui-btn icon-btn" data-type="search"><i
+                    class="layui-icon">&#xe615;</i>搜索
+            </button>
+        </div>
+        <table class="layui-table" id="discountruleDetailTable" lay-filter="discountruleDetailTable-filter"></table>
+    </div>
+</div>
+<script>
+    layui.use(['form', 'table', 'layer', 'admin', 'element'], function () {
+        var form = layui.form;
+        var table = layui.table;
+        var admin = layui.admin;
+        var element = layui.element;
+
+        // 渲染表格
+        var renderDetailTable = function (obj) {
+            table.render({
+                elem: '#discountruleDetailTable',
+                url: '[[@{/discountrule/load4detaillist}]]',
+                where: obj,
+                page: true,
+                height: 472,
+                cols: [
+                    [
+                        {field: 'cardno', title: '市民卡号', align: 'center'},
+                        {field: 'username', title: '姓名', align: 'center'}
+                    ]
+                ]
+            });
+        }
+        renderDetailTable({ruleid: $("#search-discountrule-detail-ruleid").val()});
+
+        // 搜索按钮点击事件
+        $('#btn-search-discountrule-detail').click(function () {
+            var ruleid = $("#search-discountrule-detail-ruleid").val();
+            var searchkey = $("#search-discountrule-detail-searchkey").val();
+            table.reload('discountruleDetailTable', {where: {ruleid: ruleid, searchkey: searchkey}, page: {curr: 1}});
+        });
+
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/restaurant/discountrule/ruledevbind.html b/src/main/resources/templates/restaurant/discountrule/ruledevbind.html
index e69de29..10eefab 100644
--- a/src/main/resources/templates/restaurant/discountrule/ruledevbind.html
+++ b/src/main/resources/templates/restaurant/discountrule/ruledevbind.html
@@ -0,0 +1,120 @@
+<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-discountrule-devbind-searchkey" class="layui-input search-input" maxlength="20" type="text" style="width: 300px;" placeholder="输入规则名称、设备名称或设备物理ID"/>&emsp;
+            <button id="btn-discountrule-devbind-search" class="layui-btn icon-btn" data-type="search"><i class="layui-icon">&#xe615;</i>搜索
+            </button>
+            <button id="btn-discountrule-devbind-add" class="layui-btn icon-btn" data-type="add"><i class="layui-icon">&#xe654;</i>新 增</button>
+        </div>
+        <table class="layui-table" id="discountrule-devbind-table" lay-filter="discountrule-devbind-table-filter"></table>
+    </div>
+</div>
+
+
+<!-- 表格操作列 -->
+<script type="text/html" id="discountrule-devbind-table-bar">
+    <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>
+</script>
+
+<script>
+    layui.use(['form', 'table', 'layer', 'admin', 'element'], function () {
+        var form = layui.form;
+        var table = layui.table;
+        var admin = layui.admin;
+        // 渲染表格
+        table.render({
+            elem: '#discountrule-devbind-table',
+            url: '[[@{/discountrule/devbindlist}]]',
+            page: true,
+            cols: [
+                [
+                    {field: 'deviceid', title: '设备编号', align: 'center', fixed: 'left', sort: true},
+                    {field: 'devicename', title: '设备名称', align: 'center', fixed: 'left'},
+                    {field: 'devphyid', title: '设备物理ID', align: 'center'},
+                    {field: 'rulename', title: '餐补规则名称', align: 'center', sort: true},
+                    {
+                        field: 'rulestatus', title: '餐补规则状态', align: 'center', templet: function (d) {
+                            if ('uncheck' == d.rulestatus) {
+                                return '<span class="layui-badge layui-bg-orange">待审核</span>'
+                            } else if ('normal' == d.rulestatus) {
+                                return '<span class="layui-badge layui-bg-green">有效</span>';
+                            } else if ('closed' == d.rulestatus) {
+                                return '<span class="layui-badge layui-bg-gray">无效</span>';
+                            } else if ('reject' == d.rulestatus) {
+                                return '<span class="layui-badge">驳回</span>';
+                            } else {
+                                return d.rulestatus;
+                            }
+                        }
+                    },
+                    {
+                        field: 'createtime', title: '绑定时间', align: 'center', templet: function (d) {
+                            return admin.formatDate(d.createtime);
+                        }
+                    },
+                    {align: 'center', title: '操作', width: 100, toolbar: '#discountrule-devbind-table-bar', fixed: 'right'}
+                ]
+            ]
+        });
+
+        // 搜索按钮点击事件
+        $('#btn-discountrule-devbind-search').click(function () {
+            var searchkey = $("#search-discountrule-devbind-searchkey").val();
+            table.reload('discountrule-devbind-table', {where: {searchkey: searchkey}, page: {curr: 1}});
+        });
+
+        $('#btn-discountrule-devbind-add').click(function () {
+            admin.popupCenter({
+                title: "新增餐补规则绑定关系",
+                path: '[[@{/discountrule/load4binddev}]]',
+                area: '900px',
+                finish: function () {
+                    table.reload('discountrule-devbind-table');
+                }
+            });
+        });
+
+        //监听单元格
+        table.on('tool(discountrule-devbind-table-filter)', function (obj) {
+            var data = obj.data;
+
+            if('del' == obj.event){
+                layer.confirm('确定要删除设备【'+data.devicename+'】绑定的餐补规则【'+data.rulename+'】吗?', {
+                    btn: ['确定', '取消']
+                },function(){
+                    layer.closeAll('dialog');
+                    layer.load(2);
+                    admin.go('[[@{/discountrule/deletedevbind}]]', {
+                        id: data.id,
+                        _csrf: $("meta[name='_csrf_token']").attr("value")
+                    }, 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('discountrule-devbind-table');
+                    }, function (err) {
+                        admin.errorBack(err);
+                    });
+                });
+            }
+        });
+
+    });
+</script>
\ No newline at end of file
diff --git a/src/main/resources/templates/restaurant/discountrule/ruleform.html b/src/main/resources/templates/restaurant/discountrule/ruleform.html
index aaf81ba..e82a2d3 100644
--- a/src/main/resources/templates/restaurant/discountrule/ruleform.html
+++ b/src/main/resources/templates/restaurant/discountrule/ruleform.html
@@ -1,5 +1,4 @@
-<form id="discountrule-form" lay-filter="discountrule-form-filter" class="layui-form model-form" style="padding: 30px 25px 10px 25px;">
-    <input name="ruleid" id="form-discountrule-ruleid" type="hidden"/>
+<div id="discountrule-form" lay-filter="discountrule-form-filter" class="layui-form model-form" style="padding: 10px 25px;">
     <div class="layui-form-item">
         <label class="layui-form-label">餐补类型</label>
         <div class="layui-input-block">
@@ -38,23 +37,23 @@
     </div>
 
     <div class="layui-form-item">
-        <label class="layui-form-label">可以次数/人</label>
+        <label class="layui-form-label">可用次数/人</label>
         <div class="layui-input-block">
             <input type="text" name="limitcnt" id="form-discountrule-limitcnt" maxlength="9" autocomplete="off" style="width: 90%;"
                    class="layui-input" lay-verify="required|number"/>
         </div>
     </div>
 
-
     <div class="layui-form-item">
         <label class="layui-form-label">餐补对象</label>
         <div class="layui-input-inline" style="width: auto;">
-            <button type="button" class="layui-btn" id="form-discountrule-records">
+            <button type="button" class="layui-btn upoadfile-btn" >
                 <i class="layui-icon">&#xe67c;</i>上传名单
+                <input type="file" name="file" id="form-discountrule-records" />
             </button>
         </div>
         <div class="layui-input-inline" style="padding-top: 15px;">
-            <a style="color: blue;text-decoration: none;cursor: pointer;">下载名单模板</a>
+            <a th:href="@{/discountrule/downloadexcel}" style="color: blue;text-decoration: none;cursor: pointer;">下载名单模板</a>
         </div>
     </div>
 
@@ -62,7 +61,7 @@
         <button class="layui-btn layui-btn-primary" type="button" ew-event="closeDialog">取消</button>
         <button class="layui-btn" lay-filter="discountrule-form-submit" lay-submit id="submitbtn">保存</button>
     </div>
-</form>
+</div>
 
 <script>
     layui.use(['layer', 'admin', 'form', 'laydate', 'upload'], function () {
@@ -120,18 +119,98 @@
             }
         });
         form.on('radio(discountrule-ruletype-filter)', function (data) {
-            if ('reduction' == data.value) {
+            changeDiscountRuletype(data.value);
+        });
+
+        var changeDiscountRuletype = function (val) {
+            if ('reduction' == val) {
                 $("#form-discountrule-amount-text").text("减免金额(元)");
             } else {
                 $("#form-discountrule-amount-text").text("固定金额(元)");
             }
-        });
-
-
-
+        }
 
         form.on('submit(discountrule-form-submit)', function (data) {
+            debugger
+            var token = $("meta[name='_csrf_token']").attr("value");
             var vdata = data.field;
+            if(null==vdata.starttime || null==vdata.endtime){
+                layer.msg("请选择时间段", {icon: 2, time: 1500});
+                return;
+            }else if(vdata.endtime <= vdata.starttime){
+                layer.msg("请正确选择时间段", {icon: 2, time: 1500});
+                return;
+            }
+
+            if(null==vdata.limitcnt || vdata.limitcnt<1){
+                layer.msg("可用次数必须大于零", {icon: 2, time: 1500});
+                return;
+            }
+            var formData = new FormData();
+            formData.append("ruletype", vdata.ruletype);
+            formData.append("rulename", vdata.rulename);
+            formData.append("starttime", vdata.starttime);
+            formData.append("endtime", vdata.endtime);
+            formData.append("amount", vdata.amount);
+            formData.append("limitcnt", vdata.limitcnt);
+
+            var flag = false;
+            var files = $('#form-discountrule-records').prop('files');
+            for (var i = 0; i < files.length; i++) {
+                var filename = files[i].name;
+                var suffix = filename.substr(filename.lastIndexOf("."));
+                if ('.xls' != suffix && '.xlsx' != suffix) {
+                    layer.msg("请选择excel文件", {icon: 2, time: 1500});
+                    return;
+                }
+                formData.append('file', files[i]);
+                flag = true;
+            }
+            if (!flag) {
+                layer.msg("请选择餐补名单", {icon: 2, time: 1500});
+                return;
+            }
+            console.log(formData);
+
+            $.ajax({
+                type: "POST",
+                url: '[[@{/discountrule/addrule}]]',
+                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, time: 1500});
+                        admin.finishPopupCenter();
+                    } else if (result.code == 401) {
+                        layer.msg(result.msg, {icon: 2, time: 1500}, function () {
+                            location.replace('[[@{/login}]]');
+                        }, 1000);
+                        return;
+                    } else if(result.code == 599){
+                        //自定义错误
+                        layer.open({
+                            type: 0,
+                            title: "错误信息",
+                            icon: 2,
+                            area: ['600px', '400px'],
+                            content: result.msg
+                        });
+
+                    } else {
+                        layer.msg(result.msg, {icon: 2, time: 1500});
+                    }
+                },
+                error: function (err) {
+                    admin.errorBack(err);
+                }
+            });
         });
     });
 </script>
\ No newline at end of file