物流商报价

This commit is contained in:
dev 2025-03-21 19:10:18 +08:00
parent 227f68f30f
commit 2500067e4a
191 changed files with 6240 additions and 18 deletions

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-cloud-plus</artifactId>
<version>2.2.2</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>asinkj-amz</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-sentinel</artifactId>
</dependency>
<!-- AsinKj Common Log -->
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-log</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-dict</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-doc</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-web</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-seata</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-idempotent</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-tenant</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-security</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-translation</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-sensitive</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-encrypt</artifactId>
</dependency>
<!-- AsinKj Api System -->
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-api-system</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-api-resource</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.0</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package org.asinkj;
import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
@EnableDubbo
@SpringBootApplication
public class AsinKjAmzApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(AsinKjAmzApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
System.out.println("(♥◠‿◠)ノ゙ 亚马逊模块启动成功 ლ(´ڡ`ლ)゙ ");
}
}

View File

@ -0,0 +1,117 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.BizInquiryRequestVo;
import org.asinkj.amz.domain.bo.BizInquiryRequestBo;
import org.asinkj.amz.service.IBizInquiryRequestService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 物流询价
* 前端访问路由地址为:/amz/inquiryRequest
*
* @author shuo hu
* @date 2025-03-21
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/inquiryRequest")
public class BizInquiryRequestController extends BaseController {
private final IBizInquiryRequestService bizInquiryRequestService;
/**
* 查询物流询价列表
*/
@SaCheckPermission("amz:inquiryRequest:list")
@GetMapping("/list")
public TableDataInfo<BizInquiryRequestVo> list(BizInquiryRequestBo bo, PageQuery pageQuery) {
return bizInquiryRequestService.queryPageList(bo, pageQuery);
}
/**
* 根据目的地仓库和渠道创建物流报价列表
*/
@SaCheckPermission("amz:inquiryRequest:list")
@GetMapping("/create/{destination}/{channelId}")
public R<Void> createWithDesAndChannel(@PathVariable("destination") @NotNull(message = "目的地不能为空") String destination,
@PathVariable("channelId") @NotNull(message = "渠道不能为空") String channelId) {
return bizInquiryRequestService.createWithDesAndChannel(destination, channelId);
}
/**
* 导出物流询价列表
*/
@SaCheckPermission("amz:inquiryRequest:export")
@Log(title = "物流询价", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BizInquiryRequestBo bo, HttpServletResponse response) {
List<BizInquiryRequestVo> list = bizInquiryRequestService.queryList(bo);
ExcelUtil.exportExcel(list, "物流询价", BizInquiryRequestVo.class, response);
}
/**
* 获取物流询价详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:inquiryRequest:query")
@GetMapping("/{id}")
public R<BizInquiryRequestVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bizInquiryRequestService.queryById(id));
}
/**
* 新增物流询价
*/
@SaCheckPermission("amz:inquiryRequest:add")
@Log(title = "物流询价", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BizInquiryRequestBo bo) {
return toAjax(bizInquiryRequestService.insertByBo(bo));
}
/**
* 修改物流询价
*/
@SaCheckPermission("amz:inquiryRequest:edit")
@Log(title = "物流询价", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BizInquiryRequestBo bo) {
return toAjax(bizInquiryRequestService.updateByBo(bo));
}
/**
* 删除物流询价
*
* @param ids 主键串
*/
@SaCheckPermission("amz:inquiryRequest:remove")
@Log(title = "物流询价", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bizInquiryRequestService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,112 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.BizLogisticsChannelVo;
import org.asinkj.amz.domain.bo.BizLogisticsChannelBo;
import org.asinkj.amz.service.IBizLogisticsChannelService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 物流商渠道
* 前端访问路由地址为:/amz/logisticsChannel
*
* @author shuo hu
* @date 2025-03-20
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/logisticsChannel")
public class BizLogisticsChannelController extends BaseController {
private final IBizLogisticsChannelService bizLogisticsChannelService;
/**
* 查询物流商渠道列表
*/
@SaCheckPermission("amz:logisticsChannel:list")
@GetMapping("/list")
public TableDataInfo<BizLogisticsChannelVo> list(BizLogisticsChannelBo bo, PageQuery pageQuery) {
return bizLogisticsChannelService.queryPageList(bo, pageQuery);
}
@SaCheckPermission("amz:logisticsChannel:list")
@GetMapping("/list/all")
public TableDataInfo<BizLogisticsChannelVo> listAll() {
return bizLogisticsChannelService.queryListAll();
}
/**
* 导出物流商渠道列表
*/
@SaCheckPermission("amz:logisticsChannel:export")
@Log(title = "物流商渠道", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BizLogisticsChannelBo bo, HttpServletResponse response) {
List<BizLogisticsChannelVo> list = bizLogisticsChannelService.queryList(bo);
ExcelUtil.exportExcel(list, "物流商渠道", BizLogisticsChannelVo.class, response);
}
/**
* 获取物流商渠道详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:logisticsChannel:query")
@GetMapping("/{id}")
public R<BizLogisticsChannelVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bizLogisticsChannelService.queryById(id));
}
/**
* 新增物流商渠道
*/
@SaCheckPermission("amz:logisticsChannel:add")
@Log(title = "物流商渠道", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BizLogisticsChannelBo bo) {
return toAjax(bizLogisticsChannelService.insertByBo(bo));
}
/**
* 修改物流商渠道
*/
@SaCheckPermission("amz:logisticsChannel:edit")
@Log(title = "物流商渠道", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BizLogisticsChannelBo bo) {
return toAjax(bizLogisticsChannelService.updateByBo(bo));
}
/**
* 删除物流商渠道
*
* @param ids 主键串
*/
@SaCheckPermission("amz:logisticsChannel:remove")
@Log(title = "物流商渠道", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bizLogisticsChannelService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,119 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.asinkj.amz.domain.bo.BizLogisticsQuoteBo;
import org.asinkj.amz.service.IBizLogisticsQuoteService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 物流报价
* 前端访问路由地址为:/amz/logisticsQuote
*
* @author shuo hu
* @date 2025-03-20
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/logisticsQuote")
public class BizLogisticsQuoteController extends BaseController {
private final IBizLogisticsQuoteService bizLogisticsQuoteService;
/**
* 查询物流报价列表
*/
@SaCheckPermission("amz:logisticsQuote:list")
@GetMapping("/list")
public TableDataInfo<BizLogisticsQuoteVo> list(BizLogisticsQuoteBo bo, PageQuery pageQuery) {
return bizLogisticsQuoteService.queryPageList(bo, pageQuery);
}
/**
* 根据目的地仓库和渠道查询物流报价列表
*/
@SaCheckPermission("amz:logisticsQuote:list")
@GetMapping("/query/{destination}/{channelId}")
public TableDataInfo<BizLogisticsQuoteVo> queryWithDesAndChannel(@PathVariable("destination") @NotNull(message = "目的地不能为空") String destination,
@PathVariable("channelId") @NotNull(message = "渠道不能为空") String channelId) {
return bizLogisticsQuoteService.listWithDesAndChannel(destination, channelId);
}
/**
* 导出物流报价列表
*/
@SaCheckPermission("amz:logisticsQuote:export")
@Log(title = "物流报价", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BizLogisticsQuoteBo bo, HttpServletResponse response) {
List<BizLogisticsQuoteVo> list = bizLogisticsQuoteService.queryList(bo);
ExcelUtil.exportExcel(list, "物流报价", BizLogisticsQuoteVo.class, response);
}
/**
* 获取物流报价详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:logisticsQuote:query")
@GetMapping("/{id}")
public R<BizLogisticsQuoteVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bizLogisticsQuoteService.queryById(id));
}
/**
* 新增物流报价
*/
@SaCheckPermission("amz:logisticsQuote:add")
@Log(title = "物流报价", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BizLogisticsQuoteBo bo) {
return toAjax(bizLogisticsQuoteService.insertByBo(bo));
}
/**
* 修改物流报价
*/
@SaCheckPermission("amz:logisticsQuote:edit")
@Log(title = "物流报价", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BizLogisticsQuoteBo bo) {
return toAjax(bizLogisticsQuoteService.updateByBo(bo));
}
/**
* 删除物流报价
*
* @param ids 主键串
*/
@SaCheckPermission("amz:logisticsQuote:remove")
@Log(title = "物流报价", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bizLogisticsQuoteService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,106 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.BizShipmentItemVo;
import org.asinkj.amz.domain.bo.BizShipmentItemBo;
import org.asinkj.amz.service.IBizShipmentItemService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 货品明细
* 前端访问路由地址为:/amz/shipmentItem
*
* @author shuo hu
* @date 2025-03-20
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/shipmentItem")
public class BizShipmentItemController extends BaseController {
private final IBizShipmentItemService bizShipmentItemService;
/**
* 查询货品明细列表
*/
@SaCheckPermission("amz:shipmentItem:list")
@GetMapping("/list")
public TableDataInfo<BizShipmentItemVo> list(BizShipmentItemBo bo, PageQuery pageQuery) {
return bizShipmentItemService.queryPageList(bo, pageQuery);
}
/**
* 导出货品明细列表
*/
@SaCheckPermission("amz:shipmentItem:export")
@Log(title = "货品明细", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BizShipmentItemBo bo, HttpServletResponse response) {
List<BizShipmentItemVo> list = bizShipmentItemService.queryList(bo);
ExcelUtil.exportExcel(list, "货品明细", BizShipmentItemVo.class, response);
}
/**
* 获取货品明细详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:shipmentItem:query")
@GetMapping("/{id}")
public R<BizShipmentItemVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bizShipmentItemService.queryById(id));
}
/**
* 新增货品明细
*/
@SaCheckPermission("amz:shipmentItem:add")
@Log(title = "货品明细", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BizShipmentItemBo bo) {
return toAjax(bizShipmentItemService.insertByBo(bo));
}
/**
* 修改货品明细
*/
@SaCheckPermission("amz:shipmentItem:edit")
@Log(title = "货品明细", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BizShipmentItemBo bo) {
return toAjax(bizShipmentItemService.updateByBo(bo));
}
/**
* 删除货品明细
*
* @param ids 主键串
*/
@SaCheckPermission("amz:shipmentItem:remove")
@Log(title = "货品明细", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bizShipmentItemService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,121 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.BizShipmentPlanVo;
import org.asinkj.amz.domain.bo.BizShipmentPlanBo;
import org.asinkj.amz.service.IBizShipmentPlanService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 货件计划
* 前端访问路由地址为:/amz/shipmentPlan
*
* @author shuo hu
* @date 2025-03-19
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/shipmentPlan")
public class BizShipmentPlanController extends BaseController {
private final IBizShipmentPlanService bizShipmentPlanService;
/**
* 查询货件计划列表
*/
@SaCheckPermission("amz:shipmentPlan:list")
@GetMapping("/list")
public TableDataInfo<BizShipmentPlanVo> list(BizShipmentPlanBo bo, PageQuery pageQuery) {
return bizShipmentPlanService.queryPageList(bo, pageQuery);
}
/**
* 导出货件计划列表
*/
@SaCheckPermission("amz:shipmentPlan:export")
@Log(title = "货件计划", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BizShipmentPlanBo bo, HttpServletResponse response) {
List<BizShipmentPlanVo> list = bizShipmentPlanService.queryList(bo);
ExcelUtil.exportExcel(list, "货件计划", BizShipmentPlanVo.class, response);
}
/**
* 获取货件计划详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:shipmentPlan:query")
@GetMapping("/{id}")
public R<BizShipmentPlanVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bizShipmentPlanService.queryById(id));
}
/**
* 新增货件计划
*/
@SaCheckPermission("amz:shipmentPlan:add")
@Log(title = "货件计划", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BizShipmentPlanBo bo) {
return toAjax(bizShipmentPlanService.insertByBo(bo));
}
/**
* 修改货件计划
*/
@SaCheckPermission("amz:shipmentPlan:edit")
@Log(title = "货件计划", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BizShipmentPlanBo bo) {
return toAjax(bizShipmentPlanService.updateByBo(bo));
}
/**
* 删除货件计划
*
* @param ids 主键串
*/
@SaCheckPermission("amz:shipmentPlan:remove")
@Log(title = "货件计划", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bizShipmentPlanService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 获取货件计划详细信息
*
*
*/
@SaCheckPermission("amz:shipmentPlan:query")
@GetMapping("/quote/{destination}/{channel}")
public R<List<BizLogisticsQuoteVo>> getQuote(@NotNull(message = "主键不能为空")
@PathVariable String destination,
@PathVariable String channel) {
return R.ok(bizShipmentPlanService.getQuote(destination,channel));
}
}

View File

@ -0,0 +1,106 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.BizShipmentTrackingVo;
import org.asinkj.amz.domain.bo.BizShipmentTrackingBo;
import org.asinkj.amz.service.IBizShipmentTrackingService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 物流追踪
* 前端访问路由地址为:/amz/shipmentTracking
*
* @author shuo hu
* @date 2025-03-20
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/shipmentTracking")
public class BizShipmentTrackingController extends BaseController {
private final IBizShipmentTrackingService bizShipmentTrackingService;
/**
* 查询物流追踪列表
*/
@SaCheckPermission("amz:shipmentTracking:list")
@GetMapping("/list")
public TableDataInfo<BizShipmentTrackingVo> list(BizShipmentTrackingBo bo, PageQuery pageQuery) {
return bizShipmentTrackingService.queryPageList(bo, pageQuery);
}
/**
* 导出物流追踪列表
*/
@SaCheckPermission("amz:shipmentTracking:export")
@Log(title = "物流追踪", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(BizShipmentTrackingBo bo, HttpServletResponse response) {
List<BizShipmentTrackingVo> list = bizShipmentTrackingService.queryList(bo);
ExcelUtil.exportExcel(list, "物流追踪", BizShipmentTrackingVo.class, response);
}
/**
* 获取物流追踪详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:shipmentTracking:query")
@GetMapping("/{id}")
public R<BizShipmentTrackingVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(bizShipmentTrackingService.queryById(id));
}
/**
* 新增物流追踪
*/
@SaCheckPermission("amz:shipmentTracking:add")
@Log(title = "物流追踪", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody BizShipmentTrackingBo bo) {
return toAjax(bizShipmentTrackingService.insertByBo(bo));
}
/**
* 修改物流追踪
*/
@SaCheckPermission("amz:shipmentTracking:edit")
@Log(title = "物流追踪", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody BizShipmentTrackingBo bo) {
return toAjax(bizShipmentTrackingService.updateByBo(bo));
}
/**
* 删除物流追踪
*
* @param ids 主键串
*/
@SaCheckPermission("amz:shipmentTracking:remove")
@Log(title = "物流追踪", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(bizShipmentTrackingService.deleteWithValidByIds(List.of(ids), true));
}
}

View File

@ -0,0 +1,137 @@
package org.asinkj.amz.controller;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.asinkj.common.idempotent.annotation.RepeatSubmit;
import org.asinkj.common.log.annotation.Log;
import org.asinkj.common.web.core.BaseController;
import org.asinkj.common.mybatis.core.page.PageQuery;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import org.asinkj.common.log.enums.BusinessType;
import org.asinkj.common.excel.utils.ExcelUtil;
import org.asinkj.amz.domain.vo.SysAmazonStoreVo;
import org.asinkj.amz.domain.bo.SysAmazonStoreBo;
import org.asinkj.amz.service.ISysAmazonStoreService;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
/**
* 亚马逊店铺信息
* 前端访问路由地址为:/amz/amazonStore
*
* @author shuo hu
* @date 2025-03-17
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/amazonStore")
public class SysAmazonStoreController extends BaseController {
private final ISysAmazonStoreService sysAmazonStoreService;
/**
* 查询亚马逊店铺信息列表
*/
@SaCheckPermission("amz:amazonStore:list")
@GetMapping("/list")
public TableDataInfo<SysAmazonStoreVo> list(SysAmazonStoreBo bo, PageQuery pageQuery) {
return sysAmazonStoreService.queryPageList(bo, pageQuery);
}
/**
* 导出亚马逊店铺信息列表
*/
@SaCheckPermission("amz:amazonStore:export")
@Log(title = "亚马逊店铺信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SysAmazonStoreBo bo, HttpServletResponse response) {
List<SysAmazonStoreVo> list = sysAmazonStoreService.queryList(bo);
ExcelUtil.exportExcel(list, "亚马逊店铺信息", SysAmazonStoreVo.class, response);
}
/**
* 获取亚马逊店铺信息详细信息
*
* @param id 主键
*/
@SaCheckPermission("amz:amazonStore:query")
@GetMapping("/{id}")
public R<SysAmazonStoreVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(sysAmazonStoreService.queryById(id));
}
/**
* 新增亚马逊店铺信息
*/
@SaCheckPermission("amz:amazonStore:add")
@Log(title = "亚马逊店铺信息", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SysAmazonStoreBo bo) {
return toAjax(sysAmazonStoreService.insertByBo(bo));
}
/**
* 修改亚马逊店铺信息
*/
@SaCheckPermission("amz:amazonStore:edit")
@Log(title = "亚马逊店铺信息", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysAmazonStoreBo bo) {
return toAjax(sysAmazonStoreService.updateByBo(bo));
}
/**
* 删除亚马逊店铺信息
*
* @param ids 主键串
*/
@SaCheckPermission("amz:amazonStore:remove")
@Log(title = "亚马逊店铺信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(sysAmazonStoreService.deleteWithValidByIds(List.of(ids), true));
}
/**
* 亚马逊api
*
*
*/
@SaCheckPermission("amz:amazonStore:remove")
@Log(title = "获取亚马逊店铺数据", businessType = BusinessType.OTHER)
@GetMapping("/amz-store")
public R<Void> getAmzApiToken() {
sysAmazonStoreService.collectAmzStoreData();
return R.ok();
}
/**
* 亚马逊api
*
*
*/
@SaCheckPermission("amz:amazonStore:remove")
@Log(title = "亚马逊FBA", businessType = BusinessType.OTHER)
@GetMapping("/amz-fba/{startDate}/{endDate}")
public R<Void> getAmzFbaToken(@PathVariable String startDate, @PathVariable String endDate) {
try {
sysAmazonStoreService.pullAmzFBAData(startDate,endDate);
} catch (Exception e) {
throw new RuntimeException(e);
}
return R.ok();
}
}

View File

@ -0,0 +1,95 @@
package org.asinkj.amz.domain;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 物流询价对象 biz_inquiry_request
*
* @author shuo hu
* @date 2025-03-21
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_inquiry_request")
public class BizInquiryRequest extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID自增序列
*/
private Long id;
/**
* 询价单号规则INQ+年月+6位序列
*/
private String inquiryNo;
/**
* 发起人id
*/
private Long requesterId;
/**
* 目标物流商ID列表JSON数组格式示例[101,202,303]
*/
private String targetProviders;
/**
* 目的地存储四级行政编码如CN310115
*/
private String destination;
/**
* 运输方式枚举值AIR-空运/SEA-海运/LAND-公路/RAIL-铁路
*/
private String transportChannel;
/**
* 询价状态状态机OPEN-开放中/CLOSED-已关闭/COMPLETED-已完成
*/
private String inquiryStatus;
/**
* 报价截止时间超过此时限自动关闭询价
*/
private LocalDateTime deadline;
/**
* $column.columnComment
*/
@TableLogic
private String delFlag;
/**
* 渠道IDsystem=dict_codecustom=自定义渠道ID
*/
private Long channelId;
/**
* 渠道名称
*/
private String channelName;
/**
* 报价有效的开始日期
*/
private Date effectiveStartTime;
/**
* 报价有效的结束日期
*/
private Date effectiveEndTime;
}

View File

@ -0,0 +1,66 @@
package org.asinkj.amz.domain;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 物流商渠道对象 biz_logistics_channel
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_logistics_channel")
public class BizLogisticsChannel extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 渠道ID
*/
private Long id;
/**
* 物流商用户ID关联sys_user
*/
private Long userId;
/**
* 渠道名称
*/
private String channelName;
/**
* 渠道描述
*/
private String description;
/**
* 删除标志0正常 2删除
*/
@TableLogic
private String delFlag;
/**
* 渠道类型system=系统/custom=自定义
*/
private String channelType;
/**
* 国家
*/
private String country;
/**
* 运输方式
*/
private String shippingMethod;
}

View File

@ -0,0 +1,51 @@
package org.asinkj.amz.domain;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 物流商自定义渠道对象 biz_logistics_custom_channel
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_logistics_channel")
public class BizLogisticsCustomChannel extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 渠道ID
*/
private Long id;
/**
* 物流商用户ID关联sys_user
*/
private Long userId;
/**
* 渠道名称
*/
private String channelName;
/**
* 渠道描述
*/
private String description;
/**
* 删除标志0正常 2删除
*/
@TableLogic
private String delFlag;
}

View File

@ -0,0 +1,93 @@
package org.asinkj.amz.domain;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 物流报价对象 biz_logistics_quote
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_logistics_quote")
public class BizLogisticsQuote extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 物流商用户ID关联sys_user表
*/
private Long userId;
/**
* 目的地建议使用ISO国家代码如CN/US/GB
*/
private String destination;
/**
* 渠道名称冗余存储保证查询效率
*/
private String transportChannel;
/**
* 基础价格
*/
private Long price;
/**
* 时效单位
*/
private Long leadTime;
/**
* 附加费
*/
private Long surcharge;
/**
* 报价生效日期
*/
private Date quoteDate;
/**
* 提交状态Y已提交 N未提交
*/
private String isSubmitted;
/**
* 报价备注
*/
private String remark;
/**
* 删除标志0正常 2删除
*/
@TableLogic
private String delFlag;
/**
* 渠道类型system=系统/custom=自定义
*/
private String channelType;
/**
* 渠道IDsystem=dict_codecustom=自定义渠道ID
*/
private Long channelId;
}

View File

@ -0,0 +1,83 @@
package org.asinkj.amz.domain;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 货品明细对象 biz_shipment_item
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_shipment_item")
public class BizShipmentItem extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 关联货件ID
*/
private String shipmentId;
/**
* 商家SKU
*/
private String msku;
/**
* 仓储编码
*/
private String fnsku;
/**
* 发货量
*/
private Long quantityShipped;
/**
* 收货量
*/
private Long quantityReceived;
/**
* 预处理说明
*/
private String prepInstruction;
/**
* 责任方
*/
private String prepOwner;
/**
* 商品SKU
*/
private String sku;
/**
* 有效期
*/
private Date expiration;
/**
* $column.columnComment
*/
@TableLogic
private String delFlag;
}

View File

@ -0,0 +1,137 @@
package org.asinkj.amz.domain;
import org.asinkj.amz.hanlder.AddressTypeHandler;
import org.asinkj.asinking.entity.FbaShipmentApiResponse;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.io.Serial;
/**
* 货件计划对象 biz_shipment_plan
*
* @author shuo hu
* @date 2025-03-19
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_shipment_plan")
public class BizShipmentPlan extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 关联系统ID
*/
private Long sid;
/**
* 货件编号
*/
private String shipmentId;
/**
* 货件名称
*/
private String shipmentName;
/**
* 是否关闭
*/
private String isClosed;
/**
* 货件状态
*/
private String shipmentStatus;
/**
* 物流中心编码
*/
private String destinationFulfillmentCenterId;
/**
* 运输模式
*/
private String shippingMode;
/**
* 运输方案
*/
private String shippingSolution;
/**
* 最后更新时间
*/
private Date gmtModified;
/**
* 创建时间
*/
private Date gmtCreate;
/**
* 同步时间
*/
private Date syncTime;
/**
* 计划发货日期
*/
private Date staShipmentDate;
/**
* 预计到货开始日
*/
private Date staDeliveryStartDate;
/**
* 预计到货截止日
*/
private Date staDeliveryEndDate;
/**
* 发货地址
*/
@TableField(typeHandler = AddressTypeHandler.class)
private FbaShipmentApiResponse.Address shipFromAddress;
/**
* 收货地址
*/
@TableField(typeHandler = AddressTypeHandler.class)
private FbaShipmentApiResponse.Address shipToAddress;
/**
* 参考编号
*/
private String referenceId;
/**
* 入库计划ID
*/
private String staInboundPlanId;
/**
* 是否STA计划
*/
private String isSta;
/**
* 删除标记
*/
@TableLogic
private String delFlag;
}

View File

@ -0,0 +1,51 @@
package org.asinkj.amz.domain;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 物流追踪对象 biz_shipment_tracking
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("biz_shipment_tracking")
public class BizShipmentTracking extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
private Long id;
/**
* 关联货件ID
*/
private String shipmentId;
/**
* 箱号
*/
private String boxId;
/**
* 物流单号
*/
private String trackingNumber;
/**
* $column.columnComment
*/
@TableLogic
private String delFlag;
}

View File

@ -0,0 +1,104 @@
package org.asinkj.amz.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.asinkj.common.tenant.core.TenantEntity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* 亚马逊店铺信息对象 sys_amazon_store
*
* @author shuo hu
* @date 2025-03-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_amazon_store")
public class SysAmazonStore extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@TableId(value = "id")
private Long id;
/**
* 所属用户ID关联sys_user
*/
private Long userId;
/**
* 领星ERP店铺标识ID
*/
private Long sid;
/**
* 站点ID
*/
private Long mid;
/**
* 店铺名称
*/
@JsonProperty("name")
private String storeName;
/**
* 亚马逊店铺ID如AZTOL**
*/
@JsonProperty("seller_id")
private String sellerId;
/**
* 店铺账户名称
*/
@JsonProperty("account_name")
private String accountName;
/**
* 店铺账号ID
*/
@JsonProperty("seller_account_id")
private Long sellerAccountId;
/**
* 站点简称如NA/EU
*/
private String region;
/**
* 商城所在国家
*/
private String country;
/**
* 亚马逊市场ID
*/
@JsonProperty("marketplace_id")
private String marketplaceId;
/**
* 广告授权 0未授权 1已授权
*/
@JsonProperty("has_ads_setting")
private Long hasAdsSetting;
/**
* 店铺状态 0停用 1正常 2异常 3欠费
*/
private Long status;
/**
* 删除标志0存在 2删除
*/
@TableLogic
private String delFlag;
}

View File

@ -0,0 +1,96 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizInquiryRequest;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 物流询价业务对象 biz_inquiry_request
*
* @author shuo hu
* @date 2025-03-21
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizInquiryRequest.class, reverseConvertGenerate = false)
public class BizInquiryRequestBo extends BaseEntity {
/**
* 主键ID自增序列
*/
private Long id;
/**
* 询价单号规则INQ+年月+6位序列
*/
private String inquiryNo;
/**
* 发起人id
*/
@NotNull(message = "发起人id不能为空", groups = { AddGroup.class, EditGroup.class })
private Long requesterId;
/**
* 目标物流商ID列表JSON数组格式示例[101,202,303]
*/
@NotBlank(message = "目标物流商ID列表JSON数组格式示例[101,202,303])不能为空", groups = { AddGroup.class, EditGroup.class })
private String targetProviders;
/**
* 目的地存储四级行政编码如CN310115
*/
@NotBlank(message = "目的地存储四级行政编码如CN310115不能为空", groups = { AddGroup.class, EditGroup.class })
private String destination;
/**
* 运输方式枚举值AIR-空运/SEA-海运/LAND-公路/RAIL-铁路
*/
@NotBlank(message = "运输方式枚举值AIR-空运/SEA-海运/LAND-公路/RAIL-铁路)不能为空", groups = { AddGroup.class, EditGroup.class })
private String transportChannel;
/**
* 询价状态状态机OPEN-开放中/CLOSED-已关闭/COMPLETED-已完成
*/
@NotBlank(message = "询价状态状态机OPEN-开放中/CLOSED-已关闭/COMPLETED-已完成)不能为空", groups = { AddGroup.class, EditGroup.class })
private String inquiryStatus;
/**
* 报价截止时间超过此时限自动关闭询价
*/
@NotNull(message = "报价截止时间(超过此时限自动关闭询价)不能为空", groups = { AddGroup.class, EditGroup.class })
private Date deadline;
/**
* 渠道IDsystem=dict_codecustom=自定义渠道ID
*/
@NotNull(message = "渠道IDsystem=dict_codecustom=自定义渠道ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long channelId;
/**
* 渠道名称
*/
@NotBlank(message = "渠道名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String channelName;
/**
* 报价有效的开始日期
*/
@NotNull(message = "报价有效的开始日期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date effectiveStartTime;
/**
* 报价有效的结束日期
*/
@NotNull(message = "报价有效的结束日期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date effectiveEndTime;
}

View File

@ -0,0 +1,66 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizLogisticsChannel;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 物流商渠道业务对象 biz_logistics_channel
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizLogisticsChannel.class, reverseConvertGenerate = false)
public class BizLogisticsChannelBo extends BaseEntity {
/**
* 渠道ID
*/
// @NotNull(message = "渠道ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 物流商用户ID关联sys_user
*/
// @NotNull(message = "物流商用户ID关联sys_user不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* 渠道名称
*/
@NotBlank(message = "渠道名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String channelName;
/**
* 渠道描述
*/
@NotBlank(message = "渠道描述不能为空", groups = { AddGroup.class, EditGroup.class })
private String description;
/**
* 渠道类型system=系统/custom=自定义
*/
// @NotBlank(message = "渠道类型system=系统/custom=自定义)不能为空", groups = { AddGroup.class, EditGroup.class })
private String channelType;
/**
* 国家
*/
@NotBlank(message = "国家不能为空", groups = { AddGroup.class, EditGroup.class })
private String country;
/**
* 运输方式
*/
@NotBlank(message = "运输方式不能为空", groups = { AddGroup.class, EditGroup.class })
private String shippingMethod;
}

View File

@ -0,0 +1,48 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizLogisticsCustomChannel;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 物流商自定义渠道业务对象 biz_logistics_custom_channel
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizLogisticsCustomChannel.class, reverseConvertGenerate = false)
public class BizLogisticsCustomChannelBo extends BaseEntity {
/**
* 渠道ID
*/
@NotNull(message = "渠道ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 物流商用户ID关联sys_user
*/
@NotNull(message = "物流商用户ID关联sys_user不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* 渠道名称
*/
@NotBlank(message = "渠道名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String channelName;
/**
* 渠道描述
*/
@NotBlank(message = "渠道描述不能为空", groups = { AddGroup.class, EditGroup.class })
private String description;
}

View File

@ -0,0 +1,98 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizLogisticsQuote;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 物流报价业务对象 biz_logistics_quote
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizLogisticsQuote.class, reverseConvertGenerate = false)
public class BizLogisticsQuoteBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 物流商用户ID关联sys_user表
*/
@NotNull(message = "物流商用户ID关联sys_user表不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* 目的地建议使用ISO国家代码如CN/US/GB
*/
@NotBlank(message = "目的地建议使用ISO国家代码如CN/US/GB不能为空", groups = { AddGroup.class, EditGroup.class })
private String destination;
/**
* 渠道名称冗余存储保证查询效率
*/
@NotBlank(message = "渠道名称(冗余存储,保证查询效率)不能为空", groups = { AddGroup.class, EditGroup.class })
private String transportChannel;
/**
* 基础价格
*/
@NotNull(message = "基础价格不能为空", groups = { AddGroup.class, EditGroup.class })
private Long price;
/**
* 时效单位
*/
@NotNull(message = "时效(单位:天)不能为空", groups = { AddGroup.class, EditGroup.class })
private Long leadTime;
/**
* 附加费
*/
@NotNull(message = "附加费不能为空", groups = { AddGroup.class, EditGroup.class })
private Long surcharge;
/**
* 报价生效日期
*/
@NotNull(message = "报价生效日期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date quoteDate;
/**
* 提交状态Y已提交 N未提交
*/
@NotBlank(message = "提交状态Y已提交 N未提交不能为空", groups = { AddGroup.class, EditGroup.class })
private String isSubmitted;
/**
* 报价备注
*/
@NotBlank(message = "报价备注不能为空", groups = { AddGroup.class, EditGroup.class })
private String remark;
/**
* 渠道类型system=系统/custom=自定义
*/
@NotBlank(message = "渠道类型system=系统/custom=自定义)不能为空", groups = { AddGroup.class, EditGroup.class })
private String channelType;
/**
* 渠道IDsystem=dict_codecustom=自定义渠道ID
*/
@NotNull(message = "渠道IDsystem=dict_codecustom=自定义渠道ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long channelId;
}

View File

@ -0,0 +1,86 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizShipmentItem;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 货品明细业务对象 biz_shipment_item
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizShipmentItem.class, reverseConvertGenerate = false)
public class BizShipmentItemBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 关联货件ID
*/
@NotBlank(message = "关联货件ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String shipmentId;
/**
* 商家SKU
*/
@NotBlank(message = "商家SKU不能为空", groups = { AddGroup.class, EditGroup.class })
private String msku;
/**
* 仓储编码
*/
@NotBlank(message = "仓储编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String fnsku;
/**
* 发货量
*/
@NotNull(message = "发货量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long quantityShipped;
/**
* 收货量
*/
@NotNull(message = "收货量不能为空", groups = { AddGroup.class, EditGroup.class })
private Long quantityReceived;
/**
* 预处理说明
*/
@NotBlank(message = "预处理说明不能为空", groups = { AddGroup.class, EditGroup.class })
private String prepInstruction;
/**
* 责任方
*/
@NotBlank(message = "责任方不能为空", groups = { AddGroup.class, EditGroup.class })
private String prepOwner;
/**
* 商品SKU
*/
@NotBlank(message = "商品SKU不能为空", groups = { AddGroup.class, EditGroup.class })
private String sku;
/**
* 有效期
*/
@NotNull(message = "有效期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date expiration;
}

View File

@ -0,0 +1,147 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizShipmentPlan;
import org.asinkj.asinking.entity.FbaShipmentApiResponse;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
/**
* 货件计划业务对象 biz_shipment_plan
*
* @author shuo hu
* @date 2025-03-19
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizShipmentPlan.class, reverseConvertGenerate = false)
public class BizShipmentPlanBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 关联系统ID
*/
@NotNull(message = "关联系统ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long sid;
/**
* 货件编号
*/
@NotBlank(message = "货件编号不能为空", groups = { AddGroup.class, EditGroup.class })
private String shipmentId;
/**
* 货件名称
*/
@NotBlank(message = "货件名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String shipmentName;
/**
* 是否关闭
*/
@NotBlank(message = "是否关闭不能为空", groups = { AddGroup.class, EditGroup.class })
private String isClosed;
/**
* 货件状态
*/
@NotBlank(message = "货件状态不能为空", groups = { AddGroup.class, EditGroup.class })
private String shipmentStatus;
/**
* 物流中心编码
*/
@NotBlank(message = "物流中心编码不能为空", groups = { AddGroup.class, EditGroup.class })
private String destinationFulfillmentCenterId;
/**
* 运输模式
*/
@NotBlank(message = "运输模式不能为空", groups = { AddGroup.class, EditGroup.class })
private String shippingMode;
/**
* 运输方案
*/
@NotBlank(message = "运输方案不能为空", groups = { AddGroup.class, EditGroup.class })
private String shippingSolution;
/**
* 最后更新时间
*/
@NotNull(message = "最后更新时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date gmtModified;
/**
* 创建时间
*/
@NotNull(message = "创建时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date gmtCreate;
/**
* 同步时间
*/
@NotNull(message = "同步时间不能为空", groups = { AddGroup.class, EditGroup.class })
private Date syncTime;
/**
* 计划发货日期
*/
@NotNull(message = "计划发货日期不能为空", groups = { AddGroup.class, EditGroup.class })
private Date staShipmentDate;
/**
* 预计到货开始日
*/
@NotNull(message = "预计到货开始日不能为空", groups = { AddGroup.class, EditGroup.class })
private Date staDeliveryStartDate;
/**
* 预计到货截止日
*/
@NotNull(message = "预计到货截止日不能为空", groups = { AddGroup.class, EditGroup.class })
private Date staDeliveryEndDate;
/**
* 发货地址
*/
@NotBlank(message = "发货地址不能为空", groups = { AddGroup.class, EditGroup.class })
private FbaShipmentApiResponse.Address shipFromAddress;
/**
* 收货地址
*/
@NotBlank(message = "收货地址不能为空", groups = { AddGroup.class, EditGroup.class })
private FbaShipmentApiResponse.Address shipToAddress;
/**
* 参考编号
*/
@NotBlank(message = "参考编号不能为空", groups = { AddGroup.class, EditGroup.class })
private String referenceId;
/**
* 入库计划ID
*/
@NotBlank(message = "入库计划ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String staInboundPlanId;
/**
* 是否STA计划
*/
@NotBlank(message = "是否STA计划不能为空", groups = { AddGroup.class, EditGroup.class })
private String isSta;
}

View File

@ -0,0 +1,48 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.BizShipmentTracking;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 物流追踪业务对象 biz_shipment_tracking
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = BizShipmentTracking.class, reverseConvertGenerate = false)
public class BizShipmentTrackingBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long id;
/**
* 关联货件ID
*/
@NotBlank(message = "关联货件ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String shipmentId;
/**
* 箱号
*/
@NotBlank(message = "箱号不能为空", groups = { AddGroup.class, EditGroup.class })
private String boxId;
/**
* 物流单号
*/
@NotBlank(message = "物流单号不能为空", groups = { AddGroup.class, EditGroup.class })
private String trackingNumber;
}

View File

@ -0,0 +1,102 @@
package org.asinkj.amz.domain.bo;
import org.asinkj.amz.domain.SysAmazonStore;
import org.asinkj.common.mybatis.core.domain.BaseEntity;
import org.asinkj.common.core.validate.AddGroup;
import org.asinkj.common.core.validate.EditGroup;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
/**
* 亚马逊店铺信息业务对象 sys_amazon_store
*
* @author shuo hu
* @date 2025-03-17
*/
@Data
@EqualsAndHashCode(callSuper = true)
@AutoMapper(target = SysAmazonStore.class, reverseConvertGenerate = false)
public class SysAmazonStoreBo extends BaseEntity {
/**
* 主键ID
*/
@NotNull(message = "主键ID不能为空", groups = { EditGroup.class })
private Long id;
/**
* 所属用户ID关联sys_user
*/
@NotNull(message = "所属用户ID关联sys_user不能为空", groups = { AddGroup.class, EditGroup.class })
private Long userId;
/**
* 领星ERP店铺标识ID
*/
@NotNull(message = "领星ERP店铺标识ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long sid;
/**
* 站点ID
*/
@NotNull(message = "站点ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long mid;
/**
* 店铺名称
*/
@NotBlank(message = "店铺名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String storeName;
/**
* 亚马逊店铺ID如AZTOL**
*/
@NotBlank(message = "亚马逊店铺ID如AZTOL**)不能为空", groups = { AddGroup.class, EditGroup.class })
private String sellerId;
/**
* 店铺账户名称
*/
@NotBlank(message = "店铺账户名称不能为空", groups = { AddGroup.class, EditGroup.class })
private String accountName;
/**
* 店铺账号ID
*/
@NotNull(message = "店铺账号ID不能为空", groups = { AddGroup.class, EditGroup.class })
private Long sellerAccountId;
/**
* 站点简称如NA/EU
*/
@NotBlank(message = "站点简称如NA/EU不能为空", groups = { AddGroup.class, EditGroup.class })
private String region;
/**
* 商城所在国家
*/
@NotBlank(message = "商城所在国家不能为空", groups = { AddGroup.class, EditGroup.class })
private String country;
/**
* 亚马逊市场ID
*/
@NotBlank(message = "亚马逊市场ID不能为空", groups = { AddGroup.class, EditGroup.class })
private String marketplaceId;
/**
* 广告授权 0未授权 1已授权
*/
@NotNull(message = "广告授权 0未授权 1已授权不能为空", groups = { AddGroup.class, EditGroup.class })
private Long hasAdsSetting;
/**
* 店铺状态 0停用 1正常 2异常 3欠费
*/
@NotNull(message = "店铺状态 0停用 1正常 2异常 3欠费不能为空", groups = { AddGroup.class, EditGroup.class })
private Long status;
}

View File

@ -0,0 +1,115 @@
package org.asinkj.amz.domain.vo;
import java.time.LocalDateTime;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.asinkj.amz.domain.BizInquiryRequest;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 物流询价视图对象 biz_inquiry_request
*
* @author shuo hu
* @date 2025-03-21
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizInquiryRequest.class)
public class BizInquiryRequestVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID自增序列
*/
@ExcelProperty(value = "主键ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "自=增序列")
private Long id;
/**
* 询价单号规则INQ+年月+6位序列
*/
@ExcelProperty(value = "询价单号", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "规=则INQ+年月+6位序列")
private String inquiryNo;
/**
* 发起人id
*/
@ExcelProperty(value = "发起人id")
private Long requesterId;
/**
* 目标物流商ID列表JSON数组格式示例[101,202,303]
*/
@ExcelProperty(value = "目标物流商ID列表", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "J=SON数组格式示例[101,202,303]")
private String targetProviders;
/**
* 目的地存储四级行政编码如CN310115
*/
@ExcelProperty(value = "目的地", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "存=储四级行政编码如CN310115")
private String destination;
/**
* 运输方式枚举值AIR-空运/SEA-海运/LAND-公路/RAIL-铁路
*/
@ExcelProperty(value = "运输方式", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "枚=举值AIR-空运/SEA-海运/LAND-公路/RAIL-铁路")
private String transportChannel;
/**
* 询价状态状态机OPEN-开放中/CLOSED-已关闭/COMPLETED-已完成
*/
@ExcelProperty(value = "询价状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "状=态机OPEN-开放中/CLOSED-已关闭/COMPLETED-已完成")
private String inquiryStatus;
/**
* 报价截止时间超过此时限自动关闭询价
*/
@ExcelProperty(value = "报价截止时间", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "超=过此时限自动关闭询价")
private LocalDateTime deadline;
/**
* 渠道IDsystem=dict_codecustom=自定义渠道ID
*/
@ExcelProperty(value = "渠道ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "s=ystem=dict_codecustom=自定义渠道ID")
private Long channelId;
/**
* 渠道名称
*/
@ExcelProperty(value = "渠道名称")
private String channelName;
/**
* 报价有效的开始日期
*/
@ExcelProperty(value = "报价有效的开始日期")
private Date effectiveStartTime;
/**
* 报价有效的结束日期
*/
@ExcelProperty(value = "报价有效的结束日期")
private Date effectiveEndTime;
}

View File

@ -0,0 +1,76 @@
package org.asinkj.amz.domain.vo;
import org.asinkj.amz.domain.BizLogisticsChannel;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 物流商渠道视图对象 biz_logistics_channel
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizLogisticsChannel.class)
public class BizLogisticsChannelVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 渠道ID
*/
@ExcelProperty(value = "渠道ID")
private Long id;
/**
* 物流商用户ID关联sys_user
*/
@ExcelProperty(value = "物流商用户ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联sys_user")
private Long userId;
/**
* 渠道名称
*/
@ExcelProperty(value = "渠道名称")
private String channelName;
/**
* 渠道描述
*/
@ExcelProperty(value = "渠道描述")
private String description;
/**
* 渠道类型system=系统/custom=自定义
*/
@ExcelProperty(value = "渠道类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "s=ystem=系统/custom=自定义")
private String channelType;
/**
* 国家
*/
@ExcelProperty(value = "国家")
private String country;
/**
* 运输方式
*/
@ExcelProperty(value = "运输方式")
private String shippingMethod;
}

View File

@ -0,0 +1,57 @@
package org.asinkj.amz.domain.vo;
import org.asinkj.amz.domain.BizLogisticsCustomChannel;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 物流商自定义渠道视图对象 biz_logistics_custom_channel
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizLogisticsCustomChannel.class)
public class BizLogisticsCustomChannelVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 渠道ID
*/
@ExcelProperty(value = "渠道ID")
private Long id;
/**
* 物流商用户ID关联sys_user
*/
@ExcelProperty(value = "物流商用户ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联sys_user")
private Long userId;
/**
* 渠道名称
*/
@ExcelProperty(value = "渠道名称")
private String channelName;
/**
* 渠道描述
*/
@ExcelProperty(value = "渠道描述")
private String description;
}

View File

@ -0,0 +1,113 @@
package org.asinkj.amz.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.asinkj.amz.domain.BizLogisticsQuote;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 物流报价视图对象 biz_logistics_quote
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizLogisticsQuote.class)
public class BizLogisticsQuoteVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 物流商用户ID关联sys_user表
*/
@ExcelProperty(value = "物流商用户ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联sys_user表")
private Long userId;
/**
* 目的地建议使用ISO国家代码如CN/US/GB
*/
@ExcelProperty(value = "目的地", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "建=议使用ISO国家代码如CN/US/GB")
private String destination;
/**
* 渠道名称冗余存储保证查询效率
*/
@ExcelProperty(value = "渠道名称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "冗=余存储,保证查询效率")
private String transportChannel;
/**
* 基础价格
*/
@ExcelProperty(value = "基础价格")
private Long price;
/**
* 时效单位
*/
@ExcelProperty(value = "时效", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "单=位:天")
private Long leadTime;
/**
* 附加费
*/
@ExcelProperty(value = "附加费")
private Long surcharge;
/**
* 报价生效日期
*/
@ExcelProperty(value = "报价生效日期")
private Date quoteDate;
/**
* 提交状态Y已提交 N未提交
*/
@ExcelProperty(value = "提交状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "Y=已提交,N=未提交")
private String isSubmitted;
/**
* 报价备注
*/
@ExcelProperty(value = "报价备注")
private String remark;
/**
* 渠道类型system=系统/custom=自定义
*/
@ExcelProperty(value = "渠道类型", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "s=ystem=系统/custom=自定义")
private String channelType;
/**
* 渠道IDsystem=dict_codecustom=自定义渠道ID
*/
@ExcelProperty(value = "渠道ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "s=ystem=dict_codecustom=自定义渠道ID")
private Long channelId;
}

View File

@ -0,0 +1,94 @@
package org.asinkj.amz.domain.vo;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.asinkj.amz.domain.BizShipmentItem;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 货品明细视图对象 biz_shipment_item
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizShipmentItem.class)
public class BizShipmentItemVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 关联货件ID
*/
@ExcelProperty(value = "关联货件ID")
private String shipmentId;
/**
* 商家SKU
*/
@ExcelProperty(value = "商家SKU")
private String msku;
/**
* 仓储编码
*/
@ExcelProperty(value = "仓储编码")
private String fnsku;
/**
* 发货量
*/
@ExcelProperty(value = "发货量")
private Long quantityShipped;
/**
* 收货量
*/
@ExcelProperty(value = "收货量")
private Long quantityReceived;
/**
* 预处理说明
*/
@ExcelProperty(value = "预处理说明")
private String prepInstruction;
/**
* 责任方
*/
@ExcelProperty(value = "责任方")
private String prepOwner;
/**
* 商品SKU
*/
@ExcelProperty(value = "商品SKU")
private String sku;
/**
* 有效期
*/
@ExcelProperty(value = "有效期")
private Date expiration;
}

View File

@ -0,0 +1,168 @@
package org.asinkj.amz.domain.vo;
import java.util.Date;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.asinkj.amz.domain.BizShipmentPlan;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.amz.hanlder.AddressTypeHandler;
import org.asinkj.asinking.entity.FbaShipmentApiResponse;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 货件计划视图对象 biz_shipment_plan
*
* @author shuo hu
* @date 2025-03-19
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizShipmentPlan.class)
public class BizShipmentPlanVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 关联系统ID
*/
@ExcelProperty(value = "关联系统ID")
private Long sid;
/**
* 货件编号
*/
@ExcelProperty(value = "货件编号")
private String shipmentId;
/**
* 货件名称
*/
@ExcelProperty(value = "货件名称")
private String shipmentName;
/**
* 是否关闭
*/
@ExcelProperty(value = "是否关闭")
private String isClosed;
/**
* 货件状态
*/
@ExcelProperty(value = "货件状态")
private String shipmentStatus;
/**
* 物流中心编码
*/
@ExcelProperty(value = "物流中心编码")
private String destinationFulfillmentCenterId;
/**
* 运输模式
*/
@ExcelProperty(value = "运输模式")
private String shippingMode;
/**
* 运输方案
*/
@ExcelProperty(value = "运输方案")
private String shippingSolution;
/**
* 最后更新时间
*/
@ExcelProperty(value = "最后更新时间")
private Date gmtModified;
/**
* 创建时间
*/
@ExcelProperty(value = "创建时间")
private Date gmtCreate;
/**
* 同步时间
*/
@ExcelProperty(value = "同步时间")
private Date syncTime;
/**
* 计划发货日期
*/
@ExcelProperty(value = "计划发货日期")
private Date staShipmentDate;
/**
* 预计到货开始日
*/
@ExcelProperty(value = "预计到货开始日")
private Date staDeliveryStartDate;
/**
* 预计到货截止日
*/
@ExcelProperty(value = "预计到货截止日")
private Date staDeliveryEndDate;
/**
* 发货地址
*/
@ExcelProperty(value = "发货地址")
@TableField(value = "ship_from_address", typeHandler = AddressTypeHandler.class)
private FbaShipmentApiResponse.Address shipFromAddress;
/**
* 收货地址
*/
@ExcelProperty(value = "收货地址")
@TableField(value = "ship_to_address", typeHandler = AddressTypeHandler.class)
private FbaShipmentApiResponse.Address shipToAddress;
/**
* 参考编号
*/
@ExcelProperty(value = "参考编号")
private String referenceId;
/**
* 入库计划ID
*/
@ExcelProperty(value = "入库计划ID")
private String staInboundPlanId;
/**
* 是否STA计划
*/
@ExcelProperty(value = "是否STA计划")
private String isSta;
// 显式添加 Setter即使使用 @Data
public void setShipFromAddress(FbaShipmentApiResponse.Address shipFromAddress) {
System.out.printf(String.valueOf(shipToAddress));
this.shipFromAddress = shipFromAddress;
}
}

View File

@ -0,0 +1,56 @@
package org.asinkj.amz.domain.vo;
import org.asinkj.amz.domain.BizShipmentTracking;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 物流追踪视图对象 biz_shipment_tracking
*
* @author shuo hu
* @date 2025-03-20
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = BizShipmentTracking.class)
public class BizShipmentTrackingVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 关联货件ID
*/
@ExcelProperty(value = "关联货件ID")
private String shipmentId;
/**
* 箱号
*/
@ExcelProperty(value = "箱号")
private String boxId;
/**
* 物流单号
*/
@ExcelProperty(value = "物流单号")
private String trackingNumber;
}

View File

@ -0,0 +1,113 @@
package org.asinkj.amz.domain.vo;
import org.asinkj.amz.domain.SysAmazonStore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import org.asinkj.common.excel.annotation.ExcelDictFormat;
import org.asinkj.common.excel.convert.ExcelDictConvert;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 亚马逊店铺信息视图对象 sys_amazon_store
*
* @author shuo hu
* @date 2025-03-17
*/
@Data
@ExcelIgnoreUnannotated
@AutoMapper(target = SysAmazonStore.class)
public class SysAmazonStoreVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@ExcelProperty(value = "主键ID")
private Long id;
/**
* 所属用户ID关联sys_user
*/
@ExcelProperty(value = "所属用户ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "关=联sys_user")
private Long userId;
/**
* 领星ERP店铺标识ID
*/
@ExcelProperty(value = "领星ERP店铺标识ID")
private Long sid;
/**
* 站点ID
*/
@ExcelProperty(value = "站点ID")
private Long mid;
/**
* 店铺名称
*/
@ExcelProperty(value = "店铺名称")
private String storeName;
/**
* 亚马逊店铺ID如AZTOL**
*/
@ExcelProperty(value = "亚马逊店铺ID", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "如=AZTOL**")
private String sellerId;
/**
* 店铺账户名称
*/
@ExcelProperty(value = "店铺账户名称")
private String accountName;
/**
* 店铺账号ID
*/
@ExcelProperty(value = "店铺账号ID")
private Long sellerAccountId;
/**
* 站点简称如NA/EU
*/
@ExcelProperty(value = "站点简称", converter = ExcelDictConvert.class)
@ExcelDictFormat(readConverterExp = "如=NA/EU")
private String region;
/**
* 商城所在国家
*/
@ExcelProperty(value = "商城所在国家")
private String country;
/**
* 亚马逊市场ID
*/
@ExcelProperty(value = "亚马逊市场ID")
private String marketplaceId;
/**
* 广告授权 0未授权 1已授权
*/
@ExcelProperty(value = "广告授权 0未授权 1已授权")
private Long hasAdsSetting;
/**
* 店铺状态 0停用 1正常 2异常 3欠费
*/
@ExcelProperty(value = "店铺状态 0停用 1正常 2异常 3欠费")
private Long status;
}

View File

@ -0,0 +1,51 @@
package org.asinkj.amz.hanlder;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.asinkj.asinking.entity.FbaShipmentApiResponse;
import org.asinkj.asinking.entity.FbaShipmentApiResponse.Address;
import org.postgresql.util.PGobject;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@Slf4j
@MappedTypes(FbaShipmentApiResponse.Address.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class AddressTypeHandler extends BaseTypeHandler<FbaShipmentApiResponse.Address> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Address address, JdbcType jdbcType) throws SQLException {
PGobject jsonObject = new PGobject();
jsonObject.setType("jsonb");
jsonObject.setValue(com.alibaba.fastjson2.JSON.toJSONString(address));
ps.setObject(i, jsonObject);
}
@Override
public Address getNullableResult(ResultSet rs, String columnName) throws SQLException {
log.info("getNullableResult: {}", columnName);
return parseJsonb(rs.getString(columnName));
}
@Override
public Address getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return parseJsonb(rs.getString(columnIndex));
}
@Override
public Address getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return parseJsonb(cs.getString(columnIndex));
}
private Address parseJsonb(String json) {
log.info("parseJsonb: {}", json);
return com.alibaba.fastjson2.JSON.parseObject(json, Address.class);
}
}

View File

@ -0,0 +1,17 @@
package org.asinkj.amz.hanlder;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.MybatisConfiguration;
import org.asinkj.asinking.entity.FbaShipmentApiResponse;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisConfig implements ConfigurationCustomizer {
@Override
public void customize(MybatisConfiguration configuration) {
configuration.getTypeHandlerRegistry().register(FbaShipmentApiResponse.Address.class, AddressTypeHandler.class);
}
}

View File

@ -0,0 +1,15 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.BizInquiryRequest;
import org.asinkj.amz.domain.vo.BizInquiryRequestVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 物流询价Mapper接口
*
* @author shuo hu
* @date 2025-03-21
*/
public interface BizInquiryRequestMapper extends BaseMapperPlus<BizInquiryRequest, BizInquiryRequestVo> {
}

View File

@ -0,0 +1,15 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.BizLogisticsChannel;
import org.asinkj.amz.domain.vo.BizLogisticsChannelVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 物流商渠道Mapper接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface BizLogisticsChannelMapper extends BaseMapperPlus<BizLogisticsChannel, BizLogisticsChannelVo> {
}

View File

@ -0,0 +1,15 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.BizLogisticsCustomChannel;
import org.asinkj.amz.domain.vo.BizLogisticsCustomChannelVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 物流商自定义渠道Mapper接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface BizLogisticsCustomChannelMapper extends BaseMapperPlus<BizLogisticsCustomChannel, BizLogisticsCustomChannelVo> {
}

View File

@ -0,0 +1,15 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.BizLogisticsQuote;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 物流报价Mapper接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface BizLogisticsQuoteMapper extends BaseMapperPlus<BizLogisticsQuote, BizLogisticsQuoteVo> {
}

View File

@ -0,0 +1,15 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.BizShipmentItem;
import org.asinkj.amz.domain.vo.BizShipmentItemVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 货品明细Mapper接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface BizShipmentItemMapper extends BaseMapperPlus<BizShipmentItem, BizShipmentItemVo> {
}

View File

@ -0,0 +1,23 @@
package org.asinkj.amz.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.asinkj.amz.domain.BizShipmentPlan;
import org.asinkj.amz.domain.vo.BizShipmentPlanVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
import java.util.Collection;
import java.util.List;
/**
* 货件计划Mapper接口
*
* @author shuo hu
* @date 2025-03-19
*/
@Mapper
public interface BizShipmentPlanMapper extends BaseMapperPlus<BizShipmentPlan, BizShipmentPlanVo> {
List<String> selectExistingShipmentIds(@Param("batchIds") Collection<String> batchIds);
}

View File

@ -0,0 +1,15 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.BizShipmentTracking;
import org.asinkj.amz.domain.vo.BizShipmentTrackingVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 物流追踪Mapper接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface BizShipmentTrackingMapper extends BaseMapperPlus<BizShipmentTracking, BizShipmentTrackingVo> {
}

View File

@ -0,0 +1,19 @@
package org.asinkj.amz.mapper;
import org.asinkj.amz.domain.SysAmazonStore;
import org.asinkj.amz.domain.vo.SysAmazonStoreVo;
import org.asinkj.common.mybatis.core.mapper.BaseMapperPlus;
import org.mapstruct.Mapper;
import java.util.List;
/**
* 亚马逊店铺信息Mapper接口
*
* @author shuo hu
* @date 2025-03-17
*/
public interface SysAmazonStoreMapper extends BaseMapperPlus<SysAmazonStore, SysAmazonStoreVo> {
void batchInsertOrUpdate(List<SysAmazonStore> dataList);
}

View File

@ -0,0 +1,73 @@
package org.asinkj.amz.service;
import jakarta.validation.constraints.NotNull;
import org.asinkj.amz.domain.BizInquiryRequest;
import org.asinkj.amz.domain.vo.BizInquiryRequestVo;
import org.asinkj.amz.domain.bo.BizInquiryRequestBo;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 物流询价Service接口
*
* @author shuo hu
* @date 2025-03-21
*/
public interface IBizInquiryRequestService {
/**
* 查询物流询价
*
* @param id 主键
* @return 物流询价
*/
BizInquiryRequestVo queryById(Long id);
/**
* 分页查询物流询价列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流询价分页列表
*/
TableDataInfo<BizInquiryRequestVo> queryPageList(BizInquiryRequestBo bo, PageQuery pageQuery);
/**
* 查询符合条件的物流询价列表
*
* @param bo 查询条件
* @return 物流询价列表
*/
List<BizInquiryRequestVo> queryList(BizInquiryRequestBo bo);
/**
* 新增物流询价
*
* @param bo 物流询价
* @return 是否新增成功
*/
Boolean insertByBo(BizInquiryRequestBo bo);
/**
* 修改物流询价
*
* @param bo 物流询价
* @return 是否修改成功
*/
Boolean updateByBo(BizInquiryRequestBo bo);
/**
* 校验并批量删除物流询价信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
R<Void> createWithDesAndChannel(@NotNull(message = "目的地不能为空") String destination, @NotNull(message = "渠道不能为空") String channelId);
}

View File

@ -0,0 +1,71 @@
package org.asinkj.amz.service;
import org.asinkj.amz.domain.BizLogisticsChannel;
import org.asinkj.amz.domain.vo.BizLogisticsChannelVo;
import org.asinkj.amz.domain.bo.BizLogisticsChannelBo;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 物流商渠道Service接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface IBizLogisticsChannelService {
/**
* 查询物流商渠道
*
* @param id 主键
* @return 物流商渠道
*/
BizLogisticsChannelVo queryById(Long id);
/**
* 分页查询物流商渠道列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流商渠道分页列表
*/
TableDataInfo<BizLogisticsChannelVo> queryPageList(BizLogisticsChannelBo bo, PageQuery pageQuery);
/**
* 查询符合条件的物流商渠道列表
*
* @param bo 查询条件
* @return 物流商渠道列表
*/
List<BizLogisticsChannelVo> queryList(BizLogisticsChannelBo bo);
/**
* 新增物流商渠道
*
* @param bo 物流商渠道
* @return 是否新增成功
*/
Boolean insertByBo(BizLogisticsChannelBo bo);
/**
* 修改物流商渠道
*
* @param bo 物流商渠道
* @return 是否修改成功
*/
Boolean updateByBo(BizLogisticsChannelBo bo);
/**
* 校验并批量删除物流商渠道信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
TableDataInfo<BizLogisticsChannelVo> queryListAll();
}

View File

@ -0,0 +1,77 @@
package org.asinkj.amz.service;
import jakarta.validation.constraints.NotNull;
import org.asinkj.amz.domain.BizLogisticsQuote;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.asinkj.amz.domain.bo.BizLogisticsQuoteBo;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 物流报价Service接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface IBizLogisticsQuoteService {
/**
* 查询物流报价
*
* @param id 主键
* @return 物流报价
*/
BizLogisticsQuoteVo queryById(Long id);
/**
* 分页查询物流报价列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流报价分页列表
*/
TableDataInfo<BizLogisticsQuoteVo> queryPageList(BizLogisticsQuoteBo bo, PageQuery pageQuery);
/**
* 查询符合条件的物流报价列表
*
* @param bo 查询条件
* @return 物流报价列表
*/
List<BizLogisticsQuoteVo> queryList(BizLogisticsQuoteBo bo);
/**
* 新增物流报价
*
* @param bo 物流报价
* @return 是否新增成功
*/
Boolean insertByBo(BizLogisticsQuoteBo bo);
/**
* 修改物流报价
*
* @param bo 物流报价
* @return 是否修改成功
*/
Boolean updateByBo(BizLogisticsQuoteBo bo);
/**
* 校验并批量删除物流报价信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<BizLogisticsQuoteVo> queryQuoteWithDestination(String destination, String channel);
TableDataInfo<BizLogisticsQuoteVo> listWithDesAndChannel(@NotNull(message = "目的地不能为空") String destination, @NotNull(message = "渠道不能为空") String channel);
}

View File

@ -0,0 +1,69 @@
package org.asinkj.amz.service;
import org.asinkj.amz.domain.BizShipmentItem;
import org.asinkj.amz.domain.vo.BizShipmentItemVo;
import org.asinkj.amz.domain.bo.BizShipmentItemBo;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 货品明细Service接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface IBizShipmentItemService {
/**
* 查询货品明细
*
* @param id 主键
* @return 货品明细
*/
BizShipmentItemVo queryById(Long id);
/**
* 分页查询货品明细列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 货品明细分页列表
*/
TableDataInfo<BizShipmentItemVo> queryPageList(BizShipmentItemBo bo, PageQuery pageQuery);
/**
* 查询符合条件的货品明细列表
*
* @param bo 查询条件
* @return 货品明细列表
*/
List<BizShipmentItemVo> queryList(BizShipmentItemBo bo);
/**
* 新增货品明细
*
* @param bo 货品明细
* @return 是否新增成功
*/
Boolean insertByBo(BizShipmentItemBo bo);
/**
* 修改货品明细
*
* @param bo 货品明细
* @return 是否修改成功
*/
Boolean updateByBo(BizShipmentItemBo bo);
/**
* 校验并批量删除货品明细信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@ -0,0 +1,73 @@
package org.asinkj.amz.service;
import jakarta.validation.constraints.NotNull;
import org.asinkj.amz.domain.BizShipmentPlan;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.asinkj.amz.domain.vo.BizShipmentPlanVo;
import org.asinkj.amz.domain.bo.BizShipmentPlanBo;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 货件计划Service接口
*
* @author shuo hu
* @date 2025-03-19
*/
public interface IBizShipmentPlanService {
/**
* 查询货件计划
*
* @param id 主键
* @return 货件计划
*/
BizShipmentPlanVo queryById(Long id);
/**
* 分页查询货件计划列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 货件计划分页列表
*/
TableDataInfo<BizShipmentPlanVo> queryPageList(BizShipmentPlanBo bo, PageQuery pageQuery);
/**
* 查询符合条件的货件计划列表
*
* @param bo 查询条件
* @return 货件计划列表
*/
List<BizShipmentPlanVo> queryList(BizShipmentPlanBo bo);
/**
* 新增货件计划
*
* @param bo 货件计划
* @return 是否新增成功
*/
Boolean insertByBo(BizShipmentPlanBo bo);
/**
* 修改货件计划
*
* @param bo 货件计划
* @return 是否修改成功
*/
Boolean updateByBo(BizShipmentPlanBo bo);
/**
* 校验并批量删除货件计划信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
List<BizLogisticsQuoteVo> getQuote(@NotNull(message = "主键不能为空") String destination, String channel);
}

View File

@ -0,0 +1,69 @@
package org.asinkj.amz.service;
import org.asinkj.amz.domain.BizShipmentTracking;
import org.asinkj.amz.domain.vo.BizShipmentTrackingVo;
import org.asinkj.amz.domain.bo.BizShipmentTrackingBo;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 物流追踪Service接口
*
* @author shuo hu
* @date 2025-03-20
*/
public interface IBizShipmentTrackingService {
/**
* 查询物流追踪
*
* @param id 主键
* @return 物流追踪
*/
BizShipmentTrackingVo queryById(Long id);
/**
* 分页查询物流追踪列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流追踪分页列表
*/
TableDataInfo<BizShipmentTrackingVo> queryPageList(BizShipmentTrackingBo bo, PageQuery pageQuery);
/**
* 查询符合条件的物流追踪列表
*
* @param bo 查询条件
* @return 物流追踪列表
*/
List<BizShipmentTrackingVo> queryList(BizShipmentTrackingBo bo);
/**
* 新增物流追踪
*
* @param bo 物流追踪
* @return 是否新增成功
*/
Boolean insertByBo(BizShipmentTrackingBo bo);
/**
* 修改物流追踪
*
* @param bo 物流追踪
* @return 是否修改成功
*/
Boolean updateByBo(BizShipmentTrackingBo bo);
/**
* 校验并批量删除物流追踪信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
}

View File

@ -0,0 +1,78 @@
package org.asinkj.amz.service;
import org.asinkj.amz.domain.SysAmazonStore;
import org.asinkj.amz.domain.vo.SysAmazonStoreVo;
import org.asinkj.amz.domain.bo.SysAmazonStoreBo;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
/**
* 亚马逊店铺信息Service接口
*
* @author shuo hu
* @date 2025-03-17
*/
public interface ISysAmazonStoreService {
/**
* 查询亚马逊店铺信息
*
* @param id 主键
* @return 亚马逊店铺信息
*/
SysAmazonStoreVo queryById(Long id);
/**
* 分页查询亚马逊店铺信息列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 亚马逊店铺信息分页列表
*/
TableDataInfo<SysAmazonStoreVo> queryPageList(SysAmazonStoreBo bo, PageQuery pageQuery);
/**
* 查询符合条件的亚马逊店铺信息列表
*
* @param bo 查询条件
* @return 亚马逊店铺信息列表
*/
List<SysAmazonStoreVo> queryList(SysAmazonStoreBo bo);
/**
* 新增亚马逊店铺信息
*
* @param bo 亚马逊店铺信息
* @return 是否新增成功
*/
Boolean insertByBo(SysAmazonStoreBo bo);
/**
* 修改亚马逊店铺信息
*
* @param bo 亚马逊店铺信息
* @return 是否修改成功
*/
Boolean updateByBo(SysAmazonStoreBo bo);
/**
* 校验并批量删除亚马逊店铺信息信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
void collectAmzStoreData();
void pullAmzStoreData() throws Exception;
void pullAmzFBAData(String startDate,String endDate) throws Exception;
void getAmzStoreTokenData() throws Exception;
}

View File

@ -0,0 +1,213 @@
package org.asinkj.amz.service.impl;
import cn.hutool.core.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.amz.domain.vo.BizLogisticsChannelVo;
import org.asinkj.amz.service.IBizLogisticsChannelService;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.asinkj.common.satoken.utils.LoginHelper;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.BizInquiryRequestBo;
import org.asinkj.amz.domain.vo.BizInquiryRequestVo;
import org.asinkj.amz.domain.BizInquiryRequest;
import org.asinkj.amz.mapper.BizInquiryRequestMapper;
import org.asinkj.amz.service.IBizInquiryRequestService;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 物流询价Service业务层处理
*
* @author shuo hu
* @date 2025-03-21
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class BizInquiryRequestServiceImpl implements IBizInquiryRequestService {
private final BizInquiryRequestMapper baseMapper;
private static final AtomicInteger sequence = new AtomicInteger(0);
@Resource
private IBizLogisticsChannelService bizLogisticsChannelService;
@Resource
private BizInquiryRequestMapper billingRequestMapper;
/**
* 查询物流询价
*
* @param id 主键
* @return 物流询价
*/
@Override
public BizInquiryRequestVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询物流询价列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流询价分页列表
*/
@Override
public TableDataInfo<BizInquiryRequestVo> queryPageList(BizInquiryRequestBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizInquiryRequest> lqw = buildQueryWrapper(bo);
Page<BizInquiryRequestVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的物流询价列表
*
* @param bo 查询条件
* @return 物流询价列表
*/
@Override
public List<BizInquiryRequestVo> queryList(BizInquiryRequestBo bo) {
LambdaQueryWrapper<BizInquiryRequest> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BizInquiryRequest> buildQueryWrapper(BizInquiryRequestBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizInquiryRequest> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getInquiryNo()), BizInquiryRequest::getInquiryNo, bo.getInquiryNo());
lqw.eq(bo.getRequesterId() != null, BizInquiryRequest::getRequesterId, bo.getRequesterId());
lqw.eq(StringUtils.isNotBlank(bo.getTargetProviders()), BizInquiryRequest::getTargetProviders, bo.getTargetProviders());
lqw.eq(StringUtils.isNotBlank(bo.getDestination()), BizInquiryRequest::getDestination, bo.getDestination());
lqw.eq(StringUtils.isNotBlank(bo.getTransportChannel()), BizInquiryRequest::getTransportChannel, bo.getTransportChannel());
lqw.eq(StringUtils.isNotBlank(bo.getInquiryStatus()), BizInquiryRequest::getInquiryStatus, bo.getInquiryStatus());
lqw.eq(bo.getDeadline() != null, BizInquiryRequest::getDeadline, bo.getDeadline());
lqw.eq(bo.getChannelId() != null, BizInquiryRequest::getChannelId, bo.getChannelId());
lqw.like(StringUtils.isNotBlank(bo.getChannelName()), BizInquiryRequest::getChannelName, bo.getChannelName());
lqw.eq(bo.getEffectiveStartTime() != null, BizInquiryRequest::getEffectiveStartTime, bo.getEffectiveStartTime());
lqw.eq(bo.getEffectiveEndTime() != null, BizInquiryRequest::getEffectiveEndTime, bo.getEffectiveEndTime());
return lqw;
}
/**
* 新增物流询价
*
* @param bo 物流询价
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BizInquiryRequestBo bo) {
BizInquiryRequest add = MapstructUtils.convert(bo, BizInquiryRequest.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改物流询价
*
* @param bo 物流询价
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BizInquiryRequestBo bo) {
BizInquiryRequest update = MapstructUtils.convert(bo, BizInquiryRequest.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BizInquiryRequest entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除物流询价信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public R<Void> createWithDesAndChannel(String destination, String channelId) {
BizInquiryRequest bizInquiryRequest = new BizInquiryRequest();
bizInquiryRequest.setDestination(destination);
bizInquiryRequest.setChannelId(NumberUtil.parseLong(channelId));
if (bizInquiryRequest.getChannelId() == null) {
return R.fail("渠道不能为空");
}
if (bizInquiryRequest.getDestination() == null) {
return R.fail("目的地不能为空");
}
//询价单号规则INQ+年月+6位序列
bizInquiryRequest.setInquiryNo(generateInquiryNo());
//查询出渠道信息
BizLogisticsChannelVo bizLogisticsChannelVo = bizLogisticsChannelService.queryById(bizInquiryRequest.getChannelId());
if (bizLogisticsChannelVo == null){
log.info("渠道信息为空");
}
if ("air".equals(bizLogisticsChannelVo.getShippingMethod())){
bizInquiryRequest.setEffectiveStartTime(new Date());
bizInquiryRequest.setEffectiveEndTime(new Date());
}else if("sea".equals(bizLogisticsChannelVo.getShippingMethod())){
//获取下周一的日期
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_WEEK, 8 - calendar.get(Calendar.DAY_OF_WEEK));
bizInquiryRequest.setEffectiveStartTime(calendar.getTime());
//获取下下周一的日期
calendar.add(Calendar.DAY_OF_WEEK, 7);
bizInquiryRequest.setEffectiveEndTime(calendar.getTime());
}
bizInquiryRequest.setChannelName(bizLogisticsChannelVo.getChannelName());
bizInquiryRequest.setTransportChannel(bizLogisticsChannelVo.getShippingMethod());
//获取当天上午11点的时间
bizInquiryRequest.setDeadline(LocalDate.now()
.atTime(11, 0));
bizInquiryRequest.setRequesterId(LoginHelper.getUserId());
billingRequestMapper.insert(bizInquiryRequest);
return R.ok();
}
private String generateInquiryNo() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
String datePart = sdf.format(new Date());
int seq = sequence.incrementAndGet();
if (seq > 999999) { // 处理溢出例如重置或抛出异常
sequence.set(0);
seq = 0;
}
return String.format("INQ%s%06d", datePart, seq);
}
}

View File

@ -0,0 +1,156 @@
package org.asinkj.amz.service.impl;
import cn.hutool.core.util.StrUtil;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.asinkj.common.satoken.utils.LoginHelper;
import org.asinkj.system.api.model.LoginUser;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.BizLogisticsChannelBo;
import org.asinkj.amz.domain.vo.BizLogisticsChannelVo;
import org.asinkj.amz.domain.BizLogisticsChannel;
import org.asinkj.amz.mapper.BizLogisticsChannelMapper;
import org.asinkj.amz.service.IBizLogisticsChannelService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 物流商渠道Service业务层处理
*
* @author shuo hu
* @date 2025-03-20
*/
@RequiredArgsConstructor
@Service
public class BizLogisticsChannelServiceImpl implements IBizLogisticsChannelService {
private final BizLogisticsChannelMapper baseMapper;
/**
* 查询物流商渠道
*
* @param id 主键
* @return 物流商渠道
*/
@Override
public BizLogisticsChannelVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询物流商渠道列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流商渠道分页列表
*/
@Override
public TableDataInfo<BizLogisticsChannelVo> queryPageList(BizLogisticsChannelBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizLogisticsChannel> lqw = buildQueryWrapper(bo);
Page<BizLogisticsChannelVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的物流商渠道列表
*
* @param bo 查询条件
* @return 物流商渠道列表
*/
@Override
public List<BizLogisticsChannelVo> queryList(BizLogisticsChannelBo bo) {
LambdaQueryWrapper<BizLogisticsChannel> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BizLogisticsChannel> buildQueryWrapper(BizLogisticsChannelBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizLogisticsChannel> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getUserId() != null, BizLogisticsChannel::getUserId, bo.getUserId());
lqw.like(StringUtils.isNotBlank(bo.getChannelName()), BizLogisticsChannel::getChannelName, bo.getChannelName());
lqw.eq(StringUtils.isNotBlank(bo.getDescription()), BizLogisticsChannel::getDescription, bo.getDescription());
lqw.eq(StringUtils.isNotBlank(bo.getChannelType()), BizLogisticsChannel::getChannelType, bo.getChannelType());
lqw.eq(StringUtils.isNotBlank(bo.getCountry()), BizLogisticsChannel::getCountry, bo.getCountry());
lqw.eq(StringUtils.isNotBlank(bo.getShippingMethod()), BizLogisticsChannel::getShippingMethod, bo.getShippingMethod());
lqw.in(BizLogisticsChannel::getUserId, LoginHelper.getUserId(), 1L);
return lqw;
}
/**
* 新增物流商渠道
*
* @param bo 物流商渠道
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BizLogisticsChannelBo bo) {
BizLogisticsChannel add = MapstructUtils.convert(bo, BizLogisticsChannel.class);
validEntityBeforeSave(add);
LoginUser loginUser = LoginHelper.getLoginUser();
assert add != null;
if (LoginHelper.isSuperAdmin()) {
add.setUserId(1L);
add.setChannelType("system");
} else {
add.setUserId(loginUser.getUserId());
add.setChannelType("custom");
}
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改物流商渠道
*
* @param bo 物流商渠道
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BizLogisticsChannelBo bo) {
BizLogisticsChannel update = MapstructUtils.convert(bo, BizLogisticsChannel.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BizLogisticsChannel entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除物流商渠道信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public TableDataInfo<BizLogisticsChannelVo> queryListAll() {
LambdaQueryWrapper<BizLogisticsChannel> lqw = Wrappers.lambdaQuery();
lqw.eq(BizLogisticsChannel::getChannelType, "system");
return TableDataInfo.build(baseMapper.selectVoList(lqw));
}
}

View File

@ -0,0 +1,185 @@
package org.asinkj.amz.service.impl;
import cn.hutool.core.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.amz.domain.BizInquiryRequest;
import org.asinkj.amz.domain.BizLogisticsChannel;
import org.asinkj.amz.domain.vo.BizLogisticsChannelVo;
import org.asinkj.amz.mapper.BizInquiryRequestMapper;
import org.asinkj.amz.service.IBizInquiryRequestService;
import org.asinkj.amz.service.IBizLogisticsChannelService;
import org.asinkj.common.core.domain.R;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.BizLogisticsQuoteBo;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.asinkj.amz.domain.BizLogisticsQuote;
import org.asinkj.amz.mapper.BizLogisticsQuoteMapper;
import org.asinkj.amz.service.IBizLogisticsQuoteService;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 物流报价Service业务层处理
*
* @author shuo hu
* @date 2025-03-20
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class BizLogisticsQuoteServiceImpl implements IBizLogisticsQuoteService {
private final BizLogisticsQuoteMapper baseMapper;
@Resource
private IBizLogisticsChannelService bizLogisticsChannelService;
@Resource
private BizInquiryRequestMapper billingRequestMapper;
/**
* 查询物流报价
*
* @param id 主键
* @return 物流报价
*/
@Override
public BizLogisticsQuoteVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询物流报价列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流报价分页列表
*/
@Override
public TableDataInfo<BizLogisticsQuoteVo> queryPageList(BizLogisticsQuoteBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizLogisticsQuote> lqw = buildQueryWrapper(bo);
Page<BizLogisticsQuoteVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的物流报价列表
*
* @param bo 查询条件
* @return 物流报价列表
*/
@Override
public List<BizLogisticsQuoteVo> queryList(BizLogisticsQuoteBo bo) {
LambdaQueryWrapper<BizLogisticsQuote> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BizLogisticsQuote> buildQueryWrapper(BizLogisticsQuoteBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizLogisticsQuote> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getUserId() != null, BizLogisticsQuote::getUserId, bo.getUserId());
lqw.eq(StringUtils.isNotBlank(bo.getDestination()), BizLogisticsQuote::getDestination, bo.getDestination());
lqw.eq(StringUtils.isNotBlank(bo.getTransportChannel()), BizLogisticsQuote::getTransportChannel, bo.getTransportChannel());
lqw.eq(bo.getPrice() != null, BizLogisticsQuote::getPrice, bo.getPrice());
lqw.eq(bo.getLeadTime() != null, BizLogisticsQuote::getLeadTime, bo.getLeadTime());
lqw.eq(bo.getSurcharge() != null, BizLogisticsQuote::getSurcharge, bo.getSurcharge());
lqw.eq(bo.getQuoteDate() != null, BizLogisticsQuote::getQuoteDate, bo.getQuoteDate());
lqw.eq(StringUtils.isNotBlank(bo.getIsSubmitted()), BizLogisticsQuote::getIsSubmitted, bo.getIsSubmitted());
lqw.eq(StringUtils.isNotBlank(bo.getChannelType()), BizLogisticsQuote::getChannelType, bo.getChannelType());
lqw.eq(bo.getChannelId() != null, BizLogisticsQuote::getChannelId, bo.getChannelId());
return lqw;
}
/**
* 新增物流报价
*
* @param bo 物流报价
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BizLogisticsQuoteBo bo) {
BizLogisticsQuote add = MapstructUtils.convert(bo, BizLogisticsQuote.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改物流报价
*
* @param bo 物流报价
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BizLogisticsQuoteBo bo) {
BizLogisticsQuote update = MapstructUtils.convert(bo, BizLogisticsQuote.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BizLogisticsQuote entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除物流报价信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public List<BizLogisticsQuoteVo> queryQuoteWithDestination(String destination, String channel) {
LambdaQueryWrapper<BizLogisticsQuote> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(BizLogisticsQuote::getDestination, destination);
queryWrapper.eq(BizLogisticsQuote::getTransportChannel, channel);
return baseMapper.selectVoList(queryWrapper);
}
@Override
public TableDataInfo<BizLogisticsQuoteVo> listWithDesAndChannel(String destination, String channel) {
if (StringUtils.isNotBlank(destination) && StringUtils.isNotBlank(channel)) {
LambdaQueryWrapper<BizLogisticsQuote> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(BizLogisticsQuote::getDestination, destination);
queryWrapper.eq(BizLogisticsQuote::getChannelId, NumberUtil.parseLong(channel));
return TableDataInfo.build(baseMapper.selectVoList(queryWrapper));
}
return null;
}
}

View File

@ -0,0 +1,137 @@
package org.asinkj.amz.service.impl;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.BizShipmentItemBo;
import org.asinkj.amz.domain.vo.BizShipmentItemVo;
import org.asinkj.amz.domain.BizShipmentItem;
import org.asinkj.amz.mapper.BizShipmentItemMapper;
import org.asinkj.amz.service.IBizShipmentItemService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 货品明细Service业务层处理
*
* @author shuo hu
* @date 2025-03-20
*/
@RequiredArgsConstructor
@Service
public class BizShipmentItemServiceImpl implements IBizShipmentItemService {
private final BizShipmentItemMapper baseMapper;
/**
* 查询货品明细
*
* @param id 主键
* @return 货品明细
*/
@Override
public BizShipmentItemVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询货品明细列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 货品明细分页列表
*/
@Override
public TableDataInfo<BizShipmentItemVo> queryPageList(BizShipmentItemBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizShipmentItem> lqw = buildQueryWrapper(bo);
Page<BizShipmentItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的货品明细列表
*
* @param bo 查询条件
* @return 货品明细列表
*/
@Override
public List<BizShipmentItemVo> queryList(BizShipmentItemBo bo) {
LambdaQueryWrapper<BizShipmentItem> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BizShipmentItem> buildQueryWrapper(BizShipmentItemBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizShipmentItem> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getShipmentId()), BizShipmentItem::getShipmentId, bo.getShipmentId());
lqw.eq(StringUtils.isNotBlank(bo.getMsku()), BizShipmentItem::getMsku, bo.getMsku());
lqw.eq(StringUtils.isNotBlank(bo.getFnsku()), BizShipmentItem::getFnsku, bo.getFnsku());
lqw.eq(bo.getQuantityShipped() != null, BizShipmentItem::getQuantityShipped, bo.getQuantityShipped());
lqw.eq(bo.getQuantityReceived() != null, BizShipmentItem::getQuantityReceived, bo.getQuantityReceived());
lqw.eq(StringUtils.isNotBlank(bo.getPrepInstruction()), BizShipmentItem::getPrepInstruction, bo.getPrepInstruction());
lqw.eq(StringUtils.isNotBlank(bo.getPrepOwner()), BizShipmentItem::getPrepOwner, bo.getPrepOwner());
lqw.eq(StringUtils.isNotBlank(bo.getSku()), BizShipmentItem::getSku, bo.getSku());
lqw.eq(bo.getExpiration() != null, BizShipmentItem::getExpiration, bo.getExpiration());
return lqw;
}
/**
* 新增货品明细
*
* @param bo 货品明细
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BizShipmentItemBo bo) {
BizShipmentItem add = MapstructUtils.convert(bo, BizShipmentItem.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改货品明细
*
* @param bo 货品明细
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BizShipmentItemBo bo) {
BizShipmentItem update = MapstructUtils.convert(bo, BizShipmentItem.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BizShipmentItem entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除货品明细信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@ -0,0 +1,159 @@
package org.asinkj.amz.service.impl;
import org.asinkj.amz.domain.BizLogisticsQuote;
import org.asinkj.amz.domain.vo.BizLogisticsQuoteVo;
import org.asinkj.amz.service.IBizLogisticsQuoteService;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.BizShipmentPlanBo;
import org.asinkj.amz.domain.vo.BizShipmentPlanVo;
import org.asinkj.amz.domain.BizShipmentPlan;
import org.asinkj.amz.mapper.BizShipmentPlanMapper;
import org.asinkj.amz.service.IBizShipmentPlanService;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 货件计划Service业务层处理
*
* @author shuo hu
* @date 2025-03-19
*/
@RequiredArgsConstructor
@Service
public class BizShipmentPlanServiceImpl implements IBizShipmentPlanService {
private final BizShipmentPlanMapper baseMapper;
@Resource
private IBizLogisticsQuoteService iLogisticsQuoteService;;
/**
* 查询货件计划
*
* @param id 主键
* @return 货件计划
*/
@Override
public BizShipmentPlanVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询货件计划列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 货件计划分页列表
*/
@Override
public TableDataInfo<BizShipmentPlanVo> queryPageList(BizShipmentPlanBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizShipmentPlan> lqw = buildQueryWrapper(bo);
Page<BizShipmentPlanVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的货件计划列表
*
* @param bo 查询条件
* @return 货件计划列表
*/
@Override
public List<BizShipmentPlanVo> queryList(BizShipmentPlanBo bo) {
LambdaQueryWrapper<BizShipmentPlan> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BizShipmentPlan> buildQueryWrapper(BizShipmentPlanBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizShipmentPlan> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getSid() != null, BizShipmentPlan::getSid, bo.getSid());
lqw.eq(StringUtils.isNotBlank(bo.getShipmentId()), BizShipmentPlan::getShipmentId, bo.getShipmentId());
lqw.like(StringUtils.isNotBlank(bo.getShipmentName()), BizShipmentPlan::getShipmentName, bo.getShipmentName());
lqw.eq(StringUtils.isNotBlank(bo.getIsClosed()), BizShipmentPlan::getIsClosed, bo.getIsClosed());
lqw.eq(StringUtils.isNotBlank(bo.getShipmentStatus()), BizShipmentPlan::getShipmentStatus, bo.getShipmentStatus());
lqw.eq(StringUtils.isNotBlank(bo.getDestinationFulfillmentCenterId()), BizShipmentPlan::getDestinationFulfillmentCenterId, bo.getDestinationFulfillmentCenterId());
lqw.eq(StringUtils.isNotBlank(bo.getShippingMode()), BizShipmentPlan::getShippingMode, bo.getShippingMode());
lqw.eq(StringUtils.isNotBlank(bo.getShippingSolution()), BizShipmentPlan::getShippingSolution, bo.getShippingSolution());
lqw.eq(bo.getGmtModified() != null, BizShipmentPlan::getGmtModified, bo.getGmtModified());
lqw.eq(bo.getGmtCreate() != null, BizShipmentPlan::getGmtCreate, bo.getGmtCreate());
lqw.eq(bo.getSyncTime() != null, BizShipmentPlan::getSyncTime, bo.getSyncTime());
lqw.eq(bo.getStaShipmentDate() != null, BizShipmentPlan::getStaShipmentDate, bo.getStaShipmentDate());
lqw.eq(bo.getStaDeliveryStartDate() != null, BizShipmentPlan::getStaDeliveryStartDate, bo.getStaDeliveryStartDate());
lqw.eq(bo.getStaDeliveryEndDate() != null, BizShipmentPlan::getStaDeliveryEndDate, bo.getStaDeliveryEndDate());
// lqw.eq(StringUtils.isNotBlank(bo.getShipFromAddress()), BizShipmentPlan::getShipFromAddress, bo.getShipFromAddress());
// lqw.eq(StringUtils.isNotBlank(bo.getShipToAddress()), BizShipmentPlan::getShipToAddress, bo.getShipToAddress());
lqw.eq(StringUtils.isNotBlank(bo.getReferenceId()), BizShipmentPlan::getReferenceId, bo.getReferenceId());
lqw.eq(StringUtils.isNotBlank(bo.getStaInboundPlanId()), BizShipmentPlan::getStaInboundPlanId, bo.getStaInboundPlanId());
lqw.eq(StringUtils.isNotBlank(bo.getIsSta()), BizShipmentPlan::getIsSta, bo.getIsSta());
return lqw;
}
/**
* 新增货件计划
*
* @param bo 货件计划
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BizShipmentPlanBo bo) {
BizShipmentPlan add = MapstructUtils.convert(bo, BizShipmentPlan.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改货件计划
*
* @param bo 货件计划
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BizShipmentPlanBo bo) {
BizShipmentPlan update = MapstructUtils.convert(bo, BizShipmentPlan.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BizShipmentPlan entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除货件计划信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public List<BizLogisticsQuoteVo> getQuote(String destination, String channel) {
return iLogisticsQuoteService.queryQuoteWithDestination(destination, channel);
}
}

View File

@ -0,0 +1,131 @@
package org.asinkj.amz.service.impl;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.BizShipmentTrackingBo;
import org.asinkj.amz.domain.vo.BizShipmentTrackingVo;
import org.asinkj.amz.domain.BizShipmentTracking;
import org.asinkj.amz.mapper.BizShipmentTrackingMapper;
import org.asinkj.amz.service.IBizShipmentTrackingService;
import java.util.List;
import java.util.Map;
import java.util.Collection;
/**
* 物流追踪Service业务层处理
*
* @author shuo hu
* @date 2025-03-20
*/
@RequiredArgsConstructor
@Service
public class BizShipmentTrackingServiceImpl implements IBizShipmentTrackingService {
private final BizShipmentTrackingMapper baseMapper;
/**
* 查询物流追踪
*
* @param id 主键
* @return 物流追踪
*/
@Override
public BizShipmentTrackingVo queryById(Long id){
return baseMapper.selectVoById(id);
}
/**
* 分页查询物流追踪列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 物流追踪分页列表
*/
@Override
public TableDataInfo<BizShipmentTrackingVo> queryPageList(BizShipmentTrackingBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<BizShipmentTracking> lqw = buildQueryWrapper(bo);
Page<BizShipmentTrackingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的物流追踪列表
*
* @param bo 查询条件
* @return 物流追踪列表
*/
@Override
public List<BizShipmentTrackingVo> queryList(BizShipmentTrackingBo bo) {
LambdaQueryWrapper<BizShipmentTracking> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<BizShipmentTracking> buildQueryWrapper(BizShipmentTrackingBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<BizShipmentTracking> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getShipmentId()), BizShipmentTracking::getShipmentId, bo.getShipmentId());
lqw.eq(StringUtils.isNotBlank(bo.getBoxId()), BizShipmentTracking::getBoxId, bo.getBoxId());
lqw.eq(StringUtils.isNotBlank(bo.getTrackingNumber()), BizShipmentTracking::getTrackingNumber, bo.getTrackingNumber());
return lqw;
}
/**
* 新增物流追踪
*
* @param bo 物流追踪
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(BizShipmentTrackingBo bo) {
BizShipmentTracking add = MapstructUtils.convert(bo, BizShipmentTracking.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改物流追踪
*
* @param bo 物流追踪
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(BizShipmentTrackingBo bo) {
BizShipmentTracking update = MapstructUtils.convert(bo, BizShipmentTracking.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(BizShipmentTracking entity){
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除物流追踪信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if(isValid){
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
}

View File

@ -0,0 +1,430 @@
package org.asinkj.amz.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
import org.apache.dubbo.config.annotation.DubboReference;
import org.asinkj.amz.domain.BizShipmentItem;
import org.asinkj.amz.domain.BizShipmentPlan;
import org.asinkj.amz.domain.BizShipmentTracking;
import org.asinkj.amz.mapper.BizShipmentItemMapper;
import org.asinkj.amz.mapper.BizShipmentPlanMapper;
import org.asinkj.amz.mapper.BizShipmentTrackingMapper;
import org.asinkj.asinking.entity.FbaShipmentApiResponse;
import org.asinkj.asinking.entity.Result;
import org.asinkj.asinking.entity.SellerAccountResponse;
import org.asinkj.asinking.entity.TokenInfo;
import org.asinkj.asinking.okhttp.AKRestClientBuild;
import org.asinkj.common.core.utils.MapstructUtils;
import org.asinkj.common.core.utils.StringUtils;
import org.asinkj.common.mybatis.core.page.TableDataInfo;
import org.asinkj.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.asinkj.common.redis.utils.RedisUtils;
import org.asinkj.common.satoken.utils.LoginHelper;
import org.asinkj.resource.api.RemoteMessageService;
import org.asinkj.system.api.model.LoginUser;
import org.asinkj.utils.HttpUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.asinkj.amz.domain.bo.SysAmazonStoreBo;
import org.asinkj.amz.domain.vo.SysAmazonStoreVo;
import org.asinkj.amz.domain.SysAmazonStore;
import org.asinkj.amz.mapper.SysAmazonStoreMapper;
import org.asinkj.amz.service.ISysAmazonStoreService;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import javax.annotation.Resource;
import java.io.IOException;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;
/**
* 亚马逊店铺信息Service业务层处理
*
* @author shuo hu
* @date 2025-03-17
*/
@RequiredArgsConstructor
@Service
@Slf4j
public class SysAmazonStoreServiceImpl implements ISysAmazonStoreService {
public static final String REFRESH_TOKEN = "refresh_token";
public static final String ACCESS_TOKEN = "access_token";
@DubboReference(stub = "true")
private final RemoteMessageService remoteMessageService;
private final SysAmazonStoreMapper baseMapper;
@Resource
private BizShipmentPlanMapper bizShipmentPlanMapper;
@Resource
private BizShipmentItemMapper bizShipmentItemMapper;
@Resource
private BizShipmentTrackingMapper bizShipmentTrackingMapper;
@Value("${lingxing.appId}")
private String appId;
@Value("${lingxing.appSecret}")
private String appSecret;
@Value("${lingxing.url}")
private String url;
/**
* 查询亚马逊店铺信息
*
* @param id 主键
* @return 亚马逊店铺信息
*/
@Override
public SysAmazonStoreVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
* 分页查询亚马逊店铺信息列表
*
* @param bo 查询条件
* @param pageQuery 分页参数
* @return 亚马逊店铺信息分页列表
*/
@Override
public TableDataInfo<SysAmazonStoreVo> queryPageList(SysAmazonStoreBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysAmazonStore> lqw = buildQueryWrapper(bo);
Page<SysAmazonStoreVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询符合条件的亚马逊店铺信息列表
*
* @param bo 查询条件
* @return 亚马逊店铺信息列表
*/
@Override
public List<SysAmazonStoreVo> queryList(SysAmazonStoreBo bo) {
LambdaQueryWrapper<SysAmazonStore> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SysAmazonStore> buildQueryWrapper(SysAmazonStoreBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SysAmazonStore> lqw = Wrappers.lambdaQuery();
lqw.eq(bo.getUserId() != null, SysAmazonStore::getUserId, bo.getUserId());
lqw.eq(bo.getSid() != null, SysAmazonStore::getSid, bo.getSid());
lqw.eq(bo.getMid() != null, SysAmazonStore::getMid, bo.getMid());
lqw.like(StringUtils.isNotBlank(bo.getStoreName()), SysAmazonStore::getStoreName, bo.getStoreName());
lqw.eq(StringUtils.isNotBlank(bo.getSellerId()), SysAmazonStore::getSellerId, bo.getSellerId());
lqw.like(StringUtils.isNotBlank(bo.getAccountName()), SysAmazonStore::getAccountName, bo.getAccountName());
lqw.eq(bo.getSellerAccountId() != null, SysAmazonStore::getSellerAccountId, bo.getSellerAccountId());
lqw.eq(StringUtils.isNotBlank(bo.getRegion()), SysAmazonStore::getRegion, bo.getRegion());
lqw.eq(StringUtils.isNotBlank(bo.getCountry()), SysAmazonStore::getCountry, bo.getCountry());
lqw.eq(StringUtils.isNotBlank(bo.getMarketplaceId()), SysAmazonStore::getMarketplaceId, bo.getMarketplaceId());
lqw.eq(bo.getHasAdsSetting() != null, SysAmazonStore::getHasAdsSetting, bo.getHasAdsSetting());
lqw.eq(bo.getStatus() != null, SysAmazonStore::getStatus, bo.getStatus());
lqw.orderByDesc(SysAmazonStore::getSid);
return lqw;
}
/**
* 新增亚马逊店铺信息
*
* @param bo 亚马逊店铺信息
* @return 是否新增成功
*/
@Override
public Boolean insertByBo(SysAmazonStoreBo bo) {
SysAmazonStore add = MapstructUtils.convert(bo, SysAmazonStore.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
bo.setId(add.getId());
}
return flag;
}
/**
* 修改亚马逊店铺信息
*
* @param bo 亚马逊店铺信息
* @return 是否修改成功
*/
@Override
public Boolean updateByBo(SysAmazonStoreBo bo) {
SysAmazonStore update = MapstructUtils.convert(bo, SysAmazonStore.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
* 保存前的数据校验
*/
private void validEntityBeforeSave(SysAmazonStore entity) {
//TODO 做一些数据校验,如唯一约束
}
/**
* 校验并批量删除亚马逊店铺信息信息
*
* @param ids 待删除的主键集合
* @param isValid 是否进行有效性校验
* @return 是否删除成功
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteByIds(ids) > 0;
}
@Override
public void collectAmzStoreData() {
try {
pullAmzStoreData();
} catch (Exception e) {
log.error("error", e);
}
}
@Override
public void pullAmzStoreData() throws Exception {
// if (ObjectUtil.isNull(RedisUtils.getCacheObject(ACCESS_TOKEN))){
// getAmzStoreTokenData();
// }
//
// Map<String, Object> queryParam = new HashMap<>();
// queryParam.put("timestamp", System.currentTimeMillis() / 1000 + "");
// queryParam.put("access_token", RedisUtils.getCacheObject(ACCESS_TOKEN));
// queryParam.put("app_key", appId);
//// queryParam.put("offset", 0);
//// queryParam.put("length", 20);
//
// String sign = ApiSign.sign(queryParam, appId);
// queryParam.put("sign", sign);
// log.info("sign:{}", sign);
//
// HttpRequest<Object> build = HttpRequest.builder(Object.class)
// .method(HttpMethod.GET)
// .endpoint(url)
// .path("erp/sc/data/seller/lists")
// .queryParams(queryParam)
// .build();
// HttpResponse execute = HttpExecutor.create().execute(build);
//// log.info("HttpResponse:{}",execute.readEntity(Object.class));
// SellerAccountResponse sellerAccountResponse = execute.readEntity(SellerAccountResponse.class);
// List<SysAmazonStore> dataList = sellerAccountResponse.getData();
// for (SysAmazonStore datum : dataList) {
// datum.setUserId(1L);
// }
// log.info("execute:{}", sellerAccountResponse);
// baseMapper.insertBatch(dataList);
Map<String, String> queryParam = new HashMap<>();
Long userId = LoginHelper.getLoginUser().getUserId();
HttpUtil.postWithUrlParams("/erp/sc/data/seller/lists", queryParam, new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
log.info("onFailure");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String string = response.body().string();
SellerAccountResponse sellerAccountResponse = JSONObject.parseObject(string, SellerAccountResponse.class);
// SellerAccountResponse sellerAccountResponse = JSON.parseObject(string, SellerAccountResponse.class);
List<SysAmazonStore> dataList = sellerAccountResponse.getData();
for (SysAmazonStore datum : dataList) {
datum.setUserId(1L);
datum.setCreateBy(1L);
datum.setTenantId("000000");
datum.setDelFlag("0");
datum.setUpdateBy(0L);
}
log.info("execute:{}", sellerAccountResponse);
baseMapper.batchInsertOrUpdate(dataList);
remoteMessageService.publishMessage(userId, "获取亚马逊店铺信息完成");
}
});
}
@Override
public void pullAmzFBAData(String startDate, String endDate) throws Exception {
Map<String, String> queryParam = new HashMap<>();
queryParam.put("sid", String.valueOf(143));
queryParam.put("start_date", startDate);
queryParam.put("end_date", endDate);
queryParam.put("shipment_status", "READY_TO_SHIP");
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
HttpUtil.postWithUrlParams("/erp/sc/data/fba_report/shipmentList", queryParam, new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
log.info("onFailure");
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
RequestContextHolder.setRequestAttributes(ra);
try {
String string = response.body().string();
log.info("string:{}", string);
JSONObject jsonObject = JSONObject.parse(string);
JSONObject data = jsonObject.getJSONObject("data");
if (ObjectUtil.isEmpty(data)) {
log.info("未获取到库存");
return;
}
JSONArray list = data.getJSONArray("list");
if (CollectionUtil.isEmpty(list)) {
log.info("未获取到库存");
return;
}
log.info("data:{}", list);
List<FbaShipmentApiResponse.ShipmentPlan> listData = list.toList(FbaShipmentApiResponse.ShipmentPlan.class);
log.info("fbaShipmentApiResponse:{}", listData);
Set<String> shipmentIds = listData.stream().map(FbaShipmentApiResponse.ShipmentPlan::getShipmentId).collect(Collectors.toSet());
// 查询数据库中存在的shipmentId 使用mybatis-plus批量查询
Set<String> selectExistingShipmentIds = bizShipmentPlanMapper.selectList(new LambdaQueryWrapper<BizShipmentPlan>().in(BizShipmentPlan::getShipmentId, shipmentIds)).stream().map(BizShipmentPlan::getShipmentId).collect(Collectors.toSet());
ArrayList<BizShipmentItem> bizShipmentItemsList = new ArrayList<>();
ArrayList<BizShipmentTracking> bizShipmentTrackingsList = new ArrayList<>();
ArrayList<BizShipmentPlan> BizShipmentPlanList = new ArrayList<>();
listData.removeIf(shipmentPlan -> selectExistingShipmentIds.contains(shipmentPlan.getShipmentId()));
for (FbaShipmentApiResponse.ShipmentPlan listDatum : listData) {
listDatum.setId(null);
BizShipmentPlan bizShipmentPlan = BeanUtil.copyProperties(listDatum, BizShipmentPlan.class);
BizShipmentPlanList.add(bizShipmentPlan);
listDatum.getItemList().forEach(item -> {
item.setId(null);
item.setZid(null);
item.setShipmentPlanList(null);
});
List<BizShipmentItem> bizShipmentItems = BeanUtil.copyToList(listDatum.getItemList(), BizShipmentItem.class);
for (BizShipmentItem bizShipmentItem : bizShipmentItems) {
bizShipmentItem.setId(null);
bizShipmentItem.setShipmentId(bizShipmentPlan.getShipmentId());
}
bizShipmentItemsList.addAll(bizShipmentItems);
List<BizShipmentTracking> bizShipmentTrackings = BeanUtil.copyToList(listDatum.getTrackingNumberList(), BizShipmentTracking.class);
for (BizShipmentTracking bizShipmentTracking : bizShipmentTrackings) {
bizShipmentTracking.setId(null);
bizShipmentTracking.setShipmentId(bizShipmentPlan.getShipmentId());
}
bizShipmentTrackingsList.addAll(bizShipmentTrackings);
log.info("bizShipmentPlan:{}", bizShipmentPlan);
}
bizShipmentPlanMapper.insertBatch(BizShipmentPlanList);
bizShipmentItemMapper.insertBatch(bizShipmentItemsList);
bizShipmentTrackingMapper.insertBatch(bizShipmentTrackingsList);
} finally {
RequestContextHolder.resetRequestAttributes();
}
}
});
// if (ObjectUtil.isNull(RedisUtils.getCacheObject(ACCESS_TOKEN))){
// getAmzStoreTokenData();
// }
//
// Map<String, Object> queryParam = new HashMap<>();
// queryParam.put("timestamp", System.currentTimeMillis() / 1000 + "");
// queryParam.put("access_token", RedisUtils.getCacheObject(ACCESS_TOKEN));
// queryParam.put("app_key", appId);
// queryParam.put("sid",536);
// queryParam.put("start_date","2025-01-17");
// queryParam.put("end_date","2025-03-18");
//// queryParam.put("offset", 0);
//// queryParam.put("length", 20);
//
// String sign = ApiSign.sign(queryParam, appId);
// queryParam.put("sign", sign);
//
// log.info("sign:{}", sign);
//
// HttpRequest<Object> build = HttpRequest.builder(Object.class)
// .method(HttpMethod.POST)
// .endpoint(url)
// .path("erp/sc/data/fba_report/shipmentList")
// .queryParams(queryParam)
// .build();
// HttpResponse execute = HttpExecutor.create().execute(build);
// Object o = execute.readEntity(Object.class);
// log.info("execute:{}", o);
// Shipment shipment = execute.readEntity(Shipment.class);
// log.info("HttpResponse:{}", JSON.toJSON(shipment));
}
@Override
public void getAmzStoreTokenData() throws Exception {
// 如果用postman等其他工具调试时需要将appSecret用urlencode.encode()进行转义
if (ObjectUtil.isNull(RedisUtils.getCacheObject(REFRESH_TOKEN))) {
Result result = AKRestClientBuild.builder().endpoint(url).getAccessToken(appId, appSecret);
Object data = result.getData();
if (data instanceof LinkedHashMap) {
// 将LinkedHashMap转为TokenInfo
ObjectMapper mapper = new ObjectMapper();
TokenInfo tokenInfo = mapper.convertValue(data, TokenInfo.class); // 关键点
log.info("token:{}", tokenInfo.getRefreshToken());
RedisUtils.setCacheObject(REFRESH_TOKEN, tokenInfo.getRefreshToken(), Duration.ofHours(2));
RedisUtils.setCacheObject(ACCESS_TOKEN, tokenInfo.getAccessToken(), Duration.ofSeconds(tokenInfo.getExpiresIn()));
} else {
throw new IllegalStateException("data字段类型不匹配");
}
} else {
Object result = AKRestClientBuild.builder().endpoint(url).refreshToken(appId, RedisUtils.getCacheObject(REFRESH_TOKEN));
ObjectMapper mapper = new ObjectMapper();
Result result1 = mapper.convertValue(result, Result.class); // 关键点
if (result1.getData() != null && result1.getData() instanceof LinkedHashMap) {
TokenInfo tokenInfo = mapper.convertValue(result1.getData(), TokenInfo.class); // 关键点
log.info("tokenInfo:{}", tokenInfo.getRefreshToken());
RedisUtils.setCacheObject(REFRESH_TOKEN, tokenInfo.getRefreshToken(), Duration.ofHours(2));
RedisUtils.setCacheObject(ACCESS_TOKEN, tokenInfo.getAccessToken(), Duration.ofSeconds(tokenInfo.getExpiresIn()));
} else {
log.info("删除Redis存储的token");
RedisUtils.deleteObject(REFRESH_TOKEN);
RedisUtils.deleteObject(ACCESS_TOKEN);
}
}
}
}

View File

@ -1,5 +1,6 @@
package org.asinkj.asinking.core;
import okhttp3.Headers;
import okhttp3.Response;
import org.asinkj.asinking.constant.ClientConstants;

View File

@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.SerializationFeature;
public class ObjectMapperSingleton {
@ -22,6 +23,9 @@ public class ObjectMapperSingleton {
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
rootMapper = new ObjectMapper();
rootMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
rootMapper.enable(SerializationFeature.INDENT_OUTPUT);

View File

@ -0,0 +1,225 @@
package org.asinkj.asinking.entity;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class FbaShipmentApiResponse {
private Integer code;
private String message;
private List<String> error_details;
private String request_id;
private String response_time;
private List<ShipmentPlan> data;
private Integer total;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class ShipmentPlan {
private Long id;
private Integer sid;
private Integer uid;
@JSONField(name = "shipment_id")
private String shipmentId;
@JSONField(name = "shipment_name")
private String shipmentName;
@JSONField(name = "is_closed")
private Integer isClosed;
@JSONField(name = "shipment_status")
private String shipmentStatus;
@JSONField(name = "gmt_modified")
private String gmtModified;
@JSONField(name = "gmt_create")
private String gmtCreate;
@JSONField(name = "sync_time")
private String syncTime;
@JSONField(name = "destination_fulfillment_center_id")
private String destinationFulfillmentCenterId;
private String username;
private String seller;
@JSONField(name = "item_list")
private List<Item> itemList;
@JSONField(name = "is_synchronous")
private Integer isSynchronous;
@JSONField(name = "is_uploaded_box")
private Integer isUploadedBox;
@JSONField(name = "working_time")
private String workingTime;
@JSONField(name = "shipped_time")
private String shippedTime;
@JSONField(name = "receiving_time")
private String receivingTime;
@JSONField(name = "closed_time")
private String closedTime;
@JSONField(name = "reference_id")
private String referenceId;
@JSONField(name = "is_sta")
private Integer isSta;
@JSONField(name = "sta_plan_name")
private String staPlanName;
@JSONField(name = "sta_inbound_plan_id")
private String staInboundPlanId;
@JSONField(name = "sta_shipment_date")
private String staShipmentDate;
@JSONField(name = "sta_delivery_start_date")
private String staDeliveryStartDate;
@JSONField(name = "sta_delivery_end_date")
private String staDeliveryEndDate;
@JSONField(name = "ship_from_address")
private Address shipFromAddress;
@JSONField(name = "ship_to_address")
private Address shipToAddress;
@JSONField(name = "shipping_mode")
private String shippingMode;
@JSONField(name = "shipping_solution")
private String shippingSolution;
@JSONField(name = "alpha_code")
private String alphaCode;
@JSONField(name = "alpha_name")
private String alphaName;
@JSONField(name = "tracking_number_list")
private List<TrackingNumber> trackingNumberList;
@JSONField(name = "bill_of_lading_number")
private String billOfLadingNumber;
@JSONField(name = "freight_bill_number")
private String freightBillNumber;
@JSONField(name = "sta_shipment_id")
private String staShipmentId;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class Item {
private Long id;
private Integer zid;
private String msku;
private String fnsku;
@JSONField(name = "quantity_shipped")
private Integer quantityShipped;
@JSONField(name = "init_quantity_shipped")
private Integer initQuantityShipped;
@JSONField(name = "quantity_received")
private Integer quantityReceived;
@JSONField(name = "quantity_shipped_local")
private Integer quantityShippedLocal;
@JSONField(name = "quantity_in_case")
private Integer quantityInCase;
@JSONField(name = "prep_details")
private String prepDetails;
@JSONField(name = "prep_instruction")
private String prepInstruction;
@JSONField(name = "prep_owner")
private String prepOwner;
@JSONField(name = "release_date")
private String releaseDate;
@JSONField(name = "ware_house_storage_id")
private Integer wareHouseStorageId;
@JSONField(name = "shipment_plan_list")
private List<?> shipmentPlanList; // 空数组类型保持通用
private String sku;
@JSONField(name = "prep_labelowner")
private String prepLabelOwner;
private String expiration;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class Address {
private String name;
@JSONField(name = "country_code")
private String countryCode;
@JSONField(name = "state_or_province_code")
private String stateOrProvinceCode;
private String city;
private String region;
@JSONField(name = "address_line1")
private String addressLine1;
@JSONField(name = "address_line2")
private String addressLine2;
@JSONField(name = "postal_code")
private String postalCode;
private String phone;
private String doorplate;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public static class TrackingNumber {
@JSONField(name = "box_id")
private String boxId;
@JSONField(name = "tracking_number")
private String trackingNumber;
}
}

View File

@ -0,0 +1,43 @@
package org.asinkj.asinking.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.asinkj.amz.domain.SysAmazonStore;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class SellerAccountResponse implements Serializable {
@Serial
private static final long serialVersionUID = 6717170236221300711L;
private String code;
private String message;
private List<String> error_details; // 根据实际错误数据结构调整
private String request_id;
private String response_time;
private List<SysAmazonStore> data;
private Integer total;
}
@Data
class SellerAccount implements Serializable {
@Serial
private static final long serialVersionUID = -2568726414949839482L;
private Long sid;
private Long mid;
private String name;
private String seller_id;
private String account_name;
private Long seller_account_id;
private String region;
private String country;
private String marketplace_id;
private String status;
private String has_ads_setting;
}

View File

@ -0,0 +1,101 @@
package org.asinkj.asinking.entity;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.time.LocalDateTime;
@Data
public class Shipment {
private Integer id;
private Integer sid;
private Integer uid;
@JsonProperty("shipment_id")
private String shipmentId; // 处理空字符串
@JsonProperty("shipment_name")
private String shipmentName;
@JsonProperty("is_closed")
private Integer isClosed;
@JsonProperty("shipment_status")
private String shipmentStatus;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("gmt_modified")
private LocalDateTime gmtModified;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("gmt_create")
private LocalDateTime gmtCreate;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("sync_time")
private LocalDateTime syncTime; // 空字符串会反序列化为null
@JsonProperty("destination_fulfillment_center_id")
private String destinationFulfillmentCenterId;
private String username;
private String seller;
@JsonProperty("is_synchronous")
private Integer isSynchronous;
@JsonProperty("is_uploaded_box")
private Integer isUploadedBox;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("working_time")
private LocalDateTime workingTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("shipped_time")
private LocalDateTime shippedTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("receiving_time")
private LocalDateTime receivingTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm")
@JsonProperty("closed_time")
private LocalDateTime closedTime;
@JsonProperty("reference_id")
private String referenceId;
@JsonProperty("ship_from_address")
private Address shipFromAddress;
@JsonProperty("ship_to_address")
private Address shipToAddress;
@Data
public static class Address {
private String name;
@JsonProperty("country_code")
private String countryCode;
@JsonProperty("state_or_province_code")
private String stateOrProvinceCode;
private String city;
private String region;
@JsonProperty("address_line1")
private String addressLine1;
@JsonProperty("address_line2")
private String addressLine2;
@JsonProperty("postal_code")
private String postalCode;
// 特殊字段不同地址类型特有
private String phone; // ship_from_address特有
private String doorplate; // ship_to_address特有
}
}

View File

@ -0,0 +1,36 @@
package org.asinkj.asinking.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
public class TokenInfo {
/**
* 访问令牌
*/
@JsonProperty("access_token")
private String accessToken;
/**
* 刷新令牌
*/
@JsonProperty("refresh_token")
private String refreshToken;
/**
* 过期时间
*/
@JsonProperty("expires_in")
private int expiresIn;
@Override
public String toString() {
return "TokenInfo{" +
"accessToken='" + accessToken + '\'' +
", refreshToken='" + refreshToken + '\'' +
", expiresIn=" + expiresIn +
'}';
}
}

View File

@ -7,6 +7,7 @@ import org.asinkj.asinking.core.HttpMethod;
import org.asinkj.asinking.core.HttpRequest;
import org.asinkj.asinking.core.HttpResponse;
import org.asinkj.asinking.entity.Result;
import org.asinkj.asinking.entity.TokenInfo;
import java.util.Map;

View File

@ -1,10 +1,15 @@
package org.asinkj.asinking.samples;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.asinking.entity.Result;
import org.asinkj.asinking.entity.TokenInfo;
import org.asinkj.asinking.okhttp.AKRestClientBuild;
import java.io.DataInput;
import java.util.LinkedHashMap;
@Slf4j
public class AccessTokenDemo {
@ -18,8 +23,17 @@ public class AccessTokenDemo {
String appId = "ak_XNNp2fMr6JPF5";
// 如果用postman等其他工具调试时需要将appSecret用urlencode.encode()进行转义
String appSecret = "923QKLc3Y4m7brPYHPXBIQ==";
Result result = AKRestClientBuild.builder().endpoint("https://openapi.lingxing.com").getAccessToken(appId, appSecret);
log.info("token:{}", result);
Result result = AKRestClientBuild.builder().endpoint("http://112.74.106.216:12526").getAccessToken(appId, appSecret);
Object data = result.getData();
if (data instanceof LinkedHashMap) {
// 将LinkedHashMap转为TokenInfo
ObjectMapper mapper = new ObjectMapper();
TokenInfo tokenInfo = mapper.convertValue(data, TokenInfo.class); // 关键点
log.info("token:{}", tokenInfo.getRefreshToken());
} else {
throw new IllegalStateException("data字段类型不匹配");
}
}
}

View File

@ -0,0 +1,41 @@
package org.asinkj.asinking.samples;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.asinking.core.HttpMethod;
import org.asinkj.asinking.core.HttpRequest;
import org.asinkj.asinking.core.HttpResponse;
import org.asinkj.asinking.okhttp.HttpExecutor;
import org.asinkj.asinking.sign.ApiSign;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class GetFBADemo {
public static void main(String[] args) throws Exception {
String appId = "ak_XNNp2fMr6JPF5";
Map<String, Object> queryParam = new HashMap<>();
queryParam.put("timestamp", System.currentTimeMillis() / 1000 + "");
queryParam.put("access_token", "e3141db5-0e0a-4c41-a25d-df4a809fb573");
queryParam.put("app_key", appId);
// queryParam.put("offset", 0);
// queryParam.put("length", 20);
String sign = ApiSign.sign(queryParam, appId);
queryParam.put("sign", sign);
log.info("sign:{}", sign);
HttpRequest<Object> build = HttpRequest.builder(Object.class)
.method(HttpMethod.GET)
.endpoint("http://112.74.106.216:12526")
.path("/erp/sc/data/fba_report/shipmentList")
.queryParams(queryParam)
.build();
HttpResponse execute = HttpExecutor.create().execute(build);
log.info("execute:{}", execute.readEntity(Object.class));
}
}

View File

@ -1,7 +1,6 @@
package org.asinkj.asinking.samples;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.asinking.core.Config;
import org.asinkj.asinking.core.HttpMethod;

View File

@ -2,7 +2,6 @@ package org.asinkj.asinking.samples;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.asinking.core.Config;
import org.asinkj.asinking.core.HttpMethod;

View File

@ -2,7 +2,6 @@ package org.asinkj.asinking.samples;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.asinking.core.HttpMethod;
import org.asinkj.asinking.core.HttpRequest;

View File

@ -1,7 +1,6 @@
package org.asinkj.asinking.samples;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.asinkj.asinking.core.HttpMethod;
import org.asinkj.asinking.core.HttpRequest;

View File

@ -0,0 +1,25 @@
package org.asinkj.config;
import org.asinkj.utils.HttpUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class HttpUtilConfig {
@Value("${lingxing.appId}")
String appId;
@Value("${lingxing.appSecret}")
String appSecret;
@Value("${lingxing.url}")
String url;
@PostConstruct
public void initHttpUtil() {
// 通过Supplier关联TokenManager
HttpUtil.init(appId, appSecret,url);
}
}

View File

@ -0,0 +1,193 @@
package org.asinkj.utils;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.HttpUrl;
import org.asinkj.asinking.entity.Result;
import org.asinkj.asinking.entity.TokenInfo;
import org.asinkj.asinking.okhttp.AKRestClientBuild;
import org.asinkj.asinking.sign.ApiSign;
import org.asinkj.common.redis.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Value;
import java.io.IOException;
import java.time.Duration;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
@Slf4j
public class HttpUtil {
public static final String REFRESH_TOKEN = "refresh_token";
public static final String ACCESS_TOKEN = "access_token";
// 静态配置
private static String appId;
private static String baseurl;
private static String appSecret;
private static Supplier<String> accessTokenSupplier;
private static final OkHttpClient client = createHttpClient();
private static final Object lock = new Object();
// 防止实例化
private HttpUtil() {}
/**
* 初始化方法需在Spring启动后调用
* @param appId 应用ID
*/
public static void init(@Value("${lingxing.appId}") String appId,
@Value("${lingxing.appSecret}") String appSecret,
@Value("${lingxing.url}") String baseurl
) {
synchronized (lock) {
HttpUtil.appId = appId;
HttpUtil.baseurl = baseurl;
HttpUtil.appSecret = appSecret;
}
}
// GET 请求
public static void get(String url, Map<String, String> customParams, Callback callback) {
Map<String, Object> allParams = mergeParams(customParams);
Map<String, String> queryParams = convertToStringMap(allParams);
buildAndSendRequest(url, queryParams, "GET", null, callback);
}
// POST 表单
public static void postForm(String url, Map<String, String> customParams, Callback callback) {
Map<String, Object> allParams = mergeParams(customParams);
Map<String, String> formParams = convertToStringMap(allParams);
FormBody formBody = buildFormBody(formParams);
buildAndSendRequest(url, null, "POST", formBody, callback);
}
// POST 请求参数在URL无请求体
public static void postWithUrlParams(String url, Map<String, String> customParams, Callback callback) {
Map<String, Object> allParams = mergeParams(customParams);
Map<String, String> queryParams = convertToStringMap(allParams);
buildAndSendRequest(url, queryParams, "POST", RequestBody.create(new byte[0], null), callback);
}
// POST JSON
public static void postJson(String url, String jsonBody, Callback callback) {
RequestBody body = RequestBody.create(jsonBody, MediaType.get("application/json"));
buildAndSendRequest(url, null, "POST", body, callback);
}
private static Map<String, Object> mergeParams(Map<String, String> customParams) {
checkInitialized();
Map<String, Object> allParams = new HashMap<>();
if (customParams != null) allParams.putAll(customParams);
// 动态获取最新access_token
allParams.put("app_key", appId);
allParams.put("access_token", RedisUtils.getCacheObject(ACCESS_TOKEN));
allParams.put("timestamp", System.currentTimeMillis() / 1000);
String sign = ApiSign.sign(allParams, appId);
allParams.put("sign", sign);
return allParams;
}
public static void getAmzStoreTokenData() throws Exception {
// 如果用postman等其他工具调试时需要将appSecret用urlencode.encode()进行转义
if (ObjectUtil.isNull(RedisUtils.getCacheObject(REFRESH_TOKEN))) {
Result result = AKRestClientBuild.builder().endpoint(baseurl).getAccessToken(appId, appSecret);
Object data = result.getData();
if (data instanceof LinkedHashMap) {
// 将LinkedHashMap转为TokenInfo
ObjectMapper mapper = new ObjectMapper();
TokenInfo tokenInfo = mapper.convertValue(data, TokenInfo.class); // 关键点
log.info("token:{}", tokenInfo.getRefreshToken());
RedisUtils.setCacheObject(REFRESH_TOKEN, tokenInfo.getRefreshToken(), Duration.ofHours(2));
RedisUtils.setCacheObject(ACCESS_TOKEN, tokenInfo.getAccessToken(), Duration.ofSeconds(tokenInfo.getExpiresIn()));
} else {
throw new IllegalStateException("data字段类型不匹配");
}
}else {
Object result = AKRestClientBuild.builder().endpoint(baseurl).refreshToken(appId, RedisUtils.getCacheObject(REFRESH_TOKEN));
ObjectMapper mapper = new ObjectMapper();
Result result1 = mapper.convertValue(result, Result.class); // 关键点
if (result1.getData() != null && result1.getData() instanceof LinkedHashMap) {
TokenInfo tokenInfo = mapper.convertValue(result1.getData(), TokenInfo.class); // 关键点
log.info("tokenInfo:{}", tokenInfo.getRefreshToken());
RedisUtils.setCacheObject(REFRESH_TOKEN, tokenInfo.getRefreshToken(),Duration.ofHours(2));
RedisUtils.setCacheObject(ACCESS_TOKEN, tokenInfo.getAccessToken(), Duration.ofSeconds(tokenInfo.getExpiresIn()));
}else {
log.info("删除Redis存储的token");
RedisUtils.deleteObject(REFRESH_TOKEN);
RedisUtils.deleteObject(ACCESS_TOKEN);
}
}
}
private static void checkInitialized() {
if (appId == null) {
throw new IllegalStateException("HttpUtil未初始化请先调用init方法");
}
if (ObjectUtil.isNull(RedisUtils.getCacheObject(ACCESS_TOKEN))){
try {
getAmzStoreTokenData();
} catch (Exception e) {
log.error("获取ACCESS_TOKEN出错",e);
}
}
}
// 其余工具方法保持不变...
private static Map<String, String> convertToStringMap(Map<String, Object> sourceMap) {
Map<String, String> stringMap = new HashMap<>();
for (Map.Entry<String, Object> entry : sourceMap.entrySet()) {
Object value = entry.getValue();
if (value != null) {
stringMap.put(entry.getKey(), value.toString());
}
}
return stringMap;
}
private static FormBody buildFormBody(Map<String, String> params) {
FormBody.Builder builder = new FormBody.Builder();
params.forEach(builder::add);
return builder.build();
}
private static OkHttpClient createHttpClient() {
return new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
}
private static void buildAndSendRequest(String url, Map<String, String> queryParams,
String method, RequestBody body, Callback callback) {
try {
HttpUrl.Builder urlBuilder = HttpUrl.parse(baseurl+url).newBuilder();
if (queryParams != null) queryParams.forEach(urlBuilder::addQueryParameter);
Request.Builder requestBuilder = new Request.Builder().url(urlBuilder.build());
if ("POST".equalsIgnoreCase(method)) {
requestBuilder.post(body);
} else {
requestBuilder.get();
}
client.newCall(requestBuilder.build()).enqueue(callback);
} catch (Exception e) {
callback.onFailure(null, new IOException("请求配置错误", e));
}
}
}

View File

@ -0,0 +1,117 @@
# Tomcat
server:
port: 9404
# Spring
spring:
application:
# 应用名称
name: asinkj-amz
profiles:
# 环境配置
active: @profiles.active@
--- # nacos 配置
spring:
cloud:
nacos:
# nacos 服务地址
server-addr: @nacos.server@
username: @nacos.username@
password: @nacos.password@
discovery:
# 注册组
group: @nacos.discovery.group@
namespace: ${spring.profiles.active}
config:
# 配置组
group: @nacos.config.group@
namespace: ${spring.profiles.active}
config:
import:
- optional:nacos:application-common.yml
- optional:nacos:asinkj-resource.yml
- optional:nacos:datasource.yml
- optional:nacos:${spring.application.name}.yml
--- # 数据源设置 需在 system 数据源下 执行 test.sql 文件
#spring:
# datasource:
# dynamic:
# seata: false
# # 设置默认的数据源或者数据源组,默认值即为 master
# primary: master
# datasource:
# # 主库数据源
# master:
# type: ${spring.datasource.type}
# driver-class-name: com.mysql.cj.jdbc.Driver
# url: ${datasource.system-master.url}
# username: ${datasource.system-master.username}
# password: ${datasource.system-master.password}
# sharding:
# lazy: true
# type: ${spring.datasource.type}
# driver-class-name: com.mysql.cj.jdbc.Driver
# # shardingproxy 服务的ip地址
# url: jdbc:mysql://127.0.0.1:3307/data-center_db?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
# username: root
# password: root
## oracle:
## type: ${spring.datasource.type}
## driverClassName: oracle.jdbc.OracleDriver
## url: ${datasource.system-oracle.url}
## username: ${datasource.system-oracle.username}
## password: ${datasource.system-oracle.password}
## hikari:
## connectionTestQuery: SELECT 1 FROM DUAL
## postgres:
## type: ${spring.datasource.type}
## driverClassName: org.postgresql.Driver
## url: ${datasource.system-postgres.url}
## username: ${datasource.system-postgres.username}
## password: ${datasource.system-postgres.password}
#
#--- # elasticsearch 功能配置
## 文档地址: https://www.easy-es.cn/
## 更改包名需要去 EasyEsConfiguration 修改包扫描(后续版本支持配置文件读取)
#easy-es:
# # 是否开启EE自动配置
# enable: false
# # es连接地址+端口 格式必须为ip:port,如果是集群则可用逗号隔开
# address : localhost:9200
# # 默认为http
# schema: http
# # 注意ES建议使用账号认证 不使用会报警告日志
# #如果无账号密码则可不配置此行
# #username:
# #如果无账号密码则可不配置此行
# #password:
# # 心跳策略时间 单位:ms
# keep-alive-millis: 18000
# # 连接超时时间 单位:ms
# connectTimeout: 5000
# # 通信超时时间 单位:ms
# socketTimeout: 5000
# # 连接请求超时时间 单位:ms
# connectionRequestTimeout: 5000
# # 最大连接数 单位:个
# maxConnTotal: 100
# # 最大连接路由数 单位:个
# maxConnPerRoute: 100
# global-config:
# # 开启控制台打印通过本框架生成的DSL语句,默认为开启,测试稳定后的生产环境建议关闭,以提升少量性能
# print-dsl: true
# # 异步处理索引是否阻塞主线程 默认阻塞 数据量过大时调整为非阻塞异步进行 项目启动更快
# asyncProcessIndexBlocking: true
# db-config:
# # 是否开启下划线转驼峰 默认为false
# map-underscore-to-camel-case: true
# # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成
# id-type: customize
# # 字段更新策略 默认为not_null
# field-strategy: not_null
# # 默认开启,查询若指定了size超过1w条时也会自动开启,开启后查询所有匹配数据,若不开启,会导致无法获取数据总条数,其它功能不受影响.
# enable-track-total-hits: true
# # 数据刷新策略,默认为不刷新
# refresh-policy: immediate

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/${project.artifactId}" />
<!-- 日志输出格式 -->
<property name="console.log.pattern"
value="%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${console.log.pattern}</pattern>
<charset>utf-8</charset>
</encoder>
</appender>
<include resource="logback-common.xml" />
<!--系统操作日志-->
<root level="info">
<appender-ref ref="console" />
</root>
<logger name="org.asinkj.amz" level="DEBUG" additivity="false">
<appender-ref ref="console" />
</logger>
</configuration>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.BizInquiryRequestMapper">
</mapper>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.BizLogisticsChannelMapper">
</mapper>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.BizLogisticsQuoteMapper">
</mapper>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.BizShipmentItemMapper">
</mapper>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.BizShipmentPlanMapper">
<select id="selectExistingShipmentIds" resultType="java.lang.String">
SELECT shipmentid
FROM biz_shipment_plan
WHERE del_flag = '0'
WHERE shipmentid IN
<foreach item="id" collection="batchIds" open="(" separator="," close=")">
#{id}
</foreach>
</select>
</mapper>

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.BizShipmentTrackingMapper">
</mapper>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.asinkj.amz.mapper.SysAmazonStoreMapper">
<insert id="batchInsertOrUpdate" useGeneratedKeys="true" keyProperty="id">
INSERT INTO sys_amazon_store (
tenant_id, user_id, sid, mid, store_name, seller_id,
account_name, seller_account_id, region, country,
marketplace_id, has_ads_setting, status, del_flag,
create_by, create_time, update_by, create_dept
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.tenantId}, #{item.userId}, #{item.sid}, #{item.mid},
#{item.storeName}, #{item.sellerId}, #{item.accountName},
#{item.sellerAccountId}, #{item.region}, #{item.country},
#{item.marketplaceId}, #{item.hasAdsSetting}, #{item.status},
#{item.delFlag}, #{item.createBy}, #{item.createTime},
#{item.updateBy}, #{item.createDept}
)
</foreach>
ON CONFLICT (sid) DO UPDATE SET
tenant_id = EXCLUDED.tenant_id,
mid = EXCLUDED.mid,
store_name = EXCLUDED.store_name,
seller_id = EXCLUDED.seller_id,
account_name = EXCLUDED.account_name,
seller_account_id = EXCLUDED.seller_account_id,
region = EXCLUDED.region,
country = EXCLUDED.country,
marketplace_id = EXCLUDED.marketplace_id,
has_ads_setting = EXCLUDED.has_ads_setting,
status = EXCLUDED.status,
del_flag = EXCLUDED.del_flag,
create_by = EXCLUDED.create_by,
create_time = EXCLUDED.create_time,
update_by = EXCLUDED.update_by,
create_dept = EXCLUDED.create_dept;
</insert>
</mapper>

View File

@ -4,7 +4,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-example</artifactId>
<artifactId>asinkj-biz</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
@ -22,6 +22,11 @@
<artifactId>asinkj-common-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.asinkj</groupId>
<artifactId>asinkj-common-sentinel</artifactId>
@ -104,6 +109,8 @@
<scope>test</scope>
</dependency>
</dependencies>
<build>

Some files were not shown because too many files have changed in this diff Show More