添加单个名单增加功能
diff --git a/config/application-devel-pg.properties b/config/application-devel-pg.properties
index 0a33918..28f9f94 100644
--- a/config/application-devel-pg.properties
+++ b/config/application-devel-pg.properties
@@ -28,6 +28,8 @@
 payapi.url=https://yy.dlsmk.cn/payapi
 
 payapi.appid=200001
+payapi.appkey=105161967fe247a493b090fd90c8b996
+
 
 cron.offlinedtl= 0 0/5 * * * ?
 payapi.logintime= 0 0/5 * * * ? 
\ No newline at end of file
diff --git a/sql/restarant_create_table.sql b/sql/restarant_create_table.sql
index 9110688..6eebdec 100644
--- a/sql/restarant_create_table.sql
+++ b/sql/restarant_create_table.sql
@@ -343,7 +343,7 @@
 -- ----------------------------
 CREATE TABLE tb_discount_rule (
   ruleid int4 NOT NULL,
-  amount numeric(9,2) NOT NULL,
+  amount float8 NOT NULL,
   check_operid varchar(32),
   create_operid varchar(32),
   createtime varchar(14),
@@ -355,6 +355,7 @@
   rulename varchar(200)  NOT NULL,
   ruletype varchar(10)  NOT NULL,
   starttime varchar(4)  NOT NULL,
+  rulemode varchar(10),
   status varchar(10)  NOT NULL,
   verno int4 NOT NULL
 );
@@ -428,13 +429,13 @@
   billno varchar(20)  NOT NULL,
   accdate varchar(8),
   acctime varchar(6),
-  amount numeric(9,2),
+  amount float8,
   attr1 varchar(1000),
   cardno varchar(9),
   custid varchar(32),
   custname varchar(30),
   custtype int4,
-  managefee numeric(9,2),
+  managefee float8,
   mealtype varchar(10),
   revbillno varchar(20),
   revflag int4,
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 755fdf3..7644bdc 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
@@ -394,64 +394,65 @@
     public PosPayConfirmResp doPayConfirm(PosPayConfirmReq req) {
         PosPayConfirmResp resp = new PosPayConfirmResp();
 
-        TTransDtl tTransdtl = transDtlService.getTransDtlByBillno(req.getBillno()); //TODO:改 事务加锁改状态
-        if (null == tTransdtl) {
-            resp.setRetcode(ErrorCode.ERRIF_POSDTL_NOTEXIST);
-            resp.setRetmsg("交易参考号" + req.getBillno() + "不存在");
-            return resp;
-        }
-
-        TDevice tDevice = deviceService.getDeviceByDevphyid(req.getDevphyid());
-        APIResp apiResp = checkDevice(resp, tDevice);
-        if (!ErrorCode.ERRIF_OK.equals(apiResp.getRetcode())) {
-            resp.setRetcode(apiResp.getRetcode());
-            resp.setRetmsg(apiResp.getRetmsg());
-            return resp;
-        }
-
-        TCustomer cus = customerService.getCustomerByCustid(tTransdtl.getCustid());
-        if (null == cus) {
-            resp.setRetcode(ErrorCode.ERRIF_POSDTL_NOTEXIST);
-            resp.setRetmsg("客户" + tTransdtl.getCustid() + "不存在");
-            return resp;
-        }
-        Double amount = req.getAmount() / 100.0;
-        Double cntamount = 0.0;
-        logger.info("交易号:" + tTransdtl.getBillno() + ",,,交易金额:" + req.getAmount());
-        DiscountBean bean = deviceDiscountRuleService.getCustomerDiscount(tDevice.getId(), req.getTermtime(), cus.getCustid());
-        if (null != bean) {
-            cntamount = getDiscountAmount(req.getTermdate(), cus.getCustid(), amount, bean);
-            if(cntamount!=amount){
-                tTransdtl.setRuleid(bean.getRuleid());
-            }
-            tTransdtl.setManagefee(amount - cntamount);
-            tTransdtl.setManagefeetype(bean.getRuletype());
-            tTransdtl.setAmount(cntamount);
-        } else {
-            tTransdtl.setManagefeetype(RestaurantConstant.RULETYPE_NORMAL);
-            tTransdtl.setAmount(amount);
-            tTransdtl.setManagefee(cntamount);
-        }
-
-        TDevparaGroup group = null;
-        TDevparaBind bind = deviceParamService.getDevparaBindByDeviceid(tDevice.getId());
-        if (null == bind) {
-            group = deviceParamService.getDefaultDevparaGroup();
-        } else {
-            group = deviceParamService.getDevparaGroupByGroupid(bind.getGroupid());
-        }
-        TDevpara para = deviceParamService.getDevparaInfoByParaname(group.getGroupid(), "once_limit_amt");
-        if (null != para || StringUtil.isEmpty(para.getParaval())) {
-            Double oncelimit = Double.parseDouble(para.getParaval()) / 100;
-            if (amount > oncelimit && cntamount > oncelimit) {
-                resp.setRetcode("99");
-                resp.setRetmsg("消费金额超出单笔消费限额");
+        try{
+            TTransDtl tTransdtl = transDtlService.getTransDtlByBillno(req.getBillno()); //TODO:改 事务加锁改状态
+            if (null == tTransdtl) {
+                resp.setRetcode(ErrorCode.ERRIF_POSDTL_NOTEXIST);
+                resp.setRetmsg("交易参考号" + req.getBillno() + "不存在");
                 return resp;
             }
-        }
 
-        tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_WAIT);
-        TTransDtl dtl = transDtlService.saveTransdtl(tTransdtl);
+            TDevice tDevice = deviceService.getDeviceByDevphyid(req.getDevphyid());
+            APIResp apiResp = checkDevice(resp, tDevice);
+            if (!ErrorCode.ERRIF_OK.equals(apiResp.getRetcode())) {
+                resp.setRetcode(apiResp.getRetcode());
+                resp.setRetmsg(apiResp.getRetmsg());
+                return resp;
+            }
+
+            TCustomer cus = customerService.getCustomerByCustid(tTransdtl.getCustid());
+            if (null == cus) {
+                resp.setRetcode(ErrorCode.ERRIF_POSDTL_NOTEXIST);
+                resp.setRetmsg("客户" + tTransdtl.getCustid() + "不存在");
+                return resp;
+            }
+            Double amount = req.getAmount() / 100.0;
+            Double cntamount = 0.0;
+            logger.info("交易号:" + tTransdtl.getBillno() + ",,,交易金额:" + req.getAmount());
+            DiscountBean bean = deviceDiscountRuleService.getCustomerDiscount(tDevice.getId(), req.getTermtime(), cus.getCustid());
+            if (null != bean) {
+                cntamount = getDiscountAmount(req.getTermdate(), cus.getCustid(), amount, bean);
+                if(cntamount!=amount){
+                    tTransdtl.setRuleid(bean.getRuleid());
+                }
+                tTransdtl.setManagefee(amount - cntamount);
+                tTransdtl.setManagefeetype(bean.getRuletype());
+                tTransdtl.setAmount(cntamount);
+            } else {
+                tTransdtl.setManagefeetype(RestaurantConstant.RULETYPE_NORMAL);
+                tTransdtl.setAmount(amount);
+                tTransdtl.setManagefee(cntamount);
+            }
+
+            TDevparaGroup group = null;
+            TDevparaBind bind = deviceParamService.getDevparaBindByDeviceid(tDevice.getId());
+            if (null == bind) {
+                group = deviceParamService.getDefaultDevparaGroup();
+            } else {
+                group = deviceParamService.getDevparaGroupByGroupid(bind.getGroupid());
+            }
+            TDevpara para = deviceParamService.getDevparaInfoByParaname(group.getGroupid(), "once_limit_amt");
+            if (null != para || StringUtil.isEmpty(para.getParaval())) {
+                Double oncelimit = Double.parseDouble(para.getParaval()) / 100;
+                if (amount > oncelimit && cntamount > oncelimit) {
+                    resp.setRetcode("99");
+                    resp.setRetmsg("消费金额超出单笔消费限额");
+                    return resp;
+                }
+            }
+
+            tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_WAIT);
+            TTransDtl dtl = transDtlService.saveTransdtl(tTransdtl);
 
 
    /*     if(RestaurantConstant.TRANSMODE_CODE.equals(dtl.getTransmode())){
@@ -475,59 +476,66 @@
             }
 
         }else{*/
-        CitizenCardPayinitParam param = new CitizenCardPayinitParam();
-        param.setBillno(dtl.getBillno());
-        param.setShopaccno(dtl.getShopid());
-        param.setTransdate(dtl.getTransdate());
-        param.setTranstime(dtl.getTranstime());
-        param.setCardNo(dtl.getCardno());
-        param.setAmount(MoneyUtil.YuanToFen(dtl.getAmount()));
-        param.setDtltype("canteen");
-        CitizenPayResponse response = citizenCardPayProxy.citizencardPayinit(param);
-        if (response.getRetcode() == 0) {
-            tTransdtl.setRefno(response.getRefno());
-            CitizenCardPayfinishParam confirmParam = new CitizenCardPayfinishParam();
-            confirmParam.setRefno(response.getRefno());
-            CitizenPayResponse confirmResp = citizenCardPayProxy.citizencardPayFinish(confirmParam);
-            if (confirmResp.getRetcode() == 0) {
-                tTransdtl.setAccdate(systemUtilService.getAccdate());
-                tTransdtl.setAcctime(systemUtilService.getSysdatetime().getHosttime());
-                tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_SUCCESS);
-                resp.setRetcode(ErrorCode.ERRIF_OK);
-            } else if (confirmResp.getRetcode() == 55555) {
-                tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_WAIT);
-                resp.setRetcode(ErrorCode.ERRIF_OK);
+            CitizenCardPayinitParam param = new CitizenCardPayinitParam();
+            param.setBillno(dtl.getBillno());
+            param.setShopaccno(dtl.getShopid());
+            param.setTransdate(dtl.getTransdate());
+            param.setTranstime(dtl.getTranstime());
+            param.setCardNo(dtl.getCardno());
+            param.setAmount(MoneyUtil.YuanToFen(dtl.getAmount()));
+            param.setDtltype("canteen");
+            CitizenPayResponse response = citizenCardPayProxy.citizencardPayinit(param);
+            if (response.getRetcode() == 0) {
+                tTransdtl.setRefno(response.getRefno());
+                CitizenCardPayfinishParam confirmParam = new CitizenCardPayfinishParam();
+                confirmParam.setRefno(response.getRefno());
+                CitizenPayResponse confirmResp = citizenCardPayProxy.citizencardPayFinish(confirmParam);
+                if (confirmResp.getRetcode() == 0) {
+                    tTransdtl.setAccdate(systemUtilService.getAccdate());
+                    tTransdtl.setAcctime(systemUtilService.getSysdatetime().getHosttime());
+                    tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_SUCCESS);
+                    resp.setRetcode(ErrorCode.ERRIF_OK);
+                } else if (confirmResp.getRetcode() == 55555) {
+                    tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_WAIT);
+                    resp.setRetcode(ErrorCode.ERRIF_OK);
+                } else {
+                    tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_FAIL);
+                    tTransdtl.setAttr1(confirmResp.getRetmsg() + "," + confirmResp.getException());
+                    resp.setRetcode(confirmResp.getRetcode().toString());
+                    resp.setRetmsg(confirmResp.getRetmsg());
+                    return resp;
+                }
             } else {
                 tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_FAIL);
-                tTransdtl.setAttr1(confirmResp.getRetmsg() + "," + confirmResp.getException());
-                resp.setRetcode(confirmResp.getRetcode().toString());
-                resp.setRetmsg(confirmResp.getRetmsg());
+                tTransdtl.setAttr1(response.getRetmsg() + "," + response.getException());
+                resp.setRetcode(response.getRetcode().toString());
+                resp.setRetmsg(response.getRetmsg());
                 return resp;
             }
-        } else {
-            tTransdtl.setStatus(RestaurantConstant.STATUS_TRANSDTL_FAIL);
-            tTransdtl.setAttr1(response.getRetmsg() + "," + response.getException());
-            resp.setRetcode(response.getRetcode().toString());
-            resp.setRetmsg(response.getRetmsg());
+            // }
+
+
+            resp.setBillno(req.getBillno());
+            Double retAmount = tTransdtl.getAmount() * 100;
+            resp.setAmount(retAmount.intValue());
+            resp.setExtraamt(0);
+            resp.setUserid(cus.getCustid());
+            resp.setUsername(cus.getCustname());
+            resp.setBalance(0);
+            transDtlService.saveTransdtl(tTransdtl);
+            if (RestaurantConstant.STATUS_TRANSDTL_WAIT.equals(tTransdtl.getStatus())) {
+                resp.setRequire_query(true);
+            } else {
+                resp.setRequire_query(false);
+            }
+            return resp;
+        }catch (Exception e){
+            resp.setRetcode("99");
+            resp.setRetmsg("程序异常");
             return resp;
         }
-        // }
 
 
-        resp.setBillno(req.getBillno());
-        Double retAmount = tTransdtl.getAmount() * 100;
-        resp.setAmount(retAmount.intValue());
-        resp.setExtraamt(0);
-        resp.setUserid(cus.getCustid());
-        resp.setUsername(cus.getCustname());
-        resp.setBalance(0);
-        transDtlService.saveTransdtl(tTransdtl);
-        if (RestaurantConstant.STATUS_TRANSDTL_WAIT.equals(tTransdtl.getStatus())) {
-            resp.setRequire_query(true);
-        } else {
-            resp.setRequire_query(false);
-        }
-        return resp;
     }
 
     @Override
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountDetailAddBean.java b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountDetailAddBean.java
new file mode 100644
index 0000000..912e53a
--- /dev/null
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/bean/DiscountDetailAddBean.java
@@ -0,0 +1,33 @@
+package com.supwisdom.dlpay.restaurant.bean;
+
+import com.supwisdom.dlpay.system.bean.PageBean;
+
+public class DiscountDetailAddBean  {
+    private String cardno;
+    private String custname;
+    private String custid;
+
+    public String getCardno() {
+        return cardno;
+    }
+
+    public void setCardno(String cardno) {
+        this.cardno = cardno;
+    }
+
+    public String getCustname() {
+        return custname;
+    }
+
+    public void setCustname(String custname) {
+        this.custname = custname;
+    }
+
+    public String getCustid() {
+        return custid;
+    }
+
+    public void setCustid(String custid) {
+        this.custid = custid;
+    }
+}
diff --git a/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustomerListController.java b/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustomerListController.java
index 74ae4b6..e26ca0f 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustomerListController.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/controller/CustomerListController.java
@@ -135,7 +135,7 @@
     }
 
     @GetMapping("/load4detail")
-    public String load4ListDetails(@RequestParam("listid") Integer listid, Model model) {
+    public String load4ListDetails(@RequestParam("listid") String listid, Model model) {
         model.addAttribute("listDetailid", listid);
         return "restaurant/customerlist/listdetail";
     }
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 0cfc2cd..46c5cd6 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/controller/DeviceDiscountRuleController.java
@@ -4,10 +4,8 @@
 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.CustomerListSelectBean;
-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.bean.*;
+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.restaurant.service.CustomerListService;
@@ -215,6 +213,28 @@
         }
     }
 
+    @GetMapping("/discountrule/load4add")
+    public String load4AddDetails(@RequestParam("ruleid") Integer ruleid, Model model) {
+        model.addAttribute("AddRuleid", ruleid);
+        return "restaurant/discountrule/ruleadd";
+    }
+
+    @GetMapping("/discountrule/load4addlist")
+    @ResponseBody
+    public PageResult<DiscountDetailAddBean> searchDetails(@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.getCustomerNotInDiscount(searchkey, ruleid, pageNo, pageSize);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return new PageResult<>(99, "系统查询错误");
+        }
+    }
+
 
     /**
      * ====================================================
@@ -411,5 +431,27 @@
         }
     }
 
+    @PostMapping("/discountrule/adddiscountdetail")
+    @ResponseBody
+    public JsonResult addDiscountdetail(@RequestParam("ruleid") Integer ruleid,
+                                     @RequestParam("custids[]") List<String> custids) {
+        try {
+            if(null==ruleid || StringUtil.isEmpty(custids)){
+                return JsonResult.error("参数传递错误");
+            }
+
+            if (deviceDiscountRuleService.saveDiscountDetails(ruleid, custids)) {
+                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/service/DeviceDiscountRuleService.java b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
index 5feeb1c..3f3f9f2 100644
--- a/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
+++ b/src/main/java/com/supwisdom/dlpay/restaurant/service/DeviceDiscountRuleService.java
@@ -4,6 +4,8 @@
 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 org.springframework.transaction.annotation.Transactional;
@@ -57,4 +59,11 @@
 
   @Transactional(rollbackFor = Exception.class)
   boolean saveRuleBindDevices(int ruleid, List<Integer> deviceIds, TOperator oper) throws WebCheckException;
+
+  @Transactional(rollbackFor = Exception.class, readOnly = true)
+  PageResult<DiscountDetailAddBean> getCustomerNotInDiscount(String searchkey,Integer ruleid, int pageNo, int pageSize);
+
+  @Transactional(rollbackFor = Exception.class)
+  boolean saveDiscountDetails(int ruleid, List<String> custids ) 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 7d6a6db..1a2d43f 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
@@ -487,4 +487,76 @@
         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) ");
+        StringBuffer countSql = new StringBuffer("select count(t.custid) as cnt 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) ");
+        if (!StringUtil.isEmpty(searchkey)) {
+            querySql.append(" and (c.cardno like :str or t.custname like :str) ");
+            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' ");
+        querySql.append(" order by c.cardno ");
+        Query query = entityManager.createNativeQuery(querySql.toString());
+        Query countQuery = entityManager.createNativeQuery(countSql.toString());
+        query.setParameter("ruleid", ruleid);
+        countQuery.setParameter("ruleid", ruleid);
+        if (!StringUtil.isEmpty(searchkey)) {
+            query.setParameter("str", "%" + searchkey.trim() + "%");
+            countQuery.setParameter("str", "%" + searchkey.trim() + "%");
+        }
+        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(DiscountDetailAddBean.class));
+        query.setFirstResult((pageNo - 1) * pageSize);
+        query.setMaxResults(pageSize); //分页显示
+        List<DiscountDetailAddBean> list = query.getResultList();
+        BigInteger count = (BigInteger) countQuery.getSingleResult();
+        return new PageResult<>(count.longValue(), list);
+    }
+
+
+
+    @Override
+    public boolean saveDiscountDetails(int ruleid, List<String> custids ) throws WebCheckException {
+        TDiscountRule rule = discountRuleDao.findByRuleid(ruleid);
+        String systime = systemUtilService.getSysdatetime().getHostdatetime();
+
+        if (null == rule) {
+            throw new WebCheckException("所选餐补规则不存在");
+        } else if (!RestaurantConstant.STATUS_DISCOUNTRULE_NORMAL.equals(rule.getStatus())) {
+            throw new WebCheckException("所选餐补规则状态异常");
+        }
+
+        for (String id : custids) {
+            DiscountDetailAddBean bean=getDiscountDetailForAdd(id);
+            if (null == bean) {
+                throw new WebCheckException("客户号为[" + id + "]的客户不存在");
+            }
+            TDiscountDetail detail = new TDiscountDetail();
+            detail.setRuleid(rule.getRuleid());
+            detail.setCardno(bean.getCardno());
+            detail.setUsername(bean.getCustname());
+            detail.setUserid(id);
+            detail.setStatus(RestaurantConstant.STATUS_CHECKSTATUS_NORMAL);
+            detail.setLastsaved(systime);
+            discountDetailDao.save(detail); //保存明细
+        }
+        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 ");
+        Query query = entityManager.createNativeQuery(querySql.toString());
+        query.setParameter("custid", custid);
+        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(DiscountDetailAddBean.class));
+        List<DiscountDetailAddBean> list = query.getResultList();
+        if (list.size() > 0) {
+            return list.get(0);
+        }
+        return null;
+
+    }
+
 }
diff --git a/src/main/resources/templates/restaurant/discountrule/rule.html b/src/main/resources/templates/restaurant/discountrule/rule.html
index 87ffeb4..9ca17e2 100644
--- a/src/main/resources/templates/restaurant/discountrule/rule.html
+++ b/src/main/resources/templates/restaurant/discountrule/rule.html
@@ -31,6 +31,7 @@
     {{# 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 layui-btn-xs" lay-event="add">手工添加</a>
         <a class="layui-btn layui-btn-warm layui-btn-xs" lay-event="closed">关闭</a>
     {{# } }}
 </script>
@@ -191,6 +192,16 @@
                     }
                 });
             }
+            else if('add' == obj.event){
+                admin.popupCenter({
+                    title: "手工添加",
+                    path: '[[@{/discountrule/load4add}]]?ruleid=' + data.ruleid,
+                    area: '600px',
+                    finish: function () {
+                        table.reload('discountruleTable');
+                    }
+                });
+            }
         });
 
     });
diff --git a/src/main/resources/templates/restaurant/discountrule/ruleadd.html b/src/main/resources/templates/restaurant/discountrule/ruleadd.html
new file mode 100644
index 0000000..45cd8e4
--- /dev/null
+++ b/src/main/resources/templates/restaurant/discountrule/ruleadd.html
@@ -0,0 +1,109 @@
+<div class="layui-card">
+    <div class="layui-card-body">
+        <div class="layui-form toolbar">
+            搜索:
+            <input type="hidden" id="search-discountrule-Add-ruleid" th:value="${AddRuleid}" />
+            <input id="search-discountrule-Add-searchkey" class="layui-input search-input" maxlength="20" type="text" style="width: 200px;"
+                   placeholder="输入市民卡号或姓名查询"/>&emsp;
+            <button id="btn-search-discountrule-Add" class="layui-btn icon-btn" data-type="search"><i
+                    class="layui-icon">&#xe615;</i>搜索
+            </button>
+        </div>
+        <table class="layui-table" id="discountruleAddTable" lay-filter="discountruleAddTable-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="ruleadd-form-submit" lay-submit id="submitbtn" style="margin-right: 20px">保存</button>
+    </div>
+</div>
+<style type="text/css" id="devparabind-form-css">
+    .layui-form-item .layui-form-checkbox[lay-skin=primary] {
+        margin-top: 0;
+    }
+</style>
+<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 renderAddTable = function (obj) {
+            table.render({
+                elem: '#discountruleAddTable',
+                url: '[[@{/discountrule/load4addlist}]]',
+                where: obj,
+                page: true,
+                height: 472,
+                cols: [
+                    [
+                        {type: 'checkbox', style: "#devparabind-form-css", fixed: 'left'},
+                        {field: 'custname', title: '姓名', align: 'center'},
+                        {field: 'cardno', title: '卡号', align: 'center'}
+                    ]
+                ]
+            });
+        }
+        renderAddTable({ruleid: $("#search-discountrule-Add-ruleid").val()});
+
+        // 搜索按钮点击事件
+        $('#btn-search-discountrule-Add').click(function () {
+            var ruleid = $("#search-discountrule-Add-ruleid").val();
+            var searchkey = $("#search-discountrule-Add-searchkey").val();
+            table.reload('discountruleAddTable', {where: {ruleid: ruleid, searchkey: searchkey}, page: {curr: 1}});
+        });
+
+
+
+        form.on('submit(ruleadd-form-submit)', function (el) {
+            var ruleid = $("#search-discountrule-Add-ruleid").val();
+            var checkStatus = table.checkStatus('discountruleAddTable');
+            var data = checkStatus.data;
+            var custids = [];
+            debugger
+            for (var i = 0; i < data.length; i++) {
+                custids.push(data[i].custid);
+            }
+            if (custids.length < 1) {
+                layer.msg("请选择客户", {icon: 2, time: 1500});
+                return;
+            }
+
+            console.log(ruleid, custids);
+            layer.load(2);
+            var token = $("meta[name='_csrf_token']").attr("value");
+            $.ajax({
+                type: "POST",
+                dataType: "json",
+                url: '[[@{/discountrule/adddiscountdetail}]]',
+                data: {
+                    "ruleid": ruleid,
+                    "custids[]": custids,
+                    "_csrf": token
+                },
+                success: function (result) {
+                    layer.closeAll('loading');
+                    if (result.code == 200) {
+                        layer.msg(result.msg, {icon: 1});
+                        table.reload('whitelist-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