1
This commit is contained in:
7
pom.xml
7
pom.xml
@@ -35,6 +35,7 @@
|
|||||||
<logback.version>1.2.13</logback.version>
|
<logback.version>1.2.13</logback.version>
|
||||||
<spring-security.version>5.7.12</spring-security.version>
|
<spring-security.version>5.7.12</spring-security.version>
|
||||||
<spring-framework.version>5.3.39</spring-framework.version>
|
<spring-framework.version>5.3.39</spring-framework.version>
|
||||||
|
<rocketmq-spring.version>2.2.3</rocketmq-spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<!-- 依赖声明 -->
|
<!-- 依赖声明 -->
|
||||||
@@ -218,6 +219,12 @@
|
|||||||
<version>${ruoyi.version}</version>
|
<version>${ruoyi.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.rocketmq</groupId>
|
||||||
|
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||||
|
<version>${rocketmq-spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -14,6 +15,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
|
|||||||
*/
|
*/
|
||||||
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
|
@EnableAsync
|
||||||
public class RuoYiApplication
|
public class RuoYiApplication
|
||||||
{
|
{
|
||||||
public static void main(String[] args)
|
public static void main(String[] args)
|
||||||
|
|||||||
@@ -1,22 +1,32 @@
|
|||||||
package com.ruoyi.web.controller.common;
|
package com.ruoyi.web.controller.common;
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.ruoyi.common.core.controller.BaseController;
|
import com.ruoyi.common.annotation.Anonymous;
|
||||||
import com.ruoyi.common.core.domain.R;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.erp.request.IERPAccount;
|
||||||
|
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
|
||||||
|
import com.ruoyi.jarvis.service.erp.ErpAccountResolver;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开放平台回调接收端
|
* 闲管家开放平台推送回调(请在开放平台填写真实 URL)
|
||||||
* 注意:/product/receive 与 /order/receive 为示例路径,请在开放平台配置时使用你自己的正式回调地址
|
* 订单:建议 POST .../open/callback/order/receive
|
||||||
*/
|
*/
|
||||||
|
@Anonymous
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/open/callback")
|
@RequestMapping("/open/callback")
|
||||||
public class OpenCallbackController extends BaseController {
|
public class OpenCallbackController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ErpAccountResolver erpAccountResolver;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpGoofishOrderService erpGoofishOrderService;
|
||||||
|
|
||||||
@PostMapping("/product/receive")
|
@PostMapping("/product/receive")
|
||||||
public JSONObject receiveProductCallback(
|
public JSONObject receiveProductCallback(
|
||||||
@@ -25,7 +35,8 @@ public class OpenCallbackController extends BaseController {
|
|||||||
@RequestParam("sign") String sign,
|
@RequestParam("sign") String sign,
|
||||||
@RequestBody JSONObject body
|
@RequestBody JSONObject body
|
||||||
) {
|
) {
|
||||||
if (!verifySign(appid, timestamp, sign, body)) {
|
IERPAccount account = erpAccountResolver.resolveStrict(appid);
|
||||||
|
if (!verifySign(account, timestamp, sign, body)) {
|
||||||
JSONObject fail = new JSONObject();
|
JSONObject fail = new JSONObject();
|
||||||
fail.put("result", "fail");
|
fail.put("result", "fail");
|
||||||
fail.put("msg", "签名失败");
|
fail.put("msg", "签名失败");
|
||||||
@@ -44,26 +55,33 @@ public class OpenCallbackController extends BaseController {
|
|||||||
@RequestParam("sign") String sign,
|
@RequestParam("sign") String sign,
|
||||||
@RequestBody JSONObject body
|
@RequestBody JSONObject body
|
||||||
) {
|
) {
|
||||||
if (!verifySign(appid, timestamp, sign, body)) {
|
IERPAccount account = erpAccountResolver.resolveStrict(appid);
|
||||||
|
if (!verifySign(account, timestamp, sign, body)) {
|
||||||
JSONObject fail = new JSONObject();
|
JSONObject fail = new JSONObject();
|
||||||
fail.put("result", "fail");
|
fail.put("result", "fail");
|
||||||
fail.put("msg", "签名失败");
|
fail.put("msg", "签名失败");
|
||||||
return fail;
|
return fail;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
erpGoofishOrderService.publishOrProcessNotify(appid, timestamp, body);
|
||||||
|
} catch (Exception e) {
|
||||||
|
JSONObject fail = new JSONObject();
|
||||||
|
fail.put("result", "fail");
|
||||||
|
fail.put("msg", "入队异常");
|
||||||
|
return fail;
|
||||||
|
}
|
||||||
JSONObject ok = new JSONObject();
|
JSONObject ok = new JSONObject();
|
||||||
ok.put("result", "success");
|
ok.put("result", "success");
|
||||||
ok.put("msg", "接收成功");
|
ok.put("msg", "接收成功");
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean verifySign(String appid, Long timestamp, String sign, JSONObject body) {
|
private boolean verifySign(IERPAccount account, Long timestamp, String sign, JSONObject body) {
|
||||||
// TODO: 这里需要根据appid查出对应的 appKey/appSecret
|
if (account == null || StringUtils.isEmpty(sign)) {
|
||||||
// 为了示例,直接使用 ERPAccount.ACCOUNT_HUGE 的常量。生产请替换为从数据库/配置读取
|
return false;
|
||||||
String appKey = "1016208368633221";
|
}
|
||||||
String appSecret = "waLiRMgFcixLbcLjUSSwo370Hp1nBcBu";
|
|
||||||
|
|
||||||
String json = body == null ? "{}" : body.toJSONString();
|
String json = body == null ? "{}" : body.toJSONString();
|
||||||
String data = appKey + "," + md5(json) + "," + (timestamp == null ? 0 : timestamp) + "," + appSecret;
|
String data = account.getApiKey() + "," + md5(json) + "," + (timestamp == null ? 0 : timestamp) + "," + account.getApiKeySecret();
|
||||||
String local = md5(data);
|
String local = md5(data);
|
||||||
return StringUtils.equalsIgnoreCase(local, sign);
|
return StringUtils.equalsIgnoreCase(local, sign);
|
||||||
}
|
}
|
||||||
@@ -82,5 +100,3 @@ public class OpenCallbackController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,10 @@ import com.ruoyi.common.utils.StringUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import com.ruoyi.erp.request.ERPAccount;
|
import com.ruoyi.erp.request.ERPAccount;
|
||||||
|
import com.ruoyi.erp.request.IERPAccount;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import com.ruoyi.jarvis.service.erp.ErpAccountResolver;
|
||||||
import com.ruoyi.erp.request.ProductCreateRequest;
|
import com.ruoyi.erp.request.ProductCreateRequest;
|
||||||
import com.ruoyi.erp.request.ProductCategoryListQueryRequest;
|
import com.ruoyi.erp.request.ProductCategoryListQueryRequest;
|
||||||
import com.ruoyi.erp.request.ProductPropertyListQueryRequest;
|
import com.ruoyi.erp.request.ProductPropertyListQueryRequest;
|
||||||
@@ -20,6 +24,7 @@ import com.ruoyi.erp.request.ProductDownShelfRequest;
|
|||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import javax.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -37,12 +42,18 @@ public class ProductController extends BaseController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IOuterIdGeneratorService outerIdGeneratorService;
|
private IOuterIdGeneratorService outerIdGeneratorService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ErpAccountResolver erpAccountResolver;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpOpenConfigService erpOpenConfigService;
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ProductController.class);
|
private static final Logger log = LoggerFactory.getLogger(ProductController.class);
|
||||||
|
|
||||||
@PostMapping("/createByPromotion")
|
@PostMapping("/createByPromotion")
|
||||||
public R<?> createByPromotion(@RequestBody @Validated CreateProductFromPromotionRequest req) {
|
public R<?> createByPromotion(@RequestBody @Validated CreateProductFromPromotionRequest req) {
|
||||||
try {
|
try {
|
||||||
ERPAccount account = resolveAccount(req.getAppid());
|
IERPAccount account = resolveAccount(req.getAppid());
|
||||||
// 1) 组装 ERPShop
|
// 1) 组装 ERPShop
|
||||||
ERPShop erpShop = new ERPShop();
|
ERPShop erpShop = new ERPShop();
|
||||||
erpShop.setChannelCatid(req.getChannelCatId());
|
erpShop.setChannelCatid(req.getChannelCatId());
|
||||||
@@ -143,7 +154,7 @@ public class ProductController extends BaseController {
|
|||||||
@PostMapping("/publish")
|
@PostMapping("/publish")
|
||||||
public R<?> publish(@RequestBody @Validated PublishRequest req) {
|
public R<?> publish(@RequestBody @Validated PublishRequest req) {
|
||||||
try {
|
try {
|
||||||
ERPAccount account = resolveAccount(req.getAppid());
|
IERPAccount account = resolveAccount(req.getAppid());
|
||||||
ProductPublishRequest publishRequest = new ProductPublishRequest(account);
|
ProductPublishRequest publishRequest = new ProductPublishRequest(account);
|
||||||
publishRequest.setProductId(req.getProductId());
|
publishRequest.setProductId(req.getProductId());
|
||||||
publishRequest.setUserName(req.getUserName());
|
publishRequest.setUserName(req.getUserName());
|
||||||
@@ -344,10 +355,22 @@ public class ProductController extends BaseController {
|
|||||||
String name = firstNonBlank(row.getString("user_name"), row.getString("xy_name"), row.getString("username"), row.getString("nick"));
|
String name = firstNonBlank(row.getString("user_name"), row.getString("xy_name"), row.getString("username"), row.getString("nick"));
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
String label = name;
|
String label = name;
|
||||||
for (ERPAccount a : ERPAccount.values()) {
|
List<ErpOpenConfig> cfgs = erpOpenConfigService.selectEnabledOrderBySort();
|
||||||
if (name.equals(a.getXyName())) {
|
if (cfgs != null) {
|
||||||
label = name + "(" + a.getRemark() + ")";
|
for (ErpOpenConfig c : cfgs) {
|
||||||
break;
|
if (name.equals(c.getXyUserName())) {
|
||||||
|
String r = c.getRemark() != null ? c.getRemark() : c.getAppKey();
|
||||||
|
label = name + "(" + r + ")";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (label.equals(name)) {
|
||||||
|
for (ERPAccount a : ERPAccount.values()) {
|
||||||
|
if (name.equals(a.getXyName())) {
|
||||||
|
label = name + "(" + a.getRemark() + ")";
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
options.add(new Option(name, label));
|
options.add(new Option(name, label));
|
||||||
@@ -376,20 +399,24 @@ public class ProductController extends BaseController {
|
|||||||
@GetMapping("/ERPAccount")
|
@GetMapping("/ERPAccount")
|
||||||
public R<?> erpAccounts() {
|
public R<?> erpAccounts() {
|
||||||
java.util.List<Option> list = new java.util.ArrayList<>();
|
java.util.List<Option> list = new java.util.ArrayList<>();
|
||||||
|
List<ErpOpenConfig> cfgs = erpOpenConfigService.selectEnabledOrderBySort();
|
||||||
|
if (cfgs != null) {
|
||||||
|
for (ErpOpenConfig c : cfgs) {
|
||||||
|
String label = StringUtils.isNotEmpty(c.getRemark()) ? c.getRemark() : c.getXyUserName();
|
||||||
|
if (StringUtils.isEmpty(label)) {
|
||||||
|
label = c.getAppKey();
|
||||||
|
}
|
||||||
|
list.add(new Option(c.getAppKey(), "【配置】" + label));
|
||||||
|
}
|
||||||
|
}
|
||||||
for (ERPAccount a : ERPAccount.values()) {
|
for (ERPAccount a : ERPAccount.values()) {
|
||||||
// 仅显示备注作为 label,value 仍为 appid
|
list.add(new Option(a.getApiKey(), "【内置】" + a.getRemark()));
|
||||||
list.add(new Option(a.getApiKey(), a.getRemark()));
|
|
||||||
}
|
}
|
||||||
return R.ok(list);
|
return R.ok(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ERPAccount resolveAccount(String appid) {
|
private IERPAccount resolveAccount(String appid) {
|
||||||
if (appid != null && !appid.isEmpty()) {
|
return erpAccountResolver.resolve(appid);
|
||||||
for (ERPAccount a : ERPAccount.values()) {
|
|
||||||
if (a.getApiKey().equals(appid)) return a;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ERPAccount.ACCOUNT_HUGE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -558,7 +585,7 @@ public class ProductController extends BaseController {
|
|||||||
@PostMapping("/downShelf")
|
@PostMapping("/downShelf")
|
||||||
public R<?> downShelf(@RequestBody @Validated DownShelfRequest req) {
|
public R<?> downShelf(@RequestBody @Validated DownShelfRequest req) {
|
||||||
try {
|
try {
|
||||||
ERPAccount account = resolveAccount(req.getAppid());
|
IERPAccount account = resolveAccount(req.getAppid());
|
||||||
ProductDownShelfRequest downShelfRequest = new ProductDownShelfRequest(account);
|
ProductDownShelfRequest downShelfRequest = new ProductDownShelfRequest(account);
|
||||||
downShelfRequest.setProductId(req.getProductId());
|
downShelfRequest.setProductId(req.getProductId());
|
||||||
String resp = downShelfRequest.getResponseBody();
|
String resp = downShelfRequest.getResponseBody();
|
||||||
@@ -576,7 +603,7 @@ public class ProductController extends BaseController {
|
|||||||
@PostMapping("/batchPublish")
|
@PostMapping("/batchPublish")
|
||||||
public R<?> batchPublish(@RequestBody @Validated BatchPublishRequest req) {
|
public R<?> batchPublish(@RequestBody @Validated BatchPublishRequest req) {
|
||||||
try {
|
try {
|
||||||
ERPAccount account = resolveAccount(req.getAppid());
|
IERPAccount account = resolveAccount(req.getAppid());
|
||||||
List<Long> productIds = req.getProductIds();
|
List<Long> productIds = req.getProductIds();
|
||||||
|
|
||||||
if (productIds == null || productIds.isEmpty()) {
|
if (productIds == null || productIds.isEmpty()) {
|
||||||
@@ -651,7 +678,7 @@ public class ProductController extends BaseController {
|
|||||||
@PostMapping("/batchDownShelf")
|
@PostMapping("/batchDownShelf")
|
||||||
public R<?> batchDownShelf(@RequestBody @Validated BatchDownShelfRequest req) {
|
public R<?> batchDownShelf(@RequestBody @Validated BatchDownShelfRequest req) {
|
||||||
try {
|
try {
|
||||||
ERPAccount account = resolveAccount(req.getAppid());
|
IERPAccount account = resolveAccount(req.getAppid());
|
||||||
List<Long> productIds = req.getProductIds();
|
List<Long> productIds = req.getProductIds();
|
||||||
|
|
||||||
if (productIds == null || productIds.isEmpty()) {
|
if (productIds == null || productIds.isEmpty()) {
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package com.ruoyi.web.controller.jarvis;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
|
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/jarvis/erpGoofishOrder")
|
||||||
|
public class ErpGoofishOrderController extends BaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpGoofishOrderService erpGoofishOrderService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private JarvisGoofishProperties goofishProperties;
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(ErpGoofishOrder query) {
|
||||||
|
startPage();
|
||||||
|
List<ErpGoofishOrder> list = erpGoofishOrderService.selectList(query);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:query')")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public AjaxResult getInfo(@PathVariable Long id) {
|
||||||
|
return AjaxResult.success(erpGoofishOrderService.selectById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:edit')")
|
||||||
|
@Log(title = "闲管家拉单", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/pull/{appKey}")
|
||||||
|
public AjaxResult pullOne(@PathVariable String appKey, @RequestParam(value = "hours", required = false) Integer hours) {
|
||||||
|
int h = hours == null ? goofishProperties.getPullLookbackHours() : hours;
|
||||||
|
int n = erpGoofishOrderService.pullOrdersForAppKey(appKey, h);
|
||||||
|
Map<String, Object> data = new LinkedHashMap<>();
|
||||||
|
data.put("processedItems", n);
|
||||||
|
data.put("lookbackHours", h);
|
||||||
|
return AjaxResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:edit')")
|
||||||
|
@Log(title = "闲管家全量拉单", businessType = BusinessType.OTHER)
|
||||||
|
@PostMapping("/pullAll")
|
||||||
|
public AjaxResult pullAll(@RequestParam(value = "hours", required = false) Integer hours) {
|
||||||
|
int h = hours == null ? goofishProperties.getPullLookbackHours() : hours;
|
||||||
|
int n = erpGoofishOrderService.pullAllEnabled(h);
|
||||||
|
Map<String, Object> data = new LinkedHashMap<>();
|
||||||
|
data.put("processedItems", n);
|
||||||
|
data.put("lookbackHours", h);
|
||||||
|
return AjaxResult.success(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:edit')")
|
||||||
|
@Log(title = "闲管家订单详情刷新", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/refreshDetail/{id}")
|
||||||
|
public AjaxResult refreshDetail(@PathVariable Long id) {
|
||||||
|
erpGoofishOrderService.refreshDetail(id);
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpGoofishOrder:edit')")
|
||||||
|
@Log(title = "闲管家重试发货", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/retryShip/{id}")
|
||||||
|
public AjaxResult retryShip(@PathVariable Long id) {
|
||||||
|
erpGoofishOrderService.retryShip(id);
|
||||||
|
return AjaxResult.success();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.ruoyi.web.controller.jarvis;
|
||||||
|
|
||||||
|
import com.ruoyi.common.annotation.Log;
|
||||||
|
import com.ruoyi.common.core.controller.BaseController;
|
||||||
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
|
import com.ruoyi.common.core.page.TableDataInfo;
|
||||||
|
import com.ruoyi.common.enums.BusinessType;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/jarvis/erpOpenConfig")
|
||||||
|
public class ErpOpenConfigController extends BaseController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpOpenConfigService erpOpenConfigService;
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpOpenConfig:list')")
|
||||||
|
@GetMapping("/list")
|
||||||
|
public TableDataInfo list(ErpOpenConfig query) {
|
||||||
|
startPage();
|
||||||
|
List<ErpOpenConfig> list = erpOpenConfigService.selectList(query);
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpOpenConfig:query')")
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public AjaxResult getInfo(@PathVariable Long id) {
|
||||||
|
return AjaxResult.success(erpOpenConfigService.selectById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpOpenConfig:add')")
|
||||||
|
@Log(title = "闲管家应用配置", businessType = BusinessType.INSERT)
|
||||||
|
@PostMapping
|
||||||
|
public AjaxResult add(@RequestBody ErpOpenConfig row) {
|
||||||
|
return toAjax(erpOpenConfigService.insert(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpOpenConfig:edit')")
|
||||||
|
@Log(title = "闲管家应用配置", businessType = BusinessType.UPDATE)
|
||||||
|
@PutMapping
|
||||||
|
public AjaxResult edit(@RequestBody ErpOpenConfig row) {
|
||||||
|
return toAjax(erpOpenConfigService.update(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreAuthorize("@ss.hasPermi('jarvis:erpOpenConfig:remove')")
|
||||||
|
@Log(title = "闲管家应用配置", businessType = BusinessType.DELETE)
|
||||||
|
@DeleteMapping("/{ids}")
|
||||||
|
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||||
|
int n = 0;
|
||||||
|
if (ids != null) {
|
||||||
|
for (Long id : ids) {
|
||||||
|
n += erpOpenConfigService.deleteById(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return toAjax(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -254,5 +254,21 @@ tencent:
|
|||||||
# 刷新Token地址(用于通过refresh_token刷新access_token)
|
# 刷新Token地址(用于通过refresh_token刷新access_token)
|
||||||
refresh-token-url: https://docs.qq.com/oauth/v2/token
|
refresh-token-url: https://docs.qq.com/oauth/v2/token
|
||||||
|
|
||||||
|
# 闲管家订单:RocketMQ(配置后订单推送走 MQ;不配则走线程池异步)
|
||||||
|
#rocketmq:
|
||||||
|
# name-server: 127.0.0.1:9876
|
||||||
|
# producer:
|
||||||
|
# group: jarvis-goofish-producer
|
||||||
|
# send-message-timeout: 3000
|
||||||
|
|
||||||
|
jarvis:
|
||||||
|
goofish-order:
|
||||||
|
mq-topic: jarvis-goofish-erp-order
|
||||||
|
consumer-group: jarvis-goofish-order-consumer
|
||||||
|
pull-lookback-hours: 72
|
||||||
|
pull-cron: "0 0/15 * * * ?"
|
||||||
|
auto-ship-cron: "0 2/10 * * * ?"
|
||||||
|
pull-max-pages-per-shop: 30
|
||||||
|
auto-ship-batch-size: 20
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
63
ruoyi-admin/src/main/resources/sql/erp_goofish_init.sql
Normal file
63
ruoyi-admin/src/main/resources/sql/erp_goofish_init.sql
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
-- 闲管家开放平台:应用配置中心 + ERP 订单落库(执行前请备份)
|
||||||
|
-- 说明:菜单需在「系统管理-菜单管理」中自行新增,组件路径示例:
|
||||||
|
-- 配置中心 system/goofish/erpOpenConfig/index
|
||||||
|
-- 订单跟踪 system/goofish/erpGoofishOrder/index
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS erp_open_config (
|
||||||
|
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
app_key varchar(64) NOT NULL COMMENT '开放平台 AppKey(appid)',
|
||||||
|
app_secret varchar(128) NOT NULL COMMENT '开放平台 AppSecret',
|
||||||
|
xy_user_name varchar(128) DEFAULT NULL COMMENT '默认闲鱼会员名(展示)',
|
||||||
|
express_code varchar(64) DEFAULT NULL COMMENT '发货用快递公司编码(日日顺,以开放平台「查询快递公司」为准)',
|
||||||
|
express_name varchar(64) DEFAULT NULL COMMENT '快递公司名称(展示)',
|
||||||
|
status char(1) NOT NULL DEFAULT '0' COMMENT '0正常 1停用',
|
||||||
|
order_num int(11) NOT NULL DEFAULT 0 COMMENT '排序(小优先)',
|
||||||
|
create_by varchar(64) DEFAULT '',
|
||||||
|
create_time datetime DEFAULT NULL,
|
||||||
|
update_by varchar(64) DEFAULT '',
|
||||||
|
update_time datetime DEFAULT NULL,
|
||||||
|
remark varchar(500) DEFAULT NULL COMMENT '备注',
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
UNIQUE KEY uk_app_key (app_key)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='闲管家开放平台应用配置';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS erp_goofish_order (
|
||||||
|
id bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
|
||||||
|
app_key varchar(64) NOT NULL COMMENT 'AppKey',
|
||||||
|
seller_id bigint(20) DEFAULT NULL COMMENT '商家ID',
|
||||||
|
user_name varchar(128) DEFAULT NULL COMMENT '闲鱼会员名',
|
||||||
|
order_no varchar(64) NOT NULL COMMENT '闲鱼订单号',
|
||||||
|
order_type int(11) DEFAULT NULL COMMENT '订单类型',
|
||||||
|
order_status int(11) DEFAULT NULL COMMENT '订单状态(推送/列表)',
|
||||||
|
refund_status int(11) DEFAULT NULL COMMENT '退款状态',
|
||||||
|
modify_time bigint(20) DEFAULT NULL COMMENT '订单更新时间(秒)',
|
||||||
|
product_id bigint(20) DEFAULT NULL COMMENT '管家商品ID',
|
||||||
|
item_id bigint(20) DEFAULT NULL COMMENT '闲鱼商品ID',
|
||||||
|
detail_json longtext COMMENT '订单详情接口全量 JSON',
|
||||||
|
last_notify_json longtext COMMENT '最近一次推送原文 JSON',
|
||||||
|
jd_order_id bigint(20) DEFAULT NULL COMMENT '关联 jd_order.id(第三方单号=闲鱼单号)',
|
||||||
|
local_waybill_no varchar(128) DEFAULT NULL COMMENT '本地物流扫描得到的运单号',
|
||||||
|
ship_status tinyint(4) NOT NULL DEFAULT '0' COMMENT '0未发货 1已调用发货成功 2发货失败',
|
||||||
|
ship_error varchar(500) DEFAULT NULL COMMENT '发货失败原因',
|
||||||
|
ship_time datetime DEFAULT NULL COMMENT '发货调用成功时间',
|
||||||
|
ship_express_code varchar(64) DEFAULT NULL COMMENT '实际发货使用的快递编码',
|
||||||
|
create_time datetime DEFAULT NULL,
|
||||||
|
update_time datetime DEFAULT NULL,
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
UNIQUE KEY uk_app_order (app_key, order_no),
|
||||||
|
KEY idx_jd_order (jd_order_id),
|
||||||
|
KEY idx_order_status (order_status),
|
||||||
|
KEY idx_modify_time (modify_time)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='闲管家 ERP 订单(全量跟踪)';
|
||||||
|
|
||||||
|
-- 可选:从旧枚举迁入两条示例(密钥请上线后立即修改)
|
||||||
|
-- INSERT INTO erp_open_config (app_key,app_secret,xy_user_name,remark,express_code,express_name,status,order_num)
|
||||||
|
-- VALUES ('1016208368633221','***','余生请多关照66','海尔胡歌',NULL,'日日顺','0',1);
|
||||||
|
|
||||||
|
-- 若依菜单(在「菜单管理」手工添加时参考)
|
||||||
|
-- 父菜单:系统管理下新增目录「闲管家ERP」
|
||||||
|
-- 子菜单1:组件 system/goofish/erpOpenConfig/index 权限前缀 jarvis:erpOpenConfig
|
||||||
|
-- 子菜单2:组件 system/goofish/erpGoofishOrder/index 权限前缀 jarvis:erpGoofishOrder
|
||||||
|
-- 按钮权限示例:
|
||||||
|
-- jarvis:erpOpenConfig:list,query,add,edit,remove
|
||||||
|
-- jarvis:erpGoofishOrder:list,query,edit
|
||||||
@@ -28,6 +28,11 @@
|
|||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.rocketmq</groupId>
|
||||||
|
<artifactId>rocketmq-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 授权列表查询请求(示例类)
|
* 授权列表查询请求(示例类)
|
||||||
*/
|
*/
|
||||||
public class AuthorizeListQueryRequest extends ERPRequestBase {
|
public class AuthorizeListQueryRequest extends ERPRequestBase {
|
||||||
public AuthorizeListQueryRequest(ERPAccount erpAccount) {
|
public AuthorizeListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/user/authorize/list", erpAccount);
|
super("https://open.goofish.pro/api/open/user/authorize/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import lombok.Getter;
|
|||||||
* @description:ERP账户枚举类
|
* @description:ERP账户枚举类
|
||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
public enum ERPAccount {
|
public enum ERPAccount implements IERPAccount {
|
||||||
// 胡歌1016208368633221
|
// 胡歌1016208368633221
|
||||||
ACCOUNT_HUGE("1016208368633221", "waLiRMgFcixLbcLjUSSwo370Hp1nBcBu","余生请多关照66","海尔胡歌"),
|
ACCOUNT_HUGE("1016208368633221", "waLiRMgFcixLbcLjUSSwo370Hp1nBcBu","余生请多关照66","海尔胡歌"),
|
||||||
// 刘强东anotherApiKey
|
// 刘强东anotherApiKey
|
||||||
|
|||||||
@@ -18,12 +18,12 @@ public abstract class ERPRequestBase {
|
|||||||
|
|
||||||
protected String url;
|
protected String url;
|
||||||
protected String sign;
|
protected String sign;
|
||||||
protected ERPAccount erpAccount;
|
protected IERPAccount erpAccount;
|
||||||
@Setter
|
@Setter
|
||||||
protected JSONObject requestBody;
|
protected JSONObject requestBody;
|
||||||
protected long timestamp; // 统一时间戳字段
|
protected long timestamp; // 统一时间戳字段
|
||||||
|
|
||||||
public ERPRequestBase(String url, ERPAccount erpAccount) {
|
public ERPRequestBase(String url, IERPAccount erpAccount) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.erpAccount = erpAccount;
|
this.erpAccount = erpAccount;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ package com.ruoyi.erp.request;
|
|||||||
* 对应接口:POST /api/open/express/companies
|
* 对应接口:POST /api/open/express/companies
|
||||||
*/
|
*/
|
||||||
public class ExpressCompaniesQueryRequest extends ERPRequestBase {
|
public class ExpressCompaniesQueryRequest extends ERPRequestBase {
|
||||||
public ExpressCompaniesQueryRequest(ERPAccount erpAccount) {
|
public ExpressCompaniesQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/express/companies", erpAccount);
|
super("https://open.goofish.pro/api/open/express/companies", erpAccount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ruoyi.erp.request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家开放平台凭证({@link ERPAccount} 或库表配置行均可实现本接口)
|
||||||
|
*/
|
||||||
|
public interface IERPAccount {
|
||||||
|
|
||||||
|
String getApiKey();
|
||||||
|
|
||||||
|
String getApiKeySecret();
|
||||||
|
|
||||||
|
/** 闲鱼会员名(授权维度展示用,可为空) */
|
||||||
|
String getXyName();
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/order/detail
|
* 对应接口:POST /api/open/order/detail
|
||||||
*/
|
*/
|
||||||
public class OrderDetailQueryRequest extends ERPRequestBase {
|
public class OrderDetailQueryRequest extends ERPRequestBase {
|
||||||
public OrderDetailQueryRequest(ERPAccount erpAccount) {
|
public OrderDetailQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/order/detail", erpAccount);
|
super("https://open.goofish.pro/api/open/order/detail", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/order/kam/list
|
* 对应接口:POST /api/open/order/kam/list
|
||||||
*/
|
*/
|
||||||
public class OrderKamListQueryRequest extends ERPRequestBase {
|
public class OrderKamListQueryRequest extends ERPRequestBase {
|
||||||
public OrderKamListQueryRequest(ERPAccount erpAccount) {
|
public OrderKamListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/order/kam/list", erpAccount);
|
super("https://open.goofish.pro/api/open/order/kam/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/order/list
|
* 对应接口:POST /api/open/order/list
|
||||||
*/
|
*/
|
||||||
public class OrderListQueryRequest extends ERPRequestBase {
|
public class OrderListQueryRequest extends ERPRequestBase {
|
||||||
public OrderListQueryRequest(ERPAccount erpAccount) {
|
public OrderListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/order/list", erpAccount);
|
super("https://open.goofish.pro/api/open/order/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/order/modify/price
|
* 对应接口:POST /api/open/order/modify/price
|
||||||
*/
|
*/
|
||||||
public class OrderModifyPriceRequest extends ERPRequestBase {
|
public class OrderModifyPriceRequest extends ERPRequestBase {
|
||||||
public OrderModifyPriceRequest(ERPAccount erpAccount) {
|
public OrderModifyPriceRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/order/modify/price", erpAccount);
|
super("https://open.goofish.pro/api/open/order/modify/price", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/order/ship
|
* 对应接口:POST /api/open/order/ship
|
||||||
*/
|
*/
|
||||||
public class OrderShipRequest extends ERPRequestBase {
|
public class OrderShipRequest extends ERPRequestBase {
|
||||||
public OrderShipRequest(ERPAccount erpAccount) {
|
public OrderShipRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/order/ship", erpAccount);
|
super("https://open.goofish.pro/api/open/order/ship", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import java.util.List;
|
|||||||
* 限制:每批次最多50个商品
|
* 限制:每批次最多50个商品
|
||||||
*/
|
*/
|
||||||
public class ProductBatchCreateRequest extends ERPRequestBase {
|
public class ProductBatchCreateRequest extends ERPRequestBase {
|
||||||
public ProductBatchCreateRequest(ERPAccount erpAccount) {
|
public ProductBatchCreateRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/batchCreate", erpAccount);
|
super("https://open.goofish.pro/api/open/product/batchCreate", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* - flash_sale_type(选填):闲鱼特卖类型
|
* - flash_sale_type(选填):闲鱼特卖类型
|
||||||
*/
|
*/
|
||||||
public class ProductCategoryListQueryRequest extends ERPRequestBase {
|
public class ProductCategoryListQueryRequest extends ERPRequestBase {
|
||||||
public ProductCategoryListQueryRequest(ERPAccount erpAccount) {
|
public ProductCategoryListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/category/list", erpAccount);
|
super("https://open.goofish.pro/api/open/product/category/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class ProductCreateRequest extends ERPRequestBase {
|
|||||||
private final JSONArray publishShop = new JSONArray();
|
private final JSONArray publishShop = new JSONArray();
|
||||||
private final JSONArray skuItems = new JSONArray();
|
private final JSONArray skuItems = new JSONArray();
|
||||||
|
|
||||||
public ProductCreateRequest(ERPAccount erpAccount) {
|
public ProductCreateRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/create", erpAccount);
|
super("https://open.goofish.pro/api/open/product/create", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/product/delete
|
* 对应接口:POST /api/open/product/delete
|
||||||
*/
|
*/
|
||||||
public class ProductDeleteRequest extends ERPRequestBase {
|
public class ProductDeleteRequest extends ERPRequestBase {
|
||||||
public ProductDeleteRequest(ERPAccount erpAccount) {
|
public ProductDeleteRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/delete", erpAccount);
|
super("https://open.goofish.pro/api/open/product/delete", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* - product_id(必填):管家商品ID
|
* - product_id(必填):管家商品ID
|
||||||
*/
|
*/
|
||||||
public class ProductDetailQueryRequest extends ERPRequestBase {
|
public class ProductDetailQueryRequest extends ERPRequestBase {
|
||||||
public ProductDetailQueryRequest(ERPAccount erpAccount) {
|
public ProductDetailQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/detail", erpAccount);
|
super("https://open.goofish.pro/api/open/product/detail", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/product/downShelf
|
* 对应接口:POST /api/open/product/downShelf
|
||||||
*/
|
*/
|
||||||
public class ProductDownShelfRequest extends ERPRequestBase {
|
public class ProductDownShelfRequest extends ERPRequestBase {
|
||||||
public ProductDownShelfRequest(ERPAccount erpAccount) {
|
public ProductDownShelfRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/downShelf", erpAccount);
|
super("https://open.goofish.pro/api/open/product/downShelf", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class ProductEditRequest extends ERPRequestBase {
|
|||||||
private final JSONArray publishShop = new JSONArray();
|
private final JSONArray publishShop = new JSONArray();
|
||||||
private final JSONArray skuItems = new JSONArray();
|
private final JSONArray skuItems = new JSONArray();
|
||||||
|
|
||||||
public ProductEditRequest(ERPAccount erpAccount) {
|
public ProductEditRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/edit", erpAccount);
|
super("https://open.goofish.pro/api/open/product/edit", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/product/edit/stock
|
* 对应接口:POST /api/open/product/edit/stock
|
||||||
*/
|
*/
|
||||||
public class ProductEditStockRequest extends ERPRequestBase {
|
public class ProductEditStockRequest extends ERPRequestBase {
|
||||||
public ProductEditStockRequest(ERPAccount erpAccount) {
|
public ProductEditStockRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/edit/stock", erpAccount);
|
super("https://open.goofish.pro/api/open/product/edit/stock", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package com.ruoyi.erp.request;
|
|||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
|
||||||
public class ProductListQueryRequest extends ERPRequestBase {
|
public class ProductListQueryRequest extends ERPRequestBase {
|
||||||
public ProductListQueryRequest(ERPAccount erpAccount) {
|
public ProductListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/list", erpAccount);
|
super("https://open.goofish.pro/api/open/product/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* - sub_property_id(选填):属性值ID(用于二级属性查询)
|
* - sub_property_id(选填):属性值ID(用于二级属性查询)
|
||||||
*/
|
*/
|
||||||
public class ProductPropertyListQueryRequest extends ERPRequestBase {
|
public class ProductPropertyListQueryRequest extends ERPRequestBase {
|
||||||
public ProductPropertyListQueryRequest(ERPAccount erpAccount) {
|
public ProductPropertyListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/pv/list", erpAccount);
|
super("https://open.goofish.pro/api/open/product/pv/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import com.alibaba.fastjson2.JSONObject;
|
|||||||
* 对应接口:POST /api/open/product/publish
|
* 对应接口:POST /api/open/product/publish
|
||||||
*/
|
*/
|
||||||
public class ProductPublishRequest extends ERPRequestBase {
|
public class ProductPublishRequest extends ERPRequestBase {
|
||||||
public ProductPublishRequest(ERPAccount erpAccount) {
|
public ProductPublishRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/publish", erpAccount);
|
super("https://open.goofish.pro/api/open/product/publish", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import java.util.Collection;
|
|||||||
* - product_id(必填):管家商品ID数组,最多100个
|
* - product_id(必填):管家商品ID数组,最多100个
|
||||||
*/
|
*/
|
||||||
public class ProductSkuListQueryRequest extends ERPRequestBase {
|
public class ProductSkuListQueryRequest extends ERPRequestBase {
|
||||||
public ProductSkuListQueryRequest(ERPAccount erpAccount) {
|
public ProductSkuListQueryRequest(IERPAccount erpAccount) {
|
||||||
super("https://open.goofish.pro/api/open/product/sku/list", erpAccount);
|
super("https://open.goofish.pro/api/open/product/sku/list", erpAccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ruoyi.jarvis.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class GoofishAsyncConfig {
|
||||||
|
|
||||||
|
@Bean("goofishTaskExecutor")
|
||||||
|
public Executor goofishTaskExecutor() {
|
||||||
|
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||||
|
executor.setCorePoolSize(2);
|
||||||
|
executor.setMaxPoolSize(8);
|
||||||
|
executor.setQueueCapacity(500);
|
||||||
|
executor.setThreadNamePrefix("goofish-");
|
||||||
|
executor.initialize();
|
||||||
|
return executor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.ruoyi.jarvis.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家订单:MQ 主题、定时拉单与自动发货调度
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "jarvis.goofish-order")
|
||||||
|
public class JarvisGoofishProperties {
|
||||||
|
|
||||||
|
/** RocketMQ Topic(需配置 rocketmq.name-server 后生效) */
|
||||||
|
private String mqTopic = "jarvis-goofish-erp-order";
|
||||||
|
|
||||||
|
private String consumerGroup = "jarvis-goofish-order-consumer";
|
||||||
|
|
||||||
|
/** 回溯拉单小时数 */
|
||||||
|
private int pullLookbackHours = 72;
|
||||||
|
|
||||||
|
/** 拉单定时 cron */
|
||||||
|
private String pullCron = "0 0/15 * * * ?";
|
||||||
|
|
||||||
|
/** 同步运单 + 自动发货 cron */
|
||||||
|
private String autoShipCron = "0 2/10 * * * ?";
|
||||||
|
|
||||||
|
/** 单次拉单每店最大页数防护 */
|
||||||
|
private int pullMaxPagesPerShop = 30;
|
||||||
|
|
||||||
|
private int autoShipBatchSize = 20;
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.ruoyi.jarvis.domain;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家 ERP 订单(推送 + 拉单 + 详情全量)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ErpGoofishOrder {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String appKey;
|
||||||
|
private Long sellerId;
|
||||||
|
private String userName;
|
||||||
|
private String orderNo;
|
||||||
|
private Integer orderType;
|
||||||
|
private Integer orderStatus;
|
||||||
|
private Integer refundStatus;
|
||||||
|
private Long modifyTime;
|
||||||
|
private Long productId;
|
||||||
|
private Long itemId;
|
||||||
|
private String detailJson;
|
||||||
|
private String lastNotifyJson;
|
||||||
|
private Long jdOrderId;
|
||||||
|
private String localWaybillNo;
|
||||||
|
/** 0未发货 1成功 2失败 */
|
||||||
|
private Integer shipStatus;
|
||||||
|
private String shipError;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date shipTime;
|
||||||
|
private String shipExpressCode;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date createTime;
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/** 联查:第三方单号(jd_order) */
|
||||||
|
private String jdThirdPartyOrderNo;
|
||||||
|
/** 联查:内部备注单号 */
|
||||||
|
private String jdRemark;
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.ruoyi.jarvis.domain;
|
||||||
|
|
||||||
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
|
import com.ruoyi.erp.request.IERPAccount;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家开放平台应用配置(配置中心)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class ErpOpenConfig extends BaseEntity implements IERPAccount {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
private String appKey;
|
||||||
|
private String appSecret;
|
||||||
|
private String xyUserName;
|
||||||
|
/** 发货:快递公司编码(如日日顺,需与开放平台一致) */
|
||||||
|
private String expressCode;
|
||||||
|
private String expressName;
|
||||||
|
private String status;
|
||||||
|
private Integer orderNum;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getApiKey() {
|
||||||
|
return appKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getApiKeySecret() {
|
||||||
|
return appSecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getXyName() {
|
||||||
|
return xyUserName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.ruoyi.jarvis.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class GoofishNotifyMessage {
|
||||||
|
private String appid;
|
||||||
|
private Long timestamp;
|
||||||
|
private String body;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ruoyi.jarvis.mapper;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ErpGoofishOrderMapper {
|
||||||
|
|
||||||
|
ErpGoofishOrder selectById(Long id);
|
||||||
|
|
||||||
|
ErpGoofishOrder selectByAppKeyAndOrderNo(@Param("appKey") String appKey, @Param("orderNo") String orderNo);
|
||||||
|
|
||||||
|
List<ErpGoofishOrder> selectList(ErpGoofishOrder query);
|
||||||
|
|
||||||
|
int insert(ErpGoofishOrder row);
|
||||||
|
|
||||||
|
int update(ErpGoofishOrder row);
|
||||||
|
|
||||||
|
List<ErpGoofishOrder> selectPendingShip(@Param("limit") int limit);
|
||||||
|
|
||||||
|
int resetShipForRetry(@Param("id") Long id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package com.ruoyi.jarvis.mapper;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ErpOpenConfigMapper {
|
||||||
|
|
||||||
|
ErpOpenConfig selectById(Long id);
|
||||||
|
|
||||||
|
ErpOpenConfig selectByAppKey(@Param("appKey") String appKey);
|
||||||
|
|
||||||
|
List<ErpOpenConfig> selectList(ErpOpenConfig query);
|
||||||
|
|
||||||
|
List<ErpOpenConfig> selectEnabledOrderBySort();
|
||||||
|
|
||||||
|
int insert(ErpOpenConfig row);
|
||||||
|
|
||||||
|
int update(ErpOpenConfig row);
|
||||||
|
|
||||||
|
int deleteById(Long id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.ruoyi.jarvis.mq;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.jarvis.dto.GoofishNotifyMessage;
|
||||||
|
import com.ruoyi.jarvis.service.goofish.GoofishNotifyAsyncFacade;
|
||||||
|
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家订单推送异步消费(需配置 rocketmq.name-server)
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ConditionalOnProperty(name = "rocketmq.name-server")
|
||||||
|
@RocketMQMessageListener(
|
||||||
|
nameServer = "${rocketmq.name-server}",
|
||||||
|
topic = "${jarvis.goofish-order.mq-topic:jarvis-goofish-erp-order}",
|
||||||
|
consumerGroup = "${jarvis.goofish-order.consumer-group:jarvis-goofish-order-consumer}"
|
||||||
|
)
|
||||||
|
public class GoofishOrderNotifyConsumer implements RocketMQListener<String> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GoofishNotifyAsyncFacade goofishNotifyAsyncFacade;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessage(String message) {
|
||||||
|
GoofishNotifyMessage m = JSON.parseObject(message, GoofishNotifyMessage.class);
|
||||||
|
if (m == null || m.getAppid() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONObject body = m.getBody() == null ? new JSONObject() : JSON.parseObject(m.getBody());
|
||||||
|
if (body == null) {
|
||||||
|
body = new JSONObject();
|
||||||
|
}
|
||||||
|
goofishNotifyAsyncFacade.afterNotify(m.getAppid(), body);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.ruoyi.jarvis.service;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface IErpGoofishOrderService {
|
||||||
|
|
||||||
|
void publishOrProcessNotify(String appid, Long timestamp, JSONObject body);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MQ 消费者或线程池:写库、拉详情、关联京东单、同步运单、尝试发货
|
||||||
|
*/
|
||||||
|
void asyncPipelineAfterNotify(String appid, JSONObject notifyBody);
|
||||||
|
|
||||||
|
List<ErpGoofishOrder> selectList(ErpGoofishOrder query);
|
||||||
|
|
||||||
|
ErpGoofishOrder selectById(Long id);
|
||||||
|
|
||||||
|
int pullOrdersForAppKey(String appKey, int lookbackHours);
|
||||||
|
|
||||||
|
int pullAllEnabled(int lookbackHours);
|
||||||
|
|
||||||
|
void refreshDetail(Long id);
|
||||||
|
|
||||||
|
void retryShip(Long id);
|
||||||
|
|
||||||
|
int syncWaybillAndTryShipBatch(int limit);
|
||||||
|
|
||||||
|
void applyListOrNotifyItem(String appKey, JSONObject item, String lastNotifyJson);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.ruoyi.jarvis.service;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface IErpOpenConfigService {
|
||||||
|
|
||||||
|
ErpOpenConfig selectById(Long id);
|
||||||
|
|
||||||
|
ErpOpenConfig selectByAppKey(String appKey);
|
||||||
|
|
||||||
|
ErpOpenConfig selectFirstEnabled();
|
||||||
|
|
||||||
|
List<ErpOpenConfig> selectList(ErpOpenConfig query);
|
||||||
|
|
||||||
|
List<ErpOpenConfig> selectEnabledOrderBySort();
|
||||||
|
|
||||||
|
int insert(ErpOpenConfig row);
|
||||||
|
|
||||||
|
int update(ErpOpenConfig row);
|
||||||
|
|
||||||
|
int deleteById(Long id);
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.ruoyi.jarvis.service.erp;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.erp.request.ERPAccount;
|
||||||
|
import com.ruoyi.erp.request.IERPAccount;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class ErpAccountResolver {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpOpenConfigService erpOpenConfigService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优先库表启用配置,其次兼容历史枚举,最后默认胡歌
|
||||||
|
*/
|
||||||
|
public IERPAccount resolve(String appid) {
|
||||||
|
if (StringUtils.isNotEmpty(appid)) {
|
||||||
|
ErpOpenConfig cfg = erpOpenConfigService.selectByAppKey(appid.trim());
|
||||||
|
if (cfg != null && "0".equals(cfg.getStatus())) {
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
for (ERPAccount a : ERPAccount.values()) {
|
||||||
|
if (a.getApiKey().equals(appid.trim())) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ErpOpenConfig first = erpOpenConfigService.selectFirstEnabled();
|
||||||
|
if (first != null) {
|
||||||
|
return first;
|
||||||
|
}
|
||||||
|
return ERPAccount.ACCOUNT_HUGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 校验回调签名时须严格对应 appid,不允许回落到默认账号 */
|
||||||
|
public IERPAccount resolveStrict(String appid) {
|
||||||
|
if (StringUtils.isEmpty(appid)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ErpOpenConfig cfg = erpOpenConfigService.selectByAppKey(appid.trim());
|
||||||
|
if (cfg != null && "0".equals(cfg.getStatus())) {
|
||||||
|
return cfg;
|
||||||
|
}
|
||||||
|
for (ERPAccount a : ERPAccount.values()) {
|
||||||
|
if (a.getApiKey().equals(appid.trim())) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.ruoyi.jarvis.service.goofish;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import org.springframework.scheduling.annotation.Async;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class GoofishNotifyAsyncFacade {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GoofishOrderPipeline goofishOrderPipeline;
|
||||||
|
|
||||||
|
@Async("goofishTaskExecutor")
|
||||||
|
public void afterNotify(String appid, JSONObject body) {
|
||||||
|
goofishOrderPipeline.runFullPipeline(appid, body);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,479 @@
|
|||||||
|
package com.ruoyi.jarvis.service.goofish;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.erp.request.AuthorizeListQueryRequest;
|
||||||
|
import com.ruoyi.erp.request.IERPAccount;
|
||||||
|
import com.ruoyi.erp.request.OrderDetailQueryRequest;
|
||||||
|
import com.ruoyi.erp.request.OrderListQueryRequest;
|
||||||
|
import com.ruoyi.erp.request.OrderShipRequest;
|
||||||
|
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.domain.JDOrder;
|
||||||
|
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
|
||||||
|
import com.ruoyi.jarvis.service.IJDOrderService;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import com.ruoyi.jarvis.service.erp.ErpAccountResolver;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
/**
|
||||||
|
* 闲管家:推送/拉单后的落库、详情、关联京东单、同步运单、发货
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class GoofishOrderPipeline {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GoofishOrderPipeline.class);
|
||||||
|
private static final String REDIS_WAYBILL_KEY_PREFIX = "logistics:waybill:order:";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ErpGoofishOrderMapper erpGoofishOrderMapper;
|
||||||
|
@Resource
|
||||||
|
private ErpAccountResolver erpAccountResolver;
|
||||||
|
@Resource
|
||||||
|
private IErpOpenConfigService erpOpenConfigService;
|
||||||
|
@Resource
|
||||||
|
private IJDOrderService jdOrderService;
|
||||||
|
@Resource
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
@Resource
|
||||||
|
private JarvisGoofishProperties goofishProperties;
|
||||||
|
|
||||||
|
public void runFullPipeline(String appid, JSONObject notifyBody) {
|
||||||
|
try {
|
||||||
|
ErpGoofishOrder row = upsertFromNotify(appid, notifyBody, notifyBody.toJSONString());
|
||||||
|
tryLinkJdOrder(row);
|
||||||
|
refreshDetail(row);
|
||||||
|
syncWaybillFromRedis(row);
|
||||||
|
tryAutoShip(row);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("闲管家订单流水线异常 appid={} body={}", appid, notifyBody, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void applyListOrNotifyItem(String appKey, JSONObject item, String lastNotifyJson) {
|
||||||
|
if (item == null || StringUtils.isEmpty(appKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ErpGoofishOrder row = upsertFromNotify(appKey, item, lastNotifyJson);
|
||||||
|
tryLinkJdOrder(row);
|
||||||
|
refreshDetail(row);
|
||||||
|
syncWaybillFromRedis(row);
|
||||||
|
tryAutoShip(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErpGoofishOrder upsertFromNotify(String appKey, JSONObject body, String lastNotifyJson) {
|
||||||
|
Date now = DateUtils.getNowDate();
|
||||||
|
String orderNo = body.getString("order_no");
|
||||||
|
if (StringUtils.isEmpty(orderNo)) {
|
||||||
|
throw new IllegalArgumentException("缺少 order_no");
|
||||||
|
}
|
||||||
|
ErpGoofishOrder existing = erpGoofishOrderMapper.selectByAppKeyAndOrderNo(appKey, orderNo);
|
||||||
|
ErpGoofishOrder e = new ErpGoofishOrder();
|
||||||
|
e.setAppKey(appKey);
|
||||||
|
e.setSellerId(body.getLong("seller_id"));
|
||||||
|
e.setUserName(body.getString("user_name"));
|
||||||
|
e.setOrderNo(orderNo);
|
||||||
|
e.setOrderType(body.getInteger("order_type"));
|
||||||
|
e.setOrderStatus(body.getInteger("order_status"));
|
||||||
|
e.setRefundStatus(body.getInteger("refund_status"));
|
||||||
|
e.setModifyTime(body.getLong("modify_time"));
|
||||||
|
e.setProductId(body.getLong("product_id"));
|
||||||
|
e.setItemId(body.getLong("item_id"));
|
||||||
|
e.setLastNotifyJson(lastNotifyJson);
|
||||||
|
e.setUpdateTime(now);
|
||||||
|
if (existing == null) {
|
||||||
|
e.setCreateTime(now);
|
||||||
|
if (e.getShipStatus() == null) {
|
||||||
|
e.setShipStatus(0);
|
||||||
|
}
|
||||||
|
erpGoofishOrderMapper.insert(e);
|
||||||
|
return erpGoofishOrderMapper.selectByAppKeyAndOrderNo(appKey, orderNo);
|
||||||
|
}
|
||||||
|
e.setId(existing.getId());
|
||||||
|
e.setDetailJson(existing.getDetailJson());
|
||||||
|
e.setJdOrderId(existing.getJdOrderId());
|
||||||
|
e.setLocalWaybillNo(existing.getLocalWaybillNo());
|
||||||
|
e.setShipStatus(existing.getShipStatus());
|
||||||
|
e.setShipTime(existing.getShipTime());
|
||||||
|
e.setShipError(existing.getShipError());
|
||||||
|
e.setShipExpressCode(existing.getShipExpressCode());
|
||||||
|
erpGoofishOrderMapper.update(e);
|
||||||
|
return erpGoofishOrderMapper.selectByAppKeyAndOrderNo(appKey, orderNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryLinkJdOrder(ErpGoofishOrder row) {
|
||||||
|
if (row == null || row.getId() == null || row.getJdOrderId() != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String orderNo = row.getOrderNo();
|
||||||
|
if (StringUtils.isEmpty(orderNo)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JDOrder jd = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo);
|
||||||
|
if (jd == null || jd.getId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ErpGoofishOrder patch = new ErpGoofishOrder();
|
||||||
|
patch.setId(row.getId());
|
||||||
|
patch.setJdOrderId(jd.getId());
|
||||||
|
patch.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
erpGoofishOrderMapper.update(patch);
|
||||||
|
row.setJdOrderId(jd.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshDetail(ErpGoofishOrder row) {
|
||||||
|
if (row == null || row.getId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
IERPAccount cred = erpAccountResolver.resolve(row.getAppKey());
|
||||||
|
OrderDetailQueryRequest req = new OrderDetailQueryRequest(cred);
|
||||||
|
req.setOrderNo(row.getOrderNo());
|
||||||
|
String resp = req.getResponseBody();
|
||||||
|
ErpGoofishOrder patch = new ErpGoofishOrder();
|
||||||
|
patch.setId(row.getId());
|
||||||
|
patch.setDetailJson(resp);
|
||||||
|
patch.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
erpGoofishOrderMapper.update(patch);
|
||||||
|
row.setDetailJson(resp);
|
||||||
|
JSONObject jo = JSON.parseObject(resp);
|
||||||
|
if (jo != null && jo.getIntValue("code") == 0) {
|
||||||
|
JSONObject data = jo.getJSONObject("data");
|
||||||
|
if (data != null) {
|
||||||
|
mergeSummaryFromDetail(row, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("拉取闲管家订单详情失败 id={} orderNo={} err={}", row.getId(), row.getOrderNo(), ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mergeSummaryFromDetail(ErpGoofishOrder row, JSONObject data) {
|
||||||
|
ErpGoofishOrder patch = new ErpGoofishOrder();
|
||||||
|
patch.setId(row.getId());
|
||||||
|
boolean any = false;
|
||||||
|
Integer os = data.getInteger("order_status");
|
||||||
|
if (os != null) {
|
||||||
|
patch.setOrderStatus(os);
|
||||||
|
row.setOrderStatus(os);
|
||||||
|
any = true;
|
||||||
|
}
|
||||||
|
Integer rs = data.getInteger("refund_status");
|
||||||
|
if (rs != null) {
|
||||||
|
patch.setRefundStatus(rs);
|
||||||
|
row.setRefundStatus(rs);
|
||||||
|
any = true;
|
||||||
|
}
|
||||||
|
Long mt = data.getLong("modify_time");
|
||||||
|
if (mt == null) {
|
||||||
|
mt = data.getLong("order_modify_time");
|
||||||
|
}
|
||||||
|
if (mt != null) {
|
||||||
|
patch.setModifyTime(mt);
|
||||||
|
row.setModifyTime(mt);
|
||||||
|
any = true;
|
||||||
|
}
|
||||||
|
if (any) {
|
||||||
|
patch.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
erpGoofishOrderMapper.update(patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void syncWaybillFromRedis(ErpGoofishOrder row) {
|
||||||
|
if (row == null || row.getId() == null || row.getJdOrderId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String key = REDIS_WAYBILL_KEY_PREFIX + row.getJdOrderId();
|
||||||
|
String wb = stringRedisTemplate.opsForValue().get(key);
|
||||||
|
if (StringUtils.isEmpty(wb)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (wb.equals(row.getLocalWaybillNo())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ErpGoofishOrder patch = new ErpGoofishOrder();
|
||||||
|
patch.setId(row.getId());
|
||||||
|
patch.setLocalWaybillNo(wb.trim());
|
||||||
|
patch.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
erpGoofishOrderMapper.update(patch);
|
||||||
|
row.setLocalWaybillNo(wb.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tryAutoShip(ErpGoofishOrder row) {
|
||||||
|
if (row == null || row.getId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (row.getOrderStatus() == null || row.getOrderStatus() != 12) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (row.getRefundStatus() != null && row.getRefundStatus() != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (row.getShipStatus() != null && row.getShipStatus() == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(row.getLocalWaybillNo())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ErpOpenConfig cfg = erpOpenConfigService.selectByAppKey(row.getAppKey());
|
||||||
|
String expressCode = cfg != null ? cfg.getExpressCode() : null;
|
||||||
|
String expressName = cfg != null && StringUtils.isNotEmpty(cfg.getExpressName()) ? cfg.getExpressName() : "日日顺";
|
||||||
|
if (StringUtils.isEmpty(expressCode)) {
|
||||||
|
log.info("闲管家自动发货跳过:未配置 express_code appKey={} orderNo={}", row.getAppKey(), row.getOrderNo());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ShipAddressParts addr = parseShipAddress(row.getDetailJson());
|
||||||
|
if (addr == null || StringUtils.isEmpty(addr.shipName) || StringUtils.isEmpty(addr.shipMobile)
|
||||||
|
|| StringUtils.isEmpty(addr.shipAddress)) {
|
||||||
|
patchShipError(row, "详情中缺少收货人/手机/地址,请核对开放平台订单详情 JSON 字段");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
IERPAccount cred = erpAccountResolver.resolve(row.getAppKey());
|
||||||
|
OrderShipRequest ship = new OrderShipRequest(cred);
|
||||||
|
ship.setOrderNo(row.getOrderNo());
|
||||||
|
ship.setShipName(addr.shipName);
|
||||||
|
ship.setShipMobile(addr.shipMobile);
|
||||||
|
ship.setShipAddress(addr.shipAddress);
|
||||||
|
if (addr.shipDistrictId != null) {
|
||||||
|
ship.setShipDistrictId(addr.shipDistrictId);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(addr.shipProvName)) {
|
||||||
|
ship.setShipProvName(addr.shipProvName);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(addr.shipCityName)) {
|
||||||
|
ship.setShipCityName(addr.shipCityName);
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotEmpty(addr.shipAreaName)) {
|
||||||
|
ship.setShipAreaName(addr.shipAreaName);
|
||||||
|
}
|
||||||
|
ship.setWaybillNo(row.getLocalWaybillNo());
|
||||||
|
ship.setExpressCode(expressCode);
|
||||||
|
ship.setExpressName(expressName);
|
||||||
|
String resp = ship.getResponseBody();
|
||||||
|
JSONObject r = JSON.parseObject(resp);
|
||||||
|
if (r != null && r.getIntValue("code") == 0) {
|
||||||
|
ErpGoofishOrder ok = new ErpGoofishOrder();
|
||||||
|
ok.setId(row.getId());
|
||||||
|
ok.setShipStatus(1);
|
||||||
|
ok.setShipTime(DateUtils.getNowDate());
|
||||||
|
ok.setShipExpressCode(expressCode);
|
||||||
|
ok.setShipError(null);
|
||||||
|
ok.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
erpGoofishOrderMapper.update(ok);
|
||||||
|
row.setShipStatus(1);
|
||||||
|
} else {
|
||||||
|
String msg = r != null ? r.getString("msg") : "unknown";
|
||||||
|
patchShipError(row, msg != null ? msg : "发货接口返回失败");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
patchShipError(row, ex.getMessage());
|
||||||
|
log.warn("闲管家发货异常 orderNo={}", row.getOrderNo(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void patchShipError(ErpGoofishOrder row, String err) {
|
||||||
|
ErpGoofishOrder p = new ErpGoofishOrder();
|
||||||
|
p.setId(row.getId());
|
||||||
|
p.setShipStatus(2);
|
||||||
|
String m = err == null ? "" : err;
|
||||||
|
if (m.length() > 480) {
|
||||||
|
m = m.substring(0, 480) + "…";
|
||||||
|
}
|
||||||
|
p.setShipError(m);
|
||||||
|
p.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
erpGoofishOrderMapper.update(p);
|
||||||
|
row.setShipStatus(2);
|
||||||
|
row.setShipError(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ShipAddressParts {
|
||||||
|
String shipName;
|
||||||
|
String shipMobile;
|
||||||
|
String shipAddress;
|
||||||
|
Integer shipDistrictId;
|
||||||
|
String shipProvName;
|
||||||
|
String shipCityName;
|
||||||
|
String shipAreaName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ShipAddressParts parseShipAddress(String detailJson) {
|
||||||
|
if (StringUtils.isEmpty(detailJson)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject root = JSON.parseObject(detailJson);
|
||||||
|
if (root == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
JSONObject data = root.getJSONObject("data");
|
||||||
|
if (data == null) {
|
||||||
|
data = root;
|
||||||
|
}
|
||||||
|
ShipAddressParts p = new ShipAddressParts();
|
||||||
|
p.shipName = firstNonEmpty(data, "ship_name", "receiver_name", "consignee", "contact_name");
|
||||||
|
p.shipMobile = firstNonEmpty(data, "ship_mobile", "receiver_mobile", "receiver_phone", "contact_mobile");
|
||||||
|
p.shipAddress = firstNonEmpty(data, "ship_address", "receiver_address", "detail_address");
|
||||||
|
p.shipDistrictId = firstInt(data, "ship_district_id", "receiver_district_id");
|
||||||
|
p.shipProvName = firstNonEmpty(data, "ship_prov_name", "receiver_province", "prov");
|
||||||
|
p.shipCityName = firstNonEmpty(data, "ship_city_name", "receiver_city", "city");
|
||||||
|
p.shipAreaName = firstNonEmpty(data, "ship_area_name", "receiver_area", "area", "district");
|
||||||
|
JSONObject recv = data.getJSONObject("receiver");
|
||||||
|
if (recv != null) {
|
||||||
|
if (StringUtils.isEmpty(p.shipName)) {
|
||||||
|
p.shipName = recv.getString("name");
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(p.shipMobile)) {
|
||||||
|
p.shipMobile = recv.getString("mobile");
|
||||||
|
if (StringUtils.isEmpty(p.shipMobile)) {
|
||||||
|
p.shipMobile = recv.getString("phone");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (StringUtils.isEmpty(p.shipAddress)) {
|
||||||
|
p.shipAddress = recv.getString("address");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String firstNonEmpty(JSONObject o, String... keys) {
|
||||||
|
if (o == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (String k : keys) {
|
||||||
|
String v = o.getString(k);
|
||||||
|
if (StringUtils.isNotEmpty(v)) {
|
||||||
|
return v.trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Integer firstInt(JSONObject o, String... keys) {
|
||||||
|
if (o == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (String k : keys) {
|
||||||
|
Integer v = o.getInteger(k);
|
||||||
|
if (v != null) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int pullForAppKey(String appKey, int lookbackHours) {
|
||||||
|
if (StringUtils.isEmpty(appKey)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
IERPAccount cred = erpAccountResolver.resolve(appKey);
|
||||||
|
long now = System.currentTimeMillis() / 1000;
|
||||||
|
long start = now - (long) lookbackHours * 3600L;
|
||||||
|
List<Long> authorizeIds = fetchAuthorizeIds(cred);
|
||||||
|
int saved = 0;
|
||||||
|
int maxPages = goofishProperties.getPullMaxPagesPerShop();
|
||||||
|
for (Long aid : authorizeIds) {
|
||||||
|
int page = 1;
|
||||||
|
while (page <= maxPages) {
|
||||||
|
OrderListQueryRequest q = new OrderListQueryRequest(cred);
|
||||||
|
q.setAuthorizeId(aid);
|
||||||
|
q.setUpdateTime(start, now);
|
||||||
|
q.setPage(page, 20);
|
||||||
|
String resp;
|
||||||
|
try {
|
||||||
|
resp = q.getResponseBody();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.warn("闲管家拉单失败 aid={} page={} {}", aid, page, ex.getMessage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONObject root = JSON.parseObject(resp);
|
||||||
|
if (root == null || root.getIntValue("code") != 0) {
|
||||||
|
log.warn("闲管家拉单接口异常 aid={} page={} resp={}", aid, page, resp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
JSONObject data = root.getJSONObject("data");
|
||||||
|
JSONArray list = data == null ? null : data.getJSONArray("list");
|
||||||
|
if (list == null || list.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
JSONObject item = list.getJSONObject(i);
|
||||||
|
applyListOrNotifyItem(appKey, item, item.toJSONString());
|
||||||
|
saved++;
|
||||||
|
}
|
||||||
|
if (list.size() < 20) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
page++;
|
||||||
|
try {
|
||||||
|
Thread.sleep(200);
|
||||||
|
} catch (InterruptedException ie) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Long> fetchAuthorizeIds(IERPAccount cred) {
|
||||||
|
List<Long> ids = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
AuthorizeListQueryRequest auth = new AuthorizeListQueryRequest(cred);
|
||||||
|
auth.setPagination(1, 100);
|
||||||
|
String resp = auth.getResponseBody();
|
||||||
|
JSONObject root = JSON.parseObject(resp);
|
||||||
|
if (root == null || root.getIntValue("code") != 0) {
|
||||||
|
log.warn("授权列表查询异常 {}", resp);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
JSONObject data = root.getJSONObject("data");
|
||||||
|
JSONArray list = data == null ? null : data.getJSONArray("list");
|
||||||
|
if (list == null) {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
JSONObject it = list.getJSONObject(i);
|
||||||
|
Long aid = it.getLong("authorize_id");
|
||||||
|
if (aid == null) {
|
||||||
|
aid = it.getLong("authorizeId");
|
||||||
|
}
|
||||||
|
if (aid != null) {
|
||||||
|
ids.add(aid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("拉取授权列表异常 {}", e.getMessage());
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int syncWaybillAndTryShipBatch(int limit) {
|
||||||
|
List<ErpGoofishOrder> rows = erpGoofishOrderMapper.selectPendingShip(limit);
|
||||||
|
if (rows == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int n = 0;
|
||||||
|
for (ErpGoofishOrder row : rows) {
|
||||||
|
ErpGoofishOrder full = erpGoofishOrderMapper.selectById(row.getId());
|
||||||
|
if (full == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
syncWaybillFromRedis(full);
|
||||||
|
tryAutoShip(full);
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
package com.ruoyi.jarvis.service.impl;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpGoofishOrder;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.dto.GoofishNotifyMessage;
|
||||||
|
import com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper;
|
||||||
|
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import com.ruoyi.jarvis.service.goofish.GoofishNotifyAsyncFacade;
|
||||||
|
import com.ruoyi.jarvis.service.goofish.GoofishOrderPipeline;
|
||||||
|
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||||
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ErpGoofishOrderServiceImpl implements IErpGoofishOrderService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectProvider<RocketMQTemplate> rocketMQTemplate;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private JarvisGoofishProperties goofishProperties;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GoofishNotifyAsyncFacade goofishNotifyAsyncFacade;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private GoofishOrderPipeline goofishOrderPipeline;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ErpGoofishOrderMapper erpGoofishOrderMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpOpenConfigService erpOpenConfigService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void publishOrProcessNotify(String appid, Long timestamp, JSONObject body) {
|
||||||
|
RocketMQTemplate mq = rocketMQTemplate.getIfAvailable();
|
||||||
|
if (mq != null) {
|
||||||
|
GoofishNotifyMessage m = new GoofishNotifyMessage();
|
||||||
|
m.setAppid(appid);
|
||||||
|
m.setTimestamp(timestamp);
|
||||||
|
m.setBody(body.toJSONString());
|
||||||
|
mq.syncSend(goofishProperties.getMqTopic(), JSON.toJSONString(m));
|
||||||
|
} else {
|
||||||
|
goofishNotifyAsyncFacade.afterNotify(appid, body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void asyncPipelineAfterNotify(String appid, JSONObject notifyBody) {
|
||||||
|
goofishOrderPipeline.runFullPipeline(appid, notifyBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ErpGoofishOrder> selectList(ErpGoofishOrder query) {
|
||||||
|
return erpGoofishOrderMapper.selectList(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ErpGoofishOrder selectById(Long id) {
|
||||||
|
return erpGoofishOrderMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int pullOrdersForAppKey(String appKey, int lookbackHours) {
|
||||||
|
return goofishOrderPipeline.pullForAppKey(appKey, lookbackHours);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int pullAllEnabled(int lookbackHours) {
|
||||||
|
int total = 0;
|
||||||
|
List<ErpOpenConfig> cfgs = erpOpenConfigService.selectEnabledOrderBySort();
|
||||||
|
if (cfgs == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (ErpOpenConfig c : cfgs) {
|
||||||
|
if (c.getAppKey() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
total += goofishOrderPipeline.pullForAppKey(c.getAppKey(), lookbackHours);
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void refreshDetail(Long id) {
|
||||||
|
ErpGoofishOrder row = erpGoofishOrderMapper.selectById(id);
|
||||||
|
if (row != null) {
|
||||||
|
goofishOrderPipeline.refreshDetail(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retryShip(Long id) {
|
||||||
|
erpGoofishOrderMapper.resetShipForRetry(id);
|
||||||
|
ErpGoofishOrder row = erpGoofishOrderMapper.selectById(id);
|
||||||
|
if (row != null) {
|
||||||
|
goofishOrderPipeline.syncWaybillFromRedis(row);
|
||||||
|
goofishOrderPipeline.tryAutoShip(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int syncWaybillAndTryShipBatch(int limit) {
|
||||||
|
return goofishOrderPipeline.syncWaybillAndTryShipBatch(limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyListOrNotifyItem(String appKey, JSONObject item, String lastNotifyJson) {
|
||||||
|
goofishOrderPipeline.applyListOrNotifyItem(appKey, item, lastNotifyJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.ruoyi.jarvis.service.impl;
|
||||||
|
|
||||||
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.mapper.ErpOpenConfigMapper;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ErpOpenConfigServiceImpl implements IErpOpenConfigService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private ErpOpenConfigMapper erpOpenConfigMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ErpOpenConfig selectById(Long id) {
|
||||||
|
return erpOpenConfigMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ErpOpenConfig selectByAppKey(String appKey) {
|
||||||
|
if (appKey == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return erpOpenConfigMapper.selectByAppKey(appKey.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ErpOpenConfig selectFirstEnabled() {
|
||||||
|
List<ErpOpenConfig> list = erpOpenConfigMapper.selectEnabledOrderBySort();
|
||||||
|
return list == null || list.isEmpty() ? null : list.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ErpOpenConfig> selectList(ErpOpenConfig query) {
|
||||||
|
return erpOpenConfigMapper.selectList(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ErpOpenConfig> selectEnabledOrderBySort() {
|
||||||
|
return erpOpenConfigMapper.selectEnabledOrderBySort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int insert(ErpOpenConfig row) {
|
||||||
|
row.setCreateTime(DateUtils.getNowDate());
|
||||||
|
return erpOpenConfigMapper.insert(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int update(ErpOpenConfig row) {
|
||||||
|
row.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
return erpOpenConfigMapper.update(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int deleteById(Long id) {
|
||||||
|
return erpOpenConfigMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,7 +7,8 @@ import org.springframework.stereotype.Service;
|
|||||||
import com.ruoyi.jarvis.mapper.ErpProductMapper;
|
import com.ruoyi.jarvis.mapper.ErpProductMapper;
|
||||||
import com.ruoyi.jarvis.domain.ErpProduct;
|
import com.ruoyi.jarvis.domain.ErpProduct;
|
||||||
import com.ruoyi.jarvis.service.IErpProductService;
|
import com.ruoyi.jarvis.service.IErpProductService;
|
||||||
import com.ruoyi.erp.request.ERPAccount;
|
import com.ruoyi.erp.request.IERPAccount;
|
||||||
|
import com.ruoyi.jarvis.service.erp.ErpAccountResolver;
|
||||||
import com.ruoyi.erp.request.ProductListQueryRequest;
|
import com.ruoyi.erp.request.ProductListQueryRequest;
|
||||||
import com.ruoyi.erp.request.ProductDeleteRequest;
|
import com.ruoyi.erp.request.ProductDeleteRequest;
|
||||||
import com.alibaba.fastjson2.JSONArray;
|
import com.alibaba.fastjson2.JSONArray;
|
||||||
@@ -32,6 +33,9 @@ public class ErpProductServiceImpl implements IErpProductService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ErpProductMapper erpProductMapper;
|
private ErpProductMapper erpProductMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ErpAccountResolver erpAccountResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询闲鱼商品
|
* 查询闲鱼商品
|
||||||
*
|
*
|
||||||
@@ -126,7 +130,7 @@ public class ErpProductServiceImpl implements IErpProductService
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// 解析ERP账号
|
// 解析ERP账号
|
||||||
ERPAccount account = resolveAccount(appid);
|
IERPAccount account = erpAccountResolver.resolve(appid);
|
||||||
|
|
||||||
// 创建查询请求
|
// 创建查询请求
|
||||||
ProductListQueryRequest request = new ProductListQueryRequest(account);
|
ProductListQueryRequest request = new ProductListQueryRequest(account);
|
||||||
@@ -319,7 +323,7 @@ public class ErpProductServiceImpl implements IErpProductService
|
|||||||
int updated = 0;
|
int updated = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ERPAccount account = resolveAccount(appid);
|
IERPAccount account = erpAccountResolver.resolve(appid);
|
||||||
|
|
||||||
// 第一步:遍历所有页码,拉取并保存所有商品
|
// 第一步:遍历所有页码,拉取并保存所有商品
|
||||||
log.info("开始全量同步商品,账号:{}", appid);
|
log.info("开始全量同步商品,账号:{}", appid);
|
||||||
@@ -463,18 +467,5 @@ public class ErpProductServiceImpl implements IErpProductService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 解析ERP账号
|
|
||||||
*/
|
|
||||||
private ERPAccount resolveAccount(String appid) {
|
|
||||||
if (appid != null && !appid.isEmpty()) {
|
|
||||||
for (ERPAccount account : ERPAccount.values()) {
|
|
||||||
if (account.getApiKey().equals(appid)) {
|
|
||||||
return account;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ERPAccount.ACCOUNT_HUGE; // 默认账号
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package com.ruoyi.jarvis.task;
|
||||||
|
|
||||||
|
import com.ruoyi.jarvis.config.JarvisGoofishProperties;
|
||||||
|
import com.ruoyi.jarvis.domain.ErpOpenConfig;
|
||||||
|
import com.ruoyi.jarvis.service.IErpGoofishOrderService;
|
||||||
|
import com.ruoyi.jarvis.service.IErpOpenConfigService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 闲管家 ERP:定时拉单与运单同步/自动发货
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class GoofishScheduledTasks {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(GoofishScheduledTasks.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpOpenConfigService erpOpenConfigService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private IErpGoofishOrderService erpGoofishOrderService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private JarvisGoofishProperties goofishProperties;
|
||||||
|
|
||||||
|
@Scheduled(cron = "${jarvis.goofish-order.pull-cron:0 0/15 * * * ?}")
|
||||||
|
public void scheduledPull() {
|
||||||
|
List<ErpOpenConfig> cfgs = erpOpenConfigService.selectEnabledOrderBySort();
|
||||||
|
if (cfgs == null || cfgs.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int hours = goofishProperties.getPullLookbackHours();
|
||||||
|
int n = 0;
|
||||||
|
for (ErpOpenConfig c : cfgs) {
|
||||||
|
try {
|
||||||
|
n += erpGoofishOrderService.pullOrdersForAppKey(c.getAppKey(), hours);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("定时拉单失败 appKey={} {}", c.getAppKey(), e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > 0) {
|
||||||
|
log.info("闲管家定时拉单本轮处理约 {} 条子订单项", n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "${jarvis.goofish-order.auto-ship-cron:0 2/10 * * * ?}")
|
||||||
|
public void scheduledWaybillAndShip() {
|
||||||
|
try {
|
||||||
|
int k = erpGoofishOrderService.syncWaybillAndTryShipBatch(goofishProperties.getAutoShipBatchSize());
|
||||||
|
if (k > 0) {
|
||||||
|
log.info("闲管家运单同步与发货扫描处理 {} 条", k);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("闲管家自动发货扫描异常 {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
<?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="com.ruoyi.jarvis.mapper.ErpGoofishOrderMapper">
|
||||||
|
|
||||||
|
<resultMap id="ErpGoofishOrderResult" type="com.ruoyi.jarvis.domain.ErpGoofishOrder">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="appKey" column="app_key"/>
|
||||||
|
<result property="sellerId" column="seller_id"/>
|
||||||
|
<result property="userName" column="user_name"/>
|
||||||
|
<result property="orderNo" column="order_no"/>
|
||||||
|
<result property="orderType" column="order_type"/>
|
||||||
|
<result property="orderStatus" column="order_status"/>
|
||||||
|
<result property="refundStatus" column="refund_status"/>
|
||||||
|
<result property="modifyTime" column="modify_time"/>
|
||||||
|
<result property="productId" column="product_id"/>
|
||||||
|
<result property="itemId" column="item_id"/>
|
||||||
|
<result property="detailJson" column="detail_json"/>
|
||||||
|
<result property="lastNotifyJson" column="last_notify_json"/>
|
||||||
|
<result property="jdOrderId" column="jd_order_id"/>
|
||||||
|
<result property="localWaybillNo" column="local_waybill_no"/>
|
||||||
|
<result property="shipStatus" column="ship_status"/>
|
||||||
|
<result property="shipError" column="ship_error"/>
|
||||||
|
<result property="shipTime" column="ship_time"/>
|
||||||
|
<result property="shipExpressCode" column="ship_express_code"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
<result property="updateTime" column="update_time"/>
|
||||||
|
<result property="jdThirdPartyOrderNo" column="jd_third_party_order_no"/>
|
||||||
|
<result property="jdRemark" column="jd_remark"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectJoinVo">
|
||||||
|
select e.id, e.app_key, e.seller_id, e.user_name, e.order_no, e.order_type, e.order_status, e.refund_status,
|
||||||
|
e.modify_time, e.product_id, e.item_id, e.detail_json, e.last_notify_json, e.jd_order_id, e.local_waybill_no,
|
||||||
|
e.ship_status, e.ship_error, e.ship_time, e.ship_express_code, e.create_time, e.update_time,
|
||||||
|
o.third_party_order_no as jd_third_party_order_no, o.remark as jd_remark
|
||||||
|
from erp_goofish_order e
|
||||||
|
left join jd_order o on e.jd_order_id = o.id
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectById" resultMap="ErpGoofishOrderResult">
|
||||||
|
<include refid="selectJoinVo"/> where e.id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByAppKeyAndOrderNo" resultMap="ErpGoofishOrderResult">
|
||||||
|
<include refid="selectJoinVo"/> where e.app_key = #{appKey} and e.order_no = #{orderNo} limit 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectList" parameterType="com.ruoyi.jarvis.domain.ErpGoofishOrder" resultMap="ErpGoofishOrderResult">
|
||||||
|
<include refid="selectJoinVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="appKey != null and appKey != ''">and e.app_key = #{appKey}</if>
|
||||||
|
<if test="userName != null and userName != ''">and e.user_name like concat('%', #{userName}, '%')</if>
|
||||||
|
<if test="orderNo != null and orderNo != ''">and e.order_no like concat('%', #{orderNo}, '%')</if>
|
||||||
|
<if test="orderStatus != null">and e.order_status = #{orderStatus}</if>
|
||||||
|
<if test="shipStatus != null">and e.ship_status = #{shipStatus}</if>
|
||||||
|
<if test="jdOrderId != null">and e.jd_order_id = #{jdOrderId}</if>
|
||||||
|
</where>
|
||||||
|
order by e.modify_time desc, e.id desc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectPendingShip" resultMap="ErpGoofishOrderResult">
|
||||||
|
<include refid="selectJoinVo"/>
|
||||||
|
where e.order_status = 12 and (e.ship_status is null or e.ship_status != 1) and e.jd_order_id is not null
|
||||||
|
order by e.update_time asc
|
||||||
|
limit #{limit}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insert" parameterType="com.ruoyi.jarvis.domain.ErpGoofishOrder" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into erp_goofish_order
|
||||||
|
(app_key, seller_id, user_name, order_no, order_type, order_status, refund_status, modify_time, product_id, item_id,
|
||||||
|
detail_json, last_notify_json, jd_order_id, local_waybill_no, ship_status, ship_error, ship_time, ship_express_code,
|
||||||
|
create_time, update_time)
|
||||||
|
values
|
||||||
|
(#{appKey}, #{sellerId}, #{userName}, #{orderNo}, #{orderType}, #{orderStatus}, #{refundStatus}, #{modifyTime}, #{productId}, #{itemId},
|
||||||
|
#{detailJson}, #{lastNotifyJson}, #{jdOrderId}, #{localWaybillNo}, #{shipStatus}, #{shipError}, #{shipTime}, #{shipExpressCode},
|
||||||
|
#{createTime}, #{updateTime})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="update" parameterType="com.ruoyi.jarvis.domain.ErpGoofishOrder">
|
||||||
|
update erp_goofish_order
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="sellerId != null">seller_id = #{sellerId},</if>
|
||||||
|
<if test="userName != null">user_name = #{userName},</if>
|
||||||
|
<if test="orderType != null">order_type = #{orderType},</if>
|
||||||
|
<if test="orderStatus != null">order_status = #{orderStatus},</if>
|
||||||
|
<if test="refundStatus != null">refund_status = #{refundStatus},</if>
|
||||||
|
<if test="modifyTime != null">modify_time = #{modifyTime},</if>
|
||||||
|
<if test="productId != null">product_id = #{productId},</if>
|
||||||
|
<if test="itemId != null">item_id = #{itemId},</if>
|
||||||
|
<if test="detailJson != null">detail_json = #{detailJson},</if>
|
||||||
|
<if test="lastNotifyJson != null">last_notify_json = #{lastNotifyJson},</if>
|
||||||
|
<if test="jdOrderId != null">jd_order_id = #{jdOrderId},</if>
|
||||||
|
<if test="localWaybillNo != null">local_waybill_no = #{localWaybillNo},</if>
|
||||||
|
<if test="shipStatus != null">ship_status = #{shipStatus},</if>
|
||||||
|
<if test="shipError != null">ship_error = #{shipError},</if>
|
||||||
|
<if test="shipTime != null">ship_time = #{shipTime},</if>
|
||||||
|
<if test="shipExpressCode != null">ship_express_code = #{shipExpressCode},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<update id="resetShipForRetry">
|
||||||
|
update erp_goofish_order
|
||||||
|
set ship_status = 0,
|
||||||
|
ship_error = null,
|
||||||
|
update_time = now()
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
</mapper>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
<?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="com.ruoyi.jarvis.mapper.ErpOpenConfigMapper">
|
||||||
|
|
||||||
|
<resultMap id="ErpOpenConfigResult" type="com.ruoyi.jarvis.domain.ErpOpenConfig">
|
||||||
|
<id property="id" column="id"/>
|
||||||
|
<result property="appKey" column="app_key"/>
|
||||||
|
<result property="appSecret" column="app_secret"/>
|
||||||
|
<result property="xyUserName" column="xy_user_name"/>
|
||||||
|
<result property="expressCode" column="express_code"/>
|
||||||
|
<result property="expressName" column="express_name"/>
|
||||||
|
<result property="status" column="status"/>
|
||||||
|
<result property="orderNum" column="order_num"/>
|
||||||
|
<result property="createBy" column="create_by"/>
|
||||||
|
<result property="createTime" column="create_time"/>
|
||||||
|
<result property="updateBy" column="update_by"/>
|
||||||
|
<result property="updateTime" column="update_time"/>
|
||||||
|
<result property="remark" column="remark"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<sql id="selectVo">
|
||||||
|
select id, app_key, app_secret, xy_user_name, express_code, express_name, status, order_num,
|
||||||
|
create_by, create_time, update_by, update_time, remark
|
||||||
|
from erp_open_config
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<select id="selectById" resultMap="ErpOpenConfigResult">
|
||||||
|
<include refid="selectVo"/> where id = #{id}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByAppKey" resultMap="ErpOpenConfigResult">
|
||||||
|
<include refid="selectVo"/> where app_key = #{appKey} limit 1
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectList" parameterType="com.ruoyi.jarvis.domain.ErpOpenConfig" resultMap="ErpOpenConfigResult">
|
||||||
|
<include refid="selectVo"/>
|
||||||
|
<where>
|
||||||
|
<if test="appKey != null and appKey != ''">and app_key = #{appKey}</if>
|
||||||
|
<if test="status != null and status != ''">and status = #{status}</if>
|
||||||
|
<if test="xyUserName != null and xyUserName != ''">and xy_user_name like concat('%', #{xyUserName}, '%')</if>
|
||||||
|
</where>
|
||||||
|
order by order_num asc, id asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectEnabledOrderBySort" resultMap="ErpOpenConfigResult">
|
||||||
|
<include refid="selectVo"/>
|
||||||
|
where status = '0'
|
||||||
|
order by order_num asc, id asc
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<insert id="insert" parameterType="com.ruoyi.jarvis.domain.ErpOpenConfig" useGeneratedKeys="true" keyProperty="id">
|
||||||
|
insert into erp_open_config
|
||||||
|
(app_key, app_secret, xy_user_name, express_code, express_name, status, order_num, create_by, create_time, remark)
|
||||||
|
values
|
||||||
|
(#{appKey}, #{appSecret}, #{xyUserName}, #{expressCode}, #{expressName}, #{status}, #{orderNum}, #{createBy}, #{createTime}, #{remark})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<update id="update" parameterType="com.ruoyi.jarvis.domain.ErpOpenConfig">
|
||||||
|
update erp_open_config
|
||||||
|
<trim prefix="SET" suffixOverrides=",">
|
||||||
|
<if test="appKey != null">app_key = #{appKey},</if>
|
||||||
|
<if test="appSecret != null">app_secret = #{appSecret},</if>
|
||||||
|
<if test="xyUserName != null">xy_user_name = #{xyUserName},</if>
|
||||||
|
<if test="expressCode != null">express_code = #{expressCode},</if>
|
||||||
|
<if test="expressName != null">express_name = #{expressName},</if>
|
||||||
|
<if test="status != null">status = #{status},</if>
|
||||||
|
<if test="orderNum != null">order_num = #{orderNum},</if>
|
||||||
|
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||||
|
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||||
|
<if test="remark != null">remark = #{remark},</if>
|
||||||
|
</trim>
|
||||||
|
where id = #{id}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
<delete id="deleteById">
|
||||||
|
delete from erp_open_config where id = #{id}
|
||||||
|
</delete>
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user