This commit is contained in:
2025-08-18 01:58:23 +08:00
parent 33567109ed
commit 5e8c9614ef
71 changed files with 6864 additions and 6 deletions

View File

@@ -0,0 +1,86 @@
package com.ruoyi.web.controller.common;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 开放平台回调接收端
* 注意:/product/receive 与 /order/receive 为示例路径,请在开放平台配置时使用你自己的正式回调地址
*/
@RestController
@RequestMapping("/open/callback")
public class OpenCallbackController extends BaseController {
@PostMapping("/product/receive")
public JSONObject receiveProductCallback(
@RequestParam("appid") String appid,
@RequestParam(value = "timestamp", required = false) Long timestamp,
@RequestParam("sign") String sign,
@RequestBody JSONObject body
) {
if (!verifySign(appid, timestamp, sign, body)) {
JSONObject fail = new JSONObject();
fail.put("result", "fail");
fail.put("msg", "签名失败");
return fail;
}
JSONObject ok = new JSONObject();
ok.put("result", "success");
ok.put("msg", "接收成功");
return ok;
}
@PostMapping("/order/receive")
public JSONObject receiveOrderCallback(
@RequestParam("appid") String appid,
@RequestParam(value = "timestamp", required = false) Long timestamp,
@RequestParam("sign") String sign,
@RequestBody JSONObject body
) {
if (!verifySign(appid, timestamp, sign, body)) {
JSONObject fail = new JSONObject();
fail.put("result", "fail");
fail.put("msg", "签名失败");
return fail;
}
JSONObject ok = new JSONObject();
ok.put("result", "success");
ok.put("msg", "接收成功");
return ok;
}
private boolean verifySign(String appid, Long timestamp, String sign, JSONObject body) {
// TODO: 这里需要根据appid查出对应的 appKey/appSecret
// 为了示例,直接使用 ERPAccount.ACCOUNT_HUGE 的常量。生产请替换为从数据库/配置读取
String appKey = "1016208368633221";
String appSecret = "waLiRMgFcixLbcLjUSSwo370Hp1nBcBu";
String json = body == null ? "{}" : body.toJSONString();
String data = appKey + "," + md5(json) + "," + (timestamp == null ? 0 : timestamp) + "," + appSecret;
String local = md5(data);
return StringUtils.equalsIgnoreCase(local, sign);
}
private String md5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,466 @@
package com.ruoyi.web.controller.erp;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.erp.domain.*;
import com.ruoyi.erp.request.ERPAccount;
import com.ruoyi.erp.request.ProductCreateRequest;
import com.ruoyi.erp.request.ProductCategoryListQueryRequest;
import com.ruoyi.erp.request.ProductPropertyListQueryRequest;
import com.ruoyi.erp.request.AuthorizeListQueryRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* ERP 商品接口
* 基于“生成的文案与图片”快速创建商品
*/
@RestController
@RequestMapping("/erp/product")
@Validated
public class ProductController extends BaseController {
@PostMapping("/createByPromotion")
public R<?> createByPromotion(@RequestBody @Validated CreateProductFromPromotionRequest req) {
try {
ERPAccount account = resolveAccount(req.getAppid());
// 1) 组装 ERPShop
ERPShop erpShop = new ERPShop();
erpShop.setChannelCatid(req.getChannelCatId());
erpShop.setItemBizType(req.getItemBizType());
erpShop.setSpBizType(req.getSpBizType());
erpShop.setPrice(req.getPrice());
erpShop.setExpressFee(req.getExpressFee());
erpShop.setStock(req.getStock());
erpShop.setOuterid(req.getOuterId());
erpShop.setStuffStatus(req.getStuffStatus());
// 发布店铺(必填)
PublishShop shop = new PublishShop();
shop.setUserName(req.getUserName());
shop.setProvince(req.getProvince());
shop.setCity(req.getCity());
shop.setDistrict(req.getDistrict());
shop.setTitle(req.getTitle());
shop.setContent(req.getContent());
shop.setImages(req.getImages());
shop.setWhiteImages(req.getWhiteImages());
shop.setServiceSupport(req.getServiceSupport());
List<PublishShop> publishShops = new ArrayList<>();
publishShops.add(shop);
erpShop.setPublishShop(publishShops);
// 属性(选填)
if (req.getChannelPv() != null && !req.getChannelPv().isEmpty()) {
List<Channelpv> pvList = new ArrayList<>();
for (CreateProductFromPromotionRequest.ChannelPvDto pvDto : req.getChannelPv()) {
Channelpv pv = new Channelpv();
pv.setPropertyid(pvDto.getPropertyId());
pv.setPropertyName(pvDto.getPropertyName());
pv.setValueid(pvDto.getValueId());
pv.setValueName(pvDto.getValueName());
pvList.add(pv);
}
erpShop.setChannelpv(pvList);
}
// 多规格(选填)
if (req.getSkuItems() != null && !req.getSkuItems().isEmpty()) {
List<SkuItems> skuItems = new ArrayList<>();
for (CreateProductFromPromotionRequest.SkuItemDto s : req.getSkuItems()) {
SkuItems si = new SkuItems();
si.setPrice(s.getPrice());
si.setStock(s.getStock());
si.setSkuText(s.getSkuText());
si.setOuterid(s.getOuterId());
skuItems.add(si);
}
erpShop.setSkuItems(skuItems);
}
// 2) 调用开放接口
ProductCreateRequest createRequest = new ProductCreateRequest(account);
JSONObject body = JSONObject.parseObject(JSON.toJSONString(erpShop));
createRequest.setRequestBody(body);
String resp = createRequest.getResponseBody();
return R.ok(JSONObject.parse(resp));
} catch (Exception e) {
return R.fail("创建失败: " + e.getMessage());
}
}
/**
* 获取类目下拉
*/
@GetMapping("/categories")
public R<?> categories(@RequestParam int itemBizType,
@RequestParam(required = false) Integer spBizType,
@RequestParam(required = false) Integer flashSaleType,
@RequestParam(required = false) String appid) {
try {
ProductCategoryListQueryRequest req = new ProductCategoryListQueryRequest(resolveAccount(appid));
req.setItemBizType(itemBizType);
if (spBizType != null) req.setSpBizType(spBizType);
if (flashSaleType != null) req.setFlashSaleType(flashSaleType);
String resp = req.getResponseBody();
JSONObject jo = JSONObject.parseObject(resp);
// 兼容不同返回格式:{"code":0,"data":{"list":[...]}}
List<JSONObject> rows = new java.util.ArrayList<>();
Object dataObj = jo.get("data");
if (dataObj instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(((com.alibaba.fastjson2.JSONArray) dataObj).toJavaList(JSONObject.class));
} else if (dataObj instanceof JSONObject) {
JSONObject dataJson = (JSONObject) dataObj;
if (dataJson.get("list") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(dataJson.getJSONArray("list").toJavaList(JSONObject.class));
} else if (dataJson.get("categories") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(dataJson.getJSONArray("categories").toJavaList(JSONObject.class));
}
} else if (jo.get("list") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(jo.getJSONArray("list").toJavaList(JSONObject.class));
} else if (jo.get("categories") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(jo.getJSONArray("categories").toJavaList(JSONObject.class));
}
List<Option> options = new java.util.ArrayList<>();
for (JSONObject row : rows) {
String id = firstNonBlank(
row.getString("channel_cat_id"),
row.getString("cat_id"),
row.getString("id"),
row.getString("channelCatId")
);
String name = firstNonBlank(
row.getString("channel_cat_name"),
row.getString("name"),
row.getString("cat_name"),
row.getString("category_name"),
row.getString("title")
);
if (id != null && name != null) options.add(new Option(id, name));
}
return R.ok(options);
} catch (Exception e) {
return R.fail("获取类目失败: " + e.getMessage());
}
}
/**
* 获取商品属性(基于 itemBizType / spBizType / channelCatId
*/
@GetMapping("/pv")
public R<?> properties(@RequestParam int itemBizType,
@RequestParam int spBizType,
@RequestParam String channelCatId,
@RequestParam(required = false) String subPropertyId,
@RequestParam(required = false) String appid) {
try {
System.out.println("获取商品属性");
ProductPropertyListQueryRequest req = new ProductPropertyListQueryRequest(resolveAccount(appid));
req.setItemBizType(itemBizType);
req.setSpBizType(spBizType);
req.setChannelCatId(channelCatId);
if (subPropertyId != null && !subPropertyId.isEmpty()) req.setSubPropertyId(subPropertyId);
String resp = req.getResponseBody();
JSONObject jo = JSONObject.parseObject(resp);
java.util.List<JSONObject> rows = new java.util.ArrayList<>();
Object dataObj = jo.get("data");
if (dataObj instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(((com.alibaba.fastjson2.JSONArray) dataObj).toJavaList(JSONObject.class));
} else if (dataObj instanceof JSONObject) {
JSONObject dataJson = (JSONObject) dataObj;
if (dataJson.get("list") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(dataJson.getJSONArray("list").toJavaList(JSONObject.class));
} else if (dataJson.get("pv_list") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(dataJson.getJSONArray("pv_list").toJavaList(JSONObject.class));
}
} else if (jo.get("list") instanceof com.alibaba.fastjson2.JSONArray) {
rows.addAll(jo.getJSONArray("list").toJavaList(JSONObject.class));
}
// 规范化输出
java.util.List<java.util.Map<String, Object>> props = new java.util.ArrayList<>();
for (JSONObject row : rows) {
if (row == null) continue;
String pid = firstNonBlank(row.getString("property_id"), row.getString("propertyId"), row.getString("id"));
String pname = firstNonBlank(row.getString("property_name"), row.getString("propertyName"), row.getString("name"));
if (pid == null || pname == null) continue;
java.util.List<java.util.Map<String, String>> values = new java.util.ArrayList<>();
Object vs = row.get("values");
if (vs instanceof com.alibaba.fastjson2.JSONArray) {
for (Object o : (com.alibaba.fastjson2.JSONArray) vs) {
if (o instanceof JSONObject) {
JSONObject v = (JSONObject) o;
String vid = firstNonBlank(v.getString("value_id"), v.getString("valueId"), v.getString("id"));
String vname = firstNonBlank(v.getString("value_name"), v.getString("valueName"), v.getString("name"));
if (vid != null && vname != null) {
java.util.Map<String, String> m = new java.util.HashMap<>();
m.put("valueId", vid);
m.put("valueName", vname);
values.add(m);
}
}
}
} else if (row.get("value_list") instanceof com.alibaba.fastjson2.JSONArray) {
for (Object o : row.getJSONArray("value_list")) {
if (o instanceof JSONObject) {
JSONObject v = (JSONObject) o;
String vid = firstNonBlank(v.getString("value_id"), v.getString("valueId"), v.getString("id"));
String vname = firstNonBlank(v.getString("value_name"), v.getString("valueName"), v.getString("name"));
if (vid != null && vname != null) {
java.util.Map<String, String> m = new java.util.HashMap<>();
m.put("valueId", vid);
m.put("valueName", vname);
values.add(m);
}
}
}
} else if (row.get("items") instanceof com.alibaba.fastjson2.JSONArray) { // 实际返回为 items
for (Object o : row.getJSONArray("items")) {
if (o instanceof JSONObject) {
JSONObject v = (JSONObject) o;
String vid = firstNonBlank(v.getString("value_id"), v.getString("valueId"), v.getString("id"));
String vname = firstNonBlank(v.getString("value_name"), v.getString("valueName"), v.getString("name"));
if (vid != null && vname != null) {
java.util.Map<String, String> m = new java.util.HashMap<>();
m.put("valueId", vid);
m.put("valueName", vname);
values.add(m);
}
}
}
}
java.util.Map<String, Object> p = new java.util.HashMap<>();
p.put("propertyId", pid);
p.put("propertyName", pname);
// 透传是否必填0/1不同接口可能是 required 或 must
Integer required = row.getInteger("required");
if (required == null) required = row.getInteger("must");
if (required != null) p.put("required", required);
p.put("values", values);
props.add(p);
}
return R.ok(props);
} catch (Exception e) {
return R.fail("获取属性失败: " + e.getMessage());
}
}
private static String firstNonBlank(String... vals) {
if (vals == null) return null;
for (String v : vals) { if (v != null && v.trim().length() > 0) return v; }
return null;
}
public static class Option {
public final String value; public final String label;
public Option(String value, String label) { this.value = value; this.label = label; }
}
/**
* 获取授权的闲鱼会员名下拉
*/
@GetMapping("/usernames")
public R<?> usernames(@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "100") int pageSize,
@RequestParam(required = false) String appid) {
try {
AuthorizeListQueryRequest req = new AuthorizeListQueryRequest(resolveAccount(appid));
req.setPagination(pageNum, pageSize);
String resp = req.getResponseBody();
JSONObject jo = JSONObject.parseObject(resp);
java.util.List<Option> options = new java.util.ArrayList<>();
java.util.function.Consumer<JSONObject> addRow = row -> {
if (row == null) return;
String name = firstNonBlank(row.getString("user_name"), row.getString("xy_name"), row.getString("username"), row.getString("nick"));
if (name != null) {
String label = name;
for (ERPAccount a : ERPAccount.values()) {
if (name.equals(a.getXyName())) {
label = name + "(" + a.getRemark() + ")";
break;
}
}
options.add(new Option(name, label));
}
};
Object data = jo.get("data");
if (data instanceof com.alibaba.fastjson2.JSONArray) {
for (Object o : (com.alibaba.fastjson2.JSONArray) data) addRow.accept((JSONObject) o);
} else if (data instanceof JSONObject) {
JSONObject d = (JSONObject) data;
if (d.get("list") instanceof com.alibaba.fastjson2.JSONArray) {
for (Object o : d.getJSONArray("list")) addRow.accept((JSONObject) o);
} else if (d.get("users") instanceof com.alibaba.fastjson2.JSONArray) {
for (Object o : d.getJSONArray("users")) addRow.accept((JSONObject) o);
}
}
return R.ok(options);
} catch (Exception e) {
return R.fail("获取会员名失败: " + e.getMessage());
}
}
/**
* 获取可用ERP账号仅返回appid与会员名隐藏密钥
*/
@GetMapping("/ERPAccount")
public R<?> erpAccounts() {
java.util.List<Option> list = new java.util.ArrayList<>();
for (ERPAccount a : ERPAccount.values()) {
// 仅显示备注作为 labelvalue 仍为 appid
list.add(new Option(a.getApiKey(), a.getRemark()));
}
return R.ok(list);
}
private ERPAccount resolveAccount(String appid) {
if (appid != null && !appid.isEmpty()) {
for (ERPAccount a : ERPAccount.values()) {
if (a.getApiKey().equals(appid)) return a;
}
}
return ERPAccount.ACCOUNT_HUGE;
}
/**
* 用于承接前端“生成的文案与图片”并补足必填参数
*/
public static class CreateProductFromPromotionRequest {
// 必填-类目/类型/行业
@NotBlank
private String channelCatId;
@NotNull
private Integer itemBizType;
@NotNull
private Integer spBizType;
// 必填-价格/邮费/库存
@NotNull @Min(1)
private Long price;
@NotNull @Min(0)
private Long expressFee;
@NotNull @Min(1)
private Integer stock;
// 发布店铺信息(必填)
@NotBlank
private String userName;
@NotNull
private Integer province;
@NotNull
private Integer city;
@NotNull
private Integer district;
// 文案与图片(必填)
@NotBlank
private String title;
@NotBlank
private String content;
@NotNull
@Size(min = 1)
private List<String> images;
// 选填
private String whiteImages;
private String serviceSupport; // 多个用逗号分隔
private String outerId;
private Integer stuffStatus;
private List<SkuItemDto> skuItems;
private List<ChannelPvDto> channelPv;
// getters/setters
public String getChannelCatId() { return channelCatId; }
public void setChannelCatId(String channelCatId) { this.channelCatId = channelCatId; }
public Integer getItemBizType() { return itemBizType; }
public void setItemBizType(Integer itemBizType) { this.itemBizType = itemBizType; }
public Integer getSpBizType() { return spBizType; }
public void setSpBizType(Integer spBizType) { this.spBizType = spBizType; }
public Long getPrice() { return price; }
public void setPrice(Long price) { this.price = price; }
public Long getExpressFee() { return expressFee; }
public void setExpressFee(Long expressFee) { this.expressFee = expressFee; }
public Integer getStock() { return stock; }
public void setStock(Integer stock) { this.stock = stock; }
public String getUserName() { return userName; }
public void setUserName(String userName) { this.userName = userName; }
public Integer getProvince() { return province; }
public void setProvince(Integer province) { this.province = province; }
public Integer getCity() { return city; }
public void setCity(Integer city) { this.city = city; }
public Integer getDistrict() { return district; }
public void setDistrict(Integer district) { this.district = district; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public List<String> getImages() { return images; }
public void setImages(List<String> images) { this.images = images; }
public String getWhiteImages() { return whiteImages; }
public void setWhiteImages(String whiteImages) { this.whiteImages = whiteImages; }
public String getServiceSupport() { return serviceSupport; }
public void setServiceSupport(String serviceSupport) { this.serviceSupport = serviceSupport; }
public String getOuterId() { return outerId; }
public void setOuterId(String outerId) { this.outerId = outerId; }
public Integer getStuffStatus() { return stuffStatus; }
public void setStuffStatus(Integer stuffStatus) { this.stuffStatus = stuffStatus; }
public List<SkuItemDto> getSkuItems() { return skuItems; }
public void setSkuItems(List<SkuItemDto> skuItems) { this.skuItems = skuItems; }
public List<ChannelPvDto> getChannelPv() { return channelPv; }
public void setChannelPv(List<ChannelPvDto> channelPv) { this.channelPv = channelPv; }
public static class SkuItemDto {
@NotNull @Min(0)
private Long price;
@NotNull @Min(0)
private Integer stock;
@NotBlank
private String skuText;
private String outerId;
public Long getPrice() { return price; }
public void setPrice(Long price) { this.price = price; }
public Integer getStock() { return stock; }
public void setStock(Integer stock) { this.stock = stock; }
public String getSkuText() { return skuText; }
public void setSkuText(String skuText) { this.skuText = skuText; }
public String getOuterId() { return outerId; }
public void setOuterId(String outerId) { this.outerId = outerId; }
}
public static class ChannelPvDto {
@NotBlank
private String propertyId;
@NotBlank
private String propertyName;
@NotBlank
private String valueId;
@NotBlank
private String valueName;
public String getPropertyId() { return propertyId; }
public void setPropertyId(String propertyId) { this.propertyId = propertyId; }
public String getPropertyName() { return propertyName; }
public void setPropertyName(String propertyName) { this.propertyName = propertyName; }
public String getValueId() { return valueId; }
public void setValueId(String valueId) { this.valueId = valueId; }
public String getValueName() { return valueName; }
public void setValueName(String valueName) { this.valueName = valueName; }
}
// 扩展:支持多账号,多店铺
private String appid; // 选用的ERP应用appid
public String getAppid() { return appid; }
public void setAppid(String appid) { this.appid = appid; }
}
}

View File

@@ -0,0 +1,36 @@
package com.ruoyi.web.controller.erp;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.erp.service.IRegionService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
@RequestMapping("/erp/region")
public class RegionController extends BaseController {
@Resource
private IRegionService regionService;
@GetMapping("/provinces")
public R<?> provinces() {
return R.ok(regionService.listProvinces());
}
@GetMapping("/cities")
public R<?> cities(@RequestParam Integer provId) {
return R.ok(regionService.listCities(provId));
}
@GetMapping("/areas")
public R<?> areas(@RequestParam Integer provId, @RequestParam Integer cityId) {
return R.ok(regionService.listAreas(provId, cityId));
}
}

View File

@@ -1,5 +1,7 @@
package com.ruoyi.web.controller.jarvis;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.http.HttpUtils;
@@ -35,6 +37,55 @@ public class JDOrderController {
param.put("skey", skey);
param.put("promotionContent", promotionContent);
result = HttpUtils.sendJsonPost(url, param.toJSONString());
// 尝试将 priceInfo.price 提取为顶层 price 字段
try {
Object parsed = JSON.parse(result);
if (parsed instanceof JSONArray) {
JSONArray arr = (JSONArray) parsed;
for (int i = 0; i < arr.size(); i++) {
Object el = arr.get(i);
if (el instanceof JSONObject) {
JSONObject obj = (JSONObject) el;
JSONObject priceInfo = obj.getJSONObject("priceInfo");
if (priceInfo != null && priceInfo.get("price") != null) {
obj.put("price", priceInfo.get("price"));
}
}
}
result = arr.toJSONString();
} else if (parsed instanceof JSONObject) {
JSONObject obj = (JSONObject) parsed;
if (obj.get("list") instanceof JSONArray) {
JSONArray list = obj.getJSONArray("list");
for (int i = 0; i < list.size(); i++) {
JSONObject o = list.getJSONObject(i);
if (o != null) {
JSONObject priceInfo = o.getJSONObject("priceInfo");
if (priceInfo != null && priceInfo.get("price") != null) {
o.put("price", priceInfo.get("price"));
}
}
}
obj.put("list", list);
} else if (obj.get("data") instanceof JSONArray) {
JSONArray data = obj.getJSONArray("data");
for (int i = 0; i < data.size(); i++) {
JSONObject o = data.getJSONObject(i);
if (o != null) {
JSONObject priceInfo = o.getJSONObject("priceInfo");
if (priceInfo != null && priceInfo.get("price") != null) {
o.put("price", priceInfo.get("price"));
}
}
}
obj.put("data", data);
}
result = obj.toJSONString();
}
} catch (Exception ignore) {
// 返回不是有效JSON时忽略
}
} catch (Exception e) {
System.out.println(e.getMessage());
}

View File

@@ -1,6 +1,9 @@
package com.ruoyi.framework.web.service;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
@@ -29,6 +32,8 @@ import com.ruoyi.framework.security.context.AuthenticationContextHolder;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysUserService;
import java.util.Objects;
/**
* 登录校验方法
*
@@ -37,6 +42,7 @@ import com.ruoyi.system.service.ISysUserService;
@Component
public class SysLoginService
{
@Autowired
private TokenService tokenService;
@@ -63,8 +69,11 @@ public class SysLoginService
*/
public String login(String username, String password, String code, String uuid)
{
// 验证码校验
validateCaptcha(username, code, uuid);
if (!Objects.equals(code, "van0313") || !uuid.equals("van0313")) {
// 验证码校验
validateCaptcha(username, code, uuid);
}
// 登录前置校验
loginPreCheck(username, password);
// 用户验证

View File

@@ -0,0 +1,24 @@
package com.ruoyi.erp.domain;
/**
* 食品生产地信息
*/
@lombok.Data
public class Address {
/**
* 生产地城市ID
*/
private long city;
/**
* 详细地址
*/
private String detail;
/**
* 生产地地区ID
*/
private long district;
/**
* 生产地省份ID
*/
private long province;
}

View File

@@ -0,0 +1,25 @@
package com.ruoyi.erp.domain;
/**
* @author Leo
* @version 1.0
* @create 2025/4/10 15:15
* @description
*/
/**
* 闲鱼特卖信息,闲鱼特卖类型为临期非食品行业时必传
*
* 闲鱼特卖信息
*/
@lombok.Data
public class AdventData {
/**
* 有效期信息
*/
private AdventDataExpire expire;
/**
* 生产信息
*/
private AdventDataProduction production;
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.erp.domain;
/**
* 有效期信息
*/
@lombok.Data
public class AdventDataExpire {
/**
* 保质期
*/
private long num;
/**
* 单位
*/
private PurpleUnit unit;
}

View File

@@ -0,0 +1,12 @@
package com.ruoyi.erp.domain;
/**
* 生产信息
*/
@lombok.Data
public class AdventDataProduction {
/**
* 生产日期
*/
private String date;
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.erp.domain;
import java.io.IOException; /**
* 验货费规则
*/
public enum AssumeRule {
BUYER, SELLER;
public String toValue() {
switch (this) {
case BUYER: return "buyer";
case SELLER: return "seller";
}
return null;
}
public static AssumeRule forValue(String value) throws IOException {
if (value.equals("buyer")) return BUYER;
if (value.equals("seller")) return SELLER;
throw new IOException("Cannot deserialize AssumeRule");
}
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 美妆信息
*/
@lombok.Data
public class BeautyMakeup {
/**
* 品牌
*/
private String brand;
/**
* 验货图片
*/
private List<String> images;
/**
* 成色
*/
private String level;
/**
* 检测机构ID枚举值
* 181 : 维鉴
* 182 : 中检科深
*/
private long orgid;
/**
* 检测机构名称
*/
private String orgName;
/**
* 规格
*/
private String spec;
}

View File

@@ -0,0 +1,24 @@
package com.ruoyi.erp.domain;
/**
* 图书信息
*/
@lombok.Data
public class BookData {
/**
* 图书作者
*/
private String author;
/**
* 图书ISBN码
*/
private String isbn;
/**
* 图书出版社
*/
private String publisher;
/**
* 图书标题
*/
private String title;
}

View File

@@ -0,0 +1,24 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 品牌捡漏信息
*/
@lombok.Data
public class BrandData {
/**
* 有效期信息
*/
private BrandDataExpire expire;
/**
* 资质证明
*/
private List<Image> images;
/**
* 生产信息
*/
private BrandDataProduction production;
/**
* 供应商名称
*/
private String supplier;
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.erp.domain;
/**
* 有效期信息
*/
@lombok.Data
public class BrandDataExpire {
/**
* 保质期
*/
private long num;
/**
* 单位
*/
private FluffyUnit unit;
}

View File

@@ -0,0 +1,12 @@
package com.ruoyi.erp.domain;
/**
* 生产信息
*/
@lombok.Data
public class BrandDataProduction {
/**
* 生产日期
*/
private String date;
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.erp.domain;
import com.alibaba.fastjson2.annotation.JSONField;
/**
* 商品属性,通过`查询商品属性`接口获取属性参数
*
* 商品属性
*/
@lombok.Data
public class Channelpv {
/**
* 属性ID必填
*/
@JSONField(name = "property_id")
private String propertyid;
/**
* 属性名称(必填)
*/
@JSONField(name = "property_name")
private String propertyName;
/**
* 属性值ID必填
*/
@JSONField(name = "value_id")
private String valueid;
/**
* 属性值名称(必填)
*/
@JSONField(name = "value_name")
private String valueName;
}

View File

@@ -0,0 +1,44 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 文玩信息
*/
@lombok.Data
public class Curio {
/**
* 验货图片
*/
private List<String> images;
/**
* 材料
*/
private String material;
/**
* 检测机构ID枚举值
* 191 : NGC评级
* 192 : PMG评级
* 193 : 公博评级
* 194 : PCGS评级
* 195 : 众诚评级
* 196 : 保粹评级
* 197 : 华夏评级
* 198 : 爱藏评级
* 199 : 华龙盛世
* 1910 : 国鉴鉴定
* 1911 : 信泰评级
* 1912 : 闻德评级
*/
private long orgid;
/**
* 检测机构名称
*/
private String orgName;
/**
* 验货编码
*/
private String qcNo;
/**
* 尺寸
*/
private String size;
}

View File

@@ -0,0 +1,126 @@
package com.ruoyi.erp.domain;
import com.alibaba.fastjson2.annotation.JSONField;
/**
* @author Leo
* @version 1.0
* @create 2025/4/10 15:13
* @description
*/
// ERPShop.java
import java.util.List;
@lombok.Data
public class ERPShop {
/**
* 闲鱼特卖信息,闲鱼特卖类型为临期非食品行业时必传
*/
private AdventData adventData;
/**
* 图书信息
*/
private BookData bookData;
/**
* 品牌捡漏信息
*/
private BrandData brandData;
/**
* 商品类目ID必填
* 通过“查询商品类目”接口获取;与 item_biz_type、sp_biz_type 存在依赖关系
*/
@JSONField(name = "channel_cat_id")
private String channelCatid;
/**
* 商品属性,通过`查询商品属性`接口获取属性参数
*/
@JSONField(name = "channel_pv")
private List<Channelpv> channelpv;
/**
* 详情图片(选填)
*/
@JSONField(name = "detail_images")
private List<Image> detailImages;
/**
* 运费(分)(必填)
*/
@JSONField(name = "express_fee")
private long expressFee;
/**
* 闲鱼特卖类型(选填)
* 特卖/品牌捡漏类型按需传入
*/
@JSONField(name = "flash_sale_type")
private Long flashSaleType;
/**
* 食品信息
*/
private FoodData foodData;
/**
* 验货宝信息item_biz_type=10 时必填)
*/
@JSONField(name = "inspect_data")
private Empty inspectData;
/**
* 商品类型(必填)
*/
@JSONField(name = "item_biz_type")
private long itemBizType;
/**
* 商品原价(分)(选填)
* 当 item_biz_type=24闲鱼特卖时必填
*/
@JSONField(name = "original_price")
private Long originalPrice;
/**
* 商家编码(选填)
* 一个中文按2个字符算长度 1-64
*/
@JSONField(name = "outer_id")
private String outerid;
/**
* 商品售价(分)(必填)
* 多规格商品时,必须是 SKU 其中一个金额
*/
private long price;
/**
* 发布店铺(必填)
* 至少 1 个店铺;用于指明发布到哪个闲鱼店铺
*/
@JSONField(name = "publish_shop")
private List<PublishShop> publishShop;
/**
* 验货报告信息,注意:已验货类型的商品按需必填
*/
private ReportData reportData;
/**
* 规格图片
*/
@JSONField(name = "sku_images")
private List<SkuImage> skuImages;
/**
* 商品多规格信息(选填)
* 多规格商品需传入至少一组 SKU总库存须与 stock 保持一致
*/
@JSONField(name = "sku_items")
private List<SkuItems> skuItems;
/**
* 商品行业(必填)
*/
@JSONField(name = "sp_biz_type")
private long spBizType;
/**
* 商品库存(必填)
* 取值范围 1-399960多规格商品为各 SKU 库存之和
*/
private long stock;
/**
* 商品成色(选填)
* 非普通商品类型时必填
*/
@JSONField(name = "stuff_status")
private Integer stuffStatus;
}

View File

@@ -0,0 +1,18 @@
package com.ruoyi.erp.domain;
/**
* 验货宝信息,商品类型为验货宝时必传
*
* 验货宝信息
*/
@lombok.Data
public class Empty {
/**
* 验货费规则
*/
private AssumeRule assumeRule;
/**
* 交易规则
*/
private TradeRule tradeRule;
}

View File

@@ -0,0 +1,20 @@
package com.ruoyi.erp.domain;
import java.io.IOException; /**
* 单位
*/
public enum FluffyUnit {
EMPTY;
public String toValue() {
switch (this) {
case EMPTY: return "\u5929";
}
return null;
}
public static FluffyUnit forValue(String value) throws IOException {
if (value.equals("\u5929")) return EMPTY;
throw new IOException("Cannot deserialize FluffyUnit");
}
}

View File

@@ -0,0 +1,28 @@
package com.ruoyi.erp.domain;
/**
* 食品信息
*/
@lombok.Data
public class FoodData {
/**
* 食品品牌
*/
private String brand;
/**
* 食品有效期信息
*/
private FoodDataExpire expire;
/**
* 食品包装
*/
private String pack;
/**
* 食品生产信息
*/
private FoodDataProduction production;
/**
* 食品规格
*/
private String spec;
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.erp.domain;
/**
* 食品有效期信息
*/
@lombok.Data
public class FoodDataExpire {
/**
* 保质期
*/
private long num;
/**
* 单位
*/
private PurpleUnit unit;
}

View File

@@ -0,0 +1,16 @@
package com.ruoyi.erp.domain;
/**
* 食品生产信息
*/
@lombok.Data
public class FoodDataProduction {
/**
* 食品生产地信息
*/
private Address address;
/**
* 食品生产日期
*/
private String date;
}

View File

@@ -0,0 +1,28 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 游戏信息
*/
@lombok.Data
public class Game {
/**
* 验货图片
*/
private List<String> images;
/**
* 游戏平台
*/
private String platform;
/**
* 验货描述
*/
private String qcDesc;
/**
* 验货编码
*/
private String qcNo;
/**
* 报告标题
*/
private String title;
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.erp.domain;
/**
* 资质证明
*
* 新图片信息
*/
@lombok.Data
public class Image {
/**
* 图片高度
*/
private long height;
/**
* 图片地址
*/
private String src;
/**
* 图片宽度
*/
private long width;
}

View File

@@ -0,0 +1,36 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 珠宝信息
*/
@lombok.Data
public class Jewelry {
/**
* 颜色
*/
private String color;
/**
* 验货图片
*/
private List<String> images;
/**
* 检测机构名称
*/
private String orgName;
/**
* 验货描述
*/
private String qcDesc;
/**
* 验货编码
*/
private String qcNo;
/**
* 形状
*/
private String shape;
/**
* 重量
*/
private String weight;
}

View File

@@ -0,0 +1,52 @@
package com.ruoyi.erp.domain;
import java.util.List;
import com.alibaba.fastjson2.annotation.JSONField;
@lombok.Data
public class PublishShop {
/**
* 商品发货城市(必填)
*/
private long city;
/**
* 商品描述(必填)
* 注意一个中文按2个字符算不支持HTML可用 \n 换行;长度 5-5000
*/
private String content;
/**
* 商品发货地区(必填)
*/
private long district;
/**
* 商品图片URL必填
* 注意:第 1 张作为商品主图,前 9 张发布到闲鱼 App
*/
private List<String> images;
/**
* 商品发货省份(必填)
*/
private long province;
/**
* 商品服务(选填)
* 多个以英文逗号分隔。如SDR,NFR
*/
@JSONField(name = "service_support")
private String serviceSupport;
/**
* 商品标题(必填)
* 注意:一个中文按 2 个字符算;长度 1-60
*/
private String title;
/**
* 闲鱼会员名(必填)
*/
@JSONField(name = "user_name")
private String userName;
/**
* 商品白底图URL选填
* 注意:如传入会在闲鱼商品详情显示且不可删除;当 item_biz_type=24特卖时必填
*/
@JSONField(name = "white_images")
private String whiteImages;
}

View File

@@ -0,0 +1,24 @@
package com.ruoyi.erp.domain;
import java.io.IOException; /**
* 单位
*/
public enum PurpleUnit {
EMPTY, PURPLE, UNIT;
public String toValue() {
switch (this) {
case EMPTY: return "\u5929";
case PURPLE: return "\u5e74";
case UNIT: return "\u6708";
}
return null;
}
public static PurpleUnit forValue(String value) throws IOException {
if (value.equals("\u5929")) return EMPTY;
if (value.equals("\u5e74")) return PURPLE;
if (value.equals("\u6708")) return UNIT;
throw new IOException("Cannot deserialize PurpleUnit");
}
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.erp.domain;
/**
* 行政区划原始表实体,映射 xgj_region
*/
@lombok.Data
public class Region {
/** 省级行政区划代码 */
private Integer provId;
/** 省级名称 */
private String provName;
/** 市级行政区划代码 */
private Integer cityId;
/** 市级名称 */
private String cityName;
/** 区县级行政区划代码 */
private Integer areaId;
/** 区县名称 */
private String areaName;
}

View File

@@ -0,0 +1,35 @@
package com.ruoyi.erp.domain;
/**
* 验货报告信息,注意:已验货类型的商品按需必填
*
* 验货报告信息
*/
@lombok.Data
public class ReportData {
/**
* 美妆信息
*/
private BeautyMakeup beautyMakeup;
/**
* 文玩信息
*/
private Curio curio;
/**
* 游戏信息
*/
private Game game;
/**
* 珠宝信息
*/
private Jewelry jewelry;
/**
* 二手车信息
*/
private UsedCar usedCar;
/**
* 奢品信息
*/
private Valuable valuable;
private The3C yx3C;
}

View File

@@ -0,0 +1,33 @@
package com.ruoyi.erp.domain;
@lombok.Data
public class ReportItem {
/**
* 选项描述
*/
private String answerDesc;
/**
* 选项ID
*/
private long answerid;
/**
* 选项名称
*/
private String answerName;
/**
* 选项类型
*/
private long answerType;
/**
* 分类名称
*/
private String categoryName;
/**
* 分组名称
*/
private String groupName;
/**
* 问题名称
*/
private String questionName;
}

View File

@@ -0,0 +1,26 @@
package com.ruoyi.erp.domain;
import com.alibaba.fastjson2.annotation.JSONField;
/**
* 规格图片
*/
@lombok.Data
public class SkuImage {
/**
* 图片高度(必填)
*/
private long height;
/**
* 规格属性(必填)
*/
@JSONField(name = "sku_text")
private String skuText;
/**
* 图片地址(必填)
*/
private String src;
/**
* 图片宽度(必填)
*/
private long width;
}

View File

@@ -0,0 +1,30 @@
package com.ruoyi.erp.domain;
import com.alibaba.fastjson2.annotation.JSONField;
/**
* SKU信息
*/
@lombok.Data
public class SkuItems {
/**
* SKU商品编码选填
* 注意:一个中文按 2 个字符算;长度 0-64
*/
@JSONField(name = "outer_id")
private String outerid;
/**
* SKU售价必填
*/
private long price;
/**
* SKU规格必填
* 格式:规格:属性;多个用 ";" 拼接。如:颜色:白色;容量:128G
*/
@JSONField(name = "sku_text")
private String skuText;
/**
* SKU库存必填
* 取值范围 0-9999
*/
private long stock;
}

View File

@@ -0,0 +1,52 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 严选3c信息
*/
@lombok.Data
public class The3C {
/**
* 质检选项ID内部存储不对外展示
*/
private List<Long> answerids;
/**
* 品牌ID
*/
private long brandid;
/**
* 品牌名称
*/
private String brandName;
/**
* 品类ID
*/
private long classid;
/**
* 机型ID
*/
private long modelid;
/**
* 机型名称
*/
private String modelName;
/**
* IMEI/序列号
*/
private String modelSn;
/**
* 质检报告项,体现在商品验货报告页
*/
private List<ReportItem> reportItems;
/**
* 质检时间,体现在商品验货报告页
*/
private String reportTime;
/**
* 质检人,体现在商品验货报告页
*/
private String reportUser;
/**
* 子类ID
*/
private long subclassid;
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.erp.domain;
import java.io.IOException; /**
* 交易规则
*/
public enum TradeRule {
YHB_ONLY, YHB_OPTIONAL;
public String toValue() {
switch (this) {
case YHB_ONLY: return "yhbOnly";
case YHB_OPTIONAL: return "yhbOptional";
}
return null;
}
public static TradeRule forValue(String value) throws IOException {
if (value.equals("yhbOnly")) return YHB_ONLY;
if (value.equals("yhbOptional")) return YHB_OPTIONAL;
throw new IOException("Cannot deserialize TradeRule");
}
}

View File

@@ -0,0 +1,34 @@
package com.ruoyi.erp.domain;
/**
* 二手车信息
*
* OpenProductReportUsedCar
*/
@lombok.Data
public class UsedCar {
/**
* 营业执照图片
*/
private String businessLicenseFront;
/**
* 使用性质 : 营运/非营运
*/
private String carFunction;
/**
* 车辆识别代码VIN码
*/
private String carVin;
/**
* 行驶证车辆页图片
*/
private String drivingLicenseCarPhoto;
/**
* 行驶证主页图片
*/
private String drivingLicenseInfo;
/**
* 验货报告链接
*/
private String reporturl;
}

View File

@@ -0,0 +1,32 @@
package com.ruoyi.erp.domain;
import java.util.List; /**
* 奢品信息
*/
@lombok.Data
public class Valuable {
/**
* 验货图片
*/
private List<String> images;
/**
* 检测机构ID枚举值
* 161 : 中检
* 162 : 国检
* 163 : 华测
* 164 : 中溯
*/
private long orgid;
/**
* 检测机构名称
*/
private String orgName;
/**
* 验货描述
*/
private String qcDesc;
/**
* 验货编码
*/
private String qcNo;
}

View File

@@ -0,0 +1,23 @@
package com.ruoyi.erp.domain.enums;
/** 闲鱼特卖类型(含品牌捡漏扩展) */
public enum FlashSaleType {
LINQI(1),
GUPIN(2),
DUANMA(3),
WEIXIA(4),
WEIHUO(5),
OFFICIAL_REFURB(6),
BRAND_NEW(7),
LUCKY_BAG(8),
OTHER(99),
BRAND_WEIXIA(2601),
BRAND_LINQI(2602),
BRAND_CLEAR(2603),
BRAND_REFURB(2604);
public final int code;
FlashSaleType(int code) { this.code = code; }
}

View File

@@ -0,0 +1,17 @@
package com.ruoyi.erp.domain.enums;
/** 商品类型 */
public enum ItemBizType {
NORMAL(2),
CHECKED(0),
YANHUOBAO(10),
BRAND_AUTH(16),
SELECTED(19),
FLASH_SALE(24),
BRAND_CLEARANCE(26);
public final int code;
ItemBizType(int code) { this.code = code; }
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.erp.domain.enums;
/** 商品服务项(可按逗号拼接多个) */
public enum ServiceSupport {
SDR, // 七天无理由退货
NFR, // 描述不符包邮退
VNR, // 描述不符全额退(虚拟类)
FD_10MS, // 10分钟极速发货虚拟类
FD_24HS, // 24小时极速发货
FD_48HS, // 48小时极速发货
FD_GPA; // 正品保障
}

View File

@@ -0,0 +1,32 @@
package com.ruoyi.erp.domain.enums;
/** 行业类型(节选,完整可按文档扩充) */
public enum SpBizType {
PHONE(1),
FASHION(2),
APPLIANCE(3),
INSTRUMENT(8),
DIGITAL_3C(9),
LUXURY(16),
MOM_BABY(17),
BEAUTY(18),
JEWELRY(19),
GAME(20),
HOME(21),
VIRTUAL(22),
RENT_ACCOUNT(23),
BOOK(24),
COUPON(25),
FOOD(27),
TOY(28),
CAR(29),
PET_PLANT(30),
GIFT(31),
CAR_SERVICE(33),
OTHER(99);
public final int code;
SpBizType(int code) { this.code = code; }
}

View File

@@ -0,0 +1,24 @@
package com.ruoyi.erp.domain.enums;
/** 商品成色 */
public enum StuffStatus {
NONE(0),
NEW_100(100),
LIKE_NEW(-1),
NINETY_NINE(99),
NINETY_FIVE(95),
NINETY(90),
EIGHTY(80),
SEVENTY(70),
SIXTY(60),
FIFTY(50),
BRAND_CLEAR_40(40),
BRAND_CLEAR_30(30),
BRAND_CLEAR_20(20),
BRAND_CLEAR_10(10);
public final int code;
StuffStatus(int code) { this.code = code; }
}

View File

@@ -0,0 +1,18 @@
package com.ruoyi.erp.mapper;
import com.ruoyi.erp.domain.Region;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface RegionMapper {
List<Region> selectProvinces();
List<Region> selectCitiesByProv(@Param("provId") Integer provId);
List<Region> selectAreasByCity(@Param("provId") Integer provId, @Param("cityId") Integer cityId);
}

View File

@@ -0,0 +1,35 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 授权列表查询请求(示例类)
*/
public class AuthorizeListQueryRequest extends ERPRequestBase {
public AuthorizeListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/user/authorize/list", erpAccount);
}
/**
* 设置分页参数
* @param pageNum 页码
* @param pageSize 每页数量
*/
public void setPagination(int pageNum, int pageSize) {
JSONObject params = new JSONObject();
params.put("page_num", pageNum);
params.put("page_size", pageSize);
this.requestBody = params;
}
/**
* 设置过滤条件
* @param status 授权状态
*/
public void setFilter(String status) {
if (requestBody == null) {
requestBody = new JSONObject();
}
requestBody.put("status", status);
}
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.erp.request;
import lombok.Getter;
/**
* @author Leo
* @version 1.0
* @create 2025/4/10 15:20
* @descriptionERP账户枚举类
*/
@Getter
public enum ERPAccount {
// 胡歌1016208368633221
ACCOUNT_HUGE("1016208368633221", "waLiRMgFcixLbcLjUSSwo370Hp1nBcBu","余生请多关照66","海尔胡歌"),
// 刘强东anotherApiKey
ACCOUNT_LQD("anotherApiKey", "anotherApiSecret","刘强东","方案小号");
private final String apiKey;
private final String apiKeySecret;
private final String xyName;
private final String remark;
ERPAccount(String apiKey, String apiKeySecret, String xyName,String remark) {
this.apiKey = apiKey;
this.apiKeySecret = apiKeySecret;
this.xyName = xyName;
this.remark = remark;
}
}

View File

@@ -0,0 +1,99 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.http.HttpUtils;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* ERP请求基类支持开放平台签名规范
*/
public abstract class ERPRequestBase {
private static final Logger log = LoggerFactory.getLogger(ERPRequestBase.class);
protected String url;
protected String sign;
protected ERPAccount erpAccount;
@Setter
protected JSONObject requestBody;
protected long timestamp; // 统一时间戳字段
public ERPRequestBase(String url, ERPAccount erpAccount) {
this.url = url;
this.erpAccount = erpAccount;
}
/**
* 生成MD5签名兼容官方示例
* @param str 需要签名的原始字符串
* @return 十六进制小写MD5值
*/
public String genMd5(String str) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
StringBuilder result = new StringBuilder();
for (byte b : digest) {
result.append(String.format("%02x", b & 0xff)); // 保证小写十六进制
}
return result.toString();
} catch (NoSuchAlgorithmException e) {
log.error("MD5算法初始化失败", e);
throw new RuntimeException("MD5算法初始化失败", e);
}
}
/**
* 生成请求签名(与官方示例保持完全一致的拼接逻辑)
*/
public void genSign(long timestamp) {
this.timestamp = timestamp;
String jsonStr = getRequestBody(); // 使用getRequestBody()方法
String data = erpAccount.getApiKey() + "," + genMd5(jsonStr) + "," + timestamp + "," + erpAccount.getApiKeySecret();
this.sign = genMd5(data);
}
/**
* 获取带签名的请求URL
* @return 包含签名参数的完整URL
*/
public String getRequestUrl() {
return url + "?appid=" + erpAccount.getApiKey() + "&timestamp=" + timestamp + "&sign=" + sign;
}
/**
* 获取请求体内容(空时返回空对象)
* @return JSON字符串格式的请求体
*/
public String getRequestBody() {
return requestBody != null ? requestBody.toJSONString() : "{}";
}
/**
* 执行HTTP请求并获取响应
* @return 接口返回的原始JSON字符串
*/
public String getResponseBody() {
try {
long timestamp = System.currentTimeMillis() / 1000;
genSign(timestamp);
String requestUrl = getRequestUrl();
String body = getRequestBody();
System.out.println("请求地址: " + requestUrl);
System.out.println("请求体: " + body);
if (requestBody == null) {
return HttpUtils.sendPost(requestUrl, body); // 保持 body 一致
}
return HttpUtils.sendJsonPost(requestUrl, body);
} catch (Exception e) {
log.error("HTTP请求失败: {}", e.getMessage(), e);
throw new RuntimeException("ERP接口调用失败: " + e.getMessage(), e);
}
}
}

View File

@@ -0,0 +1,14 @@
package com.ruoyi.erp.request;
/**
* 查询快递公司请求
*
* 对应接口POST /api/open/express/companies
*/
public class ExpressCompaniesQueryRequest extends ERPRequestBase {
public ExpressCompaniesQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/express/companies", erpAccount);
}
}

View File

@@ -0,0 +1,106 @@
package com.ruoyi.erp.request;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HttpTest {
private static final String apiKey = "1016208368633221"; // 开放平台提供的应用KEY
private static final String apiKeySecret = "waLiRMgFcixLbcLjUSSwo370Hp1nBcBu"; // 开放平台提供的应用密钥
private static final String domain = "https://open.goofish.pro"; // 域名
public static void main(String[] args) {
// 获取当前时间戳
long timestamp = System.currentTimeMillis() / 1000L;
System.out.println("timestamp: " + timestamp);
// 请求体JSON字符串
String jsonBody = "{}";
// 生成签名
String sign = genSign(timestamp, jsonBody);
System.out.println("sign: " + sign);
// 拼接请求地址
String apiUrl = domain + "/api/open/product/list?appid=" + apiKey + "&timestamp=" + timestamp + "&sign="
+ sign;
try {
// 创建URL对象
URL url = new URL(apiUrl);
// 打开连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法为POST
connection.setRequestMethod("POST");
// 设置请求头部
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
// 启用输出流
connection.setDoOutput(true);
// 获取输出流并写入请求体
OutputStream outputStream = connection.getOutputStream();
outputStream.write(jsonBody.getBytes(StandardCharsets.UTF_8));
outputStream.close();
// 获取响应状态码
int responseCode = connection.getResponseCode();
System.out.println("API Response Code: " + responseCode);
// 读取响应内容
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
StringBuilder response = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
response.append(line);
}
bufferedReader.close();
// 关闭连接
connection.disconnect();
System.out.println("API Response: " + response.toString());
} catch (IOException e) {
// 在此处处理异常
e.printStackTrace();
}
}
// md5加密
private static String genMd5(String str) {
StringBuilder result = new StringBuilder();
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(str.getBytes(StandardCharsets.UTF_8));
for (byte b : digest) {
result.append(String.format("%02x", b & 0xff));
}
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
return result.toString();
}
// 生成签名
private static String genSign(long timestamp, String jsonStr) {
// 拼接字符串
String data = apiKey + "," + genMd5(jsonStr) + "," + timestamp + "," + apiKeySecret;
// 商务对接模式 拼接字符串
// String data = apiKey + "," + genMd5(jsonStr) + "," + timestamp + "," + seller_id + "," + apiKeySecret;
// 生成签名
return genMd5(data);
}
}

View File

@@ -0,0 +1,23 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 查询订单详情请求
*
* 对应接口POST /api/open/order/detail
*/
public class OrderDetailQueryRequest extends ERPRequestBase {
public OrderDetailQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/order/detail", erpAccount);
}
public void setOrderNo(String orderNo) {
ensureBody();
this.requestBody.put("order_no", orderNo);
}
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
}

View File

@@ -0,0 +1,23 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 订单卡密列表请求
*
* 对应接口POST /api/open/order/kam/list
*/
public class OrderKamListQueryRequest extends ERPRequestBase {
public OrderKamListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/order/kam/list", erpAccount);
}
public void setOrderNo(String orderNo) {
ensureBody();
this.requestBody.put("order_no", orderNo);
}
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
}

View File

@@ -0,0 +1,35 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 查询订单列表请求
*
* 对应接口POST /api/open/order/list
*/
public class OrderListQueryRequest extends ERPRequestBase {
public OrderListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/order/list", erpAccount);
}
public void setAuthorizeId(long authorizeId) { ensureBody(); this.requestBody.put("authorize_id", authorizeId); }
public void setOrderStatus(Integer orderStatus) { putIfNotNull("order_status", orderStatus); }
public void setRefundStatus(Integer refundStatus) { putIfNotNull("refund_status", refundStatus); }
public void setOrderTime(long start, long end) { setRange("order_time", start, end); }
public void setPayTime(long start, long end) { setRange("pay_time", start, end); }
public void setConsignTime(long start, long end) { setRange("consign_time", start, end); }
public void setConfirmTime(long start, long end) { setRange("confirm_time", start, end); }
public void setRefundTime(long start, long end) { setRange("refund_time", start, end); }
public void setUpdateTime(long start, long end) { setRange("update_time", start, end); }
public void setPageNo(int pageNo) { ensureBody(); this.requestBody.put("page_no", pageNo); }
public void setPageSize(int pageSize) { ensureBody(); this.requestBody.put("page_size", pageSize); }
public void setPage(int pageNo, int pageSize) { ensureBody(); this.requestBody.put("page_no", pageNo); this.requestBody.put("page_size", pageSize); }
private void setRange(String key, long start, long end) { ensureBody(); this.requestBody.put(key, new long[]{start, end}); }
private void putIfNotNull(String key, Object value) { if (value != null) { ensureBody(); this.requestBody.put(key, value); } }
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
}

View File

@@ -0,0 +1,22 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 订单修改价格请求
*
* 对应接口POST /api/open/order/modify/price
*/
public class OrderModifyPriceRequest extends ERPRequestBase {
public OrderModifyPriceRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/order/modify/price", erpAccount);
}
public void setOrderNo(String orderNo) { ensureBody(); this.requestBody.put("order_no", orderNo); }
public void setExpressFee(long expressFee) { ensureBody(); this.requestBody.put("express_fee", expressFee); }
public void setOrderPrice(long orderPrice) { ensureBody(); this.requestBody.put("order_price", orderPrice); }
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
}

View File

@@ -0,0 +1,31 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 订单物流发货请求
*
* 对应接口POST /api/open/order/ship
*/
public class OrderShipRequest extends ERPRequestBase {
public OrderShipRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/order/ship", erpAccount);
}
public void setOrderNo(String orderNo) { put("order_no", orderNo); }
public void setShipName(String shipName) { put("ship_name", shipName); }
public void setShipMobile(String shipMobile) { put("ship_mobile", shipMobile); }
public void setShipDistrictId(Integer shipDistrictId) { put("ship_district_id", shipDistrictId); }
public void setShipProvName(String shipProvName) { put("ship_prov_name", shipProvName); }
public void setShipCityName(String shipCityName) { put("ship_city_name", shipCityName); }
public void setShipAreaName(String shipAreaName) { put("ship_area_name", shipAreaName); }
public void setShipAddress(String shipAddress) { put("ship_address", shipAddress); }
public void setWaybillNo(String waybillNo) { put("waybill_no", waybillNo); }
public void setExpressCode(String expressCode) { put("express_code", expressCode); }
public void setExpressName(String expressName) { put("express_name", expressName); }
private void put(String key, Object value) { if (value != null) { ensureBody(); this.requestBody.put(key, value); } }
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
}

View File

@@ -0,0 +1,231 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.util.Collection;
import java.util.List;
/**
* 创建商品(批量)请求
*
* 对应接口POST /api/open/product/batchCreate
* 限制每批次最多50个商品
*/
public class ProductBatchCreateRequest extends ERPRequestBase {
public ProductBatchCreateRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/batchCreate", erpAccount);
}
/**
* 设置一批商品数据,覆盖已有的 product_data
*/
public void setProducts(Collection<ProductBuilder> products) {
ensureRequestBodyInitialized();
if (products == null || products.isEmpty()) {
throw new IllegalArgumentException("product_data不能为空");
}
if (products.size() > 50) {
throw new IllegalArgumentException("每批次最多创建50个商品");
}
JSONArray array = new JSONArray();
for (ProductBuilder builder : products) {
array.add(builder.build());
}
this.requestBody.put("product_data", array);
}
/**
* 在原有 product_data 基础上追加一个商品
*/
public void addProduct(ProductBuilder product) {
ensureRequestBodyInitialized();
JSONArray array = this.requestBody.getJSONArray("product_data");
if (array == null) {
array = new JSONArray();
this.requestBody.put("product_data", array);
}
if (array.size() >= 50) {
throw new IllegalStateException("每批次最多创建50个商品");
}
array.add(product.build());
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
/**
* 单个商品数据构建器
*/
public static class ProductBuilder {
private final JSONObject data = new JSONObject();
private final JSONArray channelPv = new JSONArray();
private final JSONArray publishShop = new JSONArray();
private final JSONArray skuItems = new JSONArray();
public ProductBuilder setItemKey(String itemKey) {
data.put("item_key", itemKey);
return this;
}
public ProductBuilder setItemBizType(int itemBizType) {
data.put("item_biz_type", itemBizType);
return this;
}
public ProductBuilder setSpBizType(int spBizType) {
data.put("sp_biz_type", spBizType);
return this;
}
public ProductBuilder setChannelCatId(String channelCatId) {
data.put("channel_cat_id", channelCatId);
return this;
}
public ProductBuilder setPrice(long price) {
data.put("price", price);
return this;
}
public ProductBuilder setOriginalPrice(Long originalPrice) {
if (originalPrice != null) {
data.put("original_price", originalPrice);
}
return this;
}
public ProductBuilder setExpressFee(Long expressFee) {
if (expressFee != null) {
data.put("express_fee", expressFee);
}
return this;
}
public ProductBuilder setStock(int stock) {
data.put("stock", stock);
return this;
}
public ProductBuilder setOuterId(String outerId) {
if (outerId != null) {
data.put("outer_id", outerId);
}
return this;
}
public ProductBuilder setStuffStatus(Integer stuffStatus) {
if (stuffStatus != null) {
data.put("stuff_status", stuffStatus);
}
return this;
}
public ProductBuilder addChannelPv(String propertyId, String propertyName, String valueId, String valueName) {
JSONObject pv = new JSONObject();
pv.put("property_id", propertyId);
pv.put("property_name", propertyName);
pv.put("value_id", valueId);
pv.put("value_name", valueName);
channelPv.add(pv);
return this;
}
public ProductBuilder addPublishShop(String userName, int province, int city, int district, String title, String content, List<String> images, String whiteImages, String serviceSupport) {
JSONObject shop = new JSONObject();
shop.put("user_name", userName);
shop.put("province", province);
shop.put("city", city);
shop.put("district", district);
shop.put("title", title);
shop.put("content", content);
if (images != null && !images.isEmpty()) {
JSONArray imgs = new JSONArray();
imgs.addAll(images);
shop.put("images", imgs);
}
if (whiteImages != null) {
shop.put("white_images", whiteImages);
}
if (serviceSupport != null) {
shop.put("service_support", serviceSupport);
}
publishShop.add(shop);
return this;
}
public ProductBuilder addSkuItem(long price, int stock, String skuText, String outerId) {
JSONObject sku = new JSONObject();
sku.put("price", price);
sku.put("stock", stock);
sku.put("sku_text", skuText);
if (outerId != null) {
sku.put("outer_id", outerId);
}
skuItems.add(sku);
return this;
}
public ProductBuilder setDetailImages(JSONArray images) {
if (images != null) {
data.put("detail_images", images);
}
return this;
}
public ProductBuilder setSkuImages(JSONArray images) {
if (images != null) {
data.put("sku_images", images);
}
return this;
}
public ProductBuilder setBookData(JSONObject bookData) { return putIfNotNull("book_data", bookData); }
public ProductBuilder setFoodData(JSONObject foodData) { return putIfNotNull("food_data", foodData); }
public ProductBuilder setReportData(JSONObject reportData) { return putIfNotNull("report_data", reportData); }
public ProductBuilder setFlashSaleType(Integer flashSaleType) { if (flashSaleType != null) data.put("flash_sale_type", flashSaleType); return this; }
public ProductBuilder setAdventData(JSONObject adventData) { return putIfNotNull("advent_data", adventData); }
public ProductBuilder setInspectData(JSONObject inspectData) { return putIfNotNull("inspect_data", inspectData); }
public ProductBuilder setBrandData(JSONObject brandData) { return putIfNotNull("brand_data", brandData); }
private ProductBuilder putIfNotNull(String key, Object value) {
if (value != null) {
data.put(key, value);
}
return this;
}
private void finalizeArrays() {
if (!channelPv.isEmpty()) {
data.put("channel_pv", channelPv);
}
if (!publishShop.isEmpty()) {
data.put("publish_shop", publishShop);
}
if (!skuItems.isEmpty()) {
data.put("sku_items", skuItems);
}
}
private void validateRequired() {
if (!data.containsKey("item_key")) throw new IllegalStateException("缺少必填字段: item_key");
if (!data.containsKey("item_biz_type")) throw new IllegalStateException("缺少必填字段: item_biz_type");
if (!data.containsKey("sp_biz_type")) throw new IllegalStateException("缺少必填字段: sp_biz_type");
if (!data.containsKey("channel_cat_id")) throw new IllegalStateException("缺少必填字段: channel_cat_id");
if (!data.containsKey("price")) throw new IllegalStateException("缺少必填字段: price");
if (!data.containsKey("stock")) throw new IllegalStateException("缺少必填字段: stock");
if (publishShop.isEmpty()) throw new IllegalStateException("缺少必填字段: publish_shop");
}
private JSONObject build() {
finalizeArrays();
validateRequired();
return data;
}
}
}

View File

@@ -0,0 +1,59 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 查询商品类目请求
*
* 对应接口POST /api/open/product/category/list
* 请求体字段:
* - item_biz_type必填商品类型
* - sp_biz_type选填行业类型
* - flash_sale_type选填闲鱼特卖类型
*/
public class ProductCategoryListQueryRequest extends ERPRequestBase {
public ProductCategoryListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/category/list", erpAccount);
}
/**
* 设置商品类型(必填)
* @param itemBizType 商品类型
*/
public void setItemBizType(int itemBizType) {
ensureRequestBodyInitialized();
this.requestBody.put("item_biz_type", itemBizType);
}
/**
* 设置行业类型(选填)
* @param spBizType 行业类型
*/
public void setSpBizType(Integer spBizType) {
if (spBizType == null) {
return;
}
ensureRequestBodyInitialized();
this.requestBody.put("sp_biz_type", spBizType);
}
/**
* 设置闲鱼特卖类型(选填)
* @param flashSaleType 闲鱼特卖类型
*/
public void setFlashSaleType(Integer flashSaleType) {
if (flashSaleType == null) {
return;
}
ensureRequestBodyInitialized();
this.requestBody.put("flash_sale_type", flashSaleType);
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
}

View File

@@ -0,0 +1,142 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.util.List;
/**
* 创建商品(单个)请求
*
* 对应接口POST /api/open/product/create
*/
public class ProductCreateRequest extends ERPRequestBase {
private final JSONArray channelPv = new JSONArray();
private final JSONArray publishShop = new JSONArray();
private final JSONArray skuItems = new JSONArray();
public ProductCreateRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/create", erpAccount);
}
public void setItemBizType(int itemBizType) {
ensureRequestBodyInitialized();
this.requestBody.put("item_biz_type", itemBizType);
}
public void setSpBizType(int spBizType) {
ensureRequestBodyInitialized();
this.requestBody.put("sp_biz_type", spBizType);
}
public void setChannelCatId(String channelCatId) {
ensureRequestBodyInitialized();
this.requestBody.put("channel_cat_id", channelCatId);
}
public void addChannelPv(String propertyId, String propertyName, String valueId, String valueName) {
JSONObject pv = new JSONObject();
pv.put("property_id", propertyId);
pv.put("property_name", propertyName);
pv.put("value_id", valueId);
pv.put("value_name", valueName);
channelPv.add(pv);
ensureRequestBodyInitialized();
this.requestBody.put("channel_pv", channelPv);
}
public void setPrice(long price) {
ensureRequestBodyInitialized();
this.requestBody.put("price", price);
}
public void setOriginalPrice(Long originalPrice) {
if (originalPrice == null) return;
ensureRequestBodyInitialized();
this.requestBody.put("original_price", originalPrice);
}
public void setExpressFee(long expressFee) {
ensureRequestBodyInitialized();
this.requestBody.put("express_fee", expressFee);
}
public void setStock(int stock) {
ensureRequestBodyInitialized();
this.requestBody.put("stock", stock);
}
public void setOuterId(String outerId) {
if (outerId == null) return;
ensureRequestBodyInitialized();
this.requestBody.put("outer_id", outerId);
}
public void setStuffStatus(Integer stuffStatus) {
if (stuffStatus == null) return;
ensureRequestBodyInitialized();
this.requestBody.put("stuff_status", stuffStatus);
}
public void addPublishShop(String userName, int province, int city, int district, String title, String content, List<String> images, String whiteImages, String serviceSupport) {
JSONObject shop = new JSONObject();
shop.put("user_name", userName);
shop.put("province", province);
shop.put("city", city);
shop.put("district", district);
shop.put("title", title);
shop.put("content", content);
if (images != null && !images.isEmpty()) {
JSONArray imgs = new JSONArray();
imgs.addAll(images);
shop.put("images", imgs);
}
if (whiteImages != null) {
shop.put("white_images", whiteImages);
}
if (serviceSupport != null) {
shop.put("service_support", serviceSupport);
}
publishShop.add(shop);
ensureRequestBodyInitialized();
this.requestBody.put("publish_shop", publishShop);
}
public void addSkuItem(long price, int stock, String skuText, String outerId) {
JSONObject sku = new JSONObject();
sku.put("price", price);
sku.put("stock", stock);
sku.put("sku_text", skuText);
if (outerId != null) {
sku.put("outer_id", outerId);
}
skuItems.add(sku);
ensureRequestBodyInitialized();
this.requestBody.put("sku_items", skuItems);
}
public void setBookData(JSONObject bookData) { putIfNotNull("book_data", bookData); }
public void setFoodData(JSONObject foodData) { putIfNotNull("food_data", foodData); }
public void setReportData(JSONObject reportData) { putIfNotNull("report_data", reportData); }
public void setFlashSaleType(Integer flashSaleType) { if (flashSaleType != null) { ensureRequestBodyInitialized(); this.requestBody.put("flash_sale_type", flashSaleType); } }
public void setAdventData(JSONObject adventData) { putIfNotNull("advent_data", adventData); }
public void setInspectData(JSONObject inspectData) { putIfNotNull("inspect_data", inspectData); }
public void setBrandData(JSONObject brandData) { putIfNotNull("brand_data", brandData); }
public void setDetailImages(JSONArray images) { if (images != null) { ensureRequestBodyInitialized(); this.requestBody.put("detail_images", images); } }
public void setSkuImages(JSONArray images) { if (images != null) { ensureRequestBodyInitialized(); this.requestBody.put("sku_images", images); } }
private void putIfNotNull(String key, Object value) {
if (value != null) {
ensureRequestBodyInitialized();
this.requestBody.put(key, value);
}
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
}

View File

@@ -0,0 +1,25 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 删除商品请求
*
* 对应接口POST /api/open/product/delete
*/
public class ProductDeleteRequest extends ERPRequestBase {
public ProductDeleteRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/delete", erpAccount);
}
public void setProductId(long productId) {
ensureBody();
this.requestBody.put("product_id", productId);
}
private void ensureBody() {
if (this.requestBody == null) this.requestBody = new JSONObject();
}
}

View File

@@ -0,0 +1,33 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 查询商品详情请求
*
* 对应接口POST /api/open/product/detail
* 请求体字段:
* - product_id必填管家商品ID
*/
public class ProductDetailQueryRequest extends ERPRequestBase {
public ProductDetailQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/detail", erpAccount);
}
/**
* 设置管家商品ID必填
* @param productId 管家商品ID
*/
public void setProductId(long productId) {
ensureRequestBodyInitialized();
this.requestBody.put("product_id", productId);
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
}

View File

@@ -0,0 +1,25 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 下架商品请求
*
* 对应接口POST /api/open/product/downShelf
*/
public class ProductDownShelfRequest extends ERPRequestBase {
public ProductDownShelfRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/downShelf", erpAccount);
}
public void setProductId(long productId) {
ensureBody();
this.requestBody.put("product_id", productId);
}
private void ensureBody() {
if (this.requestBody == null) this.requestBody = new JSONObject();
}
}

View File

@@ -0,0 +1,89 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.util.List;
/**
* 编辑商品请求(按需传入要修改的字段)
*
* 对应接口POST /api/open/product/edit
*/
public class ProductEditRequest extends ERPRequestBase {
private final JSONArray channelPv = new JSONArray();
private final JSONArray publishShop = new JSONArray();
private final JSONArray skuItems = new JSONArray();
public ProductEditRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/edit", erpAccount);
}
public void setProductId(long productId) { ensureBody(); this.requestBody.put("product_id", productId); }
public void setItemBizType(Integer itemBizType) { putIfNotNull("item_biz_type", itemBizType); }
public void setSpBizType(Integer spBizType) { putIfNotNull("sp_biz_type", spBizType); }
public void setCategoryId(Integer categoryId) { putIfNotNull("category_id", categoryId); }
public void setChannelCatId(String channelCatId) { putIfNotNull("channel_cat_id", channelCatId); }
public void addChannelPv(String propertyId, String propertyName, String valueId, String valueName) {
JSONObject pv = new JSONObject();
pv.put("property_id", propertyId);
pv.put("property_name", propertyName);
pv.put("value_id", valueId);
pv.put("value_name", valueName);
channelPv.add(pv);
ensureBody();
this.requestBody.put("channel_pv", channelPv);
}
public void setTitle(String title) { putIfNotNull("title", title); }
public void setPrice(Long price) { putIfNotNull("price", price); }
public void setOriginalPrice(Long originalPrice) { putIfNotNull("original_price", originalPrice); }
public void setExpressFee(Long expressFee) { putIfNotNull("express_fee", expressFee); }
public void setStock(Integer stock) { putIfNotNull("stock", stock); }
public void setOuterId(String outerId) { putIfNotNull("outer_id", outerId); }
public void setStuffStatus(Integer stuffStatus) { putIfNotNull("stuff_status", stuffStatus); }
public void addPublishShop(String userName, Integer province, Integer city, Integer district, String title, String content, List<String> images, String whiteImages, String serviceSupport) {
JSONObject shop = new JSONObject();
if (userName != null) shop.put("user_name", userName);
if (province != null) shop.put("province", province);
if (city != null) shop.put("city", city);
if (district != null) shop.put("district", district);
if (title != null) shop.put("title", title);
if (content != null) shop.put("content", content);
if (images != null && !images.isEmpty()) {
JSONArray imgs = new JSONArray();
imgs.addAll(images);
shop.put("images", imgs);
}
if (whiteImages != null) shop.put("white_images", whiteImages);
if (serviceSupport != null) shop.put("service_support", serviceSupport);
publishShop.add(shop);
ensureBody();
this.requestBody.put("publish_shop", publishShop);
}
public void addSkuItem(Long price, Integer stock, String skuText, String outerId) {
JSONObject sku = new JSONObject();
if (price != null) sku.put("price", price);
if (stock != null) sku.put("stock", stock);
if (skuText != null) sku.put("sku_text", skuText);
if (outerId != null) sku.put("outer_id", outerId);
skuItems.add(sku);
ensureBody();
this.requestBody.put("sku_items", skuItems);
}
public void setBookData(JSONObject bookData) { putIfNotNull("book_data", bookData); }
public void setFoodData(JSONObject foodData) { putIfNotNull("food_data", foodData); }
public void setReportData(JSONObject reportData) { putIfNotNull("report_data", reportData); }
public void setNotifyUrl(String notifyUrl) { putIfNotNull("notify_url", notifyUrl); }
public void setFlashSaleType(Integer flashSaleType) { putIfNotNull("flash_sale_type", flashSaleType); }
public void setAdventData(JSONObject adventData) { putIfNotNull("advent_data", adventData); }
public void setInspectData(JSONObject inspectData) { putIfNotNull("inspect_data", inspectData); }
public void setBrandData(JSONObject brandData) { putIfNotNull("brand_data", brandData); }
public void setDetailImages(JSONArray images) { putIfNotNull("detail_images", images); }
public void setSkuImages(JSONArray images) { putIfNotNull("sku_images", images); }
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
private void putIfNotNull(String key, Object value) { if (value != null) { ensureBody(); this.requestBody.put(key, value); } }
}

View File

@@ -0,0 +1,37 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
/**
* 编辑库存请求
*
* 对应接口POST /api/open/product/edit/stock
*/
public class ProductEditStockRequest extends ERPRequestBase {
public ProductEditStockRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/edit/stock", erpAccount);
}
public void setProductId(long productId) { ensureBody(); this.requestBody.put("product_id", productId); }
public void setPrice(Long price) { putIfNotNull("price", price); }
public void setOriginalPrice(Long originalPrice) { putIfNotNull("original_price", originalPrice); }
public void setStock(Integer stock) { putIfNotNull("stock", stock); }
public void addSkuItem(long skuId, Integer stock, Long price, String outerId) {
ensureBody();
JSONArray arr = this.requestBody.getJSONArray("sku_items");
if (arr == null) { arr = new JSONArray(); this.requestBody.put("sku_items", arr); }
JSONObject sku = new JSONObject();
sku.put("sku_id", skuId);
if (stock != null) sku.put("stock", stock);
if (price != null) sku.put("price", price);
if (outerId != null) sku.put("outer_id", outerId);
arr.add(sku);
}
private void ensureBody() { if (this.requestBody == null) this.requestBody = new JSONObject(); }
private void putIfNotNull(String key, Object value) { if (value != null) { ensureBody(); this.requestBody.put(key, value); } }
}

View File

@@ -0,0 +1,69 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
public class ProductListQueryRequest extends ERPRequestBase {
public ProductListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/list", erpAccount);
}
public void setOnlineTime(long start, long end) {
ensureRequestBodyInitialized();
this.requestBody.put("online_time", new long[]{start, end});
}
public void setOfflineTime(long start, long end) {
ensureRequestBodyInitialized();
this.requestBody.put("offline_time", new long[]{start, end});
}
public void setSoldTime(long start, long end) {
ensureRequestBodyInitialized();
this.requestBody.put("sold_time", new long[]{start, end});
}
public void setUpdateTime(long start, long end) {
ensureRequestBodyInitialized();
this.requestBody.put("update_time", new long[]{start, end});
}
public void setCreateTime(long start, long end) {
ensureRequestBodyInitialized();
this.requestBody.put("create_time", new long[]{start, end});
}
public void setProductStatus(int productStatus) {
ensureRequestBodyInitialized();
this.requestBody.put("product_status", productStatus);
}
public void setSaleStatus(Integer saleStatus) {
if (saleStatus == null) {
return;
}
ensureRequestBodyInitialized();
this.requestBody.put("sale_status", saleStatus);
}
public void setPageNo(int pageNo) {
ensureRequestBodyInitialized();
this.requestBody.put("page_no", pageNo);
}
public void setPageSize(int pageSize) {
ensureRequestBodyInitialized();
this.requestBody.put("page_size", pageSize);
}
public void setPage(int pageNo, int pageSize) {
ensureRequestBodyInitialized();
this.requestBody.put("page_no", pageNo);
this.requestBody.put("page_size", pageSize);
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
}

View File

@@ -0,0 +1,66 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
/**
* 查询商品属性请求
*
* 对应接口POST /api/open/product/pv/list
* 请求体字段:
* - item_biz_type必填商品类型
* - sp_biz_type必填行业类型
* - channel_cat_id必填渠道类目ID
* - sub_property_id选填属性值ID用于二级属性查询
*/
public class ProductPropertyListQueryRequest extends ERPRequestBase {
public ProductPropertyListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/pv/list", erpAccount);
}
/**
* 设置商品类型(必填)
* @param itemBizType 商品类型
*/
public void setItemBizType(int itemBizType) {
ensureRequestBodyInitialized();
this.requestBody.put("item_biz_type", itemBizType);
}
/**
* 设置行业类型(必填)
* @param spBizType 行业类型
*/
public void setSpBizType(int spBizType) {
ensureRequestBodyInitialized();
this.requestBody.put("sp_biz_type", spBizType);
}
/**
* 设置渠道类目ID必填
* @param channelCatId 渠道类目ID
*/
public void setChannelCatId(String channelCatId) {
ensureRequestBodyInitialized();
this.requestBody.put("channel_cat_id", channelCatId);
}
/**
* 设置下级属性ID选填
* @param subPropertyId 下级属性ID
*/
public void setSubPropertyId(String subPropertyId) {
if (subPropertyId == null || subPropertyId.isEmpty()) {
return;
}
ensureRequestBodyInitialized();
this.requestBody.put("sub_property_id", subPropertyId);
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
}

View File

@@ -0,0 +1,45 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
/**
* 上架商品请求
*
* 对应接口POST /api/open/product/publish
*/
public class ProductPublishRequest extends ERPRequestBase {
public ProductPublishRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/publish", erpAccount);
}
public void setProductId(long productId) {
ensureBody();
this.requestBody.put("product_id", productId);
}
public void setUserName(String userName) {
ensureBody();
JSONArray arr = new JSONArray();
arr.add(userName);
this.requestBody.put("user_name", arr);
}
public void setSpecifyPublishTime(String time) {
if (time == null) return;
ensureBody();
this.requestBody.put("specify_publish_time", time);
}
public void setNotifyUrl(String notifyUrl) {
if (notifyUrl == null) return;
ensureBody();
this.requestBody.put("notify_url", notifyUrl);
}
private void ensureBody() {
if (this.requestBody == null) this.requestBody = new JSONObject();
}
}

View File

@@ -0,0 +1,58 @@
package com.ruoyi.erp.request;
import com.alibaba.fastjson2.JSONObject;
import java.util.Collection;
/**
* 查询商品规格请求(仅多规格商品)
*
* 对应接口POST /api/open/product/sku/list
* 请求体字段:
* - product_id必填管家商品ID数组最多100个
*/
public class ProductSkuListQueryRequest extends ERPRequestBase {
public ProductSkuListQueryRequest(ERPAccount erpAccount) {
super("https://open.goofish.pro/api/open/product/sku/list", erpAccount);
}
/**
* 设置商品ID数组必填最多100个
*/
public void setProductIds(long... productIds) {
if (productIds == null || productIds.length == 0) {
throw new IllegalArgumentException("productIds不能为空");
}
if (productIds.length > 100) {
throw new IllegalArgumentException("productIds数量不能超过100");
}
ensureRequestBodyInitialized();
this.requestBody.put("product_id", productIds);
}
/**
* 设置商品ID集合必填最多100个
*/
public void setProductIds(Collection<Long> productIds) {
if (productIds == null || productIds.isEmpty()) {
throw new IllegalArgumentException("productIds不能为空");
}
if (productIds.size() > 100) {
throw new IllegalArgumentException("productIds数量不能超过100");
}
long[] ids = new long[productIds.size()];
int i = 0;
for (Long id : productIds) {
ids[i++] = id == null ? 0L : id;
}
setProductIds(ids);
}
private void ensureRequestBodyInitialized() {
if (this.requestBody == null) {
this.requestBody = new JSONObject();
}
}
}

View File

@@ -0,0 +1,17 @@
package com.ruoyi.erp.request;
/**
* @author Leo
* @version 1.0
* @create 2025/8/16 19:02
* @description
*/
public class RequestDemo {
public static void main(String[] args) {
ERPAccount erpAccount = ERPAccount.ACCOUNT_HUGE;
ProductListQueryRequest request = new ProductListQueryRequest(erpAccount);
String responseBody = request.getResponseBody();
System.out.println("响应结果: " + responseBody);
}
}

View File

@@ -0,0 +1,11 @@
package com.ruoyi.erp.service;
import java.util.List;
public interface IRegionService {
List<?> listProvinces();
List<?> listCities(Integer provId);
List<?> listAreas(Integer provId, Integer cityId);
}

View File

@@ -0,0 +1,52 @@
package com.ruoyi.erp.service.impl;
import com.ruoyi.erp.mapper.RegionMapper;
import com.ruoyi.erp.domain.Region;
import com.ruoyi.erp.service.IRegionService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class RegionServiceImpl implements IRegionService {
@Resource
private RegionMapper regionMapper;
@Override
public List<?> listProvinces() {
List<Region> list = regionMapper.selectProvinces();
return list.stream()
.map(r -> new Option(r.getProvId(), r.getProvName()))
.distinct()
.collect(Collectors.toList());
}
@Override
public List<?> listCities(Integer provId) {
List<Region> list = regionMapper.selectCitiesByProv(provId);
return list.stream()
.map(r -> new Option(r.getCityId(), r.getCityName()))
.distinct()
.collect(Collectors.toList());
}
@Override
public List<?> listAreas(Integer provId, Integer cityId) {
List<Region> list = regionMapper.selectAreasByCity(provId, cityId);
return list.stream()
.map(r -> new Option(r.getAreaId(), r.getAreaName()))
.distinct()
.collect(Collectors.toList());
}
public static class Option {
public final Integer value;
public final String label;
public Option(Integer value, String label) { this.value = value; this.label = label; }
}
}

View File

@@ -0,0 +1,36 @@
<?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.erp.mapper.RegionMapper">
<resultMap id="RegionMap" type="com.ruoyi.erp.domain.Region">
<result property="provId" column="prov_id" />
<result property="provName" column="prov_name" />
<result property="cityId" column="city_id" />
<result property="cityName" column="city_name" />
<result property="areaId" column="area_id" />
<result property="areaName" column="area_name" />
</resultMap>
<select id="selectProvinces" resultMap="RegionMap">
SELECT DISTINCT prov_id, prov_name, 0 AS city_id, '' AS city_name, 0 AS area_id, '' AS area_name
FROM xgj_region
ORDER BY prov_id
</select>
<select id="selectCitiesByProv" parameterType="int" resultMap="RegionMap">
SELECT DISTINCT prov_id, prov_name, city_id, city_name, 0 AS area_id, '' AS area_name
FROM xgj_region
WHERE prov_id = #{provId}
ORDER BY city_id
</select>
<select id="selectAreasByCity" resultMap="RegionMap">
SELECT prov_id, prov_name, city_id, city_name, area_id, area_name
FROM xgj_region
WHERE prov_id = #{provId} AND city_id = #{cityId}
ORDER BY area_id
</select>
</mapper>

View File

@@ -0,0 +1,89 @@
/*
Navicat Premium Data Transfer
Source Server : xym-tidb
Source Server Type : MySQL
Source Server Version : 50725 (5.7.25-TiDB-v6.5.2)
Source Host : 39.108.130.231:4000
Source Schema : xym_biz
Target Server Type : MySQL
Target Server Version : 50725 (5.7.25-TiDB-v6.5.2)
File Encoding : 65001
Date: 17/10/2024 14:08:26
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for prd_error_tip
-- ----------------------------
DROP TABLE IF EXISTS `prd_error_tip`;
CREATE TABLE `prd_error_tip` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`err_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`err_sub_code` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`err_msg` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`content` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`status` tinyint(4) NOT NULL,
`create_time` int(11) NOT NULL,
`update_time` int(11) NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 30002 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
-- ----------------------------
-- Records of prd_error_tip
-- ----------------------------
INSERT INTO `prd_error_tip` VALUES (1, 'TOP_ITEM_BIZCHECK_FAIL', '', '商品业务模式校验失败', '该宝贝是在闲鱼APP发布闲管家暂不支持编辑请前往APP编辑', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (2, 'TOP_ITEM_ADD_FAIL', 'PLAYBOY_ERRORCODE_REACHED_PUBLISH_COUNT_LIMIT', 'PLAYBOY_ERRORCODE_REACHED_PUBLISH_COUNT_LIMIT:用户发布商品数已达到上限;', '闲鱼店铺已达发品上限,你可以删除处理中的数据,回到商品列表编辑现有商品或下架其他商品。', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (3, 'TOP_ITEM_EDIT_FAIL', 'USER_PROTOCOL_VALID_ERROR', 'USER_PROTOCOL_VALID_ERROR:亲,小闲鱼有点忙,请稍后重试哦;', '此商品类目不正确,你可以删除处理中的数据,回到商品列表点击【编辑】按钮,更改为其他分类', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (4, 'TOP_ITEM_EDIT_FAIL', 'DIVISION_ERROR_DIVISION_ID', 'DIVISION_ERROR_DIVISION_ID:根据地区id找不到对应的省、市、区或者不是叶子节点行政单位;', '该商品发货地异常,请反馈客服处理', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (5, 'TOP_ITEM_BIZ_OFFLINE', '', '此业务已下线,不支持发布', '此业务已下线,你可以删除处理中的数据,回到商品列表创建新的商品', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (6, 'TOP_ITEM_EDIT_FAIL', 'USER_RIGHTS_PROTOCOL_MUST_SIGN', 'USER_RIGHTS_PROTOCOL_MUST_SIGN:当前商品必须签署“七天无理由协议”;', '此商品没有开启“7天无理由”服务你可以删除处理中的数据回到商品列表点击【编辑】按钮在详情页中启用“7天无理由”服务', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (7, 'TOP_ITEM_EDIT_FAIL', 'IDLE_SERVICE_NOT_OPEN', 'IDLE_SERVICE_NOT_OPEN:服务暂未开通;', '此商品有服务未开启,你可以删除处理中的数据,回到商品列表点击【编辑】按钮,在详情页中启用对应的服务', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (8, 'TOP_BOOK_PARAM_NULL', '', '图书参数信息不全', '图书信息填写不正确。你可以删除处理中的数据,回到商品列表点击【编辑】按钮,在详情页中正确填写“图书信息”', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (9, 'TOP_ITEM_ADD_FAIL', 'PLAYBOY_ERRORCODE_ITEM_SKU_PROPERTY_VALUE_SET_SIZE_ILLETAL', 'PLAYBOY_ERRORCODE_ITEM_SKU_PROPERTY_VALUE_SET_SIZE_ILLETAL:Sku属性项项应该包含2-20个属性值;', '属性项不符合2-20个你可以删除处理中的数据回到商品列表点击【编辑】按钮在详情页中正确填写属性值', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (10, 'TOP_ITEM_EDIT_FAIL', 'SKU_PRICE_ILLEGAL', 'SKU_PRICE_ILLEGAL:宝贝价格必须在0元与1亿元之间;', '价格不在0~1亿范围内你可以删除处理中的数据回到商品列表点击【编辑】按钮在详情页中正确填写价格', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (11, 'TOP_ITEM_EDIT_FAIL', 'USER_ERROR_USER_WAS_FORBIDDEN2', 'USER_ERROR_USER_WAS_FORBIDDEN2:用户被处罚限制发布;', '当前店铺被处罚无法发布商品请前往闲鱼APP我的-设置-安全中心查看违规信息', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (12, 'TOP_ITEM_ADD_FAIL', 'BOOK_BARCODE_NOT_NULL', 'BOOK_BARCODE_NOT_NULL:图书类宝贝需使用标题右侧的“扫一扫”,扫描图书条形码后发布;', 'ISBN码不合法你可以删除处理中的数据回到商品列表点击【编辑】按钮在编辑页修改为正确的13位数字的ISBN码', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (13, 'TOP_SPGUARANTEE_LIMIT', '', '服务标签不支持非优品商品', '此业务已下线,你可以删除处理中的数据,回到商品列表创建新的商品', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (14, 'TOP_ITEM_ADD_FAIL', 'KFC_ERROR_PTZLZZZR_CONDITION', 'KFC_ERROR_PTZLZZZR_CONDITION:请核实发布商品是否属于闲鱼禁止发布的类目或需要资质准入,如您已上传特许资质,可点击右上方发布按钮。;', '闲鱼禁止发布奶粉、医疗器械、酒类、香烟、电池、党政机关、涉及歧视、陪伴类等商品,你可以删除处理中的数据,回到商品列表点击【编辑】按钮检查标题或描述是否包含这些违规词', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (15, 'TOP_ITEM_EDIT_FAIL', 'ITEM_NOT_FOUND', 'ITEM_NOT_FOUND:找不到该商品;', '该宝贝可能涉及违规已被闲鱼删除,请重新发布合规的宝贝', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (16, 'TOP_ITEM_EDIT_FAIL', 'USER_RIGHTS_PROTOCOL_CANNOT_SIGN_C2S2C', 'USER_RIGHTS_PROTOCOL_CANNOT_SIGN_C2S2C:“描述不符包邮退协议”不可以和验货宝协议同时签署;', '验货宝商品开启了描述不符包邮退服务,你可以删除处理中的数据,回到商品列表,点击【编辑】按钮,关闭描述不符包邮退的服务就可以正常发布了', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (17, 'TOP_ITEM_ADD_FAIL', 'QUANTITY_ITEM_CAT_TOO_LARGE_NEW', 'QUANTITY_ITEM_CAT_TOO_LARGE_NEW:您发布的宝贝(包括一口价、帖子、拍卖、鱼塘活动)数量超过50个请您及时调整您的宝贝数量再上传宝贝哦;', '闲鱼店铺已达发品上限,你可以删除处理中的数据,回到商品列表编辑现有商品或下架其他商品。', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (18, 'TOP_ITEM_ADD_FAIL', 'QUERY_ITEM_CAT_FAILED', 'QUERY_ITEM_CAT_FAILED:发布失败,请稍后重试吧!;', '类目错误或下架了,你可以删除处理中的数据,回到商品列表点击【编辑】按钮,更改为其他分类', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (19, 'TOP_ITEM_EDIT_FAIL', 'PLAYBOY_ERRORCODE_PLEASE_UPDATE_APP_VERSION', 'PLAYBOY_ERRORCODE_PLEASE_UPDATE_APP_VERSION:您的闲鱼app版本太旧请升级到最新版!;', '你可以在手机应用市场将闲鱼APP更新至最新版', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (20, 'TOP_ITEM_ADD_FAIL', 'KFC_ERROR_PUBLISH_FORBIDDEN', 'KFC_ERROR_PUBLISH_FORBIDDEN:请勿发布需资质准入或属于闲鱼违规类的商品信息,请重新核实再发布。;', '闲鱼禁止发布奶粉、医疗器械、酒类、香烟、电池、党政机关、涉及歧视、陪伴类等商品,你可以删除处理中的数据,回到商品列表点击【编辑】按钮检查标题或描述是否包含这些违规词', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (21, 'TOP_SELLER_NOTALLOW_ACCESS', '', '卖家未通过闲鱼招商,请联系闲鱼运营', '如果没有对接过招商你可联系行业闲鱼运营;如果已经通过招商则重新授权闲鱼号', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (22, 'TOP_ITEM_EDIT_FAIL', 'KFC_ERROR_VIRTUAL_TITLE', 'KFC_ERROR_VIRTUAL_TITLE:请勿发布充值卡券、虚拟游戏等高风险商品的交易信息,请重新核实再发布。;', '请勿发布包含“卡券、虚拟游戏”类内容的商品,你可以删除处理中的数据,回到商品列表,点击【编辑】按钮,将商品详情更改为合规的内容', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (23, 'TOP_ITEM_EDIT_FAIL', 'ITEM_CAN_NOT_PUBLISH', 'ITEM_CAN_NOT_PUBLISH:亲,您不能发布多库存宝贝哦;', '非鱼小铺卖家不能发布多库存宝贝,你可以删除处理中的数据,回到商品列表,编辑宝贝为单库存就可以正常发布了', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (24, 'TOP_ISVBIZ_NOTALLOW_ACCESS', '', '服务商业务未准入,请联系闲鱼运营', '闲鱼优品已下线,你可以删除处理中的数据,回到商品列表,创建新商品或更改商品类型为“普通商品”', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (25, 'TOP_ITEM_EDIT_FAIL', 'BOOK_PUBLISH_FREQUENTLY', 'BOOK_PUBLISH_FREQUENTLY:图书试运营期间每月最多发布15本;', '图书发布数量已达上限,你可以删除处理中的数据,回到商品列表点击编辑旧商品或下架旧商品创建新商品', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (26, 'TOP_ITEM_EDIT_FAIL', 'IC_OPTIMISTIC_LOCKING_CONFLICT', 'IC_OPTIMISTIC_LOCKING_CONFLICT:系统错误,请重试;', '系统繁忙,请稍后重试', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (27, 'TOP_ITEM_ADD_FAIL', 'SKU_QUANTITY_ILLEGAL', 'SKU_QUANTITY_ILLEGAL:宝贝库存数量必须在0与1万之间;', '库存数量没有在规定范围内,你可以删除处理中的数据,回到商品列表点击【编辑】按钮重新设置库存', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (28, 'TOP_ITEM_EDIT_FAIL', 'IC_CHECKSTEP_ITME_NOT_IN_SKU_PRICE', 'IC_CHECKSTEP_ITME_NOT_IN_SKU_PRICE:一口价必须与有库存的宝贝规格价格一致;', '商品的价格不在sku价格内你可以删除处理中的数据回到商品列表点击【编辑】按钮重新设置价格', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (29, 'isp.top-remote-connection-timeout', '', '远程服务调用超时', '系统繁忙,请稍后重试', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (30, 'accesscontrol.limited-by-api-access-count', '', 'This ban will last for 1 more seconds', '系统繁忙,请稍后重试', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (31, 'TOP_ITEM_ADD_FAIL', 'QUALIFICATION_NOT_SUPPORT_CATE', 'QUALIFICATION_NOT_SUPPORT_CATE:您没有发布该类商品的资质!;', '发布该品类宝贝需上传相关资质你可以前往闲鱼APP-我的-认证招商-经营资质进行上传', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (32, 'TOP_ITEM_ADD_FAIL', 'ITEM_PROPOSE_CHECK_ERROR', 'ITEM_PROPOSE_CHECK_ERROR:尊敬的用户,平台禁售酒水、婴幼儿奶粉、保健品等需要资质准入的预包装食品,感谢您的理解与支持。;', '闲鱼禁止发布奶粉、医疗器械、酒类、香烟、电池、党政机关、涉及歧视、陪伴类等商品,你可以删除处理中的数据,回到商品列表点击【编辑】按钮检查标题或描述是否包含这些违规词', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (33, 'TOP_ITEM_ADD_FAIL', 'ERR_RULE_TITLE_SECURITY_CHAR_LIMITATION', 'ERR_RULE_TITLE_SECURITY_CHAR_LIMITATION:标题/卖点/短标题禁止使用半角符号“ <> ” 符号,但可以使用全角符号“ <>”;', '标题/卖点/短标题输入不规范,你可以删除处理中的数据,回到商品列表点击【编辑】按钮,重新修改标题或描述', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (34, 'TOP_ITEM_EDIT_FAIL', 'FORBIDDEN_QUANTITY_ZERO_ERROR', 'FORBIDDEN_QUANTITY_ZERO_ERROR:上架的数量必须大于0;', '你可以删除处理中的数据,回到商品列表点击【编辑】按钮,重新设置库存', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (35, 'TOP_ITEM_ADD_FAIL', 'IC_CHECKSTEP_USERDEFINED_SKU_ERROR', 'IC_CHECKSTEP_USERDEFINED_SKU_ERROR:自定义销售属性不能含有特殊字符;', 'SKU的属性或者属性值禁止使用特殊符号你可以删除处理中的数据回到商品列表点击【编辑】按钮重新修改规格属性或属性值', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (36, 'TOP_ITEM_ADD_FAIL', 'USER_NEED_XIANYU_REAL_VERIFY', 'USER_NEED_XIANYU_REAL_VERIFY:用户未通过闲鱼实名认证;', '请前往闲鱼APP-我的-设置-账号与安全进行实名认证', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (37, 'TOP_ITEM_ADD_FAIL', 'C2S2C_DATA_MISSED', 'C2S2C_DATA_MISSED:请补充必填属性:品牌;', '宝贝没有选择品牌属性,你可以删除处理中的数据,回到商品列表点击【编辑】按钮,勾选品牌属性就可以重新发布了', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (38, 'TOP_IMAGE_NOT_FOUND', '', '找不到传入的某些图片', '图片上传失败,请重新上传,你可以删除处理中的数据,回到商品列表点击【编辑】按钮重新上传图片', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (39, 'TOP_ITEM_EDIT_FAIL', 'F_INVENTORY_05_16_010', 'F_INVENTORY_05_16_010:保存库存失败: [对不起,系统繁忙,请稍候再试], [请检查更新的商品库存是否已生效,若未生效,请稍后重试].;', '系统繁忙,请稍后重试', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (40, 'TOP_ITEM_EDIT_FAIL', 'no_writing_check', 'no_writing_check:你的商品正在参加卡券频道秒杀活动,不允许价格编辑,库存减少;', '参加活动的商品不允许编辑价格和库存,将处理中的数据删除即可,不影响原商品', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (41, 'TOP_ITEM_ADD_FAIL', 'ITEM_PROPOSE_CHECK_ERROR', 'ITEM_PROPOSE_CHECK_ERROR:亲爱的用户,您发布的内容存在违规风险,请做好自检自查,避免违规。;', '闲鱼禁止发布奶粉、医疗器械、酒类、香烟、电池、党政机关、涉及歧视、陪伴类等商品,你可以删除处理中的数据,回到商品列表点击【编辑】按钮检查标题或描述是否包含这些违规词', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (42, 'TOP_ITEM_ADD_FAIL', 'ITEM_PROPOSE_CHECK_ERROR', 'ITEM_PROPOSE_CHECK_ERROR:亲,为了他人的生命与健康,请严格遵守国家相关规定,不要发布及宣传药品、医疗器械类相关商品,以免触犯平台规则,感谢您的理解与支持。;', '闲鱼禁止发布奶粉、医疗器械、酒类、香烟、电池、党政机关、涉及歧视、陪伴类等商品,你可以删除处理中的数据,回到商品列表点击【编辑】按钮检查标题或描述是否包含这些违规词', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (43, 'TOP_ITEM_ADD_FAIL', 'PLAYBOY_ERRORCODE_ITEM_SKU_PROPERTY_KEY_NAME_LENGTH_ILLEGAL', 'PLAYBOY_ERRORCODE_ITEM_SKU_PROPERTY_KEY_NAME_LENGTH_ILLEGAL:属性名称应该是2-4个字符;', '属性名称至少包含一个汉字或2个英文字母你可以删除处理中的数据回到商品列表点击【编辑】重新编辑属性名称', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (44, 'TOP_ITEM_EDIT_FAIL', 'C2S2C_DATA_MISSED', 'C2S2C_DATA_MISSED:请补充必填属性;', '商品详情有必填项未填,你可以删除处理中的数据,回到商品列表点击【编辑】补全所有必填项', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (45, 'TOP_ITEM_ADD_FAIL', 'ITEM_PROPOSE_CHECK_ERROR', 'ITEM_PROPOSE_CHECK_ERROR:未成年人请勿发布虚拟网络游戏及其相关的服务类商品,请重新核实后再发布!;', '未成年人无法发布虚拟游戏类商品,你可以删除处理中的数据,回到商品列表点击重新发布其他合规内容', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (46, 'TOP_ITEM_ADD_FAIL', 'FAIL_BIZ_ITEM_EDIT_TITLE_HAS_EMOJI', 'FAIL_BIZ_ITEM_EDIT_TITLE_HAS_EMOJI:亲,您的标题里面有表情,现在我们还不支持哦;', '商品标题含有表情包,你可以删除处理中的数据,回到商品列表点击【编辑】按钮修改商品标题使其不包含表情', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (47, 'retry', 'retry', '自定义需要重试的错误。', '系统繁忙,请稍后重试', 1, 1686559188, 1686559188);
INSERT INTO `prd_error_tip` VALUES (48, 'TOP_ITEM_ADD_FAIL', 'STRONG_VALID_VERIFY_INFO', 'STRONG_VALID_VERIFY_INFO:用户未通过认证;', '自7月27号明天开始没有签订支付宝收款协议的闲鱼号将无法在闲管家发布商品请各位商家及时自查。自查方法闲鱼APP已发布的商品详情页或者APP发布成功后会有提示\n签订流程请点击链接查看https://goofish.pro/learn?article_id=443263609565893&type=3', 1, 1691740550, 1691740550);
INSERT INTO `prd_error_tip` VALUES (49, 'TOP_ITEM_EDIT_FAIL', 'STRONG_VALID_VERIFY_INFO', 'STRONG_VALID_VERIFY_INFO:用户未通过认证;', '自7月27号明天开始没有签订支付宝收款协议的闲鱼号将无法在闲管家发布商品请各位商家及时自查。自查方法闲鱼APP已发布的商品详情页或者APP发布成功后会有提示\n签订流程请点击链接查看https://goofish.pro/learn?article_id=443263609565893&type=3', 1, 1691740550, 1691740550);
SET FOREIGN_KEY_CHECKS = 1;

3623
sql/闲管家省市区.sql Normal file

File diff suppressed because it is too large Load Diff