|
@@ -11,17 +11,21 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
|
|
+import org.dromara.common.core.enums.AssigneeTypeConstants;
|
|
|
import org.dromara.common.core.enums.OrderPayType;
|
|
import org.dromara.common.core.enums.OrderPayType;
|
|
|
import org.dromara.common.core.enums.OrderStatus;
|
|
import org.dromara.common.core.enums.OrderStatus;
|
|
|
import org.dromara.common.core.exception.ServiceException;
|
|
import org.dromara.common.core.exception.ServiceException;
|
|
|
import org.dromara.common.core.exception.api.ZhongcheException;
|
|
import org.dromara.common.core.exception.api.ZhongcheException;
|
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
import org.dromara.common.core.utils.MapstructUtils;
|
|
|
|
|
+import org.dromara.common.core.utils.ObjectUtils;
|
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
import org.dromara.common.core.utils.StringUtils;
|
|
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
import org.dromara.common.redis.utils.SequenceUtils;
|
|
import org.dromara.common.redis.utils.SequenceUtils;
|
|
|
import org.dromara.customer.api.RemoteCustomerSalesService;
|
|
import org.dromara.customer.api.RemoteCustomerSalesService;
|
|
|
import org.dromara.customer.api.RemoteCustomerService;
|
|
import org.dromara.customer.api.RemoteCustomerService;
|
|
|
|
|
+import org.dromara.customer.api.RemotePartnerInfoService;
|
|
|
|
|
+import org.dromara.customer.api.RemoteSupplierInfoService;
|
|
|
import org.dromara.customer.api.domain.vo.RemoteCustomerSalesVo;
|
|
import org.dromara.customer.api.domain.vo.RemoteCustomerSalesVo;
|
|
|
import org.dromara.external.api.zhongche.RemoteZhongChePullService;
|
|
import org.dromara.external.api.zhongche.RemoteZhongChePullService;
|
|
|
import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
|
|
import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
|
|
@@ -44,6 +48,7 @@ import org.dromara.order.utils.kd100.domain.TrackData;
|
|
|
import org.dromara.order.utils.kd100.domain.TrackVO;
|
|
import org.dromara.order.utils.kd100.domain.TrackVO;
|
|
|
import org.dromara.product.api.RemoteProductShoppingCartService;
|
|
import org.dromara.product.api.RemoteProductShoppingCartService;
|
|
|
import org.dromara.system.api.*;
|
|
import org.dromara.system.api.*;
|
|
|
|
|
+import org.dromara.system.api.model.LoginUser;
|
|
|
import org.mybatis.spring.MyBatisSystemException;
|
|
import org.mybatis.spring.MyBatisSystemException;
|
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
import org.springframework.dao.DuplicateKeyException;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
@@ -75,6 +80,12 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
|
|
|
@DubboReference
|
|
@DubboReference
|
|
|
private RemoteCustomerService remoteCustomerService;
|
|
private RemoteCustomerService remoteCustomerService;
|
|
|
|
|
|
|
|
|
|
+ @DubboReference
|
|
|
|
|
+ private RemoteSupplierInfoService remoteSupplierInfoService;
|
|
|
|
|
+
|
|
|
|
|
+ @DubboReference
|
|
|
|
|
+ private RemotePartnerInfoService remotePartnerInfoService;
|
|
|
|
|
+
|
|
|
@DubboReference
|
|
@DubboReference
|
|
|
private RemoteCustomerSalesService remoteCustomerSalesService;
|
|
private RemoteCustomerSalesService remoteCustomerSalesService;
|
|
|
|
|
|
|
@@ -131,7 +142,77 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
|
|
|
|
|
|
|
|
// 2. 查询关联的商品列表--并且查询商品已发货数量与未发货数量
|
|
// 2. 查询关联的商品列表--并且查询商品已发货数量与未发货数量
|
|
|
List<OrderProductVo> orderProductVoList = orderProductMapper.selectProductsWithDelivered(orderMainVo.getId());
|
|
List<OrderProductVo> orderProductVoList = orderProductMapper.selectProductsWithDelivered(orderMainVo.getId());
|
|
|
|
|
+ if (orderProductVoList != null && !orderProductVoList.isEmpty()) {
|
|
|
|
|
+ // 2. 收集所有需要处理的 childOrderId (去重)
|
|
|
|
|
+ List<Long> childOrderIds = orderProductVoList.stream()
|
|
|
|
|
+ .map(OrderProductVo::getAssignedChildOrderId)
|
|
|
|
|
+ .filter(Objects::nonNull)
|
|
|
|
|
+ .distinct()
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+
|
|
|
|
|
+ if (!childOrderIds.isEmpty()) {
|
|
|
|
|
+ // 3. 批量查询子订单信息 (避免 N+1 数据库查询)
|
|
|
|
|
+ List<OrderMainVo> childOrderList = baseMapper.selectVoByIds(childOrderIds);
|
|
|
|
|
+
|
|
|
|
|
+ // 将子订单放入 Map 方便快速查找: Key = childOrderId, Value = OrderMainVo
|
|
|
|
|
+ Map<Long, OrderMainVo> childOrderMap = childOrderList.stream()
|
|
|
|
|
+ .collect(Collectors.toMap(OrderMainVo::getId, Function.identity(), (k1, k2) -> k1));
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 按分配类型分组收集 ID,准备批量调用远程服务
|
|
|
|
|
+ List<Long> customerIds = new ArrayList<>();
|
|
|
|
|
+ List<Long> supplierIds = new ArrayList<>();
|
|
|
|
|
+ List<Long> partnerIds = new ArrayList<>();
|
|
|
|
|
+
|
|
|
|
|
+ for (OrderMainVo childOrder : childOrderList) {
|
|
|
|
|
+ if (childOrder.getAssigneeId() == null) continue;
|
|
|
|
|
+
|
|
|
|
|
+ String type = childOrder.getAssigneeType();
|
|
|
|
|
+ if (AssigneeTypeConstants.CUSTOMER.getCode().equals(type)) {
|
|
|
|
|
+ customerIds.add(childOrder.getAssigneeId());
|
|
|
|
|
+ } else if (AssigneeTypeConstants.SUPPLIER.getCode().equals(type)) {
|
|
|
|
|
+ supplierIds.add(childOrder.getAssigneeId());
|
|
|
|
|
+ } else if (AssigneeTypeConstants.PARTNER.getCode().equals(type)) {
|
|
|
|
|
+ partnerIds.add(childOrder.getAssigneeId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 【优化点3】批量调用远程服务 (每种类型只调用一次)
|
|
|
|
|
+ Map<Long, String> customerNameMap = Collections.emptyMap();
|
|
|
|
|
+ Map<Long, String> supplierNameMap = Collections.emptyMap();
|
|
|
|
|
+ Map<Long, String> partnerNameMap = Collections.emptyMap();
|
|
|
|
|
+
|
|
|
|
|
+ if (!customerIds.isEmpty()) {
|
|
|
|
|
+ customerNameMap = remoteCustomerService.selectCustomerNameByIds(new HashSet<>(customerIds));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!supplierIds.isEmpty()) {
|
|
|
|
|
+ supplierNameMap = remoteSupplierInfoService.selectSupplierNameByIds(new HashSet<>(supplierIds));
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!partnerIds.isEmpty()) {
|
|
|
|
|
+ partnerNameMap = remotePartnerInfoService.selectPartnerNameByIds(new HashSet<>(partnerIds));
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // 6. 【优化点4】内存组装数据
|
|
|
|
|
+ for (OrderProductVo productVo : orderProductVoList) {
|
|
|
|
|
+ Long childOrderId = productVo.getAssignedChildOrderId();
|
|
|
|
|
+ if (childOrderId != null) {
|
|
|
|
|
+ OrderMainVo childOrder = childOrderMap.get(childOrderId);
|
|
|
|
|
+ if (childOrder != null && childOrder.getAssigneeId() != null) {
|
|
|
|
|
+ String assigneeName = null;
|
|
|
|
|
+ String type = childOrder.getAssigneeType();
|
|
|
|
|
+
|
|
|
|
|
+ if (AssigneeTypeConstants.CUSTOMER.getCode().equals(type)) {
|
|
|
|
|
+ assigneeName = customerNameMap.get(childOrder.getAssigneeId());
|
|
|
|
|
+ } else if (AssigneeTypeConstants.SUPPLIER.getCode().equals(type)) {
|
|
|
|
|
+ assigneeName = supplierNameMap.get(childOrder.getAssigneeId());
|
|
|
|
|
+ } else if (AssigneeTypeConstants.PARTNER.getCode().equals(type)) {
|
|
|
|
|
+ assigneeName = partnerNameMap.get(childOrder.getAssigneeId());
|
|
|
|
|
+ }
|
|
|
|
|
+ productVo.setAssigneeName(assigneeName);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
// 3. 组装数据
|
|
// 3. 组装数据
|
|
|
orderMainVo.setOrderProductList(orderProductVoList);
|
|
orderMainVo.setOrderProductList(orderProductVoList);
|
|
|
|
|
|
|
@@ -193,8 +274,8 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public OrderCountVo countOrderNum(Long customerId) {
|
|
|
|
|
- return baseMapper.countOrderNum(customerId);
|
|
|
|
|
|
|
+ public OrderCountVo countOrderNum(Long customerId, Long userId) {
|
|
|
|
|
+ return baseMapper.countOrderNum(customerId, userId);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -489,6 +570,12 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public Long insertOrder(PcSubmitOrderBo bo, OrderMainBo mainBo) {
|
|
public Long insertOrder(PcSubmitOrderBo bo, OrderMainBo mainBo) {
|
|
|
RemoteCustomerSalesVo remoteCustomerSalesVo = remoteCustomerSalesService.selectCustomerSalesInfoByCustomerId(mainBo.getCustomerId());
|
|
RemoteCustomerSalesVo remoteCustomerSalesVo = remoteCustomerSalesService.selectCustomerSalesInfoByCustomerId(mainBo.getCustomerId());
|
|
|
|
|
+
|
|
|
|
|
+ LoginUser userInfo = remoteUserService.getUserInfo(mainBo.getUserId(), "000000");
|
|
|
|
|
+ if (ObjectUtils.isNotEmpty(userInfo)) {
|
|
|
|
|
+ mainBo.setUserDept(userInfo.getDeptName());
|
|
|
|
|
+ mainBo.setCreateDept(userInfo.getDeptId());
|
|
|
|
|
+ }
|
|
|
if (null != remoteCustomerSalesVo) {
|
|
if (null != remoteCustomerSalesVo) {
|
|
|
Long salesPersonId = remoteCustomerSalesVo.getSalesPersonId();//销售人员id
|
|
Long salesPersonId = remoteCustomerSalesVo.getSalesPersonId();//销售人员id
|
|
|
Long serviceStaffId = remoteCustomerSalesVo.getServiceStaffId();//服务人员
|
|
Long serviceStaffId = remoteCustomerSalesVo.getServiceStaffId();//服务人员
|
|
@@ -647,18 +734,24 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public Boolean orderPay(Long customerId, Long orderId, String payType) {
|
|
public Boolean orderPay(Long customerId, Long orderId, String payType) {
|
|
|
- // 参数校验
|
|
|
|
|
|
|
+ // 1. 参数校验
|
|
|
if (orderId == null) {
|
|
if (orderId == null) {
|
|
|
throw new ServiceException("订单ID不能为空");
|
|
throw new ServiceException("订单ID不能为空");
|
|
|
}
|
|
}
|
|
|
if (customerId == null) {
|
|
if (customerId == null) {
|
|
|
throw new ServiceException("客户ID不能为空");
|
|
throw new ServiceException("客户ID不能为空");
|
|
|
}
|
|
}
|
|
|
- if (payType == null || !OrderPayType.CREDIT_PAY.getCode().equals(payType)) {
|
|
|
|
|
- throw new ServiceException("仅支持信用支付方式");
|
|
|
|
|
|
|
+ if (payType == null) {
|
|
|
|
|
+ throw new ServiceException("请选择支付方式");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 校验支付方式是否合法 (可选,增强健壮性)
|
|
|
|
|
+ if (!Objects.equals(payType, OrderPayType.CREDIT_PAY.getCode()) &&
|
|
|
|
|
+ !Objects.equals(payType, OrderPayType.TEMP_ORDER.getCode())) {
|
|
|
|
|
+ throw new ServiceException("不支持的支付方式");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 查询订单
|
|
|
|
|
|
|
+ // 2. 查询订单
|
|
|
OrderMainVo orderMainVo = baseMapper.selectVoById(orderId);
|
|
OrderMainVo orderMainVo = baseMapper.selectVoById(orderId);
|
|
|
if (orderMainVo == null) {
|
|
if (orderMainVo == null) {
|
|
|
throw new ServiceException("订单不存在");
|
|
throw new ServiceException("订单不存在");
|
|
@@ -672,61 +765,84 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
|
|
|
throw new ServiceException("订单金额无效");
|
|
throw new ServiceException("订单金额无效");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 查询客户信用销售信息
|
|
|
|
|
- RemoteCustomerSalesVo salesInfo = remoteCustomerSalesService.selectCustomerSalesInfoByCustomerId(customerId);
|
|
|
|
|
- if (salesInfo == null) {
|
|
|
|
|
- throw new ServiceException("客户信用信息未配置,无法使用信用支付");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 3. 根据支付方式执行不同逻辑
|
|
|
|
|
+ if (Objects.equals(payType, OrderPayType.CREDIT_PAY.getCode())) {
|
|
|
|
|
|
|
|
- // 获取可用额度:剩余额度 + 临时额度
|
|
|
|
|
- BigDecimal remainingQuota = Optional.ofNullable(salesInfo.getRemainingQuota()).orElse(BigDecimal.ZERO);
|
|
|
|
|
- BigDecimal temporaryQuota = Optional.ofNullable(salesInfo.getTemporaryQuota()).orElse(BigDecimal.ZERO);
|
|
|
|
|
|
|
+ // 查询客户信用销售信息
|
|
|
|
|
+ RemoteCustomerSalesVo salesInfo = remoteCustomerSalesService.selectCustomerSalesInfoByCustomerId(customerId);
|
|
|
|
|
+ if (salesInfo == null) {
|
|
|
|
|
+ throw new ServiceException("客户信用信息未配置,无法使用信用支付");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ // 获取可用额度:剩余额度 + 临时额度
|
|
|
|
|
+ BigDecimal remainingQuota = Optional.ofNullable(salesInfo.getRemainingQuota()).orElse(BigDecimal.ZERO);
|
|
|
|
|
+ BigDecimal temporaryQuota = Optional.ofNullable(salesInfo.getTemporaryQuota()).orElse(BigDecimal.ZERO);
|
|
|
|
|
+ BigDecimal availableCredit = remainingQuota.add(temporaryQuota);
|
|
|
|
|
|
|
|
- // 临时额度可用于支付
|
|
|
|
|
- BigDecimal availableCredit = remainingQuota.add(temporaryQuota);
|
|
|
|
|
|
|
+ // 判断额度是否足够
|
|
|
|
|
+ if (availableCredit.compareTo(totalAmount) < 0) {
|
|
|
|
|
+ throw new ServiceException("信用额度不足,无法完成支付");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 判断额度是否足够
|
|
|
|
|
- if (availableCredit.compareTo(totalAmount) < 0) {
|
|
|
|
|
- throw new ServiceException("信用额度不足,无法完成支付");
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 扣减逻辑:优先扣减临时额度,再扣剩余额度
|
|
|
|
|
+ BigDecimal newRemainingQuota = remainingQuota;
|
|
|
|
|
+ BigDecimal newTemporaryQuota = temporaryQuota;
|
|
|
|
|
|
|
|
- // 扣减逻辑:优先扣减临时额度,再扣剩余额度
|
|
|
|
|
- BigDecimal newRemainingQuota = remainingQuota;
|
|
|
|
|
- BigDecimal newTemporaryQuota = temporaryQuota;
|
|
|
|
|
|
|
+ if (temporaryQuota.compareTo(totalAmount) >= 0) {
|
|
|
|
|
+ // 临时额度足够,只扣临时额度
|
|
|
|
|
+ newTemporaryQuota = temporaryQuota.subtract(totalAmount);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 临时额度不足,先清空临时额度,再扣剩余额度
|
|
|
|
|
+ BigDecimal remainingToDeduct = totalAmount.subtract(temporaryQuota);
|
|
|
|
|
+ newTemporaryQuota = BigDecimal.ZERO;
|
|
|
|
|
+ newRemainingQuota = remainingQuota.subtract(remainingToDeduct);
|
|
|
|
|
|
|
|
- if (temporaryQuota.compareTo(totalAmount) >= 0) {
|
|
|
|
|
- // 临时额度足够,只扣临时额度
|
|
|
|
|
- newTemporaryQuota = temporaryQuota.subtract(totalAmount);
|
|
|
|
|
- } else {
|
|
|
|
|
- // 临时额度不足,先清空临时额度,再扣剩余额度
|
|
|
|
|
- BigDecimal remainingToDeduct = totalAmount.subtract(temporaryQuota);
|
|
|
|
|
- newTemporaryQuota = BigDecimal.ZERO;
|
|
|
|
|
- newRemainingQuota = remainingQuota.subtract(remainingToDeduct);
|
|
|
|
|
-
|
|
|
|
|
- // 理论上不会为负(前面已校验总额度足够),但防御性检查
|
|
|
|
|
- if (newRemainingQuota.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
|
|
- throw new ServiceException("信用额度计算异常,请联系管理员");
|
|
|
|
|
|
|
+ if (newRemainingQuota.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
|
|
+ throw new ServiceException("信用额度计算异常,请联系管理员");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
- // 更新对象
|
|
|
|
|
- salesInfo.setRemainingQuota(newRemainingQuota);
|
|
|
|
|
- salesInfo.setTemporaryQuota(newTemporaryQuota);
|
|
|
|
|
|
|
+ // 更新额度对象
|
|
|
|
|
+ salesInfo.setRemainingQuota(newRemainingQuota);
|
|
|
|
|
+ salesInfo.setTemporaryQuota(newTemporaryQuota);
|
|
|
|
|
|
|
|
- // 执行更新
|
|
|
|
|
- boolean updated = remoteCustomerSalesService.updateCustomerSalesInfo(salesInfo);
|
|
|
|
|
- if (!updated) {
|
|
|
|
|
- throw new RuntimeException("信用额度更新失败,请重试");
|
|
|
|
|
- }
|
|
|
|
|
- OrderMain order = new OrderMain();
|
|
|
|
|
- order.setId(orderId);
|
|
|
|
|
- order.setPayType(payType);
|
|
|
|
|
- order.setOrderStatus(OrderStatus.PENDING_CONFIRMATION.getCode());
|
|
|
|
|
- Boolean result = baseMapper.updateById(order) > 0;
|
|
|
|
|
- if (!result) {
|
|
|
|
|
- throw new RuntimeException("订单支付失败");
|
|
|
|
|
|
|
+ // 执行额度更新
|
|
|
|
|
+ boolean updated = remoteCustomerSalesService.updateCustomerSalesInfo(salesInfo);
|
|
|
|
|
+ if (!updated) {
|
|
|
|
|
+ throw new RuntimeException("信用额度更新失败,请重试");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 更新订单状态为:已支付
|
|
|
|
|
+ OrderMain order = new OrderMain();
|
|
|
|
|
+ order.setId(orderId);
|
|
|
|
|
+ order.setPayType(payType);
|
|
|
|
|
+ order.setPaymentStatus("1"); // 1: 已支付
|
|
|
|
|
+ order.setOrderStatus(OrderStatus.PENDING_CONFIRMATION.getCode()); // 待确认
|
|
|
|
|
+
|
|
|
|
|
+ int updateCount = baseMapper.updateById(order);
|
|
|
|
|
+ if (updateCount <= 0) {
|
|
|
|
|
+ throw new RuntimeException("订单支付状态更新失败");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ } else if (Objects.equals(payType, OrderPayType.TEMP_ORDER.getCode())) {
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 更新订单状态为:暂存/待支付
|
|
|
|
|
+ OrderMain order = new OrderMain();
|
|
|
|
|
+ order.setId(orderId);
|
|
|
|
|
+ order.setPayType(payType);
|
|
|
|
|
+
|
|
|
|
|
+ // 根据需求:支付方式改为暂存订单,状态为待支付
|
|
|
|
|
+ order.setPaymentStatus("0");
|
|
|
|
|
+
|
|
|
|
|
+ // 订单状态设为待支付
|
|
|
|
|
+ order.setOrderStatus(OrderStatus.PENDING_PAYMENT.getCode());
|
|
|
|
|
+
|
|
|
|
|
+ int updateCount = baseMapper.updateById(order);
|
|
|
|
|
+ if (updateCount <= 0) {
|
|
|
|
|
+ throw new ServiceException("订单暂存失败");
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|