feat: 订单
parent
dd42483eae
commit
02a16a6590
|
|
@ -3,19 +3,20 @@ package com.ruoyi.web.controller.xkt;
|
|||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.ruoyi.common.core.controller.XktBaseController;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
import com.ruoyi.web.controller.xkt.vo.express.ExpressAddressParseReqVO;
|
||||
import com.ruoyi.web.controller.xkt.vo.express.ExpressRegionTreeNodeVO;
|
||||
import com.ruoyi.web.controller.xkt.vo.express.ExpressStructAddressVO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressRegionTreeNodeDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressStructAddressDTO;
|
||||
import com.ruoyi.xkt.manager.ExpressManager;
|
||||
import com.ruoyi.xkt.manager.impl.ZtoExpressManagerImpl;
|
||||
import com.ruoyi.xkt.service.IExpressService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
|
@ -31,8 +32,6 @@ public class ExpressController extends XktBaseController {
|
|||
private IExpressService expressService;
|
||||
@Autowired
|
||||
private List<ExpressManager> expressManagers;
|
||||
@Autowired
|
||||
private ZtoExpressManagerImpl ztoExpressManager;
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:express:query')")
|
||||
@ApiOperation("获取行政规划树")
|
||||
|
|
@ -42,4 +41,12 @@ public class ExpressController extends XktBaseController {
|
|||
return success(BeanUtil.copyToList(dtoList, ExpressRegionTreeNodeVO.class));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('system:express:query')")
|
||||
@ApiOperation("智能解析 - 对地址、姓名、电话等,进行智能识别")
|
||||
@PostMapping("parseNamePhoneAddress")
|
||||
public R<ExpressStructAddressVO> parseNamePhoneAddress(@Valid @RequestBody ExpressAddressParseReqVO vo) {
|
||||
ExpressStructAddressDTO dto = expressService.parseNamePhoneAddress(vo.getAddress());
|
||||
return success(BeanUtil.toBean(dto, ExpressStructAddressVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package com.ruoyi.web.controller.xkt.vo.express;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-16 22:31
|
||||
*/
|
||||
@ApiModel
|
||||
@Data
|
||||
public class ExpressAddressParseReqVO {
|
||||
|
||||
@NotEmpty
|
||||
@ApiModelProperty(value = "地址,包含地址、姓名、电话等")
|
||||
private String address;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package com.ruoyi.web.controller.xkt.vo.express;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-16 16:18
|
||||
*/
|
||||
@ApiModel
|
||||
@Data
|
||||
public class ExpressStructAddressVO {
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@ApiModelProperty(value = "名称")
|
||||
private String contactName;
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
@ApiModelProperty(value = "电话")
|
||||
private String contactPhoneNumber;
|
||||
/**
|
||||
* 省
|
||||
*/
|
||||
@ApiModelProperty(value = "省")
|
||||
private String provinceCode;
|
||||
@ApiModelProperty(value = "省")
|
||||
private String provinceName;
|
||||
/**
|
||||
* 市
|
||||
*/
|
||||
@ApiModelProperty(value = "市")
|
||||
private String cityCode;
|
||||
@ApiModelProperty(value = "市")
|
||||
private String cityName;
|
||||
/**
|
||||
* 区县
|
||||
*/
|
||||
@ApiModelProperty(value = "区县")
|
||||
private String countyCode;
|
||||
@ApiModelProperty(value = "区县")
|
||||
private String countyName;
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
@ApiModelProperty(value = "详细地址")
|
||||
private String detailAddress;
|
||||
}
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
package com.ruoyi.xkt.dto.express;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-16 15:24
|
||||
|
|
@ -70,5 +73,48 @@ public class ExpressShipReqDTO {
|
|||
* 收货人-详细地址
|
||||
*/
|
||||
private String destinationDetailAddress;
|
||||
/**
|
||||
* 物品信息
|
||||
*/
|
||||
private List<OrderItem> orderItems;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public static class OrderItem {
|
||||
/**
|
||||
* 货品名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 商品分类
|
||||
*/
|
||||
private String category;
|
||||
/**
|
||||
* 商品材质
|
||||
*/
|
||||
private String material;
|
||||
/**
|
||||
* 大小(长,宽,高)(单位:厘米), 用半角的逗号来分隔长宽高
|
||||
*/
|
||||
private String size;
|
||||
/**
|
||||
* 重量(单位:克)
|
||||
*/
|
||||
private Long weight;
|
||||
/**
|
||||
* 单价(单位:元)
|
||||
*/
|
||||
private Integer unitprice;
|
||||
/**
|
||||
* 货品数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
/**
|
||||
* 货品备注
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
package com.ruoyi.xkt.dto.express;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-16 16:18
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ExpressStructAddressDTO {
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
private String contactName;
|
||||
/**
|
||||
* 电话
|
||||
*/
|
||||
private String contactPhoneNumber;
|
||||
/**
|
||||
* 省
|
||||
*/
|
||||
private String provinceCode;
|
||||
private String provinceName;
|
||||
/**
|
||||
* 市
|
||||
*/
|
||||
private String cityCode;
|
||||
private String cityName;
|
||||
/**
|
||||
* 区县
|
||||
*/
|
||||
private String countyCode;
|
||||
private String countyName;
|
||||
/**
|
||||
* 详细地址
|
||||
*/
|
||||
private String detailAddress;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.ruoyi.xkt.manager.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
|
|
@ -72,6 +73,34 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
throw new ServiceException("中通订单创建失败");
|
||||
}
|
||||
|
||||
/**
|
||||
* 智能解析
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public JSONObject structureNamePhoneAddress(String str) {
|
||||
ZopClient client = new ZopClient(appKey, appSecret);
|
||||
ZopPublicRequest request = new ZopPublicRequest();
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("address", str);
|
||||
request.setBody(body.toString());
|
||||
request.setUrl(gatewayUrl + STRUCTURE_ADDRESS_URI);
|
||||
request.setEncryptionType(EncryptionType.MD5);
|
||||
try {
|
||||
String bodyStr = client.execute(request);
|
||||
log.info("中通智能解析返回信息: {}", bodyStr);
|
||||
JSONObject bodyJson = JSONUtil.parseObj(bodyStr);
|
||||
boolean success = bodyJson.getBool("status");
|
||||
if (success) {
|
||||
return bodyJson.getJSONObject("result");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("中通智能解析异常", e);
|
||||
}
|
||||
throw new ServiceException("中通智能解析失败");
|
||||
}
|
||||
|
||||
private ZtoCreateOrderReqDTO trans2CreateOrderReq(ExpressShipReqDTO expressShipReqDTO) {
|
||||
ZtoCreateOrderReqDTO reqDTO = new ZtoCreateOrderReqDTO();
|
||||
//合作模式 ,1:集团客户;2:非集团客户
|
||||
|
|
@ -113,6 +142,10 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
receiveInfo.setReceiverDistrict(expressShipReqDTO.getDestinationCountyName());
|
||||
receiveInfo.setReceiverAddress(expressShipReqDTO.getDestinationDetailAddress());
|
||||
|
||||
//货物信息
|
||||
reqDTO.setOrderItems(BeanUtil.copyToList(expressShipReqDTO.getOrderItems(),
|
||||
ZtoCreateOrderReqDTO.OrderItem.class));
|
||||
|
||||
return reqDTO;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.ruoyi.xkt.domain.ExpressRegion;
|
|||
import com.ruoyi.xkt.dto.express.ExpressContactDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressRegionDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressRegionTreeNodeDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressStructAddressDTO;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
|
@ -80,5 +81,13 @@ public interface IExpressService {
|
|||
*/
|
||||
List<ExpressRegionTreeNodeDTO> getRegionTreeCache();
|
||||
|
||||
/**
|
||||
* 智能解析地址信息
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
ExpressStructAddressDTO parseNamePhoneAddress(String str);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
|
|
@ -16,6 +17,8 @@ import com.ruoyi.xkt.domain.Store;
|
|||
import com.ruoyi.xkt.dto.express.ExpressContactDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressRegionDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressRegionTreeNodeDTO;
|
||||
import com.ruoyi.xkt.dto.express.ExpressStructAddressDTO;
|
||||
import com.ruoyi.xkt.manager.impl.ZtoExpressManagerImpl;
|
||||
import com.ruoyi.xkt.mapper.*;
|
||||
import com.ruoyi.xkt.service.IExpressService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -36,13 +39,13 @@ import java.util.stream.Collectors;
|
|||
@Service
|
||||
public class ExpressServiceImpl implements IExpressService {
|
||||
|
||||
private ExpressRegionDTO emptyRegion = new ExpressRegionDTO();
|
||||
@Value("${express.default.province:510000}")
|
||||
private String expressDefaultProvince;
|
||||
@Value("${express.default.city:510100}")
|
||||
private String expressDefaultCity;
|
||||
@Value("${express.default.county:510114}")
|
||||
private String expressDefaultCounty;
|
||||
|
||||
@Autowired
|
||||
private ExpressMapper expressMapper;
|
||||
@Autowired
|
||||
|
|
@ -55,6 +58,8 @@ public class ExpressServiceImpl implements IExpressService {
|
|||
private StoreMapper storeMapper;
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
@Autowired
|
||||
private ZtoExpressManagerImpl ztoExpressManager;
|
||||
|
||||
@Override
|
||||
public void checkExpress(Long expressId) {
|
||||
|
|
@ -173,4 +178,39 @@ public class ExpressServiceImpl implements IExpressService {
|
|||
}
|
||||
return treeNodeList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressStructAddressDTO parseNamePhoneAddress(String str) {
|
||||
/**
|
||||
* {"address":{"province":"重庆","town":"","city":"重庆市","countyId":"500107","county":"九龙坡区",
|
||||
* "cityId":"500100","detail":"杨九路志龙·观江岭1号","provinceId":"500000"},"phone":"15888888888","name":"张三丰"}
|
||||
*/
|
||||
JSONObject rtn = ztoExpressManager.structureNamePhoneAddress(str);
|
||||
JSONObject address = rtn.getJSONObject("address");
|
||||
Assert.notNull(address, "获取行政区划失败");
|
||||
String provinceCode = address.getStr("province");
|
||||
String cityCode = address.getStr("cityId");
|
||||
String countyCode = address.getStr("countyId");
|
||||
String name = rtn.getStr("name");
|
||||
String phone = rtn.getStr("phone");
|
||||
String detailAddress = rtn.getStr("detail");
|
||||
// Assert.notEmpty(provinceCode, "获取省失败");
|
||||
// Assert.notEmpty(cityCode, "获取市失败");
|
||||
// Assert.notEmpty(countyCode, "获取区县失败");
|
||||
// Assert.notEmpty(detailAddress, "获取详细地址失败");
|
||||
// Assert.notEmpty(name, "获取联系人失败");
|
||||
// Assert.isTrue(PhoneUtil.isPhone(phone), "获取联系电话失败");
|
||||
Map<String, ExpressRegionDTO> regionMap = getRegionMapCache();
|
||||
return ExpressStructAddressDTO.builder()
|
||||
.contactName(name)
|
||||
.contactPhoneNumber(phone)
|
||||
.provinceCode(provinceCode)
|
||||
.provinceName(regionMap.getOrDefault(provinceCode, emptyRegion).getRegionName())
|
||||
.cityCode(cityCode)
|
||||
.cityName(regionMap.getOrDefault(cityCode, emptyRegion).getRegionName())
|
||||
.countyCode(countyCode)
|
||||
.countyName(regionMap.getOrDefault(countyCode, emptyRegion).getRegionName())
|
||||
.detailAddress(detailAddress)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -614,7 +614,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
|
|||
}
|
||||
}
|
||||
//发货
|
||||
ExpressShipReqDTO shipReq = trans2ShipReq(order, orderDetails);
|
||||
ExpressShipReqDTO shipReq = createShipReq(order, orderDetails);
|
||||
String expressWaybillNo = expressManager.shipStoreOrder(shipReq);
|
||||
|
||||
List<Long> orderDetailIdList = new ArrayList<>(orderDetails.size());
|
||||
|
|
@ -904,7 +904,7 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
|
|||
throw new ServiceException("未知物流渠道");
|
||||
}
|
||||
|
||||
private ExpressShipReqDTO trans2ShipReq(StoreOrder order, List<StoreOrderDetail> orderDetails) {
|
||||
private ExpressShipReqDTO createShipReq(StoreOrder order, List<StoreOrderDetail> orderDetails) {
|
||||
ExpressShipReqDTO reqDTO = BeanUtil.toBean(order, ExpressShipReqDTO.class);
|
||||
//生成请求号
|
||||
reqDTO.setExpressReqNo(IdUtil.simpleUUID());
|
||||
|
|
@ -922,6 +922,17 @@ public class StoreOrderServiceImpl implements IStoreOrderService {
|
|||
.map(ExpressRegionDTO::getParentRegionName).orElse(null));
|
||||
reqDTO.setOriginCountyName(Optional.ofNullable(regionMap.get(order.getOriginCountyCode()))
|
||||
.map(ExpressRegionDTO::getParentRegionName).orElse(null));
|
||||
//货物信息
|
||||
List<ExpressShipReqDTO.OrderItem> orderItems = CollUtil.emptyIfNull(orderDetails).stream()
|
||||
.map(o -> ExpressShipReqDTO.OrderItem
|
||||
.builder()
|
||||
//TODO 其他信息?
|
||||
.name(o.getProdTitle())
|
||||
.quantity(o.getGoodsQuantity())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
reqDTO.setOrderItems(orderItems);
|
||||
|
||||
return reqDTO;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue