Просмотр исходного кода

缴费功能加入分布式锁功能

wuxw лет назад: 6
Родитель
Сommit
ff5a0ebccb
16 измененных файлов с 962 добавлено и 271 удалено
  1. 118 0
      Api/src/main/java/com/java110/api/listener/fee/PayFeeConfirmListener.java
  2. 263 0
      Api/src/main/java/com/java110/api/listener/fee/PayFeePreListener.java
  3. 1 1
      FeeService/src/main/java/com/java110/fee/FeeServiceApplicationStart.java
  4. 33 34
      FeeService/src/main/java/com/java110/fee/listener/fee/AbstractFeeBusinessServiceDataFlowListener.java
  5. 99 44
      FeeService/src/main/java/com/java110/fee/listener/fee/UpdateFeeInfoListener.java
  6. 28 6
      OrderService/src/main/java/com/java110/order/dao/ICenterServiceDAO.java
  7. 11 0
      OrderService/src/main/java/com/java110/order/dao/impl/CenterServiceDAOImpl.java
  8. 10 0
      OrderService/src/main/java/com/java110/order/smo/impl/OrderInnerServiceSMOImpl.java
  9. 62 0
      java110-bean/src/main/java/com/java110/dto/order/BusinessDto.java
  10. 9 0
      java110-core/src/main/java/com/java110/core/smo/order/IOrderInnerServiceSMO.java
  11. 31 0
      java110-db/src/main/resources/mapper/center/CenterServiceDAOImplMapper.xml
  12. 187 185
      java110-db/src/main/resources/mapper/fee/FeeDetailServiceDaoImplMapper.xml
  13. 2 0
      java110-db/src/main/resources/mapper/fee/FeeServiceDaoImplMapper.xml
  14. 1 1
      java110-utils/src/main/java/com/java110/utils/cache/BaseCache.java
  15. 6 0
      java110-utils/src/main/java/com/java110/utils/constant/ServiceCodeConstant.java
  16. 101 0
      java110-utils/src/main/java/com/java110/utils/lock/DistributedLock.java

+ 118 - 0
Api/src/main/java/com/java110/api/listener/fee/PayFeeConfirmListener.java

@@ -0,0 +1,118 @@
+package com.java110.api.listener.fee;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.java110.api.listener.AbstractServiceApiDataFlowListener;
+import com.java110.core.annotation.Java110Listener;
+import com.java110.core.context.DataFlowContext;
+import com.java110.core.smo.fee.IFeeConfigInnerServiceSMO;
+import com.java110.core.smo.fee.IFeeInnerServiceSMO;
+import com.java110.core.smo.room.IRoomInnerServiceSMO;
+import com.java110.dto.FeeConfigDto;
+import com.java110.dto.FeeDto;
+import com.java110.dto.RoomDto;
+import com.java110.entity.center.AppService;
+import com.java110.entity.order.Orders;
+import com.java110.event.service.api.ServiceDataFlowEvent;
+import com.java110.utils.constant.*;
+import com.java110.utils.exception.ListenerExecuteException;
+import com.java110.utils.util.Assert;
+import com.java110.utils.util.BeanConvertUtil;
+import com.java110.utils.util.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName PayFeeListener
+ * @Description TODO 交费通知侦听
+ * @Author wuxw
+ * @Date 2019/6/3 13:46
+ * @Version 1.0
+ * add by wuxw 2019/6/3
+ **/
+@Java110Listener("PayFeeConfirmListener")
+public class PayFeeConfirmListener extends AbstractServiceApiDataFlowListener {
+
+    private static Logger logger = LoggerFactory.getLogger(PayFeeConfirmListener.class);
+
+    @Override
+    public String getServiceCode() {
+        return ServiceCodeConstant.SERVICE_CODE_PAY_CONFIRM_PRE;
+    }
+
+    @Override
+    public HttpMethod getHttpMethod() {
+        return HttpMethod.POST;
+    }
+
+    @Override
+    public void soService(ServiceDataFlowEvent event) {
+
+        logger.debug("ServiceDataFlowEvent : {}", event);
+
+        DataFlowContext dataFlowContext = event.getDataFlowContext();
+        AppService service = event.getAppService();
+
+        String paramIn = dataFlowContext.getReqData();
+
+        //校验数据
+        validate(paramIn);
+        JSONObject paramObj = JSONObject.parseObject(paramIn);
+
+        HttpHeaders header = new HttpHeaders();
+        dataFlowContext.getRequestCurrentHeaders().put(CommonConstant.HTTP_ORDER_TYPE_CD, "D");
+        JSONArray businesses = new JSONArray();
+
+
+        JSONObject paramInObj = super.restToCenterProtocol(businesses, dataFlowContext.getRequestCurrentHeaders());
+
+        //将 rest header 信息传递到下层服务中去
+        super.freshHttpHeader(header, dataFlowContext.getRequestCurrentHeaders());
+
+        ResponseEntity<String> responseEntity = this.callService(dataFlowContext, service.getServiceCode(), paramInObj);
+
+        dataFlowContext.setResponseEntity(responseEntity);
+
+    }
+
+    /**
+     * 刷入order信息
+     *
+     * @param orders  订单信息
+     * @param headers 头部信息
+     */
+    protected void freshOrderProtocol(JSONObject orders, Map<String, String> headers) {
+        super.freshOrderProtocol(orders,headers);
+        orders.put("orderProcess", Orders.ORDER_PROCESS_ORDER_CONFIRM_SUBMIT);
+        orders.put("oId",orders.getString("oId"));
+    }
+
+    /**
+     * 数据校验
+     *
+     * @param paramIn "communityId": "7020181217000001",
+     *                "memberId": "3456789",
+     *                "memberTypeCd": "390001200001"
+     */
+    private void validate(String paramIn) {
+        Assert.jsonObjectHaveKey(paramIn, "oId", "请求报文中未包含订单信息");
+        JSONObject paramInObj = JSONObject.parseObject(paramIn);
+        Assert.hasLength(paramInObj.getString("oId"), "订单信息不能为空");
+
+    }
+
+    @Override
+    public int getOrder() {
+        return DEFAULT_ORDER;
+    }
+
+}

+ 263 - 0
Api/src/main/java/com/java110/api/listener/fee/PayFeePreListener.java

@@ -0,0 +1,263 @@
+package com.java110.api.listener.fee;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.java110.api.listener.AbstractServiceApiDataFlowListener;
+import com.java110.core.annotation.Java110Listener;
+import com.java110.core.context.DataFlowContext;
+import com.java110.core.smo.fee.IFeeConfigInnerServiceSMO;
+import com.java110.core.smo.fee.IFeeInnerServiceSMO;
+import com.java110.core.smo.room.IRoomInnerServiceSMO;
+import com.java110.dto.FeeConfigDto;
+import com.java110.dto.FeeDto;
+import com.java110.dto.RoomDto;
+import com.java110.entity.center.AppService;
+import com.java110.entity.order.Orders;
+import com.java110.event.service.api.ServiceDataFlowEvent;
+import com.java110.utils.constant.*;
+import com.java110.utils.exception.ListenerExecuteException;
+import com.java110.utils.util.Assert;
+import com.java110.utils.util.BeanConvertUtil;
+import com.java110.utils.util.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.ResponseEntity;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @ClassName PayFeeListener
+ * @Description TODO 预交费侦听
+ * @Author wuxw
+ * @Date 2019/6/3 13:46
+ * @Version 1.0
+ * add by wuxw 2019/6/3
+ **/
+@Java110Listener("payFeePreListener")
+public class PayFeePreListener extends AbstractServiceApiDataFlowListener {
+
+    private static Logger logger = LoggerFactory.getLogger(PayFeePreListener.class);
+
+
+    @Autowired
+    private IFeeInnerServiceSMO feeInnerServiceSMOImpl;
+
+    @Autowired
+    private IRoomInnerServiceSMO roomInnerServiceSMOImpl;
+
+    @Autowired
+    private IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl;
+
+
+    @Override
+    public String getServiceCode() {
+        return ServiceCodeConstant.SERVICE_CODE_PAY_FEE_PRE;
+    }
+
+    @Override
+    public HttpMethod getHttpMethod() {
+        return HttpMethod.POST;
+    }
+
+    @Override
+    public void soService(ServiceDataFlowEvent event) {
+
+        logger.debug("ServiceDataFlowEvent : {}", event);
+
+        DataFlowContext dataFlowContext = event.getDataFlowContext();
+        AppService service = event.getAppService();
+
+        String paramIn = dataFlowContext.getReqData();
+
+        //校验数据
+        validate(paramIn);
+        JSONObject paramObj = JSONObject.parseObject(paramIn);
+
+        HttpHeaders header = new HttpHeaders();
+        dataFlowContext.getRequestCurrentHeaders().put(CommonConstant.HTTP_ORDER_TYPE_CD, "D");
+        JSONArray businesses = new JSONArray();
+
+        //添加单元信息
+        businesses.add(addFeeDetail(paramObj, dataFlowContext));
+        businesses.add(modifyFee(paramObj, dataFlowContext));
+
+        JSONObject paramInObj = super.restToCenterProtocol(businesses, dataFlowContext.getRequestCurrentHeaders());
+
+        //将 rest header 信息传递到下层服务中去
+        super.freshHttpHeader(header, dataFlowContext.getRequestCurrentHeaders());
+
+        ResponseEntity<String> responseEntity = this.callService(dataFlowContext, service.getServiceCode(), paramInObj);
+
+        dataFlowContext.setResponseEntity(responseEntity);
+
+    }
+
+    /**
+     * 刷入order信息
+     *
+     * @param orders  订单信息
+     * @param headers 头部信息
+     */
+    protected void freshOrderProtocol(JSONObject orders, Map<String, String> headers) {
+        super.freshOrderProtocol(orders,headers);
+        orders.put("orderProcess", Orders.ORDER_PROCESS_ORDER_PRE_SUBMIT);
+
+    }
+    /**
+     * 添加费用明细信息
+     *
+     * @param paramInJson     接口调用放传入入参
+     * @param dataFlowContext 数据上下文
+     * @return 订单服务能够接受的报文
+     */
+    private JSONObject addFeeDetail(JSONObject paramInJson, DataFlowContext dataFlowContext) {
+
+
+        JSONObject business = JSONObject.parseObject("{\"datas\":{}}");
+        business.put(CommonConstant.HTTP_BUSINESS_TYPE_CD, BusinessTypeConstant.BUSINESS_TYPE_SAVE_FEE_DETAIL);
+        business.put(CommonConstant.HTTP_SEQ, DEFAULT_SEQ);
+        business.put(CommonConstant.HTTP_INVOKE_MODEL, CommonConstant.HTTP_INVOKE_MODEL_S);
+        JSONObject businessFeeDetail = new JSONObject();
+        businessFeeDetail.putAll(paramInJson);
+        businessFeeDetail.put("detailId", "-1");
+        businessFeeDetail.put("primeRate", "1.00");
+        //计算 应收金额
+        FeeDto feeDto = new FeeDto();
+        feeDto.setFeeId(paramInJson.getString("feeId"));
+        feeDto.setCommunityId(paramInJson.getString("communityId"));
+        List<FeeDto> feeDtos = feeInnerServiceSMOImpl.queryFees(feeDto);
+
+        if (feeDtos == null || feeDtos.size() != 1){
+            throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "查询费用信息失败,未查到数据或查到多条数据");
+        }
+
+        feeDto = feeDtos.get(0);
+        paramInJson.put("feeInfo",feeDto);
+
+
+        FeeConfigDto feeConfigDto = new FeeConfigDto();
+        feeConfigDto.setFeeTypeCd(feeDto.getFeeTypeCd());
+        feeConfigDto.setCommunityId(feeDto.getCommunityId());
+        List<FeeConfigDto> feeConfigDtos = feeConfigInnerServiceSMOImpl.queryFeeConfigs(feeConfigDto);
+        if (feeConfigDtos == null || feeConfigDtos.size() != 1){
+            throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "未查到费用配置信息,查询多条数据");
+        }
+
+        feeConfigDto = feeConfigDtos.get(0);
+        String builtUpArea = "0.00";
+
+        //物业费时 需要建筑面积 但是停车费不需要建筑面积
+        if(FeeTypeConstant.FEE_TYPE_PROPERTY.equals(feeConfigDto.getFeeTypeCd())) {
+
+            RoomDto roomDto = new RoomDto();
+            roomDto.setRoomId(feeDto.getPayerObjId());
+            roomDto.setCommunityId(feeDto.getCommunityId());
+            List<RoomDto> roomDtos = roomInnerServiceSMOImpl.queryRooms(roomDto);
+            if (roomDtos == null || roomDtos.size() != 1) {
+                throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_ERROR, "未查到房屋信息,查询多条数据");
+            }
+            roomDto = roomDtos.get(0);
+            builtUpArea = roomDto.getBuiltUpArea();
+        }
+
+
+
+        double receivableAmount = Double.parseDouble(feeConfigDto.getSquarePrice())
+                                    * Double.parseDouble(builtUpArea)
+                                    + Double.parseDouble(feeConfigDto.getAdditionalAmount());
+        receivableAmount = Double.parseDouble(paramInJson.getString("cycles")) * receivableAmount;
+
+        businessFeeDetail.put("receivableAmount", receivableAmount);
+        business.getJSONObject(CommonConstant.HTTP_BUSINESS_DATAS).put("businessFeeDetail", businessFeeDetail);
+
+        return business;
+    }
+
+
+    /**
+     * 修改费用信息
+     *
+     * @param paramInJson     接口调用放传入入参
+     * @param dataFlowContext 数据上下文
+     * @return 订单服务能够接受的报文
+     */
+    private JSONObject modifyFee(JSONObject paramInJson, DataFlowContext dataFlowContext) {
+
+
+        JSONObject business = JSONObject.parseObject("{\"datas\":{}}");
+        business.put(CommonConstant.HTTP_BUSINESS_TYPE_CD, BusinessTypeConstant.BUSINESS_TYPE_UPDATE_FEE_INFO);
+        business.put(CommonConstant.HTTP_SEQ, DEFAULT_SEQ+1);
+        business.put(CommonConstant.HTTP_INVOKE_MODEL, CommonConstant.HTTP_INVOKE_MODEL_S);
+        JSONObject businessFee = new JSONObject();
+        FeeDto feeInfo = (FeeDto)paramInJson.get("feeInfo");
+        Date endTime = feeInfo.getEndTime();
+        Calendar endCalender = Calendar.getInstance();
+        endCalender.setTime(endTime);
+        endCalender.add(Calendar.MONTH, Integer.parseInt(paramInJson.getString("cycles")));
+        feeInfo.setEndTime(endCalender.getTime());
+        Map feeMap = BeanConvertUtil.beanCovertMap(feeInfo);
+        feeMap.put("startTime", DateUtil.getFormatTimeString(feeInfo.getStartTime(), DateUtil.DATE_FORMATE_STRING_A));
+        feeMap.put("endTime", DateUtil.getFormatTimeString(feeInfo.getEndTime(), DateUtil.DATE_FORMATE_STRING_A));
+        businessFee.putAll(feeMap);
+        business.getJSONObject(CommonConstant.HTTP_BUSINESS_DATAS).put("businessFee", businessFee);
+
+        return business;
+    }
+
+    /**
+     * 数据校验
+     *
+     * @param paramIn "communityId": "7020181217000001",
+     *                "memberId": "3456789",
+     *                "memberTypeCd": "390001200001"
+     */
+    private void validate(String paramIn) {
+        Assert.jsonObjectHaveKey(paramIn, "communityId", "请求报文中未包含communityId节点");
+        Assert.jsonObjectHaveKey(paramIn, "cycles", "请求报文中未包含cycles节点");
+        Assert.jsonObjectHaveKey(paramIn, "receivedAmount", "请求报文中未包含receivedAmount节点");
+        Assert.jsonObjectHaveKey(paramIn, "feeId", "请求报文中未包含feeId节点");
+
+        JSONObject paramInObj = JSONObject.parseObject(paramIn);
+        Assert.hasLength(paramInObj.getString("communityId"), "小区ID不能为空");
+        Assert.hasLength(paramInObj.getString("cycles"), "周期不能为空");
+        Assert.hasLength(paramInObj.getString("receivedAmount"), "实收金额不能为空");
+        Assert.hasLength(paramInObj.getString("feeId"), "费用ID不能为空");
+
+    }
+
+    @Override
+    public int getOrder() {
+        return DEFAULT_ORDER;
+    }
+
+
+    public IFeeInnerServiceSMO getFeeInnerServiceSMOImpl() {
+        return feeInnerServiceSMOImpl;
+    }
+
+    public void setFeeInnerServiceSMOImpl(IFeeInnerServiceSMO feeInnerServiceSMOImpl) {
+        this.feeInnerServiceSMOImpl = feeInnerServiceSMOImpl;
+    }
+
+    public IFeeConfigInnerServiceSMO getFeeConfigInnerServiceSMOImpl() {
+        return feeConfigInnerServiceSMOImpl;
+    }
+
+    public void setFeeConfigInnerServiceSMOImpl(IFeeConfigInnerServiceSMO feeConfigInnerServiceSMOImpl) {
+        this.feeConfigInnerServiceSMOImpl = feeConfigInnerServiceSMOImpl;
+    }
+
+    public IRoomInnerServiceSMO getRoomInnerServiceSMOImpl() {
+        return roomInnerServiceSMOImpl;
+    }
+
+    public void setRoomInnerServiceSMOImpl(IRoomInnerServiceSMO roomInnerServiceSMOImpl) {
+        this.roomInnerServiceSMOImpl = roomInnerServiceSMOImpl;
+    }
+}

+ 1 - 1
FeeService/src/main/java/com/java110/fee/FeeServiceApplicationStart.java

@@ -33,7 +33,7 @@ import java.nio.charset.Charset;
 @EnableDiscoveryClient
 @Java110ListenerDiscovery(listenerPublishClass = BusinessServiceDataFlowEventPublishing.class,
         basePackages = {"com.java110.fee.listener"})
-@EnableFeignClients(basePackages = {"com.java110.core.smo.user"})
+@EnableFeignClients(basePackages = {"com.java110.core.smo.user","com.java110.core.smo.order"})
 public class FeeServiceApplicationStart {
 
     private static Logger logger = LoggerFactory.getLogger(FeeServiceApplicationStart.class);

+ 33 - 34
FeeService/src/main/java/com/java110/fee/listener/fee/AbstractFeeBusinessServiceDataFlowListener.java

@@ -15,16 +15,16 @@ import java.util.List;
 import java.util.Map;
 
 /**
- *
  * 费用 服务侦听 父类
  * Created by wuxw on 2018/7/4.
  */
-public abstract class AbstractFeeBusinessServiceDataFlowListener extends AbstractBusinessServiceDataFlowListener{
+public abstract class AbstractFeeBusinessServiceDataFlowListener extends AbstractBusinessServiceDataFlowListener {
     private static Logger logger = LoggerFactory.getLogger(AbstractFeeBusinessServiceDataFlowListener.class);
 
 
     /**
      * 获取 DAO工具类
+     *
      * @return
      */
     public abstract IFeeServiceDao getFeeServiceDaoImpl();
@@ -32,61 +32,60 @@ public abstract class AbstractFeeBusinessServiceDataFlowListener extends Abstrac
     /**
      * 刷新 businessFeeInfo 数据
      * 主要将 数据库 中字段和 接口传递字段建立关系
+     *
      * @param businessFeeInfo
      */
-    protected void flushBusinessFeeInfo(Map businessFeeInfo,String statusCd){
+    protected void flushBusinessFeeInfo(Map businessFeeInfo, String statusCd) {
         businessFeeInfo.put("newBId", businessFeeInfo.get("b_id"));
-        businessFeeInfo.put("amount",businessFeeInfo.get("amount"));
-businessFeeInfo.put("operate",businessFeeInfo.get("operate"));
-businessFeeInfo.put("incomeObjId",businessFeeInfo.get("income_obj_id"));
-businessFeeInfo.put("feeTypeCd",businessFeeInfo.get("fee_type_cd"));
-businessFeeInfo.put("startTime",businessFeeInfo.get("start_time"));
-businessFeeInfo.put("endTime",businessFeeInfo.get("end_time"));
-businessFeeInfo.put("communityId",businessFeeInfo.get("community_id"));
-businessFeeInfo.put("feeId",businessFeeInfo.get("fee_id"));
-businessFeeInfo.put("userId",businessFeeInfo.get("user_id"));
-businessFeeInfo.put("payerObjId",businessFeeInfo.get("payer_obj_id"));
-businessFeeInfo.remove("bId");
+        businessFeeInfo.put("amount", businessFeeInfo.get("amount"));
+        businessFeeInfo.put("operate", businessFeeInfo.get("operate"));
+        businessFeeInfo.put("incomeObjId", businessFeeInfo.get("income_obj_id"));
+        businessFeeInfo.put("feeTypeCd", businessFeeInfo.get("fee_type_cd"));
+        businessFeeInfo.put("startTime", businessFeeInfo.get("start_time"));
+        businessFeeInfo.put("endTime", businessFeeInfo.get("end_time"));
+        businessFeeInfo.put("communityId", businessFeeInfo.get("community_id"));
+        businessFeeInfo.put("feeId", businessFeeInfo.get("fee_id"));
+        businessFeeInfo.put("userId", businessFeeInfo.get("user_id"));
+        businessFeeInfo.put("payerObjId", businessFeeInfo.get("payer_obj_id"));
+        businessFeeInfo.remove("bId");
         businessFeeInfo.put("statusCd", statusCd);
     }
 
 
     /**
      * 当修改数据时,查询instance表中的数据 自动保存删除数据到business中
+     *
      * @param businessFee 费用信息
      */
-    protected void autoSaveDelBusinessFee(Business business, JSONObject businessFee){
+    protected void autoSaveDelBusinessFee(Business business, JSONObject businessFee) {
 //自动插入DEL
         Map info = new HashMap();
-        info.put("feeId",businessFee.getString("feeId"));
-        info.put("statusCd",StatusConstant.STATUS_CD_VALID);
+        info.put("feeId", businessFee.getString("feeId"));
+        info.put("statusCd", StatusConstant.STATUS_CD_VALID);
         List<Map> currentFeeInfos = getFeeServiceDaoImpl().getFeeInfo(info);
-        if(currentFeeInfos == null || currentFeeInfos.size() != 1){
-            throw new ListenerExecuteException(ResponseConstant.RESULT_PARAM_ERROR,"未找到需要修改数据信息,入参错误或数据有问题,请检查"+info);
+        if (currentFeeInfos == null || currentFeeInfos.size() != 1) {
+            throw new ListenerExecuteException(ResponseConstant.RESULT_PARAM_ERROR, "未找到需要修改数据信息,入参错误或数据有问题,请检查" + info);
         }
 
         Map currentFeeInfo = currentFeeInfos.get(0);
 
-        currentFeeInfo.put("bId",business.getbId());
+        currentFeeInfo.put("bId", business.getbId());
 
-        currentFeeInfo.put("amount",currentFeeInfo.get("amount"));
-currentFeeInfo.put("operate",currentFeeInfo.get("operate"));
-currentFeeInfo.put("incomeObjId",currentFeeInfo.get("income_obj_id"));
-currentFeeInfo.put("feeTypeCd",currentFeeInfo.get("fee_type_cd"));
-currentFeeInfo.put("startTime",currentFeeInfo.get("start_time"));
-currentFeeInfo.put("endTime",currentFeeInfo.get("end_time"));
-currentFeeInfo.put("communityId",currentFeeInfo.get("community_id"));
-currentFeeInfo.put("feeId",currentFeeInfo.get("fee_id"));
-currentFeeInfo.put("userId",currentFeeInfo.get("user_id"));
-currentFeeInfo.put("payerObjId",currentFeeInfo.get("payer_obj_id"));
+        currentFeeInfo.put("amount", currentFeeInfo.get("amount"));
+        currentFeeInfo.put("operate", currentFeeInfo.get("operate"));
+        currentFeeInfo.put("incomeObjId", currentFeeInfo.get("income_obj_id"));
+        currentFeeInfo.put("feeTypeCd", currentFeeInfo.get("fee_type_cd"));
+        currentFeeInfo.put("startTime", currentFeeInfo.get("start_time"));
+        currentFeeInfo.put("endTime", currentFeeInfo.get("end_time"));
+        currentFeeInfo.put("communityId", currentFeeInfo.get("community_id"));
+        currentFeeInfo.put("feeId", currentFeeInfo.get("fee_id"));
+        currentFeeInfo.put("userId", currentFeeInfo.get("user_id"));
+        currentFeeInfo.put("payerObjId", currentFeeInfo.get("payer_obj_id"));
 
 
-        currentFeeInfo.put("operate",StatusConstant.OPERATE_DEL);
+        currentFeeInfo.put("operate", StatusConstant.OPERATE_DEL);
         getFeeServiceDaoImpl().saveBusinessFeeInfo(currentFeeInfo);
     }
 
 
-
-
-
 }

+ 99 - 44
FeeService/src/main/java/com/java110/fee/listener/fee/UpdateFeeInfoListener.java

@@ -2,10 +2,14 @@ package com.java110.fee.listener.fee;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.java110.core.smo.order.IOrderInnerServiceSMO;
+import com.java110.dto.order.BusinessDto;
+import com.java110.fee.dao.IFeeDetailServiceDao;
 import com.java110.utils.constant.BusinessTypeConstant;
 import com.java110.utils.constant.ResponseConstant;
 import com.java110.utils.constant.StatusConstant;
 import com.java110.utils.exception.ListenerExecuteException;
+import com.java110.utils.lock.DistributedLock;
 import com.java110.utils.util.Assert;
 import com.java110.core.annotation.Java110Listener;
 import com.java110.core.context.DataFlowContext;
@@ -16,13 +20,11 @@ import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 修改费用信息 侦听
- *
+ * <p>
  * 处理节点
  * 1、businessFee:{} 费用基本信息节点
  * 2、businessFeeAttr:[{}] 费用属性信息节点
@@ -36,9 +38,16 @@ import java.util.Map;
 public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowListener {
 
     private static Logger logger = LoggerFactory.getLogger(UpdateFeeInfoListener.class);
+
+    @Autowired
+    private IOrderInnerServiceSMO orderInnerServiceSMOImpl;
+
     @Autowired
     private IFeeServiceDao feeServiceDaoImpl;
 
+    @Autowired
+    private IFeeDetailServiceDao feeDetailServiceDaoImpl;
+
     @Override
     public int getOrder() {
         return 2;
@@ -51,33 +60,34 @@ public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowLis
 
     /**
      * business过程
+     *
      * @param dataFlowContext 上下文对象
-     * @param business 业务对象
+     * @param business        业务对象
      */
     @Override
     protected void doSaveBusiness(DataFlowContext dataFlowContext, Business business) {
 
         JSONObject data = business.getDatas();
 
-        Assert.notEmpty(data,"没有datas 节点,或没有子节点需要处理");
+        Assert.notEmpty(data, "没有datas 节点,或没有子节点需要处理");
 
         //处理 businessFee 节点
-        if(data.containsKey("businessFee")){
+        if (data.containsKey("businessFee")) {
             //处理 businessFee 节点
-            if(data.containsKey("businessFee")){
+            if (data.containsKey("businessFee")) {
                 Object _obj = data.get("businessFee");
                 JSONArray businessFees = null;
-                if(_obj instanceof JSONObject){
+                if (_obj instanceof JSONObject) {
                     businessFees = new JSONArray();
                     businessFees.add(_obj);
-                }else {
-                    businessFees = (JSONArray)_obj;
+                } else {
+                    businessFees = (JSONArray) _obj;
                 }
                 //JSONObject businessFee = data.getJSONObject("businessFee");
-                for (int _feeIndex = 0; _feeIndex < businessFees.size();_feeIndex++) {
+                for (int _feeIndex = 0; _feeIndex < businessFees.size(); _feeIndex++) {
                     JSONObject businessFee = businessFees.getJSONObject(_feeIndex);
                     doBusinessFee(business, businessFee);
-                    if(_obj instanceof JSONObject) {
+                    if (_obj instanceof JSONObject) {
                         dataFlowContext.addParamOut("feeId", businessFee.getString("feeId"));
                     }
                 }
@@ -88,37 +98,78 @@ public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowLis
 
     /**
      * business to instance 过程
+     *
      * @param dataFlowContext 数据对象
-     * @param business 当前业务对象
+     * @param business        当前业务对象
      */
     @Override
     protected void doBusinessToInstance(DataFlowContext dataFlowContext, Business business) {
 
-        JSONObject data = business.getDatas();
 
+        JSONObject data = business.getDatas();
         Map info = new HashMap();
-        info.put("bId",business.getbId());
-        info.put("operate",StatusConstant.OPERATE_ADD);
-
+        info.put("bId", business.getbId());
+        info.put("operate", StatusConstant.OPERATE_ADD);
         //费用信息
         List<Map> businessFeeInfos = feeServiceDaoImpl.getBusinessFeeInfo(info);
-        if( businessFeeInfos != null && businessFeeInfos.size() >0) {
-            for (int _feeIndex = 0; _feeIndex < businessFeeInfos.size();_feeIndex++) {
+
+        //查询同订单 缴费记录bId
+        BusinessDto businessDto = new BusinessDto();
+        businessDto.setbId(business.getbId());
+        businessDto.setBusinessTypeCd("610100030001");
+        List<BusinessDto> businessDtos = orderInnerServiceSMOImpl.querySameOrderBusiness(businessDto);
+        Assert.listOnlyOne(businessDtos, "存在多条缴费记录或没有");
+
+        //查询费用明细过程表
+        Map feeDetailInfo = new HashMap();
+        feeDetailInfo.put("bId", businessDtos.get(0).getbId());
+        feeDetailInfo.put("operate", "ADD");
+        List<Map> feeDetails = feeDetailServiceDaoImpl.getBusinessFeeDetailInfo(feeDetailInfo);
+        Assert.listOnlyOne(feeDetails, "business表中存在多条缴费记录或没有");
+
+        int cycles = Integer.parseInt(feeDetails.get(0).get("cycles").toString());
+
+        Map feeMap = null;
+        if (businessFeeInfos != null && businessFeeInfos.size() > 0) {
+            for (int _feeIndex = 0; _feeIndex < businessFeeInfos.size(); _feeIndex++) {
                 Map businessFeeInfo = businessFeeInfos.get(_feeIndex);
-                flushBusinessFeeInfo(businessFeeInfo,StatusConstant.STATUS_CD_VALID);
-                feeServiceDaoImpl.updateFeeInfoInstance(businessFeeInfo);
-                if(businessFeeInfo.size() == 1) {
-                    dataFlowContext.addParamOut("feeId", businessFeeInfo.get("fee_id"));
+                //开始锁代码
+                String requestId = DistributedLock.getLockUUID();
+                String key = this.getClass().getSimpleName() + businessFeeInfo.get("fee_id");
+                try {
+                    DistributedLock.waitGetDistributedLock(key, requestId);
+                    //这里考虑并发问题
+                    feeMap = new HashMap();
+                    feeMap.put("feeId", businessFeeInfo.get("fee_id"));
+                    feeMap.put("communityId", businessFeeInfo.get("community_id"));
+                    feeMap.put("statusCd", "0");
+                    List<Map> feeInfo = feeServiceDaoImpl.getFeeInfo(feeMap);
+                    Assert.listOnlyOne(feeInfo, "查询到多条数据或未查询到数据" + feeMap);
+                    //根据当前的结束时间 修改
+                    Date endTime = (Date) feeInfo.get(0).get("end_time");
+                    Calendar endCalender = Calendar.getInstance();
+                    endCalender.setTime(endTime);
+                    endCalender.add(Calendar.MONTH, cycles);
+                    businessFeeInfo.put("end_time", endCalender.getTime());
+                    flushBusinessFeeInfo(businessFeeInfo, StatusConstant.STATUS_CD_VALID);
+                    feeServiceDaoImpl.updateFeeInfoInstance(businessFeeInfo);
+                    if (businessFeeInfo.size() == 1) {
+                        dataFlowContext.addParamOut("feeId", businessFeeInfo.get("fee_id"));
+                    }
+                } finally {
+                    DistributedLock.releaseDistributedLock(requestId, key);
                 }
             }
         }
 
+
     }
 
     /**
      * 撤单
+     *
      * @param dataFlowContext 数据对象
-     * @param business 当前业务对象
+     * @param business        当前业务对象
      */
     @Override
     protected void doRecover(DataFlowContext dataFlowContext, Business business) {
@@ -126,24 +177,24 @@ public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowLis
         String bId = business.getbId();
         //Assert.hasLength(bId,"请求报文中没有包含 bId");
         Map info = new HashMap();
-        info.put("bId",bId);
-        info.put("statusCd",StatusConstant.STATUS_CD_VALID);
+        info.put("bId", bId);
+        info.put("statusCd", StatusConstant.STATUS_CD_VALID);
         Map delInfo = new HashMap();
-        delInfo.put("bId",business.getbId());
-        delInfo.put("operate",StatusConstant.OPERATE_DEL);
+        delInfo.put("bId", business.getbId());
+        delInfo.put("operate", StatusConstant.OPERATE_DEL);
         //费用信息
         List<Map> feeInfo = feeServiceDaoImpl.getFeeInfo(info);
-        if(feeInfo != null && feeInfo.size() > 0){
+        if (feeInfo != null && feeInfo.size() > 0) {
 
             //费用信息
             List<Map> businessFeeInfos = feeServiceDaoImpl.getBusinessFeeInfo(delInfo);
             //除非程序出错了,这里不会为空
-            if(businessFeeInfos == null || businessFeeInfos.size() == 0){
-                throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_INNER_ERROR,"撤单失败(fee),程序内部异常,请检查! "+delInfo);
+            if (businessFeeInfos == null || businessFeeInfos.size() == 0) {
+                throw new ListenerExecuteException(ResponseConstant.RESULT_CODE_INNER_ERROR, "撤单失败(fee),程序内部异常,请检查! " + delInfo);
             }
-            for (int _feeIndex = 0; _feeIndex < businessFeeInfos.size();_feeIndex++) {
+            for (int _feeIndex = 0; _feeIndex < businessFeeInfos.size(); _feeIndex++) {
                 Map businessFeeInfo = businessFeeInfos.get(_feeIndex);
-                flushBusinessFeeInfo(businessFeeInfo,StatusConstant.STATUS_CD_VALID);
+                flushBusinessFeeInfo(businessFeeInfo, StatusConstant.STATUS_CD_VALID);
                 feeServiceDaoImpl.updateFeeInfoInstance(businessFeeInfo);
             }
         }
@@ -151,23 +202,23 @@ public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowLis
     }
 
 
-
     /**
      * 处理 businessFee 节点
-     * @param business 总的数据节点
+     *
+     * @param business    总的数据节点
      * @param businessFee 费用节点
      */
-    private void doBusinessFee(Business business,JSONObject businessFee){
+    private void doBusinessFee(Business business, JSONObject businessFee) {
 
-        Assert.jsonObjectHaveKey(businessFee,"feeId","businessFee 节点下没有包含 feeId 节点");
+        Assert.jsonObjectHaveKey(businessFee, "feeId", "businessFee 节点下没有包含 feeId 节点");
 
-        if(businessFee.getString("feeId").startsWith("-")){
-            throw new ListenerExecuteException(ResponseConstant.RESULT_PARAM_ERROR,"feeId 错误,不能自动生成(必须已经存在的feeId)"+businessFee);
+        if (businessFee.getString("feeId").startsWith("-")) {
+            throw new ListenerExecuteException(ResponseConstant.RESULT_PARAM_ERROR, "feeId 错误,不能自动生成(必须已经存在的feeId)" + businessFee);
         }
         //自动保存DEL
-        autoSaveDelBusinessFee(business,businessFee);
+        autoSaveDelBusinessFee(business, businessFee);
 
-        businessFee.put("bId",business.getbId());
+        businessFee.put("bId", business.getbId());
         businessFee.put("operate", StatusConstant.OPERATE_ADD);
         //保存费用信息
         feeServiceDaoImpl.saveBusinessFeeInfo(businessFee);
@@ -175,8 +226,6 @@ public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowLis
     }
 
 
-
-
     public IFeeServiceDao getFeeServiceDaoImpl() {
         return feeServiceDaoImpl;
     }
@@ -186,5 +235,11 @@ public class UpdateFeeInfoListener extends AbstractFeeBusinessServiceDataFlowLis
     }
 
 
+    public IOrderInnerServiceSMO getOrderInnerServiceSMOImpl() {
+        return orderInnerServiceSMOImpl;
+    }
 
+    public void setOrderInnerServiceSMOImpl(IOrderInnerServiceSMO orderInnerServiceSMOImpl) {
+        this.orderInnerServiceSMOImpl = orderInnerServiceSMOImpl;
+    }
 }

+ 28 - 6
OrderService/src/main/java/com/java110/order/dao/ICenterServiceDAO.java

@@ -13,6 +13,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 保存订单信息
+     *
      * @param order 订单信息
      * @return
      */
@@ -20,6 +21,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 保存属性信息
+     *
      * @param orderAttrs
      * @return
      */
@@ -28,6 +30,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 保存订单项信息
+     *
      * @param businesses 订单项信息
      * @return
      */
@@ -35,12 +38,14 @@ public interface ICenterServiceDAO {
 
     /**
      * 保存订单项信息
+     *
      * @param business 订单项信息
      */
     public void saveBusiness(Map business) throws DAOException;
 
     /**
      * 保存属性信息
+     *
      * @param businessAttrs
      * @return
      */
@@ -48,6 +53,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 更新订单信息(一般就更新订单状态)
+     *
      * @param order
      * @throws DAOException
      */
@@ -55,6 +61,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 更新订单项信息(一般就更新订单状态)
+     *
      * @param order
      * @throws DAOException
      */
@@ -62,6 +69,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 根据bId 修改业务项信息
+     *
      * @param business
      * @throws DAOException
      */
@@ -69,6 +77,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 当所有业务动作是否都是C,将订单信息改为 C
+     *
      * @param bId
      * @return
      * @throws DAOException
@@ -77,45 +86,52 @@ public interface ICenterServiceDAO {
 
     /**
      * 当所有业务动作是否都是C,将订单信息改为 C
+     *
      * @param oId
      * @return
      * @throws DAOException
      */
     public void completeOrderByOId(String oId) throws DAOException;
+
     /**
      * 判断 business 过程是否完成 1 表示完成 0表示未完成
+     *
      * @param oId
      * @return
      * @throws DAOException
      */
-    public int judgeAllBusinessCompleted(String oId,String statusCd) throws DAOException;
+    public int judgeAllBusinessCompleted(String oId, String statusCd) throws DAOException;
 
     /**
      * 判断 business 过程是否是否满足撤单条件
+     *
      * @param oId
      * @return
      * @throws DAOException
      */
-    public int judgeAllBusinessDeleteOrder(String oId,String statusCd) throws DAOException;
+    public int judgeAllBusinessDeleteOrder(String oId, String statusCd) throws DAOException;
 
     /**
      * 根据bId查询订单信息
+     *
      * @param bId
      * @return
      * @throws DAOException
      */
-    public Map getOrderInfoByBId(String bId)throws DAOException;
+    public Map getOrderInfoByBId(String bId) throws DAOException;
 
     /**
      * 根据oId查询订单信息
+     *
      * @param oId
      * @return
      * @throws DAOException
      */
-    public Map getDeleteOrderBusinessByOId(String oId)throws DAOException;
+    public Map getDeleteOrderBusinessByOId(String oId) throws DAOException;
 
     /**
      * 获取同个订单中已经完成的订单项
+     *
      * @param bId
      * @return
      * @throws DAOException
@@ -124,6 +140,7 @@ public interface ICenterServiceDAO {
 
     /**
      * 根据oId 查询Business
+     *
      * @param info
      * @return
      * @throws DAOException
@@ -132,35 +149,40 @@ public interface ICenterServiceDAO {
 
     /**
      * 查询所有组件
+     *
      * @return
      */
     public List<Map> getAppRouteAndServiceInfoAll();
 
     /**
      * 查询映射表
+     *
      * @return
      */
     public List<Mapping> getMappingInfoAll();
 
     /**
      * 查询业主 添加 修改 删除订单
+     *
      * @param info
      * @return
      */
     public List<Map> queryOwenrOrders(Map info);
+
     /**
      * 查询业主 添加 修改 删除订单
+     *
      * @param info
      * @return
      */
     public int updateBusinessStatusCd(Map info);
 
 
-
     public List<Map> queryManchineOrders(Map info);
-    public List<Map> queryApplicationKeyOrders(Map info);
 
+    public List<Map> queryApplicationKeyOrders(Map info);
 
+    public List<Map> querySameOrderBusiness(Map info);
 
 
 }

+ 11 - 0
OrderService/src/main/java/com/java110/order/dao/impl/CenterServiceDAOImpl.java

@@ -322,5 +322,16 @@ public class CenterServiceDAOImpl extends BaseServiceDao implements ICenterServi
         return sqlSessionTemplate.selectList("centerServiceDAOImpl.getBusinessByOId",info);
     }
 
+    /**
+     * 查询同订单 订单项
+     * @param info
+     * @return
+     * @throws DAOException
+     */
+    public List<Map> querySameOrderBusiness(Map info) throws DAOException{
+        logger.debug("----【CenterServiceDAOImpl.querySameOrderBusiness】数据入参 : " + JSONObject.toJSONString(info));
+
+        return sqlSessionTemplate.selectList("centerServiceDAOImpl.querySameOrderBusiness",info);
+    }
 
 }

+ 10 - 0
OrderService/src/main/java/com/java110/order/smo/impl/OrderInnerServiceSMOImpl.java

@@ -4,6 +4,7 @@ package com.java110.order.smo.impl;
 import com.java110.core.base.smo.BaseServiceSMO;
 import com.java110.core.smo.order.IOrderInnerServiceSMO;
 import com.java110.core.smo.user.IUserInnerServiceSMO;
+import com.java110.dto.order.BusinessDto;
 import com.java110.dto.order.OrderDto;
 import com.java110.order.dao.ICenterServiceDAO;
 import com.java110.utils.util.BeanConvertUtil;
@@ -81,6 +82,15 @@ public class OrderInnerServiceSMOImpl extends BaseServiceSMO implements IOrderIn
         return BeanConvertUtil.covertBeanList(centerServiceDAOImpl.queryApplicationKeyOrders(BeanConvertUtil.beanCovertMap(orderDto)), OrderDto.class);
     }
 
+    /**
+     * 查询 同订单 订单项
+     * @param businessDto
+     * @return
+     */
+    public List<BusinessDto> querySameOrderBusiness(@RequestBody BusinessDto businessDto){
+        return BeanConvertUtil.covertBeanList(centerServiceDAOImpl.querySameOrderBusiness(BeanConvertUtil.beanCovertMap(businessDto)), BusinessDto.class);
+    }
+
 
     public IUserInnerServiceSMO getUserInnerServiceSMOImpl() {
         return userInnerServiceSMOImpl;

+ 62 - 0
java110-bean/src/main/java/com/java110/dto/order/BusinessDto.java

@@ -0,0 +1,62 @@
+package com.java110.dto.order;
+
+import com.java110.dto.PageDto;
+
+import java.io.Serializable;
+
+/**
+ * 订单项
+ */
+public class BusinessDto  extends PageDto implements Serializable {
+
+    private String oId;
+
+    private String bId;
+
+    private String businessTypeCd;
+
+    private String finishTime;
+
+    private String statusCd;
+
+
+    public String getoId() {
+        return oId;
+    }
+
+    public void setoId(String oId) {
+        this.oId = oId;
+    }
+
+    public String getbId() {
+        return bId;
+    }
+
+    public void setbId(String bId) {
+        this.bId = bId;
+    }
+
+    public String getBusinessTypeCd() {
+        return businessTypeCd;
+    }
+
+    public void setBusinessTypeCd(String businessTypeCd) {
+        this.businessTypeCd = businessTypeCd;
+    }
+
+    public String getFinishTime() {
+        return finishTime;
+    }
+
+    public void setFinishTime(String finishTime) {
+        this.finishTime = finishTime;
+    }
+
+    public String getStatusCd() {
+        return statusCd;
+    }
+
+    public void setStatusCd(String statusCd) {
+        this.statusCd = statusCd;
+    }
+}

+ 9 - 0
java110-core/src/main/java/com/java110/core/smo/order/IOrderInnerServiceSMO.java

@@ -1,6 +1,7 @@
 package com.java110.core.smo.order;
 
 import com.java110.core.feign.FeignConfiguration;
+import com.java110.dto.order.BusinessDto;
 import com.java110.dto.order.OrderDto;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -70,4 +71,12 @@ public interface IOrderInnerServiceSMO {
      */
     @RequestMapping(value = "/queryApplicationKeyOrders", method = RequestMethod.POST)
     List<OrderDto> queryApplicationKeyOrders(@RequestBody OrderDto orderDto);
+
+    /**
+     * 查询 同订单 订单项
+     * @param businessDto
+     * @return
+     */
+    @RequestMapping(value = "/querySameOrderBusiness", method = RequestMethod.POST)
+    List<BusinessDto> querySameOrderBusiness(@RequestBody BusinessDto businessDto);
 }

+ 31 - 0
java110-db/src/main/resources/mapper/center/CenterServiceDAOImplMapper.xml

@@ -235,4 +235,35 @@
     </update>
 
 
+    <!-- querySameOrderBusiness 查询同订单 订单项 -->
+    <select id="querySameOrderBusiness" parameterType="map" resultType="map">
+
+                SELECT
+                    cb1.b_id bId,
+                    cb1.o_id oId,
+                    cb1.create_time createTime,
+                    cb1.business_type_cd businessTypeCd,
+                    cb1.finish_time finishTime,
+                    cb1.status_cd statusCd
+                FROM
+                    c_business cb1
+                    <if test="bId != null and bId != ''">
+                        ,c_business cb2
+                    </if>
+                WHERE
+                    1=1
+                    <if test="bId != null and bId != ''">
+                        and cb1.o_id = cb2.o_id
+                        AND cb2.b_id = #{bId}
+                    </if>
+                    <if test="oId != null and oId != ''">
+                        and cb1.o_id = #{oId}
+                    </if>
+                    <if test="businessTypeCd != null and businessTypeCd != ''">
+                        and cb1.business_type_cd = #{businessTypeCd}
+                    </if>
+
+
+    </select>
+
 </mapper>

+ 187 - 185
java110-db/src/main/resources/mapper/fee/FeeDetailServiceDaoImplMapper.xml

@@ -5,7 +5,7 @@
 <mapper namespace="feeDetailServiceDaoImpl">
 
     <!-- 保存费用明细信息 add by wuxw 2018-07-03 -->
-       <insert id="saveBusinessFeeDetailInfo" parameterType="Map">
+    <insert id="saveBusinessFeeDetailInfo" parameterType="Map">
            insert into business_pay_fee_detail(
 operate,prime_rate,detail_id,receivable_amount,cycles,remark,received_amount,community_id,b_id,fee_id
 ) values (
@@ -14,219 +14,221 @@ operate,prime_rate,detail_id,receivable_amount,cycles,remark,received_amount,com
        </insert>
 
 
-       <!-- 查询费用明细信息(Business) add by wuxw 2018-07-03 -->
-       <select id="getBusinessFeeDetailInfo" parameterType="Map" resultType="Map">
-           select  t.operate,t.prime_rate,t.prime_rate primeRate,t.detail_id,t.detail_id detailId,t.receivable_amount,t.receivable_amount receivableAmount,t.cycles,t.remark,t.received_amount,t.received_amount receivedAmount,t.community_id,t.community_id communityId,t.b_id,t.b_id bId,t.fee_id,t.fee_id feeId 
-from business_pay_fee_detail t 
-where 1 =1 
-<if test="operate !=null and operate != ''">
-   and t.operate= #{operate}
-</if> 
-<if test="primeRate !=null and primeRate != ''">
-   and t.prime_rate= #{primeRate}
-</if> 
-<if test="detailId !=null and detailId != ''">
-   and t.detail_id= #{detailId}
-</if> 
-<if test="receivableAmount !=null and receivableAmount != ''">
-   and t.receivable_amount= #{receivableAmount}
-</if> 
-<if test="cycles !=null and cycles != ''">
-   and t.cycles= #{cycles}
-</if> 
-<if test="remark !=null and remark != ''">
-   and t.remark= #{remark}
-</if> 
-<if test="receivedAmount !=null and receivedAmount != ''">
-   and t.received_amount= #{receivedAmount}
-</if> 
-<if test="communityId !=null and communityId != ''">
-   and t.community_id= #{communityId}
-</if> 
-<if test="bId !=null and bId != ''">
-   and t.b_id= #{bId}
-</if> 
-<if test="feeId !=null and feeId != ''">
-   and t.fee_id= #{feeId}
-</if> 
-
-       </select>
-
-
+    <!-- 查询费用明细信息(Business) add by wuxw 2018-07-03 -->
+    <select id="getBusinessFeeDetailInfo" parameterType="Map" resultType="Map">
+        select t.operate,t.prime_rate,t.prime_rate primeRate,t.detail_id,t.detail_id
+        detailId,t.receivable_amount,t.receivable_amount
+        receivableAmount,t.cycles,t.remark,t.received_amount,t.received_amount
+        receivedAmount,t.community_id,t.community_id communityId,t.b_id,t.b_id bId,t.fee_id,t.fee_id feeId
+        from business_pay_fee_detail t
+        where 1 =1
+        <if test="operate !=null and operate != ''">
+            and t.operate= #{operate}
+        </if>
+        <if test="primeRate !=null and primeRate != ''">
+            and t.prime_rate= #{primeRate}
+        </if>
+        <if test="detailId !=null and detailId != ''">
+            and t.detail_id= #{detailId}
+        </if>
+        <if test="receivableAmount !=null and receivableAmount != ''">
+            and t.receivable_amount= #{receivableAmount}
+        </if>
+        <if test="cycles !=null and cycles != ''">
+            and t.cycles= #{cycles}
+        </if>
+        <if test="remark !=null and remark != ''">
+            and t.remark= #{remark}
+        </if>
+        <if test="receivedAmount !=null and receivedAmount != ''">
+            and t.received_amount= #{receivedAmount}
+        </if>
+        <if test="communityId !=null and communityId != ''">
+            and t.community_id= #{communityId}
+        </if>
+        <if test="bId !=null and bId != ''">
+            and t.b_id= #{bId}
+        </if>
+        <if test="feeId !=null and feeId != ''">
+            and t.fee_id= #{feeId}
+        </if>
 
+    </select>
 
 
     <!-- 保存费用明细信息至 instance表中 add by wuxw 2018-07-03 -->
     <insert id="saveFeeDetailInfoInstance" parameterType="Map">
         insert into pay_fee_detail(
-prime_rate,detail_id,receivable_amount,cycles,remark,status_cd,received_amount,community_id,b_id,fee_id
-) select t.prime_rate,t.detail_id,t.receivable_amount,t.cycles,t.remark,'0',t.received_amount,t.community_id,t.b_id,t.fee_id from business_pay_fee_detail t where 1=1
-   and t.operate= 'ADD'
-<if test="primeRate !=null and primeRate != ''">
-   and t.prime_rate= #{primeRate}
-</if> 
-<if test="detailId !=null and detailId != ''">
-   and t.detail_id= #{detailId}
-</if> 
-<if test="receivableAmount !=null and receivableAmount != ''">
-   and t.receivable_amount= #{receivableAmount}
-</if> 
-<if test="cycles !=null and cycles != ''">
-   and t.cycles= #{cycles}
-</if> 
-<if test="remark !=null and remark != ''">
-   and t.remark= #{remark}
-</if> 
-<if test="receivedAmount !=null and receivedAmount != ''">
-   and t.received_amount= #{receivedAmount}
-</if> 
-<if test="communityId !=null and communityId != ''">
-   and t.community_id= #{communityId}
-</if> 
-<if test="bId !=null and bId != ''">
-   and t.b_id= #{bId}
-</if> 
-<if test="feeId !=null and feeId != ''">
-   and t.fee_id= #{feeId}
-</if> 
+        prime_rate,detail_id,receivable_amount,cycles,remark,status_cd,received_amount,community_id,b_id,fee_id
+        ) select
+        t.prime_rate,t.detail_id,t.receivable_amount,t.cycles,t.remark,'0',t.received_amount,t.community_id,t.b_id,t.fee_id
+        from business_pay_fee_detail t where 1=1
+        and t.operate= 'ADD'
+        <if test="primeRate !=null and primeRate != ''">
+            and t.prime_rate= #{primeRate}
+        </if>
+        <if test="detailId !=null and detailId != ''">
+            and t.detail_id= #{detailId}
+        </if>
+        <if test="receivableAmount !=null and receivableAmount != ''">
+            and t.receivable_amount= #{receivableAmount}
+        </if>
+        <if test="cycles !=null and cycles != ''">
+            and t.cycles= #{cycles}
+        </if>
+        <if test="remark !=null and remark != ''">
+            and t.remark= #{remark}
+        </if>
+        <if test="receivedAmount !=null and receivedAmount != ''">
+            and t.received_amount= #{receivedAmount}
+        </if>
+        <if test="communityId !=null and communityId != ''">
+            and t.community_id= #{communityId}
+        </if>
+        <if test="bId !=null and bId != ''">
+            and t.b_id= #{bId}
+        </if>
+        <if test="feeId !=null and feeId != ''">
+            and t.fee_id= #{feeId}
+        </if>
 
     </insert>
 
 
-
     <!-- 查询费用明细信息 add by wuxw 2018-07-03 -->
     <select id="getFeeDetailInfo" parameterType="Map" resultType="Map">
-        select  t.prime_rate,t.prime_rate primeRate,t.detail_id,t.detail_id detailId,t.receivable_amount,t.receivable_amount receivableAmount,
-        t.cycles,t.remark,t.status_cd,t.status_cd statusCd,t.received_amount,t.received_amount receivedAmount,t.community_id,
+        select t.prime_rate,t.prime_rate primeRate,t.detail_id,t.detail_id
+        detailId,t.receivable_amount,t.receivable_amount receivableAmount,
+        t.cycles,t.remark,t.status_cd,t.status_cd statusCd,t.received_amount,t.received_amount
+        receivedAmount,t.community_id,
         t.community_id communityId,t.b_id,t.b_id bId,t.fee_id,t.fee_id feeId ,t.create_time createTime
-from pay_fee_detail t 
-where 1 =1 
-<if test="primeRate !=null and primeRate != ''">
-   and t.prime_rate= #{primeRate}
-</if> 
-<if test="detailId !=null and detailId != ''">
-   and t.detail_id= #{detailId}
-</if> 
-<if test="receivableAmount !=null and receivableAmount != ''">
-   and t.receivable_amount= #{receivableAmount}
-</if> 
-<if test="cycles !=null and cycles != ''">
-   and t.cycles= #{cycles}
-</if> 
-<if test="remark !=null and remark != ''">
-   and t.remark= #{remark}
-</if> 
-<if test="statusCd !=null and statusCd != ''">
-   and t.status_cd= #{statusCd}
-</if> 
-<if test="receivedAmount !=null and receivedAmount != ''">
-   and t.received_amount= #{receivedAmount}
-</if> 
-<if test="communityId !=null and communityId != ''">
-   and t.community_id= #{communityId}
-</if> 
-<if test="bId !=null and bId != ''">
-   and t.b_id= #{bId}
-</if> 
-<if test="feeId !=null and feeId != ''">
-   and t.fee_id= #{feeId}
-</if>
+        from pay_fee_detail t
+        where 1 =1
+        <if test="primeRate !=null and primeRate != ''">
+            and t.prime_rate= #{primeRate}
+        </if>
+        <if test="detailId !=null and detailId != ''">
+            and t.detail_id= #{detailId}
+        </if>
+        <if test="receivableAmount !=null and receivableAmount != ''">
+            and t.receivable_amount= #{receivableAmount}
+        </if>
+        <if test="cycles !=null and cycles != ''">
+            and t.cycles= #{cycles}
+        </if>
+        <if test="remark !=null and remark != ''">
+            and t.remark= #{remark}
+        </if>
+        <if test="statusCd !=null and statusCd != ''">
+            and t.status_cd= #{statusCd}
+        </if>
+        <if test="receivedAmount !=null and receivedAmount != ''">
+            and t.received_amount= #{receivedAmount}
+        </if>
+        <if test="communityId !=null and communityId != ''">
+            and t.community_id= #{communityId}
+        </if>
+        <if test="bId !=null and bId != ''">
+            and t.b_id= #{bId}
+        </if>
+        <if test="feeId !=null and feeId != ''">
+            and t.fee_id= #{feeId}
+        </if>
         <if test="startTime !=null ">
             and t.create_time &gt;= #{startTime}
         </if>
         <if test="endTime !=null ">
             and t.create_time &lt;= #{endTime}
         </if>
-   order by t.create_time desc
-<if test="page != -1 and page != null ">
-   limit #{page}, #{row}
-</if>
+        order by t.create_time desc
+        <if test="page != -1 and page != null ">
+            limit #{page}, #{row}
+        </if>
 
 
     </select>
 
 
-
-
     <!-- 修改费用明细信息 add by wuxw 2018-07-03 -->
     <update id="updateFeeDetailInfoInstance" parameterType="Map">
-        update  pay_fee_detail t set t.status_cd = #{statusCd}
-<if test="newBId != null and newBId != ''">
-,t.b_id = #{newBId}
-</if> 
-<if test="primeRate !=null and primeRate != ''">
-, t.prime_rate= #{primeRate}
-</if> 
-<if test="receivableAmount !=null and receivableAmount != ''">
-, t.receivable_amount= #{receivableAmount}
-</if> 
-<if test="cycles !=null and cycles != ''">
-, t.cycles= #{cycles}
-</if> 
-<if test="remark !=null and remark != ''">
-, t.remark= #{remark}
-</if> 
-<if test="receivedAmount !=null and receivedAmount != ''">
-, t.received_amount= #{receivedAmount}
-</if> 
-<if test="communityId !=null and communityId != ''">
-, t.community_id= #{communityId}
-</if> 
-<if test="feeId !=null and feeId != ''">
-, t.fee_id= #{feeId}
-</if> 
- where 1=1 <if test="detailId !=null and detailId != ''">
-and t.detail_id= #{detailId}
-</if> 
-<if test="bId !=null and bId != ''">
-and t.b_id= #{bId}
-</if> 
+        update pay_fee_detail t set t.status_cd = #{statusCd}
+        <if test="newBId != null and newBId != ''">
+            ,t.b_id = #{newBId}
+        </if>
+        <if test="primeRate !=null and primeRate != ''">
+            , t.prime_rate= #{primeRate}
+        </if>
+        <if test="receivableAmount !=null and receivableAmount != ''">
+            , t.receivable_amount= #{receivableAmount}
+        </if>
+        <if test="cycles !=null and cycles != ''">
+            , t.cycles= #{cycles}
+        </if>
+        <if test="remark !=null and remark != ''">
+            , t.remark= #{remark}
+        </if>
+        <if test="receivedAmount !=null and receivedAmount != ''">
+            , t.received_amount= #{receivedAmount}
+        </if>
+        <if test="communityId !=null and communityId != ''">
+            , t.community_id= #{communityId}
+        </if>
+        <if test="feeId !=null and feeId != ''">
+            , t.fee_id= #{feeId}
+        </if>
+        where 1=1
+        <if test="detailId !=null and detailId != ''">
+            and t.detail_id= #{detailId}
+        </if>
+        <if test="bId !=null and bId != ''">
+            and t.b_id= #{bId}
+        </if>
 
     </update>
 
     <!-- 查询费用明细数量 add by wuxw 2018-07-03 -->
-     <select id="queryFeeDetailsCount" parameterType="Map" resultType="Map">
-        select  count(1) count 
-from pay_fee_detail t 
-where 1 =1 
-<if test="primeRate !=null and primeRate != ''">
-   and t.prime_rate= #{primeRate}
-</if> 
-<if test="detailId !=null and detailId != ''">
-   and t.detail_id= #{detailId}
-</if> 
-<if test="receivableAmount !=null and receivableAmount != ''">
-   and t.receivable_amount= #{receivableAmount}
-</if> 
-<if test="cycles !=null and cycles != ''">
-   and t.cycles= #{cycles}
-</if> 
-<if test="remark !=null and remark != ''">
-   and t.remark= #{remark}
-</if> 
-<if test="statusCd !=null and statusCd != ''">
-   and t.status_cd= #{statusCd}
-</if> 
-<if test="receivedAmount !=null and receivedAmount != ''">
-   and t.received_amount= #{receivedAmount}
-</if> 
-<if test="communityId !=null and communityId != ''">
-   and t.community_id= #{communityId}
-</if> 
-<if test="bId !=null and bId != ''">
-   and t.b_id= #{bId}
-</if> 
-<if test="feeId !=null and feeId != ''">
-   and t.fee_id= #{feeId}
-</if>
-         <if test="startTime !=null ">
-             and t.create_time &gt;= #{startTime}
-         </if>
-         <if test="endTime !=null ">
-             and t.create_time &lt;= #{endTime}
-         </if>
-
-
-     </select>
+    <select id="queryFeeDetailsCount" parameterType="Map" resultType="Map">
+        select count(1) count
+        from pay_fee_detail t
+        where 1 =1
+        <if test="primeRate !=null and primeRate != ''">
+            and t.prime_rate= #{primeRate}
+        </if>
+        <if test="detailId !=null and detailId != ''">
+            and t.detail_id= #{detailId}
+        </if>
+        <if test="receivableAmount !=null and receivableAmount != ''">
+            and t.receivable_amount= #{receivableAmount}
+        </if>
+        <if test="cycles !=null and cycles != ''">
+            and t.cycles= #{cycles}
+        </if>
+        <if test="remark !=null and remark != ''">
+            and t.remark= #{remark}
+        </if>
+        <if test="statusCd !=null and statusCd != ''">
+            and t.status_cd= #{statusCd}
+        </if>
+        <if test="receivedAmount !=null and receivedAmount != ''">
+            and t.received_amount= #{receivedAmount}
+        </if>
+        <if test="communityId !=null and communityId != ''">
+            and t.community_id= #{communityId}
+        </if>
+        <if test="bId !=null and bId != ''">
+            and t.b_id= #{bId}
+        </if>
+        <if test="feeId !=null and feeId != ''">
+            and t.fee_id= #{feeId}
+        </if>
+        <if test="startTime !=null ">
+            and t.create_time &gt;= #{startTime}
+        </if>
+        <if test="endTime !=null ">
+            and t.create_time &lt;= #{endTime}
+        </if>
+
+
+    </select>
 
 </mapper>

+ 2 - 0
java110-db/src/main/resources/mapper/fee/FeeServiceDaoImplMapper.xml

@@ -140,6 +140,7 @@
         </if>
         <if test="communityId !=null and communityId != ''">
             and t.community_id= #{communityId}
+            and pfc.community_id= #{communityId}
         </if>
         <if test="bId !=null and bId != ''">
             and t.b_id= #{bId}
@@ -236,6 +237,7 @@
         </if>
         <if test="communityId !=null and communityId != ''">
             and t.community_id= #{communityId}
+            and pfc.community_id= #{communityId}
         </if>
         <if test="bId !=null and bId != ''">
             and t.b_id= #{bId}

+ 1 - 1
java110-utils/src/main/java/com/java110/utils/cache/BaseCache.java

@@ -11,7 +11,7 @@ import java.util.Set;
  * 缓存基类
  * Created by wuxw on 2018/4/14.
  */
-public class BaseCache /*extends LoggerEngine*/{
+public class BaseCache {
 
     protected static Jedis getJedis(){
         JedisPool jedisPool = (JedisPool) ApplicationContextFactory.getBean("jedisPool");

+ 6 - 0
java110-utils/src/main/java/com/java110/utils/constant/ServiceCodeConstant.java

@@ -494,6 +494,12 @@ public class ServiceCodeConstant {
     //缴费
     public static final String SERVICE_CODE_PAY_FEE = "fee.payFee";
 
+    //预交费
+    public static final String SERVICE_CODE_PAY_FEE_PRE = "fee.payFeePre";
+
+    //交费通知
+    public static final String SERVICE_CODE_PAY_CONFIRM_PRE = "fee.payFeeConfirm";
+
 
     //查询停车位
     public static final String SERVICE_CODE_QUERY_PARKING_SPACE = "parkingSpace.queryParkingSpaces";

+ 101 - 0
java110-utils/src/main/java/com/java110/utils/lock/DistributedLock.java

@@ -0,0 +1,101 @@
+package com.java110.utils.lock;
+
+import com.java110.utils.cache.BaseCache;
+import redis.clients.jedis.Jedis;
+
+import java.util.Collections;
+import java.util.UUID;
+
+/**
+ * 分布式事务锁
+ * add by wuxw 2020-01-11
+ */
+public class DistributedLock extends BaseCache {
+
+    private static final String LOCK_SUCCESS = "OK";
+    private static final String SET_IF_NOT_EXIST = "NX";
+    private static final String SET_WITH_EXPIRE_TIME = "PX";
+    private static final int DEFAULT_EXPIRE_TIME = 1000;
+
+
+    private static final Long RELEASE_SUCCESS = 1L;
+
+    /**
+     * 获取UUID
+     * @return
+     */
+    public static String getLockUUID(){
+        return UUID.randomUUID().toString();
+    }
+
+    /**
+     * 等待获取锁
+     *
+     * @param lockKey   锁
+     * @param requestId 请求标识
+     * @return
+     */
+    public static boolean waitGetDistributedLock(String lockKey, String requestId) {
+        return waitGetDistributedLock(lockKey, requestId, DEFAULT_EXPIRE_TIME);
+    }
+
+    public static boolean waitGetDistributedLock(String lockKey, String requestId, int expireTime) {
+        Jedis redis = null;
+        try {
+            redis = getJedis();
+            while (true) {
+                if (tryGetDistributedLock(redis, lockKey, requestId, expireTime)) {
+                    return true;
+                }
+            }
+        } finally {
+            if (redis != null) {
+                redis.close();
+            }
+        }
+    }
+
+
+    /**
+     * 尝试获取分布式锁
+     *
+     * @param lockKey    锁
+     * @param requestId  请求标识
+     * @param expireTime 超期时间
+     * @return 是否获取成功
+     */
+    public static boolean tryGetDistributedLock(Jedis redis, String lockKey, String requestId, int expireTime) {
+        String result = redis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
+
+        if (LOCK_SUCCESS.equals(result)) {
+            return true;
+        }
+
+        return false;
+
+    }
+
+    /**
+     * 释放分布式锁
+     *
+     * @param lockKey   锁
+     * @param requestId 请求标识
+     * @return 是否释放成功
+     */
+    public static boolean releaseDistributedLock(String lockKey, String requestId) {
+        Jedis redis = null;
+        try {
+            redis = getJedis();
+            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
+            Object result = redis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
+            if (RELEASE_SUCCESS.equals(result)) {
+                return true;
+            }
+            return false;
+        } finally {
+            if (redis != null) {
+                redis.close();
+            }
+        }
+    }
+}