230 lines
9.4 KiB
Java
230 lines
9.4 KiB
Java
|
|
package com.linhelp.express;
|
||
|
|
|
||
|
|
import com.linhelp.common.enums.ExpressOrderStatus;
|
||
|
|
import com.linhelp.common.enums.OfflinePayStatus;
|
||
|
|
import com.linhelp.common.exception.BizException;
|
||
|
|
import com.linhelp.user.AddressResponse;
|
||
|
|
import com.linhelp.user.UserAddressService;
|
||
|
|
import org.springframework.stereotype.Service;
|
||
|
|
|
||
|
|
import java.time.LocalDateTime;
|
||
|
|
import java.util.ArrayList;
|
||
|
|
import java.util.LinkedHashMap;
|
||
|
|
import java.util.List;
|
||
|
|
import java.util.Map;
|
||
|
|
import java.util.concurrent.atomic.AtomicLong;
|
||
|
|
|
||
|
|
@Service
|
||
|
|
public class ExpressOrderService {
|
||
|
|
private final UserAddressService addressService;
|
||
|
|
private final AtomicLong orderIds = new AtomicLong(1L);
|
||
|
|
private final AtomicLong logIds = new AtomicLong(1L);
|
||
|
|
private final Map<Long, ExpressOrderResponse> orders = new LinkedHashMap<Long, ExpressOrderResponse>();
|
||
|
|
|
||
|
|
public ExpressOrderService(UserAddressService addressService) {
|
||
|
|
this.addressService = addressService;
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse create(Long userId, ExpressOrderRequest request) {
|
||
|
|
AddressResponse address = addressService.detailMine(userId, request.getAddressId());
|
||
|
|
Long orderId = orderIds.getAndIncrement();
|
||
|
|
ExpressOrderResponse order = new ExpressOrderResponse();
|
||
|
|
order.setId(orderId);
|
||
|
|
order.setOrderNo("EO" + String.format("%08d", orderId));
|
||
|
|
order.setTenantId(request.getTenantId());
|
||
|
|
order.setCommunityId(request.getCommunityId());
|
||
|
|
order.setUserId(userId);
|
||
|
|
order.setAddressId(request.getAddressId());
|
||
|
|
order.setContactName(address.getContactName());
|
||
|
|
order.setContactPhone(address.getPhone());
|
||
|
|
order.setDeliveryAddress(buildDeliveryAddress(address));
|
||
|
|
order.setExpressCompany(request.getExpressCompany());
|
||
|
|
order.setPickupCode(request.getPickupCode());
|
||
|
|
order.setPickupAddress(request.getPickupAddress());
|
||
|
|
order.setReceiverPhone(request.getReceiverPhone());
|
||
|
|
order.setPackageCount(request.getPackageCount());
|
||
|
|
order.setFeeCent(ExpressFeeCalculator.calculateCent(request.getPackageCount()));
|
||
|
|
order.setOfflinePayStatus(OfflinePayStatus.UNPAID);
|
||
|
|
order.setStatus(ExpressOrderStatus.PENDING_CONFIRM);
|
||
|
|
order.setRemark(request.getRemark());
|
||
|
|
order.setCreatedAt(LocalDateTime.now());
|
||
|
|
order.setUpdatedAt(order.getCreatedAt());
|
||
|
|
addLog(order, "CREATE", "用户提交快递代取");
|
||
|
|
orders.put(order.getId(), order);
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse detail(Long id) {
|
||
|
|
return copyOrder(requireOrder(id));
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized List<ExpressOrderResponse> listMine(Long userId) {
|
||
|
|
List<ExpressOrderResponse> result = new ArrayList<ExpressOrderResponse>();
|
||
|
|
for (ExpressOrderResponse order : orders.values()) {
|
||
|
|
if (userId.equals(order.getUserId())) {
|
||
|
|
result.add(copyOrder(order));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized List<ExpressOrderResponse> listAdmin(Long communityId, ExpressOrderStatus status) {
|
||
|
|
List<ExpressOrderResponse> result = new ArrayList<ExpressOrderResponse>();
|
||
|
|
for (ExpressOrderResponse order : orders.values()) {
|
||
|
|
if (!communityId.equals(order.getCommunityId())) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
if (status != null && status != order.getStatus()) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
result.add(copyOrder(order));
|
||
|
|
}
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse confirm(Long id) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
move(order, ExpressOrderStatus.PENDING_PICKUP, "CONFIRM", "后台确认快递代取");
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse adjustFee(Long id, int feeCent, String reason) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
order.setFeeCent(feeCent);
|
||
|
|
order.setUpdatedAt(LocalDateTime.now());
|
||
|
|
addLog(order, "ADJUST_FEE", "调整服务费为" + feeCent + "分:" + reason);
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse cancel(Long id, String reason) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
order.setCancelReason(reason);
|
||
|
|
move(order, ExpressOrderStatus.CANCELED, "CANCEL", "取消订单:" + nullToEmpty(reason));
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse complete(Long id) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
move(order, ExpressOrderStatus.COMPLETED, "COMPLETE", "订单完成");
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse markPickingUp(Long id) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
move(order, ExpressOrderStatus.PICKING_UP, "PICKING_UP", "配送员开始取件");
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse markDelivering(Long id) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
move(order, ExpressOrderStatus.DELIVERING, "DELIVERING", "配送员开始配送");
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse markDelivered(Long id, String photoUrl) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
order.setDeliveredPhotoUrl(photoUrl);
|
||
|
|
move(order, ExpressOrderStatus.DELIVERED, "DELIVERED", "配送员送达");
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
public synchronized ExpressOrderResponse updateOfflinePayStatus(Long id, OfflinePayStatus status) {
|
||
|
|
ExpressOrderResponse order = requireOrder(id);
|
||
|
|
order.setOfflinePayStatus(status);
|
||
|
|
order.setUpdatedAt(LocalDateTime.now());
|
||
|
|
addLog(order, "OFFLINE_PAY", "线下收款状态:" + status.name());
|
||
|
|
return copyOrder(order);
|
||
|
|
}
|
||
|
|
|
||
|
|
private void move(ExpressOrderResponse order, ExpressOrderStatus target, String action, String content) {
|
||
|
|
if (!order.getStatus().canMoveTo(target)) {
|
||
|
|
throw new BizException("订单状态不允许操作");
|
||
|
|
}
|
||
|
|
order.setStatus(target);
|
||
|
|
order.setUpdatedAt(LocalDateTime.now());
|
||
|
|
addLog(order, action, content);
|
||
|
|
}
|
||
|
|
|
||
|
|
private ExpressOrderResponse requireOrder(Long id) {
|
||
|
|
ExpressOrderResponse order = orders.get(id);
|
||
|
|
if (order == null) {
|
||
|
|
throw new BizException(404, "快递代取订单不存在");
|
||
|
|
}
|
||
|
|
return order;
|
||
|
|
}
|
||
|
|
|
||
|
|
private void addLog(ExpressOrderResponse order, String action, String content) {
|
||
|
|
ExpressOrderLogResponse log = new ExpressOrderLogResponse();
|
||
|
|
log.setId(logIds.getAndIncrement());
|
||
|
|
log.setOrderId(order.getId());
|
||
|
|
log.setAction(action);
|
||
|
|
log.setContent(content);
|
||
|
|
log.setCreatedAt(LocalDateTime.now());
|
||
|
|
order.getLogs().add(log);
|
||
|
|
}
|
||
|
|
|
||
|
|
private String buildDeliveryAddress(AddressResponse address) {
|
||
|
|
StringBuilder builder = new StringBuilder();
|
||
|
|
append(builder, address.getBuilding());
|
||
|
|
append(builder, address.getRoom());
|
||
|
|
append(builder, address.getDetail());
|
||
|
|
return builder.toString();
|
||
|
|
}
|
||
|
|
|
||
|
|
private void append(StringBuilder builder, String value) {
|
||
|
|
if (value == null || value.trim().isEmpty()) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (builder.length() > 0) {
|
||
|
|
builder.append(' ');
|
||
|
|
}
|
||
|
|
builder.append(value);
|
||
|
|
}
|
||
|
|
|
||
|
|
private String nullToEmpty(String value) {
|
||
|
|
return value == null ? "" : value;
|
||
|
|
}
|
||
|
|
|
||
|
|
private ExpressOrderResponse copyOrder(ExpressOrderResponse source) {
|
||
|
|
ExpressOrderResponse target = new ExpressOrderResponse();
|
||
|
|
target.setId(source.getId());
|
||
|
|
target.setOrderNo(source.getOrderNo());
|
||
|
|
target.setTenantId(source.getTenantId());
|
||
|
|
target.setCommunityId(source.getCommunityId());
|
||
|
|
target.setUserId(source.getUserId());
|
||
|
|
target.setAddressId(source.getAddressId());
|
||
|
|
target.setContactName(source.getContactName());
|
||
|
|
target.setContactPhone(source.getContactPhone());
|
||
|
|
target.setDeliveryAddress(source.getDeliveryAddress());
|
||
|
|
target.setExpressCompany(source.getExpressCompany());
|
||
|
|
target.setPickupCode(source.getPickupCode());
|
||
|
|
target.setPickupAddress(source.getPickupAddress());
|
||
|
|
target.setReceiverPhone(source.getReceiverPhone());
|
||
|
|
target.setPackageCount(source.getPackageCount());
|
||
|
|
target.setFeeCent(source.getFeeCent());
|
||
|
|
target.setOfflinePayStatus(source.getOfflinePayStatus());
|
||
|
|
target.setStatus(source.getStatus());
|
||
|
|
target.setRemark(source.getRemark());
|
||
|
|
target.setCancelReason(source.getCancelReason());
|
||
|
|
target.setDeliveredPhotoUrl(source.getDeliveredPhotoUrl());
|
||
|
|
target.setCreatedAt(source.getCreatedAt());
|
||
|
|
target.setUpdatedAt(source.getUpdatedAt());
|
||
|
|
target.setLogs(copyLogs(source.getLogs()));
|
||
|
|
return target;
|
||
|
|
}
|
||
|
|
|
||
|
|
private List<ExpressOrderLogResponse> copyLogs(List<ExpressOrderLogResponse> sourceLogs) {
|
||
|
|
List<ExpressOrderLogResponse> logs = new ArrayList<ExpressOrderLogResponse>();
|
||
|
|
for (ExpressOrderLogResponse source : sourceLogs) {
|
||
|
|
ExpressOrderLogResponse target = new ExpressOrderLogResponse();
|
||
|
|
target.setId(source.getId());
|
||
|
|
target.setOrderId(source.getOrderId());
|
||
|
|
target.setAction(source.getAction());
|
||
|
|
target.setContent(source.getContent());
|
||
|
|
target.setCreatedAt(source.getCreatedAt());
|
||
|
|
logs.add(target);
|
||
|
|
}
|
||
|
|
return logs;
|
||
|
|
}
|
||
|
|
}
|