zhuyifan

feat(settlement): 增加用户资源权限控制及优化结算逻辑- 在LoginContextHolder中增加clientId字段以支持客户端标识- 更…

…新LoginInterceptor以从客户和操作员信息中提取并设置clientId
- 引入ClientResourceTagServiceRpcClient用于获取用户资源权限
- 根据用户权限动态过滤档口ID,若请求未指定则使用用户拥有的档口
-优化订单筛选条件,简化在线支付与非在线支付的判断逻辑
- 移除冗余的空值检查,提升代码可读性与健壮性
- 简化字符串判空逻辑,提高代码简洁度- 安全获取订单备注、忌口、医嘱等字段,避免空指针异常
- 调整订单详情构建过程,确保字段安全访问-优化餐品名称与SKU名称的安全获取方式
......@@ -57,6 +57,8 @@ public class LoginContextHolder {
private Integer enterpriseId;
private Integer clientId;
private String name;
@Builder.Default
......
......@@ -93,7 +93,7 @@ public class LoginInterceptor implements HandlerInterceptor {
ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
return false;
}
builder.id(loginId).enterpriseId(enterpriseId).name(customer.getResponse().getName()).openId(openId).loginSource(LoginSourceEnum.CUSTOMER);
builder.id(loginId).enterpriseId(enterpriseId).clientId(customer.getResponse().getClientId()).name(customer.getResponse().getName()).openId(openId).loginSource(LoginSourceEnum.CUSTOMER);
return true;
} else if (loginSource.equals(LoginSourceEnum.OPERATOR.getValue())){
final var loginId = StpUtil.getLoginIdAsInt();
......@@ -103,7 +103,7 @@ public class LoginInterceptor implements HandlerInterceptor {
ResponseUtil.write(response, ResponseResult.failed(ErrorCodeEnum.FORBIDDEN));
return false;
}
builder.id(loginId).enterpriseId(enterpriseId).name(opeartor.getName()).loginSource(LoginSourceEnum.OPERATOR);
builder.id(loginId).enterpriseId(enterpriseId).clientId(opeartor.getClientId()).name(opeartor.getName()).loginSource(LoginSourceEnum.OPERATOR);
return true;
} else if (loginSource.equals(LoginSourceEnum.KDS.getValue())) {
final var loginId = StpUtil.getLoginIdAsInt();
......
package com.infoloop.tianting.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.infoloop.tianting.SingleDishSkuByIdsRpcResponse;
import com.infoloop.tianting.clientcustomerorderservice.OnlinePayEnum;
......@@ -31,6 +32,7 @@ import com.infoloop.tianting.model.enums.desc.OnlinePayDescEnum;
import com.infoloop.tianting.service.SettlementService;
import com.infoloop.tianting.service.client.ClientCustomerServiceRpcClient;
import com.infoloop.tianting.service.client.ClientInventoryServiceRpcClient;
import com.infoloop.tianting.service.client.ClientResourceTagServiceRpcClient;
import com.infoloop.tianting.service.client.MealServiceRpcClient;
import com.infoloop.tianting.service.client.MenuServiceRpcClient;
import com.infoloop.tianting.service.client.OrderServiceRpcClient;
......@@ -82,6 +84,7 @@ public class SettlementServiceImpl implements SettlementService {
private final ClientInventoryServiceRpcClient clientInventoryServiceRpcClient;
private final MealServiceRpcClient mealServiceRpcClient;
private final ClientCustomerServiceRpcClient clientCustomerServiceRpcClient;
private final ClientResourceTagServiceRpcClient clientResourceTagServiceRpcClient;
public static ByteArrayOutputStream writeToExcelBySku(SettlementDataDto settlementDataDto)
throws IOException {
......@@ -311,6 +314,9 @@ public class SettlementServiceImpl implements SettlementService {
throw BusinessException.build(ErrorCodeEnum.GENERATE_EXCEL_ERROR);
}
final var loginInfo = LoginContextHolder.getLoginInfo();
final var userResources = clientResourceTagServiceRpcClient.getUserResources(loginInfo.getEnterpriseId(), loginInfo.getClientId(), loginInfo.getId());
// 计算日期范围
final var startDate = settlementRequest.getTimeStart().plusHours(8).toLocalDate().atStartOfDay();
final var endDate = settlementRequest.getTimeEnd().plusHours(8).toLocalDate().plusDays(1).atStartOfDay();
......@@ -319,6 +325,13 @@ public class SettlementServiceImpl implements SettlementService {
final var operatorLoginInfo = LoginContextHolder.getLoginInfo();
final int enterpriseId = LoginContextHolder.hasLogin() ? operatorLoginInfo.getEnterpriseId() : settlementRequest.getEnterpriseId();
final var stallIds = new ArrayList<Integer>();
if (CollectionUtil.isEmpty(settlementRequest.getStallIds())) {
stallIds.addAll(userResources.getStallIdsList());
} else {
stallIds.addAll(settlementRequest.getStallIds());
}
// 构建查询条件
final var queryOrderDto = QueryOrderByConditionDto.builder()
.enterpriseId(enterpriseId)
......@@ -326,8 +339,8 @@ public class SettlementServiceImpl implements SettlementService {
.mealTimeStart(startDate)
.shouldFilterMealTimeEnd(true)
.mealTimeEnd(endDate)
.shouldFilterStallIds(settlementRequest.getStallIds() != null && !settlementRequest.getStallIds().isEmpty())
.stallIds(settlementRequest.getStallIds() != null ? settlementRequest.getStallIds() : Collections.emptyList())
.shouldFilterStallIds(true)
.stallIds(stallIds)
.build();
// 查询订单列表
......@@ -342,15 +355,14 @@ public class SettlementServiceImpl implements SettlementService {
.filter(Objects::nonNull)
.filter(o -> {
// 在线支付订单需要支付成功
if (o.getOnlinePay() != null && o.getOnlinePay() == OnlinePayEnum.ONLINE) {
return o.getPayStatus() != null && o.getPayStatus() == PayStatusEnum.SUCCEED;
if (o.getOnlinePay() == OnlinePayEnum.ONLINE) {
return o.getPayStatus() == PayStatusEnum.SUCCEED;
} else {
// 非在线支付订单需要未取消
return o.getStatus() != null && o.getStatus() != OrderStatusEnum.ORDER_CANCELED;
return o.getStatus() != OrderStatusEnum.ORDER_CANCELED;
}
})
.map(SingleClientCustomerOrderRpcResponse::getId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
......@@ -361,7 +373,6 @@ public class SettlementServiceImpl implements SettlementService {
// 构建订单映射
final var orderMap = orderList.stream()
.filter(Objects::nonNull)
.filter(o -> o.getId() != 0)
.collect(Collectors.toMap(SingleClientCustomerOrderRpcResponse::getId, o -> o, (o1, o2) -> o1));
......@@ -375,15 +386,14 @@ public class SettlementServiceImpl implements SettlementService {
// 订单详情按订单ID分组
final var orderDetailGroupByOrderId = orderDetailList.stream()
.filter(Objects::nonNull)
.filter(d -> d.getServeStatus() != null && !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
.filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
.collect(Collectors.groupingBy(SingleClientCustomerOrderDetailRpcResponse::getOrderId));
// 获取SKU数据
List<Integer> skuIds = orderDetailList.stream()
.filter(Objects::nonNull)
.filter(d -> d.getServeStatus() != null && !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
.filter(d -> !d.getServeStatus().equals(ServeStatusEnum.SERVE_REJECT))
.map(SingleClientCustomerOrderDetailRpcResponse::getSkuId)
.filter(Objects::nonNull)
.distinct()
.collect(Collectors.toList());
......@@ -484,9 +494,12 @@ public class SettlementServiceImpl implements SettlementService {
String onlinePayDesc = getOnlinePayDescSafely(order);
// 构建订单详情
order.getOrderCode();
order.getRemark();
order.getAvoidRemark();
SettlementDTO.SettlementOrderDetail settlementOrderDetail = SettlementDTO.SettlementOrderDetail.builder()
.mealTime(order.getMealTime() != 0L ? LocalDateTimeUtil.of(order.getMealTime()).format(DateUtil.YYYY_MM_DD_LEFT_SYMBOL) : "")
.code(order.getOrderCode() != null ? order.getOrderCode() : "")
.code(order.getOrderCode())
.mealName(mealName)
.roomNo(roomNo)
.customerName(customerName)
......@@ -498,8 +511,8 @@ public class SettlementServiceImpl implements SettlementService {
.count(orderDetail.getCount() != 0 ? orderDetail.getCount() : 0)
.price(calculatePrice(orderDetail.getPrice()))
.totalPrice(calculateTotalPrice(orderDetail.getPrice(), orderDetail.getCount()))
.remark(order.getRemark() != null ? order.getRemark() : "")
.avoidRemark(order.getAvoidRemark() != null ? order.getAvoidRemark() : "")
.remark(order.getRemark())
.avoidRemark(order.getAvoidRemark())
.onlinePay(onlinePayDesc)
.build();
classifyOrders.add(settlementOrderDetail);
......@@ -536,7 +549,7 @@ public class SettlementServiceImpl implements SettlementService {
}
final var meal = mealMap.get(menuDetail.getMealId());
return meal != null && meal.getName() != null ? meal.getName() : "";
return meal != null ? meal.getName() : "";
}
/**
......@@ -549,7 +562,7 @@ public class SettlementServiceImpl implements SettlementService {
}
final var sku = skuMap.get(orderDetail.getSkuId());
return sku != null && sku.getName() != null ? sku.getName() : "";
return sku != null ? sku.getName() : "";
}
/**
......@@ -561,43 +574,40 @@ public class SettlementServiceImpl implements SettlementService {
}
String syncRoomNo = order.getSyncRoomNo();
if (syncRoomNo != null && !syncRoomNo.isEmpty()) {
if (!syncRoomNo.isEmpty()) {
return syncRoomNo;
}
String roomNo = order.getRoomNo();
return roomNo != null ? roomNo : "";
return order.getRoomNo();
}
/**
* 安全获取忌口列表
*/
private List<String> getAvoidsSafely(SingleClientCustomerOrderRpcResponse order) {
if (order == null || order.getCustomerNoticeJson() == null) {
if (order == null) {
return Collections.emptyList();
}
List<String> avoids = order.getCustomerNoticeJson().getAvoidsList();
return avoids != null ? avoids : Collections.emptyList();
return order.getCustomerNoticeJson().getAvoidsList();
}
/**
* 安全获取医嘱列表
*/
private List<String> getDoctorsSafely(SingleClientCustomerOrderRpcResponse order) {
if (order == null || order.getCustomerNoticeJson() == null) {
if (order == null) {
return Collections.emptyList();
}
List<String> doctors = order.getCustomerNoticeJson().getDoctorsList();
return doctors != null ? doctors : Collections.emptyList();
return order.getCustomerNoticeJson().getDoctorsList();
}
/**
* 安全获取在线支付描述
*/
private String getOnlinePayDescSafely(SingleClientCustomerOrderRpcResponse order) {
if (order == null || order.getOnlinePay() == null) {
if (order == null) {
return "";
}
......