增加餐补过期,脱敏功能,修改流水导出报表
diff --git a/config/application-devel-pg.properties b/config/application-devel-pg.properties
index cf4f1be..4f5b86c 100644
--- a/config/application-devel-pg.properties
+++ b/config/application-devel-pg.properties
@@ -34,4 +34,4 @@
 cron.offlinedtl= 0 0/5 * * * ?
 payapi.logintime= 0 0/5 * * * ? 
 
-restaurant.check_discount_expire.cron= 0 0/2 * * * ?
\ No newline at end of file
+restaurant.check_discount_expire.cron=-
\ No newline at end of file
diff --git a/sql/restarant_create_table.sql b/sql/restarant_create_table.sql
index 247c2cb..60cdc07 100644
--- a/sql/restarant_create_table.sql
+++ b/sql/restarant_create_table.sql
@@ -319,7 +319,8 @@
   ruleid int4,
   status varchar(10)  NOT NULL,
   userid varchar(32),
-  username varchar(60) 
+  username varchar(60) ,
+  expiredate varchar(8)
 );
 ALTER TABLE tb_discount_detail ADD CONSTRAINT tb_discount_detail_pkey PRIMARY KEY (id);
 CREATE INDEX discountdetail_ruleid_idx ON tb_discount_detail(ruleid);
diff --git a/src/main/java/com/supwisdom/dlpay/api/service/impl/PosPayServiceImpl.java b/src/main/java/com/supwisdom/dlpay/api/service/impl/PosPayServiceImpl.java
index 104c421..650c6a1 100644
--- a/src/main/java/com/supwisdom/dlpay/api/service/impl/PosPayServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/api/service/impl/PosPayServiceImpl.java
@@ -442,6 +442,11 @@
                 if(cntamount!=amount){
                     tTransdtl.setRuleid(bean.getRuleid());
                 }
+                TBusinesspara cntflag = businessparaDao.findByParakey("need.ceil");
+                if(null!=cntflag) {
+                    cntamount=Math.ceil(cntamount);
+
+                }
 
                 tTransdtl.setManagefee(amount - cntamount);
                 tTransdtl.setManagefeetype(bean.getRuletype());
@@ -530,7 +535,6 @@
             }
             // }
 
-
             resp.setBillno(req.getBillno());
             Double retAmount = tTransdtl.getAmount() * 100;
             resp.setAmount(retAmount.intValue());
diff --git a/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java b/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java
index fffc97f..861bfb4 100644
--- a/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java
+++ b/src/main/java/com/supwisdom/dlpay/framework/util/DateUtil.java
@@ -138,6 +138,7 @@
         }
     }
 
+
     /**
      * Description: 比较两个时间字符串的前后关系 @param firstTime String 格式:pattern
      *
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustTypeController.java b/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustTypeController.java
index 39f4109..52ea76e 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustTypeController.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustTypeController.java
@@ -1,27 +1,18 @@
 package com.supwisdom.dlpay.restaurant.controller;
 
 
-import com.google.gson.Gson;
 import com.supwisdom.dlpay.api.bean.JsonResult;
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.framework.util.WebConstant;
-import com.supwisdom.dlpay.restaurant.bean.AreaSearchBean;
 import com.supwisdom.dlpay.restaurant.bean.CustTypeSearchBean;
-import com.supwisdom.dlpay.restaurant.domain.TArea;
 import com.supwisdom.dlpay.restaurant.domain.TCustType;
-import com.supwisdom.dlpay.restaurant.service.AreaService;
 import com.supwisdom.dlpay.restaurant.service.CustTypeService;
 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 java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
 @Controller
 @RequestMapping("/custtype")
 public class CustTypeController {
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 f372667..6e26cf7 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
@@ -479,5 +479,70 @@
         }
     }
 
+    @PostMapping("/discountrule/updatedetailexpiredate")
+    @ResponseBody
+    public JsonResult updateDetailExpiredate(@RequestParam("ruleid") Integer ruleid,
+                                             @RequestParam("id") String id,
+                                             @RequestParam("expiredate") String expiredate,
+                                             @AuthenticationPrincipal UserDetails operUser) {
+        try {
+            if (null == ruleid || StringUtil.isEmpty(id)) {
+                return JsonResult.error("参数传递错误");
+            }
+
+            TOperator oper = (TOperator) operUser;
+            if (null == oper || StringUtil.isEmpty(oper.getOperid())) {
+                return JsonResult.error("登录过期,请重新登录");
+            }
+
+            if (deviceDiscountRuleService.updateDetailExpiredate(ruleid, id,expiredate, 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);
+        }
+    }
+
+    @GetMapping("/discountrule/expiredownload")
+    @ResponseBody
+    public void downloadExpireExcel(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            String[] title = {"市民卡号", "姓名","过期日期"}; //表头
+            String[][] infos = {{"19045632", "张三","20200805"}}; // 示例内容
+            ExportExcel.queryexcel("餐补过期导入名单模板", title, infos, request, response);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @PostMapping("/discountrule/updateexpiredatebyexcel")
+    @ResponseBody
+    public JsonResult updateExpireDateByExcel(
+                                              @RequestParam(value = "file", required = false) MultipartFile file,
+                                              @AuthenticationPrincipal UserDetails operUser) {
+        try {
+
+            if (deviceDiscountRuleService.updateExpireDateByExcel(file)) {
+                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/loadexpireimport")
+    public String loadExpireImport(Model model) {
+        return "restaurant/discountrule/expireimport";
+    }
 
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java
index d56a099..7fc4b87 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/dao/DiscountDetailDao.java
@@ -20,7 +20,16 @@
   @Query("update TDiscountDetail t set t.status=?1 where t.ruleid=?2 ")
   void updateRuleDetailStatusByRuleid(String status, int ruleid);
 
+
+  @Modifying
+  @Query("update TDiscountDetail t set t.expiredate=?1 where t.userid=?2 ")
+  void updateDetailExpiredate(String expiredate, String userid);
+
+
   List<TDiscountDetail> findAllByUserid(String userid);
 
   void deleteByUserid(String userid);
+
+  TDiscountDetail findByRuleidAndUserid(int ruleid,String userid);
+
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java
index c959c1d..16cc780 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TDiscountDetail.java
@@ -32,6 +32,9 @@
   @Column(name="LASTSAVED", length = 14)
   private String lastsaved;
 
+  @Column(name="EXPIREDATE", length = 8)
+  private String expiredate;
+
   public String getId() {
     return id;
   }
@@ -87,4 +90,12 @@
   public void setLastsaved(String lastsaved) {
     this.lastsaved = lastsaved;
   }
+
+  public String getExpiredate() {
+    return expiredate;
+  }
+
+  public void setExpiredate(String expiredate) {
+    this.expiredate = expiredate;
+  }
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/domain/TOperDeviceGroupBind.java b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TOperDeviceGroupBind.java
new file mode 100644
index 0000000..a4ce747
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/domain/TOperDeviceGroupBind.java
@@ -0,0 +1,46 @@
+package com.supwisdom.dlpay.restaurant.domain;
+
+import org.hibernate.annotations.GenericGenerator;
+
+import javax.persistence.*;
+
+@Entity
+@Table(name = "TB_Oper_DeviceGroup_Bind")
+@SequenceGenerator(name="SEQ_AREA",sequenceName="SEQ_AREA",allocationSize=1)
+public class TOperDeviceGroupBind {
+
+    @Id
+    @GenericGenerator(name = "idGenerator", strategy = "uuid")
+    @GeneratedValue(generator = "idGenerator")
+    @Column(name = "bid", nullable = false, length = 32)
+    private String bid;
+    @Column(name = "OPERID", nullable = false, length = 32)
+    private String operid;
+    @Column(name = "devgroupid", nullable = false, length = 8)
+    private Integer devgroupid;
+
+
+    public String getBid() {
+        return bid;
+    }
+
+    public void setBid(String bid) {
+        this.bid = bid;
+    }
+
+    public String getOperid() {
+        return operid;
+    }
+
+    public void setOperid(String operid) {
+        this.operid = operid;
+    }
+
+    public Integer getDevgroupid() {
+        return devgroupid;
+    }
+
+    public void setDevgroupid(Integer devgroupid) {
+        this.devgroupid = devgroupid;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/service/DeptService.java b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeptService.java
index 3c32211..5731d2c 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/DeptService.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeptService.java
@@ -2,20 +2,12 @@
 
 import com.supwisdom.dlpay.api.bean.JsonResult;
 import com.supwisdom.dlpay.framework.util.PageResult;
-import com.supwisdom.dlpay.restaurant.bean.AreaSearchBean;
 import com.supwisdom.dlpay.restaurant.bean.DeptSearchBean;
-import com.supwisdom.dlpay.restaurant.bean.TDeptShowBean;
-import com.supwisdom.dlpay.restaurant.domain.TArea;
-import com.supwisdom.dlpay.restaurant.domain.TDeviceGroup;
+import com.supwisdom.dlpay.restaurant.domain.TDept;
 import com.supwisdom.dlpay.system.bean.TreeSelectNode;
-import com.supwisdom.dlpay.system.bean.ZTreeNode;
 import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 
-import com.supwisdom.dlpay.restaurant.domain.TDept;
-import org.springframework.web.multipart.MultipartFile;
-
-import javax.servlet.http.HttpServletRequest;
 import java.util.List;
 
 public interface DeptService {
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 7d938a1..23062ef 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
@@ -5,8 +5,6 @@
 import com.supwisdom.dlpay.framework.domain.TOperator;
 import com.supwisdom.dlpay.framework.util.PageResult;
 import com.supwisdom.dlpay.restaurant.bean.*;
-import com.supwisdom.dlpay.restaurant.domain.TCustomer;
-import com.supwisdom.dlpay.restaurant.domain.TCustomerList;
 import com.supwisdom.dlpay.restaurant.domain.TDiscountDetail;
 import com.supwisdom.dlpay.restaurant.domain.TDiscountDevbind;
 import com.supwisdom.dlpay.system.bean.ZTreeNode;
@@ -26,6 +24,10 @@
   @Transactional(rollbackFor = Exception.class, readOnly = true)
   public List<TDiscountDetail> getExpiredDisCountDetail(Integer custtypeid);
 
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  public List<TDiscountDetail> getExpiredDisCountDetailByExpireDate();
+
+
   @Transactional(rollbackFor = Exception.class)
   public boolean changeDiscountRuleLimitCnt(int ruleid,int limitcnt) throws WebCheckException;
 
@@ -69,6 +71,9 @@
   @Transactional(rollbackFor = Exception.class)
   boolean saveRuleBindDevices(int ruleid, List<Integer> deviceIds, TOperator oper) throws WebCheckException;
 
+  @Transactional(rollbackFor = Exception.class)
+  boolean updateDetailExpiredate(int ruleid, String custid, String id, TOperator oper) throws WebCheckException;
+
   @Transactional(rollbackFor = Exception.class, readOnly = true)
   PageResult<DiscountDetailAddBean> getCustomerNotInDiscount(String searchkey,Integer ruleid, int pageNo, int pageSize);
 
@@ -78,6 +83,9 @@
   @Transactional(rollbackFor = Exception.class)
   boolean updateDiscountDetail(TDiscountDetail detail ) ;
 
+  @Transactional(rollbackFor = Exception.class)
+  boolean deleteDiscountDetail(TDiscountDetail detail ) ;
+
 
   @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class,readOnly = true)
   List<ZTreeNode> getUserDiscount(String custid);
@@ -85,4 +93,7 @@
   @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
   JsonResult saveDiscountDetails(String custid, String rules);
 
+  @Transactional(rollbackFor = Exception.class)
+  boolean updateExpireDateByExcel(MultipartFile file) throws Exception;
+
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/CustomerServiceImpl.java b/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/CustomerServiceImpl.java
index 36eb00e..10c69a9 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/CustomerServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/CustomerServiceImpl.java
@@ -12,6 +12,7 @@
 import com.supwisdom.dlpay.restaurant.service.CardService;
 import com.supwisdom.dlpay.restaurant.service.CustomerService;
 import com.supwisdom.dlpay.restaurant.service.DeptService;
+import com.supwisdom.dlpay.restaurant.util.DataUtil;
 import com.supwisdom.dlpay.restaurant.util.RestaurantConstant;
 import com.supwisdom.dlpay.system.bean.ZTreeNode;
 import org.apache.commons.lang3.StringUtils;
@@ -111,6 +112,12 @@
         query.setMaxResults(param.getPageSize()); //分页显示
         query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(CustomerShowBean.class));
         List<CustomerShowBean> list = query.getResultList();
+        if(null!=list){
+           for(CustomerShowBean bean:list){
+               bean.setCustname(DataUtil.dataDesensitization(bean.getCustname(),1));
+               bean.setCardno(DataUtil.dataDesensitization(bean.getCardno(),4));
+           }
+        }
         BigInteger count = (BigInteger) countQuery.getSingleResult();
         return new PageResult<>(count.longValue(), list);
     }
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 48604ea..18255fb 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
@@ -41,6 +41,7 @@
 import javax.persistence.criteria.Root;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Optional;
 
@@ -204,6 +205,18 @@
     }
 
     @Override
+    public List<TDiscountDetail> getExpiredDisCountDetailByExpireDate() {
+        StringBuffer sb = new StringBuffer("select t.* from tb_discount_detail t " +
+                "where  t.expiredate <>''  " +
+                "and t.status='normal'");
+        Query query = entityManager.createNativeQuery(sb.toString());
+        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(TDiscountDetail.class));
+        List<TDiscountDetail> list = query.getResultList();
+        if (null != list) return list;
+        return new ArrayList<>(0);
+    }
+
+    @Override
     public boolean saveNewDiscountRule(String rulename, String ruletype, String starttime,
                                        String endtime, Double amount, Integer limitcnt, String listid, TOperator oper, String rulemode) throws Exception {
         TDiscountRule rule = new TDiscountRule();
@@ -327,8 +340,8 @@
 
     @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 ");
+        StringBuffer querySql = new StringBuffer("from TDiscountDetail t where t.ruleid=:rlid and t.status='normal' ");
+        StringBuffer countSql = new StringBuffer("select count(t.id) as cnt from TDiscountDetail t where t.ruleid=:rlid and t.status='normal' ");
         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) ");
@@ -520,6 +533,33 @@
     }
 
     @Override
+    public boolean updateDetailExpiredate(int ruleid, String id, String expiredate, 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("所选餐补规则状态异常");
+        }
+        if(!StringUtil.isEmpty(expiredate)){
+            boolean isdate=DateUtil.checkDatetimeValid(expiredate,"yyyyMMdd");
+            if(!isdate){
+                throw new WebCheckException("日期格式错误");
+            }
+        }else{
+            expiredate="";
+        }
+
+        Optional<TDiscountDetail> detail=discountDetailDao.findById(id);
+        if(null==detail){
+            throw new WebCheckException("所选餐补规则不存在");
+        }
+        TDiscountDetail discountDetail=detail.get();
+        discountDetail.setExpiredate(expiredate);
+        discountDetailDao.save(discountDetail);
+        return true;
+    }
+
+    @Override
     public PageResult<DiscountDetailAddBean> getCustomerNotInDiscount(String searchkey, Integer ruleid, int pageNo, int pageSize) {
         StringBuffer querySql = new StringBuffer("select t.custid,t.custname,c.cardno from tb_card c " +
                 "left join tb_customer t on t.custid=c.custid where t.custid not in (select userid from TB_DISCOUNT_DETAIL where ruleid=:ruleid) ");
@@ -530,6 +570,8 @@
             countSql.append(" and (c.cardno like :str or t.custname like :str) ");
         }
         querySql.append(" and t.status='normal' and c.status='normal' and c.transstatus='normal' ");
+        countSql.append(" and t.status='normal' and c.status='normal' and c.transstatus='normal' ");
+
         querySql.append(" order by c.cardno ");
         Query query = entityManager.createNativeQuery(querySql.toString());
         Query countQuery = entityManager.createNativeQuery(countSql.toString());
@@ -583,6 +625,12 @@
     }
 
     @Override
+    public boolean deleteDiscountDetail(TDiscountDetail detail) {
+        discountDetailDao.delete(detail);
+        return true;
+    }
+
+    @Override
     public List<ZTreeNode> getUserDiscount(String custid) {
         List<NodeData> nodeData = discountRuleDao.findDiscountRuleNode();
         List<TDiscountDetail> details = discountDetailDao.findAllByUserid(custid);
@@ -622,7 +670,7 @@
         discountDetailDao.deleteByUserid(custid);
         String[] datas = rules.split(",");
         for (String rule : datas) {
-            if ("0".equals(rule)) {
+            if ("0".equals(rule)||"".equals(rule)) {
                 continue;
             }
             TDiscountDetail detail = new TDiscountDetail();
@@ -638,6 +686,117 @@
 
     }
 
+    @Override
+    public boolean updateExpireDateByExcel(MultipartFile file) throws Exception {
+        String filename = file.getOriginalFilename();
+        if (!filename.endsWith(".xls") && !filename.endsWith(".xlsx")) {
+            throw new WebCheckException("文件格式错误,请选择excel文件");
+        }
+
+        List<Object[][]> excelData = null;
+        try {
+            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文件解析错误");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new WebCheckException("模板格式错误,请重新下载模板");
+        }
+
+        int index_cardno = -1;
+        int index_name = -1;
+        int index_expiredate=-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;
+            }else if ("过期日期".equals(titleRow[i])) {
+                index_expiredate = i;
+                continue;
+            }
+        }
+        if (index_cardno == -1 || index_name == -1 || excelData.get(0).length < 2) {
+            throw new WebCheckException("名单模板表头不能修改,且必须包含数据!");
+        }
+        String systime = systemUtilService.getSysdatetime().getHostdatetime();
+
+        List<String> successCardnos = new ArrayList<>(0);
+        List<String> errmsgList = new ArrayList<>(0);
+        try {
+            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();
+                String expiredate=row[index_expiredate] == null ? null : row[index_expiredate].toString().trim();
+                if (StringUtil.isEmpty(cardno)) {
+                    msg += ",市民卡号为空";
+                }
+                if (StringUtil.isEmpty(name)) {
+                    msg += ",姓名为空";
+                }
+                if (StringUtil.isEmpty(expiredate)) {
+                    msg += ",过期日期为空";
+                }
+                TCustomer customer = customerService.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 += ",市民卡号重复!";
+                }
+                boolean isdate=true;
+                if(!StringUtil.isEmpty(expiredate)){
+                    isdate=DateUtil.checkDatetimeValid(expiredate,"yyyyMMdd");
+                    if(!isdate){
+                        throw new WebCheckException("日期格式错误");
+                    }
+                }else{
+                    expiredate="";
+                }
+
+                if(!isdate){
+                    msg += ",日期格式错误";
+                }
+
+
+                if (!StringUtil.isEmpty(msg)) {
+                    errmsgList.add("第" + (n + 1) + "行数据错误" + msg);
+                } else {
+                    discountDetailDao.updateDetailExpiredate(expiredate,customer.getCustid());
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new WebCheckException("模板格式有误,请确保卡号为文本格式");
+        }
+
+        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;
+    }
+
     private DiscountDetailAddBean getDiscountDetailForAdd(String custid) {
         StringBuffer querySql = new StringBuffer("select t.custid,t.custname,c.cardno from tb_customer t " +
                 "left join tb_card c on t.custid=c.custid where  t.custid=:custid ");
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/TransDtlServiceImpl.java b/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/TransDtlServiceImpl.java
index 121f2a9..757ef15 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/TransDtlServiceImpl.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/impl/TransDtlServiceImpl.java
@@ -15,12 +15,14 @@
 import com.supwisdom.dlpay.restaurant.dao.TransDtlDao;
 import com.supwisdom.dlpay.restaurant.domain.TTransDtl;
 import com.supwisdom.dlpay.restaurant.service.TransDtlService;
+import com.supwisdom.dlpay.restaurant.util.DataUtil;
 import com.supwisdom.dlpay.restaurant.util.RestaurantConstant;
 import org.hibernate.query.internal.NativeQueryImpl;
 import org.hibernate.transform.Transformers;
 import org.jetbrains.annotations.NotNull;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
 import org.springframework.data.domain.PageRequest;
 import org.springframework.data.domain.Pageable;
 import org.springframework.data.domain.Sort;
@@ -57,8 +59,13 @@
                 , Sort.by("billno").descending());
 
         Specification<TTransDtl> spec = gettTransDtlSpecification(param);
+        Page<TTransDtl> dtls= transDtlDao.findAll(spec, pageable);
+        dtls.forEach((dtl)->{
+            dtl.setCustname(DataUtil.dataDesensitization(dtl.getCustname(),1));
+            dtl.setCardno(DataUtil.dataDesensitization(dtl.getCardno(),4));
+        });
 
-        return new PageResult<>(transDtlDao.findAll(spec, pageable));
+        return new PageResult<>(dtls);
     }
 
     @NotNull
@@ -128,7 +135,7 @@
                 switch (t.getStatus()){
                     case "init":status="未入账"; break;
                     case "success":status="已入账"; break;
-                    case "fail":status="已入账"; break;
+                    case "fail":status="失败"; break;
                     default:status="未知状态";
                 }
                 info0[i][7]=status;
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/task/CheckTransdtlTask.java b/src/main/java/com/supwisdom/dlpay/restaurant/task/CheckTransdtlTask.java
index 8efd88f..298063c 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/task/CheckTransdtlTask.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/task/CheckTransdtlTask.java
@@ -108,7 +108,7 @@
         param.setCheckdate(checkdate);
         param.setShopaccno(shop.getShopid());
         param.setDtltype("canteen");
-
+        param.setTenantid("");
         String returnString = shopProxy.downloadShopBill(param);
         if (StringUtil.isEmpty(returnString)) {
           errmsg = "请求核心平台对账返回为空!";
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/task/RestaurantTask.java b/src/main/java/com/supwisdom/dlpay/restaurant/task/RestaurantTask.java
index d34def5..dbff687 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/task/RestaurantTask.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/task/RestaurantTask.java
@@ -108,6 +108,19 @@
     public void checkDiscountExpire() {
         long t1 = System.currentTimeMillis();
         logger.info("=================== 检查餐补过期任务开始: ===================");
+        List<TenantDetails> multiTenantSchemas = multiTenantService.getSystemAllTenantDetails();
+        for (TenantDetails schema : multiTenantSchemas) {
+            TenantContextHolder.getContext().setTenant(schema);  //切换schema
+            logger.info("开始执行schema=[" + schema.getDbSchema() + "]的对账任务:");
+            doCheckDiscountExpire(); //TODO:执行task
+        }
+
+
+        long t2 = System.currentTimeMillis();
+        logger.info("=================== 检查餐补过期任务结束,耗时 " + (t2 - t1) + " ms ===================");
+    }
+
+    /*private void doCheckDiscountExpire() {
         List<TCustType> custTypes=custTypeDao.findAll();
         for(TCustType custType:custTypes){
             Integer expireday = custType.getExpireday();
@@ -126,16 +139,19 @@
                 }
             }
         }
+    }*/
 
-        long t2 = System.currentTimeMillis();
-        logger.info("=================== 检查餐补过期任务结束,耗时 " + (t2 - t1) + " ms ===================");
+    private void doCheckDiscountExpire() {
+        List<TDiscountDetail> details=deviceDiscountRuleService.getExpiredDisCountDetailByExpireDate( );
+        for(TDiscountDetail detail:details){
+            String datenow = DateUtil.getNow("yyyyMMdd");
+            String expiredate = detail.getExpiredate();
+            if (DateUtil.compareDatetime(expiredate,datenow,"yyyyMMdd")<0){
+               // detail.setStatus(RestaurantConstant.STATUS_DISCOUNTRULE_CLOSED);
+                deviceDiscountRuleService.deleteDiscountDetail(detail);
+            }
+        }
+
     }
 
-//    //TODO
-//    @Scheduled(cron = "0 0/1 * * * ? ")
-//    private void deleteExpiredWhitelist(){
-//        List<TCustomer> expiredCustomer=customerDao.findAll();
-//
-//    }
-
 }
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/util/DataUtil.java b/src/main/java/com/supwisdom/dlpay/restaurant/util/DataUtil.java
new file mode 100644
index 0000000..30d079c
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/util/DataUtil.java
@@ -0,0 +1,18 @@
+package com.supwisdom.dlpay.restaurant.util;
+
+import com.supwisdom.dlpay.framework.util.StringUtil;
+
+public class DataUtil {
+    public static String dataDesensitization(String data,int length) {
+        if (StringUtil.isEmpty(data)) {
+            return "";
+        }
+        int originLength = data.length();
+        String preStr = data.substring(0, length);
+        StringBuilder result = new StringBuilder(preStr);
+        for (int i = 0; i < originLength - preStr.length(); i++) {
+            result.append("X");
+        }
+        return result.toString();
+    }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java b/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java
index 8222e90..ee1d1e3 100644
--- a/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java
+++ b/src/main/java/com/supwisdom/dlpay/util/PaytypeUtil.java
@@ -7,4 +7,5 @@
     public static final String YKTPAY = "yktpay";
 
     public static final String WECHAT = "wechat";
+
 }
diff --git a/src/main/resources/templates/restaurant/customer/discount.html b/src/main/resources/templates/restaurant/customer/discount.html
index c350363..a0c8168 100644
--- a/src/main/resources/templates/restaurant/customer/discount.html
+++ b/src/main/resources/templates/restaurant/customer/discount.html
@@ -56,9 +56,7 @@
             for (let i = 0; i < nodes.length; i++) {
                 ids.push(nodes[i].id);//存功能ID
             }
-            if (ids.length < 1) {
-                return;
-            }
+
             let idStr = ids.toString();
             console.log(idStr)
             let token = $("meta[name='_csrf_token']").attr("value");
diff --git a/src/main/resources/templates/restaurant/discountrule/expireimport.html b/src/main/resources/templates/restaurant/discountrule/expireimport.html
new file mode 100644
index 0000000..cf8244d
--- /dev/null
+++ b/src/main/resources/templates/restaurant/discountrule/expireimport.html
@@ -0,0 +1,87 @@
+<div style="color: #0c91e5" align="right">
+    <a th:href="@{/discountrule/expiredownload}" class="layui-btn layui-btn-primary" style="margin: 5px">点击此处下载导入模板</a>
+</div>
+<form lay-filter="form" class="layui-form model-form" >
+    <!-- row -->
+    <div class="layui-form-item">
+        <label class="control-label">请选择导入文件<span style="color: red"> * </span></label>
+        <input type="file" name="file" id="expire-file" placeholder="请选择xls格式文件">
+    </div>
+
+    <!-- /row -->
+    <!-- row -->
+    <div class="layui-form-item" align="center">
+        <div id="expire-importError" style="color:red">
+        </div>
+        <div id="expire-importInfo" >
+        </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="expire-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 = '[[@{/discountrule/updateexpiredatebyexcel}]]';
+        // 回显user数据
+
+        /* let fid = admin.getTempData("fid");
+         if (fid) {
+             form.val('form', {"fid": fid});
+         }*/
+        // 表单提交事件
+        form.on('submit(expire-form-import)', function (data) {
+            $("#expire-importError").html("");
+            var files = $('#expire-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 {
+                        $("#expire-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/restaurant/discountrule/rule.html b/src/main/resources/templates/restaurant/discountrule/rule.html
index de36541..beb9f43 100644
--- a/src/main/resources/templates/restaurant/discountrule/rule.html
+++ b/src/main/resources/templates/restaurant/discountrule/rule.html
@@ -19,6 +19,8 @@
             <button id="btn-search-discountrule" class="layui-btn icon-btn" data-type="search"><i class="layui-icon">&#xe615;</i>搜索
             </button>
             <button id="btn-discountrule-add" class="layui-btn icon-btn" data-type="add"><i class="layui-icon">&#xe654;</i>新 增</button>
+            <button id="btn-discountrule-import" class="layui-btn icon-btn" ><i class="layui-icon"></i>批量更新有效期</button>
+
         </div>
         <table class="layui-table" id="discountruleTable" lay-filter="discountruleTable-filter"></table>
     </div>
@@ -52,7 +54,7 @@
             cols: [
                 [
                     {field: 'rulename', title: '餐补名称', align: 'center', fixed: 'left' },
-                    {field: 'timeperiod',width:100, title: '优惠时间段',  align: 'center'},
+                    {field: 'timeperiod',width:150, title: '优惠时间段',  align: 'center'},
                     {
                         field: 'ruletype', title: '餐补类型', align: 'center', width: 120,  sort: true, templet: function (d) {
                             if ('quota' == d.ruletype) {
@@ -125,6 +127,20 @@
             });
         });
 
+        $('#btn-discountrule-import').click(function () {
+            showDownload();
+        });
+        let showDownload = function () {
+            let title ='导入';
+            admin.popupCenter({
+                title: title,
+                path: '[[@{/discountrule/loadexpireimport}]]',
+                finish: function () {
+                 //   table.reload('customer-table', {});
+                }
+            });
+        };
+
 
         table.on('edit(discountruleTable-filter)', function (obj) {
             var row = obj.data; //得到所在行所有键值
diff --git a/src/main/resources/templates/restaurant/discountrule/ruledetail.html b/src/main/resources/templates/restaurant/discountrule/ruledetail.html
index 01928ae..48162ca 100644
--- a/src/main/resources/templates/restaurant/discountrule/ruledetail.html
+++ b/src/main/resources/templates/restaurant/discountrule/ruledetail.html
@@ -30,7 +30,8 @@
                 cols: [
                     [
                         {field: 'cardno', title: '市民卡号', align: 'center'},
-                        {field: 'username', title: '姓名', align: 'center'}
+                        {field: 'username', title: '姓名', align: 'center'},
+                        {field: 'expiredate', title: '过期日期', align: 'center', edit: 'text'}
                     ]
                 ]
             });
@@ -44,5 +45,31 @@
             table.reload('discountruleDetailTable', {where: {ruleid: ruleid, searchkey: searchkey}, page: {curr: 1}});
         });
 
+        table.on('edit(discountruleDetailTable-filter)', function (obj) {
+            console.log(obj.data)
+            var ruleid = $("#search-discountrule-detail-ruleid").val();
+
+            var row = obj.data; //得到所在行所有键值
+            var expiredate = obj.value; //得到修改后的值
+            admin.go('[[@{/discountrule/updatedetailexpiredate}]]', {
+                ruleid: ruleid,
+                id: row.id,
+                expiredate: expiredate,
+                _csrf: $("meta[name='_csrf_token']").attr("value"),
+            }, function (data) {
+                if (data.code == 200) {
+                    layer.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 () {
+                layer.msg('修改失败了,请稍后再试', {icon: 2});
+            });
+        })
     });
 </script>
\ No newline at end of file