提交 ef3c2bfa authored 作者: 窦馨雨's avatar 窦馨雨

合并分支 'dxy' 到 'qa'

增加定时任务执行旺店通其他出入库库存数据获取 查看合并请求 !148
package com.sfa.job.domain.stock.dao;
/**
* @Author: DouXinYu
* @Date: 2026-04-17 16:59
* @Description: 旺店通其他数据访问层接口
*/
public interface IWdtOtherStockDao {
void syncLastDayOtherStockOut(String startTime, String endTime);
void syncLastDayOtherStockIn(String startTime, String endTime);
}
package com.sfa.job.domain.stock.dao.impl;
import cn.hutool.json.JSONUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.sfa.common.core.exception.ServiceException;
import com.sfa.job.domain.stock.dao.IWdtOtherStockDao;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockInOrder;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockInOrderDetail;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockOutOrder;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockOutOrderDetail;
import com.sfa.job.domain.stock.mapper.WdtQimenOtherStockInOrderDetailMapper;
import com.sfa.job.domain.stock.mapper.WdtQimenOtherStockInOrderMapper;
import com.sfa.job.domain.stock.mapper.WdtQimenOtherStockOutOrderDetailMapper;
import com.sfa.job.domain.stock.mapper.WdtQimenOtherStockOutOrderMapper;
import com.sfa.job.pojo.request.BaseRequest;
import com.sfa.job.pojo.response.BaseResponse;
import com.sfa.job.util.WangDianTongQimenApiUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@DS("bi")
@Service
@Slf4j
public class WdtOtherStockDaoImpl implements IWdtOtherStockDao {
private static final String OUT_METHOD = "wdt.wms.stockother.outquery.querywithdetail";
private static final String IN_METHOD = "wdt.wms.stockother.inquery.querywithdetail";
private static final int PAGE_SIZE = 1000;
@Autowired
private WdtQimenOtherStockOutOrderMapper otherStockOrderMapper;
@Autowired
private WdtQimenOtherStockOutOrderDetailMapper otherStockDetailMapper;
@Autowired
private WdtQimenOtherStockInOrderMapper otherStockInOrderMapper;
@Autowired
private WdtQimenOtherStockInOrderDetailMapper otherStockInDetailMapper;
@Override
@Transactional(rollbackFor = Exception.class)
public void syncLastDayOtherStockOut(String startTime, String endTime) {
Integer pageNo = 1;
Integer totalCount = 0;
Integer totalPage = 0;
List<WdtQimenOtherStockOutOrder> allOrders = new ArrayList<>();
List<WdtQimenOtherStockOutOrderDetail> allDetails = new ArrayList<>();
log.info("开始同步其他出库单 - 开始时间: {}, 结束时间: {}", startTime, endTime);
do {
Map<String, Object> params = new HashMap<>();
params.put("time_type", 2);
params.put("start_time", startTime);
params.put("end_time", endTime);
params.put("pageNo", pageNo);
params.put("pageSize", PAGE_SIZE);
try {
BaseRequest<BaseResponse> request = new BaseRequest<>();
request.setRequestMethod(OUT_METHOD);
BaseResponse response = WangDianTongQimenApiUtil.createBuilder()
.execute(request, params);
String body = response.getBody();
log.info("查询其他出库单 - 页码: {}, 返回: {}", pageNo, body);
// 解析响应数据
OtherStockResponseBodyDto responseBody = JSONUtil.toBean(body, OtherStockResponseBodyDto.class);
if (responseBody != null && responseBody.getResponse() != null) {
OtherStockResponseDataDto data = responseBody.getResponse().getData();
if (data != null) {
totalCount = data.getTotalCount();
totalPage = (totalCount + PAGE_SIZE - 1) / PAGE_SIZE;
log.info("总记录数: {}, 总页数: {}, 当前页: {}", totalCount, totalPage, pageNo);
// 解析订单数据
List<Map<String, Object>> orderList = data.getOrder();
if (orderList != null && !orderList.isEmpty()) {
for (Map<String, Object> orderMap : orderList) {
WdtQimenOtherStockOutOrder order = convertToOrder(orderMap);
allOrders.add(order);
// 解析明细数据
List<Map<String, Object>> detailList = (List<Map<String, Object>>) orderMap.get("detail_list");
if (detailList != null && !detailList.isEmpty()) {
List<WdtQimenOtherStockOutOrderDetail> details = detailList.stream()
.map(this::convertToDetail)
.collect(Collectors.toList());
allDetails.addAll(details);
}
}
}
}
}
pageNo++;
// 添加延迟,避免频率限制
if (pageNo <= totalPage) {
Thread.sleep(100);
}
} catch (Exception e) {
log.error("奇门API调用异常", e);
throw new ServiceException("奇门API调用异常:" + e.getMessage());
}
} while (pageNo <= totalPage);
// 批量保存数据
if (!allOrders.isEmpty()) {
log.info("开始批量保存其他出库单,数量: {}", allOrders.size());
try {
otherStockOrderMapper.insertOrUpdateBatch(allOrders);
} catch (Exception e) {
log.error("批量保存其他出库单失败,数量: {}, 异常信息: {}", allOrders.size(), e.getMessage(), e);
throw new ServiceException("批量保存其他出库单失败:" + e.getMessage());
}
}
if (!allDetails.isEmpty()) {
log.info("开始批量保存其他出库单明细,数量: {}", allDetails.size());
try {
otherStockDetailMapper.insertOrUpdateBatch(allDetails);
} catch (Exception e) {
log.error("批量保存其他出库单明细失败,数量: {}, 异常信息: {}", allDetails.size(), e.getMessage(), e);
throw new ServiceException("批量保存其他出库单明细失败:" + e.getMessage());
}
}
log.info("同步其他出库单完成 - 总订单数: {}, 总明细数: {}", allOrders.size(), allDetails.size());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void syncLastDayOtherStockIn(String startTime, String endTime) {
Integer pageNo = 1;
Integer totalCount = 0;
Integer totalPage = 0;
List<WdtQimenOtherStockInOrder> allOrders = new ArrayList<>();
List<WdtQimenOtherStockInOrderDetail> allDetails = new ArrayList<>();
log.info("开始同步其他入库单 - 开始时间: {}, 结束时间: {}", startTime, endTime);
do {
Map<String, Object> params = new HashMap<>();
params.put("time_type", 2);
params.put("start_time", startTime);
params.put("end_time", endTime);
params.put("pageNo", pageNo);
params.put("pageSize", PAGE_SIZE);
try {
BaseRequest<BaseResponse> request = new BaseRequest<>();
request.setRequestMethod(IN_METHOD);
BaseResponse response = WangDianTongQimenApiUtil.createBuilder()
.execute(request, params);
String body = response.getBody();
log.info("查询其他入库单 - 页码: {}, 返回: {}", pageNo, body);
// 解析响应数据
OtherStockResponseBodyDto responseBody = JSONUtil.toBean(body, OtherStockResponseBodyDto.class);
if (responseBody != null && responseBody.getResponse() != null) {
OtherStockResponseDataDto data = responseBody.getResponse().getData();
if (data != null) {
totalCount = data.getTotalCount();
totalPage = (totalCount + PAGE_SIZE - 1) / PAGE_SIZE;
log.info("总记录数: {}, 总页数: {}, 当前页: {}", totalCount, totalPage, pageNo);
// 解析订单数据
List<Map<String, Object>> orderList = data.getOrder();
if (orderList != null && !orderList.isEmpty()) {
for (Map<String, Object> orderMap : orderList) {
WdtQimenOtherStockInOrder order = convertToInOrder(orderMap);
allOrders.add(order);
// 解析明细数据
List<Map<String, Object>> detailList = (List<Map<String, Object>>) orderMap.get("detail_list");
if (detailList != null && !detailList.isEmpty()) {
List<WdtQimenOtherStockInOrderDetail> details = detailList.stream()
.map(this::convertToInDetail)
.collect(Collectors.toList());
allDetails.addAll(details);
}
}
}
}
}
pageNo++;
// 添加延迟,避免频率限制
if (pageNo <= totalPage) {
Thread.sleep(100);
}
} catch (Exception e) {
log.error("奇门API调用异常", e);
throw new ServiceException("奇门API调用异常:" + e.getMessage());
}
} while (pageNo <= totalPage);
// 批量保存数据
if (!allOrders.isEmpty()) {
log.info("开始批量保存其他入库单,数量: {}", allOrders.size());
try {
otherStockInOrderMapper.insertOrUpdateBatch(allOrders);
} catch (Exception e) {
log.error("批量保存其他入库单失败,数量: {}, 异常信息: {}", allOrders.size(), e.getMessage(), e);
throw new ServiceException("批量保存其他入库单失败:" + e.getMessage());
}
}
if (!allDetails.isEmpty()) {
log.info("开始批量保存其他入库单明细,数量: {}", allDetails.size());
try {
otherStockInDetailMapper.insertOrUpdateBatch(allDetails);
} catch (Exception e) {
log.error("批量保存其他入库单明细失败,数量: {}, 异常信息: {}", allDetails.size(), e.getMessage(), e);
throw new ServiceException("批量保存其他入库单明细失败:" + e.getMessage());
}
}
log.info("同步其他入库单完成 - 总订单数: {}, 总明细数: {}", allOrders.size(), allDetails.size());
}
private WdtQimenOtherStockOutOrder convertToOrder(Map<String, Object> orderMap) {
WdtQimenOtherStockOutOrder order = new WdtQimenOtherStockOutOrder();
order.setRecId(getLongValue(orderMap, "rec_id"));
order.setOtherOutNo(getStringValue(orderMap, "other_out_no"));
order.setOuterNo(getStringValue(orderMap, "outer_no"));
order.setWarehouseNo(getStringValue(orderMap, "warehouse_no"));
order.setWarehouseName(getStringValue(orderMap, "warehouse_name"));
order.setCreated(convertMillisToDate(getLongValue(orderMap, "created")));
order.setCreatorId(getLongValue(orderMap, "creator_id"));
order.setEmployeeName(getStringValue(orderMap, "employee_name"));
order.setWarehouseType(getIntegerValue(orderMap, "warehouse_type"));
order.setActualNum(getBigDecimalValue(orderMap, "actual_num"));
order.setExpectNum(getBigDecimalValue(orderMap, "expect_num"));
order.setLogisticsNo(getStringValue(orderMap, "logistics_no"));
order.setLogisticsId(getLongValue(orderMap, "logistics_id"));
order.setLogisticsName(getStringValue(orderMap, "logistics_name"));
order.setReceiverName(getStringValue(orderMap, "receiver_name"));
order.setReceiverProvince(getStringValue(orderMap, "receiver_province"));
order.setReceiverCity(getStringValue(orderMap, "receiver_city"));
order.setReceiverDistrict(getStringValue(orderMap, "receiver_district"));
order.setReceiverMobile(getStringValue(orderMap, "receiver_mobile"));
order.setReceiverAddress(getStringValue(orderMap, "receiver_address"));
order.setReason(getStringValue(orderMap, "reason"));
order.setRemark(getStringValue(orderMap, "remark"));
order.setStatus(getIntegerValue(orderMap, "status"));
order.setModified(convertMillisToDate(getLongValue(orderMap, "modified")));
order.setCheckTime(getStringValue(orderMap, "check_time"));
order.setNoteCount(getIntegerValue(orderMap, "note_count"));
order.setIsReserved(getBooleanValue(orderMap, "is_reserved"));
order.setProp1(getStringValue(orderMap, "prop1"));
order.setProp2(getStringValue(orderMap, "prop2"));
order.setProp3(getStringValue(orderMap, "prop3"));
order.setProp4(getStringValue(orderMap, "prop4"));
order.setProp5(getStringValue(orderMap, "prop5"));
order.setProp6(getStringValue(orderMap, "prop6"));
order.setWarehouseId(getIntegerValue(orderMap, "warehouse_id"));
return order;
}
private WdtQimenOtherStockOutOrderDetail convertToDetail(Map<String, Object> detailMap) {
WdtQimenOtherStockOutOrderDetail detail = new WdtQimenOtherStockOutOrderDetail();
detail.setRecId(getLongValue(detailMap, "rec_id"));
detail.setOtherOutId(getLongValue(detailMap, "other_out_id"));
detail.setBarcode(getStringValue(detailMap, "barcode"));
detail.setBaseUnitId(getIntegerValue(detailMap, "base_unit_id"));
detail.setBaseUnitName(getStringValue(detailMap, "base_unit_name"));
detail.setBatchNo(getStringValue(detailMap, "batch_no"));
detail.setBatchRemark(getStringValue(detailMap, "batch_remark"));
detail.setBrandId(getLongValue(detailMap, "brand_id"));
detail.setBrandName(getStringValue(detailMap, "brand_name"));
detail.setCreatedDate(convertMillisToDate(getLongValue(detailMap, "created_date")));
detail.setDefect(getBooleanValue(detailMap, "defect"));
detail.setExpireDate(getStringValue(detailMap, "expire_date"));
detail.setGoodsId(getLongValue(detailMap, "goods_id"));
detail.setGoodsName(getStringValue(detailMap, "goods_name"));
detail.setGoodsNo(getStringValue(detailMap, "goods_no"));
detail.setModifiedDate(convertMillisToDate(getLongValue(detailMap, "modified_date")));
detail.setNum(getBigDecimalValue(detailMap, "num"));
detail.setNum2(getBigDecimalValue(detailMap, "num2"));
detail.setOutNum(getBigDecimalValue(detailMap, "out_num"));
detail.setProductionDate(getStringValue(detailMap, "production_date"));
detail.setRemark(getStringValue(detailMap, "remark"));
detail.setShortName(getStringValue(detailMap, "short_name"));
detail.setSpecCode(getStringValue(detailMap, "spec_code"));
detail.setSpecId(getLongValue(detailMap, "spec_id"));
detail.setSpecName(getStringValue(detailMap, "spec_name"));
detail.setSpecNo(getStringValue(detailMap, "spec_no"));
return detail;
}
private WdtQimenOtherStockInOrder convertToInOrder(Map<String, Object> orderMap) {
WdtQimenOtherStockInOrder order = new WdtQimenOtherStockInOrder();
order.setRecId(getLongValue(orderMap, "rec_id"));
order.setOtherInNo(getStringValue(orderMap, "other_in_no"));
order.setOuterNo(getStringValue(orderMap, "outer_no"));
order.setWarehouseNo(getStringValue(orderMap, "warehouse_no"));
order.setWarehouseName(getStringValue(orderMap, "warehouse_name"));
order.setCreated(convertMillisToDate(getLongValue(orderMap, "created")));
order.setCreatorId(getLongValue(orderMap, "creator_id"));
order.setEmployeeName(getStringValue(orderMap, "employee_name"));
order.setWarehouseType(getIntegerValue(orderMap, "warehouse_type"));
order.setActualNum(getBigDecimalValue(orderMap, "actual_num"));
order.setExpectNum(getBigDecimalValue(orderMap, "expect_num"));
order.setLogisticsNo(getStringValue(orderMap, "logistics_no"));
order.setLogisticsId(getLongValue(orderMap, "logistics_id"));
order.setLogisticsName(getStringValue(orderMap, "logistics_name"));
order.setReason(getStringValue(orderMap, "reason"));
order.setRemark(getStringValue(orderMap, "remark"));
order.setStatus(getIntegerValue(orderMap, "status"));
order.setModified(convertMillisToDate(getLongValue(orderMap, "modified")));
order.setCheckTime(getStringValue(orderMap, "check_time"));
order.setNoteCount(getBigDecimalValue(orderMap, "note_count"));
order.setWarehouseId(getLongValue(orderMap, "warehouse_id"));
return order;
}
private WdtQimenOtherStockInOrderDetail convertToInDetail(Map<String, Object> detailMap) {
WdtQimenOtherStockInOrderDetail detail = new WdtQimenOtherStockInOrderDetail();
detail.setRecId(getLongValue(detailMap, "rec_id"));
detail.setOtherInId(getLongValue(detailMap, "other_in_id"));
detail.setBarcode(getStringValue(detailMap, "barcode"));
detail.setBaseUnitId(getLongValue(detailMap, "base_unit_id"));
detail.setBaseUnitName(getStringValue(detailMap, "base_unit_name"));
detail.setBatchNo(getStringValue(detailMap, "batch_no"));
detail.setBatchRemark(getStringValue(detailMap, "batch_remark"));
detail.setBrandId(getLongValue(detailMap, "brand_id"));
detail.setBrandName(getStringValue(detailMap, "brand_name"));
detail.setCreatedDate(convertMillisToDate(getLongValue(detailMap, "created_date")));
detail.setDefect(getBooleanValue(detailMap, "defect"));
detail.setExpireDate(getStringValue(detailMap, "expire_date"));
detail.setGoodsId(getLongValue(detailMap, "goods_id"));
detail.setGoodsName(getStringValue(detailMap, "goods_name"));
detail.setGoodsNo(getStringValue(detailMap, "goods_no"));
detail.setModifiedDate(convertMillisToDate(getLongValue(detailMap, "modified_date")));
detail.setNum(getBigDecimalValue(detailMap, "num"));
detail.setNum2(getBigDecimalValue(detailMap, "num2"));
detail.setInNum(getBigDecimalValue(detailMap, "in_num"));
detail.setProductionDate(getStringValue(detailMap, "production_date"));
detail.setRemark(getStringValue(detailMap, "remark"));
detail.setShortName(getStringValue(detailMap, "short_name"));
detail.setSpecCode(getStringValue(detailMap, "spec_code"));
detail.setSpecId(getLongValue(detailMap, "spec_id"));
detail.setSpecName(getStringValue(detailMap, "spec_name"));
detail.setSpecNo(getStringValue(detailMap, "spec_no"));
return detail;
}
private String getStringValue(Map<String, Object> map, String key) {
Object value = map.get(key);
return value != null ? value.toString() : null;
}
private Integer getIntegerValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Integer) {
return (Integer) value;
}
if (value instanceof String) {
try {
return Integer.parseInt((String) value);
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
private BigDecimal getBigDecimalValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof BigDecimal) {
return (BigDecimal) value;
}
if (value instanceof String) {
try {
return new BigDecimal((String) value);
} catch (NumberFormatException e) {
return null;
}
}
if (value instanceof Double) {
return new BigDecimal((Double) value);
}
if (value instanceof Float) {
return new BigDecimal((Float) value);
}
if (value instanceof Integer) {
return new BigDecimal((Integer) value);
}
return null;
}
private Boolean getBooleanValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Boolean) {
return (Boolean) value;
}
if (value instanceof String) {
return Boolean.parseBoolean((String) value);
}
return null;
}
private Long getLongValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Long) {
return (Long) value;
}
if (value instanceof String) {
try {
return Long.parseLong((String) value);
} catch (NumberFormatException e) {
return null;
}
}
if (value instanceof Integer) {
return (long) (Integer) value;
}
return null;
}
/**
* 将毫秒时间戳转换为 yyyy-MM-dd 格式字符串
* @param millis 毫秒时间戳
* @return yyyy-MM-dd 格式日期字符串
*/
private String convertMillisToDate(Long millis) {
if (millis == null) {
return null;
}
return java.time.Instant.ofEpochMilli(millis)
.atZone(java.time.ZoneId.systemDefault())
.toLocalDateTime().format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
@Data
public static class OtherStockResponseBodyDto {
private OtherStockResponseDto response;
private String message;
private Integer status;
}
@Data
public static class OtherStockResponseDto {
private OtherStockResponseDataDto data;
private String message;
private Integer status;
}
@Data
public static class OtherStockResponseDataDto {
private List<Map<String, Object>> order;
private Integer totalCount;
}
}
package com.sfa.job.domain.stock.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
@TableName("wdt_qimen_other_stock_in_order")
public class WdtQimenOtherStockInOrder implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 记录id
*/
private Long recId;
/**
* 其他入库单号
*/
private String otherInNo;
/**
* 外部单号
*/
private String outerNo;
/**
* 仓库号
*/
private String warehouseNo;
/**
* 仓库名称
*/
private String warehouseName;
/**
* 创建时间
*/
private String created;
/**
* 创建人id
*/
private Long creatorId;
/**
* 创建人姓名
*/
private String employeeName;
/**
* 仓库类型
*/
private Integer warehouseType;
/**
* 实际数量
*/
private BigDecimal actualNum;
/**
* 预期数量
*/
private BigDecimal expectNum;
/**
* 物流单号
*/
private String logisticsNo;
/**
* 物流id
*/
private Long logisticsId;
/**
* 物流名称
*/
private String logisticsName;
/**
* 入库原因
*/
private String reason;
/**
* 备注
*/
private String remark;
/**
* 状态
*/
private Integer status;
/**
* 修改时间
*/
private String modified;
/**
* 审核时间
*/
private String checkTime;
/**
* 备注数量
*/
private BigDecimal noteCount;
/**
* 仓库id
*/
private Long warehouseId;
/**
* 其他入库单详情列表
*/
private List<WdtQimenOtherStockInOrderDetail> detailList;
/**
* 总数量
*/
private Integer totalCount;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date updateTime;
/**
* 是否删除
*/
private Integer isDeleted = 1;
}
package com.sfa.job.domain.stock.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@TableName("wdt_qimen_other_stock_in_order_detail")
public class WdtQimenOtherStockInOrderDetail implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 记录id
*/
private Long recId;
/**
* 其他入库单id
*/
private Long otherInId;
/**
* 商品条码
*/
private String barcode;
/**
* 基础单位id
*/
private Long baseUnitId;
/**
* 基础单位名称
*/
private String baseUnitName;
/**
* 批次号
*/
private String batchNo;
/**
* 批次备注
*/
private String batchRemark;
/**
* 品牌id
*/
private Long brandId;
/**
* 品牌名称
*/
private String brandName;
/**
* 创建日期
*/
private String createdDate;
/**
* 是否缺陷
*/
private Boolean defect;
/**
* 过期日期
*/
private String expireDate;
/**
* 商品id
*/
private Long goodsId;
/**
* 商品名称
*/
private String goodsName;
/**
* 商品编号
*/
private String goodsNo;
/**
* 修改日期
*/
private String modifiedDate;
/**
* 数量
*/
private BigDecimal num;
/**
* 数量2
*/
private BigDecimal num2;
/**
* 入库数量
*/
private BigDecimal inNum;
/**
* 生产日期
*/
private String productionDate;
/**
* 备注
*/
private String remark;
/**
* 商品简称
*/
private String shortName;
/**
* 商品规格编码
*/
private String specCode;
/**
* 商品规格id
*/
private Long specId;
/**
* 商品规格名称
*/
private String specName;
/**
* 商品规格编号
*/
private String specNo;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
private Integer isDeleted = 1;
}
package com.sfa.job.domain.stock.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
@Data
@TableName("wdt_qimen_other_stock_out_order")
public class WdtQimenOtherStockOutOrder implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 记录id
*/
private Long recId;
/**
* 其他出库单编号
*/
private String otherOutNo;
/**
* 外部单号
*/
private String outerNo;
/**
* 仓库编号
*/
private String warehouseNo;
/**
* 仓库名称
*/
private String warehouseName;
/**
* 创建时间
*/
private String created;
/**
* 创建人id
*/
private Long creatorId;
/**
* 创建人姓名
*/
private String employeeName;
/**
* 仓库类型
*/
private Integer warehouseType;
/**
* 实际出库数量
*/
private BigDecimal actualNum;
/**
* 预期出库数量
*/
private BigDecimal expectNum;
/**
* 物流单号
*/
private String logisticsNo;
/**
* 物流id
*/
private Long logisticsId;
/**
* 物流名称
*/
private String logisticsName;
/**
* 接收人姓名
*/
private String receiverName;
/**
* 接收人省份
*/
private String receiverProvince;
/**
* 接收人城市
*/
private String receiverCity;
/**
* 接收人区县
*/
private String receiverDistrict;
/**
* 接收人手机号
*/
private String receiverMobile;
/**
* 接收人地址
*/
private String receiverAddress;
/**
* 出库原因
*/
private String reason;
/**
* 备注
*/
private String remark;
/**
* 状态
*/
private Integer status;
/**
* 修改时间
*/
private String modified;
/**
* 审核时间
*/
private String checkTime;
/**
* 审核备注
*/
private String checkRemark;
/**
* 备注数量
*/
private Integer noteCount;
/**
* 是否预约
*/
private Boolean isReserved;
/**
* 自定义属性值1
*/
private String prop1;
/**
* 自定义属性值2
*/
private String prop2;
/**
* 自定义属性值3
*/
private String prop3;
/**
* 自定义属性值4
*/
private String prop4;
/**
* 自定义属性值5
*/
private String prop5;
/**
* 自定义属性值6
*/
private String prop6;
/**
* 仓库id
*/
private Integer warehouseId;
/**
* 详情列表
*/
private List<WdtQimenOtherStockOutOrderDetail> detailList;
/**
* 总数量
*/
private Integer totalCount;
/**
* 创建时间
*/
private Date createTime;
/**
* 修改时间
*/
private Date updateTime;
/**
* 是否删除
*/
private Integer isDeleted = 1;
}
package com.sfa.job.domain.stock.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Data
@TableName("wdt_qimen_other_stock_out_order_detail")
public class WdtQimenOtherStockOutOrderDetail implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* 记录id
*/
private Long recId;
/**
* 其他出库单id
*/
private Long otherOutId;
/**
* 商品条码
*/
private String barcode;
/**
* 基础单位id
*/
private Integer baseUnitId;
/**
* 基础单位名称
*/
private String baseUnitName;
/**
* 批次号
*/
private String batchNo;
/**
* 批次备注
*/
private String batchRemark;
/**
* 品牌id
*/
private Long brandId;
/**
* 品牌名称
*/
private String brandName;
/**
* 创建时间
*/
private String createdDate;
/**
* 是否缺陷
*/
private Boolean defect;
/**
* 过期时间
*/
private String expireDate;
/**
* 商品id
*/
private Long goodsId;
/**
* 商品名称
*/
private String goodsName;
/**
* 商品编号
*/
private String goodsNo;
/**
* 修改时间
*/
private String modifiedDate;
/**
* 数量
*/
private BigDecimal num;
/**
* 数量2
*/
private BigDecimal num2;
/**
* 出库数量
*/
private BigDecimal outNum;
/**
* 生产时间
*/
private String productionDate;
/**
* 备注
*/
private String remark;
/**
* 商品简称
*/
private String shortName;
/**
* 商品规格
*/
private String specCode;
/**
* 商品规格id
*/
private Long specId;
/**
* 商品规格名称
*/
private String specName;
/**
* 商品规格编号
*/
private String specNo;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
private Integer isDeleted = 1;
}
package com.sfa.job.domain.stock.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockInOrderDetail;
import java.util.List;
/**
* 其他入库单明细 Mapper
*/
public interface WdtQimenOtherStockInOrderDetailMapper extends BaseMapper<WdtQimenOtherStockInOrderDetail> {
void insertOrUpdateBatch(List<WdtQimenOtherStockInOrderDetail> stockInDetailList);
}
package com.sfa.job.domain.stock.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockInOrder;
import java.util.List;
/**
* 其他入库单 Mapper
*/
public interface WdtQimenOtherStockInOrderMapper extends BaseMapper<WdtQimenOtherStockInOrder> {
/**
* 插入或更新其他入库单
* @param stockInOrder 其他入库单
* @return 影响的行数
*/
int insertOrUpdate(WdtQimenOtherStockInOrder stockInOrder);
/**
* 批量插入或更新其他入库单
* @param stockInOrders 其他入库单列表
* @return 影响的行数
*/
int insertOrUpdateBatch(List<WdtQimenOtherStockInOrder> stockInOrders);
}
package com.sfa.job.domain.stock.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockOutOrderDetail;
import java.util.List;
/**
* 其他出库单明细 Mapper
*/
public interface WdtQimenOtherStockOutOrderDetailMapper extends BaseMapper<WdtQimenOtherStockOutOrderDetail> {
void insertOrUpdateBatch(List<WdtQimenOtherStockOutOrderDetail> stockoutDetailList);
}
\ No newline at end of file
package com.sfa.job.domain.stock.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sfa.job.domain.stock.entity.WdtQimenOtherStockOutOrder;
import java.util.List;
/**
* 其他出库单 Mapper
*/
public interface WdtQimenOtherStockOutOrderMapper extends BaseMapper<WdtQimenOtherStockOutOrder> {
/**
* 插入或更新其他出库单
* @param stockoutOrder 其他出库单
* @return 影响的行数
*/
int insertOrUpdate(WdtQimenOtherStockOutOrder stockoutOrder);
/**
* 批量插入或更新其他出库单
* @param stockoutOrders 其他出库单列表
* @return 影响的行数
*/
int insertOrUpdateBatch(List<WdtQimenOtherStockOutOrder> stockoutOrders);
}
\ No newline at end of file
package com.sfa.job.pojo.request;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sfa.job.pojo.response.BaseResponse;
import com.sfa.job.util.WangDianTongQimenApiUtil;
import com.taobao.api.ApiRuleException;
import com.taobao.api.BaseTaobaoRequest;
import com.taobao.api.internal.mapping.ApiField;
import com.taobao.api.internal.util.TaobaoHashMap;
import com.taobao.api.internal.util.json.JSONWriter;
import java.util.Map;
/**
* @Author: DouXinYu
* @Date: 2026-04-20 18:31
* @Description: 旺店通基础请求类
*/
public class BaseRequest<T> extends BaseTaobaoRequest<BaseResponse>
implements WangDianTongQimenApiUtil.HasSetParams,
WangDianTongQimenApiUtil.HasSetPager,
WangDianTongQimenApiUtil.HasSetTargetAppKey,
WangDianTongQimenApiUtil.HasSetWdtSign,
WangDianTongQimenApiUtil.HasSetDatetime,
WangDianTongQimenApiUtil.HasSetWdtAppkey,
WangDianTongQimenApiUtil.HasSetWdtSalt {
private String datetime;
private String pager;
private String params;
private String wdtAppkey;
private String wdtSalt;
private String wdtSign;
private String topContentType;
private String topResponseType = "qimen1";
private String topApiVersion = "1.0";
private String topApiFormat;
private String targetAppKey;
private String requestMethod;
private static final ObjectMapper objectMapper = new ObjectMapper();
public BaseRequest() {
}
public void setDatetime(String datetime) {
this.datetime = datetime;
}
public String getDatetime() {
return this.datetime;
}
public void setPager(String pager) {
this.pager = pager;
}
public void setPager(Pager pager) {
this.pager = (new JSONWriter(false, false, true)).write(pager);
}
public String getPager() {
return this.pager;
}
public void setParams(String params) {
this.params = params;
}
public void setParams(Params params) {
this.params = (new JSONWriter(false, false, true)).write(params);
}
public String getParams() {
return this.params;
}
public void setWdtAppkey(String wdtAppkey) {
this.wdtAppkey = wdtAppkey;
}
public String getWdtAppkey() {
return this.wdtAppkey;
}
public void setWdtSalt(String wdtSalt) {
this.wdtSalt = wdtSalt;
}
public String getWdtSalt() {
return this.wdtSalt;
}
public void setWdtSign(String wdtSign) {
this.wdtSign = wdtSign;
}
public String getWdtSign() {
return this.wdtSign;
}
public String getTopContentType() {
return this.topContentType;
}
public void setTopContentType(String topContentType) {
this.topContentType = topContentType;
}
public String getTopResponseType() {
return this.topResponseType;
}
public void setTopResponseType(String topResponseType) {
this.topResponseType = topResponseType;
}
public String getTopApiVersion() {
return this.topApiVersion;
}
public void setTopApiVersion(String topApiVersion) {
this.topApiVersion = topApiVersion;
}
public String getTopApiFormat() {
return this.topApiFormat;
}
public void setTopApiFormat(String topApiFormat) {
this.topApiFormat = topApiFormat;
}
public void setTargetAppKey(String targetAppKey) {
this.targetAppKey = targetAppKey;
}
public String getTargetAppKey() {
return this.targetAppKey;
}
public void setRequestMethod(String requestMethod) {
this.requestMethod = requestMethod;
}
public String getRequestMethod() {
return this.requestMethod;
}
@Override
public String getApiMethodName() {
return this.requestMethod;
}
@Override
public Map<String, String> getTextParams() {
TaobaoHashMap txtParams = new TaobaoHashMap();
txtParams.put("datetime", this.datetime);
txtParams.put("pager", this.pager);
txtParams.put("params", this.params);
txtParams.put("wdt_appkey", this.wdtAppkey);
txtParams.put("wdt_salt", this.wdtSalt);
txtParams.put("wdt_sign", this.wdtSign);
if (this.udfParams != null) {
txtParams.putAll(this.udfParams);
}
return txtParams;
}
@Override
public Class<BaseResponse> getResponseClass() {
return BaseResponse.class;
}
@Override
public void check() throws ApiRuleException {
}
public static class Pager {
@ApiField("page_no")
private Long pageNo;
@ApiField("page_size")
private Long pageSize;
public Pager() {
}
public Long getPageNo() {
return this.pageNo;
}
public void setPageNo(Long pageNo) {
this.pageNo = pageNo;
}
public Long getPageSize() {
return this.pageSize;
}
public void setPageSize(Long pageSize) {
this.pageSize = pageSize;
}
}
public static class Params {
@ApiField("start_time")
private String startTime;
@ApiField("end_time")
private String endTime;
@ApiField("status_type")
private Integer statusType;
@ApiField("time_type")
private Integer timeType;
@ApiField("status")
private String status;
@ApiField("stockout_no")
private String stockoutNo;
@ApiField("shop_no")
private String shopNo;
@ApiField("warehouse_no")
private String warehouseNo;
@ApiField("platform_code")
private String platformCode;
@ApiField("trade_no")
private String tradeNo;
@ApiField("order_no")
private String orderNo;
@ApiField("outer_no")
private String outerNo;
@ApiField("process_id")
private String processId;
@ApiField("process_type")
private Integer processType;
@ApiField("is_detail")
private Integer isDetail;
@ApiField("owner_no")
private String ownerNo;
@ApiField("consignee")
private String consignee;
@ApiField("remark")
private String remark;
@ApiField("operator")
private String operator;
@ApiField("operator_name")
private String operatorName;
@ApiField("confirm_time")
private String confirmTime;
@ApiField("confirm_type")
private Integer confirmType;
@ApiField("confirm_remark")
private String confirmRemark;
@ApiField("creator")
private String creator;
@ApiField("creator_name")
private String creatorName;
@ApiField("create_time")
private String createTime;
@ApiField("modifier")
private String modifier;
@ApiField("modifier_name")
private String modifierName;
@ApiField("modify_time")
private String modifyTime;
@ApiField("is_delete")
private Integer isDelete;
@ApiField("delete_time")
private String deleteTime;
@ApiField("deleter")
private String deleter;
@ApiField("deleter_name")
private String deleterName;
@ApiField("batch_no")
private String batchNo;
@ApiField("page_no")
private Integer pageNo;
@ApiField("page_size")
private Integer pageSize;
@ApiField("keywords")
private String keywords;
@ApiField("fields")
private String fields;
@ApiField("customerid")
private String customerid;
@ApiField("sd_code")
private String sdCode;
@ApiField("start_modified")
private String startModified;
@ApiField("end_modified")
private String endModified;
public Params() {
}
public String getStartTime() {
return startTime;
}
public void setStartTime(String startTime) {
this.startTime = startTime;
}
public String getEndTime() {
return endTime;
}
public void setEndTime(String endTime) {
this.endTime = endTime;
}
public Integer getStatusType() {
return statusType;
}
public void setStatusType(Integer statusType) {
this.statusType = statusType;
}
public Integer getTimeType() {
return timeType;
}
public void setTimeType(Integer timeType) {
this.timeType = timeType;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getStockoutNo() {
return stockoutNo;
}
public void setStockoutNo(String stockoutNo) {
this.stockoutNo = stockoutNo;
}
public String getShopNo() {
return shopNo;
}
public void setShopNo(String shopNo) {
this.shopNo = shopNo;
}
public String getWarehouseNo() {
return warehouseNo;
}
public void setWarehouseNo(String warehouseNo) {
this.warehouseNo = warehouseNo;
}
public String getPlatformCode() {
return platformCode;
}
public void setPlatformCode(String platformCode) {
this.platformCode = platformCode;
}
public String getTradeNo() {
return tradeNo;
}
public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public String getOuterNo() {
return outerNo;
}
public void setOuterNo(String outerNo) {
this.outerNo = outerNo;
}
public String getProcessId() {
return processId;
}
public void setProcessId(String processId) {
this.processId = processId;
}
public Integer getProcessType() {
return processType;
}
public void setProcessType(Integer processType) {
this.processType = processType;
}
public Integer getIsDetail() {
return isDetail;
}
public void setIsDetail(Integer isDetail) {
this.isDetail = isDetail;
}
public String getOwnerNo() {
return ownerNo;
}
public void setOwnerNo(String ownerNo) {
this.ownerNo = ownerNo;
}
public String getConsignee() {
return consignee;
}
public void setConsignee(String consignee) {
this.consignee = consignee;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
public String getOperatorName() {
return operatorName;
}
public void setOperatorName(String operatorName) {
this.operatorName = operatorName;
}
public String getConfirmTime() {
return confirmTime;
}
public void setConfirmTime(String confirmTime) {
this.confirmTime = confirmTime;
}
public Integer getConfirmType() {
return confirmType;
}
public void setConfirmType(Integer confirmType) {
this.confirmType = confirmType;
}
public String getConfirmRemark() {
return confirmRemark;
}
public void setConfirmRemark(String confirmRemark) {
this.confirmRemark = confirmRemark;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public String getCreatorName() {
return creatorName;
}
public void setCreatorName(String creatorName) {
this.creatorName = creatorName;
}
public String getCreateTime() {
return createTime;
}
public void setCreateTime(String createTime) {
this.createTime = createTime;
}
public String getModifier() {
return modifier;
}
public void setModifier(String modifier) {
this.modifier = modifier;
}
public String getModifierName() {
return modifierName;
}
public void setModifierName(String modifierName) {
this.modifierName = modifierName;
}
public String getModifyTime() {
return modifyTime;
}
public void setModifyTime(String modifyTime) {
this.modifyTime = modifyTime;
}
public Integer getIsDelete() {
return isDelete;
}
public void setIsDelete(Integer isDelete) {
this.isDelete = isDelete;
}
public String getDeleteTime() {
return deleteTime;
}
public void setDeleteTime(String deleteTime) {
this.deleteTime = deleteTime;
}
public String getDeleter() {
return deleter;
}
public void setDeleter(String deleter) {
this.deleter = deleter;
}
public String getDeleterName() {
return deleterName;
}
public void setDeleterName(String deleterName) {
this.deleterName = deleterName;
}
public String getBatchNo() {
return batchNo;
}
public void setBatchNo(String batchNo) {
this.batchNo = batchNo;
}
public Integer getPageNo() {
return pageNo;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public String getKeywords() {
return keywords;
}
public void setKeywords(String keywords) {
this.keywords = keywords;
}
public String getFields() {
return fields;
}
public void setFields(String fields) {
this.fields = fields;
}
public String getCustomerid() {
return customerid;
}
public void setCustomerid(String customerid) {
this.customerid = customerid;
}
public String getSdCode() {
return sdCode;
}
public void setSdCode(String sdCode) {
this.sdCode = sdCode;
}
public String getStartModified() {
return startModified;
}
public void setStartModified(String startModified) {
this.startModified = startModified;
}
public String getEndModified() {
return endModified;
}
public void setEndModified(String endModified) {
this.endModified = endModified;
}
public void setOtherField(String key, Object value) {
if ("time_type".equals(key) && value instanceof Integer) {
this.timeType = (Integer) value;
} else if ("status_type".equals(key) && value instanceof Integer) {
this.statusType = (Integer) value;
}
}
}
}
\ No newline at end of file
package com.sfa.job.pojo.response;
import com.taobao.api.TaobaoResponse;
import lombok.Data;
/**
* @Author: DouXinYu
* @Date: 2026-04-20 18:32
* @Description: 旺店通基础响应类
*/
@Data
public class BaseResponse extends TaobaoResponse{
String flag;
String message;
String subMessage;
String code;
String data;
String result;
String requestId;
}
package com.sfa.job.service.stock;
/**
* @Author: DouXinYu
* @Date: 2026-04-17 16:52
* @Description: 旺店通其他出库单服务同步接口
*/
public interface IWdtOtherStockSyncService {
void syncLastDayOtherStockOut(String startTime, String endTime);
void syncLastDayOtherStockIn(String startTime, String endTime);
}
package com.sfa.job.service.stock.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.sfa.job.domain.stock.dao.IWdtOtherStockDao;
import com.sfa.job.service.stock.IWdtOtherStockSyncService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author: DouXinYu
* @Date: 2026-04-17 16:54
* @Description: 旺店通其他入库单同步服务实现类
*/
@Service
@DS("bi")
public class WdtOtherStockSyncServiceImpl implements IWdtOtherStockSyncService {
@Autowired
private IWdtOtherStockDao wdtOtherStockDao;
/**
* 同步昨日其他出库单
*/
@Override
public void syncLastDayOtherStockOut(String startTime, String endTime) {
wdtOtherStockDao.syncLastDayOtherStockOut(startTime, endTime);
}
@Override
public void syncLastDayOtherStockIn(String startTime, String endTime) {
wdtOtherStockDao.syncLastDayOtherStockIn(startTime, endTime);
}
}
package com.sfa.job.util;
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qimencloud.api.DefaultQimenCloudClient;
import com.qimencloud.api.QimenCloudClient;
import com.sfa.common.core.exception.ServiceException;
import com.sfa.job.config.WdtQimenConfig;
import com.sfa.job.pojo.request.BaseRequest;
import com.sfa.job.pojo.response.BaseResponse;
import com.taobao.api.ApiException;
import com.taobao.api.BaseTaobaoRequest;
import com.taobao.api.TaobaoResponse;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.*;
@Component
public class WangDianTongQimenApiUtil implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(WangDianTongQimenApiUtil.class);
private static final ObjectMapper objectMapper = new ObjectMapper();
private static ApplicationContext applicationContext;
public interface HasSetParams {
void setParams(String params);
}
public interface HasSetPager {
void setPager(String pager);
}
public interface HasSetTargetAppKey {
void setTargetAppKey(String targetAppKey);
}
public interface HasSetWdtSign {
void setWdtSign(String wdtSign);
}
public interface HasSetDatetime {
void setDatetime(String datetime);
}
public interface HasSetWdtAppkey {
void setWdtAppkey(String wdtAppkey);
}
public interface HasSetWdtSalt {
void setWdtSalt(String wdtSalt);
}
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeansException {
applicationContext = ctx;
}
private static WdtQimenConfig getConfig() {
if (applicationContext == null) {
throw new IllegalStateException("ApplicationContext未初始化");
}
return applicationContext.getBean(WdtQimenConfig.class);
}
public static QimenRequestBuilder createBuilder() {
return new QimenRequestBuilder(getConfig());
}
public static class QimenRequestBuilder {
private final String serverUrl;
private final String appKey;
private final String appSecret;
private final String wdtSecret;
private final String wdtSalt;
private final String wdtAppKey;
private final String targetAppSecret;
private final String wdtSid;
private QimenRequestBuilder(WdtQimenConfig config) {
this.serverUrl = config.getServerUrl();
this.appKey = config.getAppKey();
this.appSecret = config.getAppSecret();
String wdtAppSecret = config.getWdtAppSecret();
String[] secretParts = wdtAppSecret.split(":");
if (secretParts.length != 2) {
throw new ServiceException("wdtAppSecret配置格式错误,应为 'secret:salt' 格式");
}
this.wdtSecret = secretParts[0];
this.wdtSalt = secretParts[1];
this.wdtAppKey = config.getWdtAppKey();
this.targetAppSecret = config.getTargetAppSecret();
this.wdtSid = config.getWdtSid();
}
public <T extends TaobaoResponse> T execute(BaseTaobaoRequest<T> request, Map<String, Object> params) {
logger.info("执行奇门请求 - 方法: {}", request.getApiMethodName());
QimenCloudClient client = new DefaultQimenCloudClient(serverUrl, appKey, appSecret);
Map<String, Object> paramsMap = new HashMap<>();
Map<String, Object> pagerMap = new HashMap<>();
if (params != null) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if ("startTime".equals(key) && value instanceof Date) {
paramsMap.put("start_time", DateUtil.formatDateTime((Date) value));
} else if ("endTime".equals(key) && value instanceof Date) {
paramsMap.put("end_time", DateUtil.formatDateTime((Date) value));
} else if ("pageNo".equals(key) && value != null) {
pagerMap.put("page_no", value);
} else if ("pageSize".equals(key) && value != null) {
pagerMap.put("page_size", value);
} else if (value != null) {
paramsMap.put(key, value);
}
}
}
String paramsJson = null;
String pagerJson = null;
if (!paramsMap.isEmpty()) {
try {
paramsJson = objectMapper.writeValueAsString(paramsMap);
if (request instanceof HasSetParams) {
((HasSetParams) request).setParams(paramsJson);
}
} catch (Exception e) {
logger.error("构建params JSON失败", e);
}
}
if (!pagerMap.isEmpty()) {
try {
pagerJson = objectMapper.writeValueAsString(pagerMap);
if (request instanceof HasSetPager) {
((HasSetPager) request).setPager(pagerJson);
}
} catch (Exception e) {
logger.error("构建pager JSON失败", e);
}
}
String dateTime = DateUtil.formatDateTime(new Date());
if (request instanceof HasSetDatetime) {
((HasSetDatetime) request).setDatetime(dateTime);
}
request.putOtherTextParam("wdt3_customer_id", wdtSid);
if (request instanceof HasSetTargetAppKey) {
((HasSetTargetAppKey) request).setTargetAppKey(targetAppSecret);
}
if (request instanceof HasSetWdtAppkey) {
((HasSetWdtAppkey) request).setWdtAppkey(wdtAppKey);
}
if (request instanceof HasSetWdtSalt) {
((HasSetWdtSalt) request).setWdtSalt(wdtSalt);
}
String wdtSign = WdtQimenUtil.getQimenCustomWdtSign(request, wdtSecret);
if (request instanceof HasSetWdtSign) {
((HasSetWdtSign) request).setWdtSign(wdtSign);
}
try {
long startTime = System.currentTimeMillis();
T response = client.execute(request);
long duration = System.currentTimeMillis() - startTime;
logger.info("奇门请求成功 - 方法: {}, 耗时: {}ms", request.getApiMethodName(), duration);
if (ObjectUtils.isNotEmpty(response)) {
String flag = getFlagValue(response);
String bodyFlag = getBodyFlagValue(response);
if ("failure".equals(flag) || "failure".equals(bodyFlag)) {
String message = getMessageValue(response);
String subMessage = getSubMessageValue(response);
String bodyMessage = getBodyMessageValue(response);
logger.error("奇门加载数据异常 - 消息: {}, 子消息: {}, body消息: {}", message, subMessage, bodyMessage);
throw new ServiceException("奇门加载数据异常:" + message + subMessage + bodyMessage);
}
}
return response;
} catch (ApiException e) {
logger.error("奇门API调用异常 - 方法: {}, 错误: {}", request.getApiMethodName(), e.getMessage(), e);
throw new ServiceException("奇门API调用异常:" + e.getMessage());
}
}
public <T extends TaobaoResponse> T execute(BaseTaobaoRequest<T> request) {
return execute(request, null);
}
public BaseResponse execute(String method, Map<String, Object> params) {
BaseRequest<BaseResponse> request = new BaseRequest<>();
request.setRequestMethod(method);
Map<String, Object> paramsMap = new HashMap<>();
Map<String, Object> pagerMap = new HashMap<>();
if (params != null) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if ("startTime".equals(key) && value instanceof Date) {
paramsMap.put("start_time", DateUtil.formatDateTime((Date) value));
} else if ("endTime".equals(key) && value instanceof Date) {
paramsMap.put("end_time", DateUtil.formatDateTime((Date) value));
} else if ("pageNo".equals(key) && value != null) {
pagerMap.put("page_no", value);
} else if ("pageSize".equals(key) && value != null) {
pagerMap.put("page_size", value);
} else if (value != null) {
paramsMap.put(key, value);
}
}
}
if (!paramsMap.isEmpty()) {
BaseRequest.Params requestParams = new BaseRequest.Params();
for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if ("start_time".equals(key)) {
requestParams.setStartTime(value.toString());
} else if ("end_time".equals(key)) {
requestParams.setEndTime(value.toString());
} else if ("status".equals(key)) {
requestParams.setStatus(value.toString());
} else {
requestParams.setOtherField(key, value);
}
}
request.setParams(requestParams);
}
if (!pagerMap.isEmpty()) {
BaseRequest.Pager requestPager = new BaseRequest.Pager();
if (pagerMap.containsKey("page_no")) {
requestPager.setPageNo(Long.valueOf(pagerMap.get("page_no").toString()));
}
if (pagerMap.containsKey("page_size")) {
requestPager.setPageSize(Long.valueOf(pagerMap.get("page_size").toString()));
}
request.setPager(requestPager);
}
return execute(request, null);
}
private String removeMethodPrefix(String method) {
if (method == null || method.isEmpty()) {
return method;
}
int firstDotIndex = method.indexOf('.');
if (firstDotIndex > 0) {
return method.substring(firstDotIndex + 1);
}
return method;
}
private String buildSignString(Map<String, Object> signMap) {
List<String> sortedKeys = new ArrayList<>(signMap.keySet());
Collections.sort(sortedKeys);
StringBuilder sb = new StringBuilder();
for (String key : sortedKeys) {
Object value = signMap.get(key);
sb.append(key);
appendValue(sb, value);
}
return sb.toString();
}
private void appendValue(StringBuilder sb, Object value) {
if (value == null) {
return;
}
if (value instanceof Map) {
Map<?, ?> map = (Map<?, ?>) value;
List<String> sortedKeys = new ArrayList<>();
for (Object key : map.keySet()) {
sortedKeys.add(key.toString());
}
Collections.sort(sortedKeys);
for (String key : sortedKeys) {
Object mapValue = map.get(key);
if (mapValue != null) {
sb.append(key);
appendValue(sb, mapValue);
}
}
} else if (value instanceof List) {
List<?> list = (List<?>) value;
for (Object item : list) {
appendValue(sb, item);
}
} else if (value instanceof String) {
String strValue = (String) value;
if (isValidJsonObject(strValue)) {
try {
Map<String, Object> jsonMap = objectMapper.readValue(strValue, Map.class);
appendValue(sb, jsonMap);
} catch (Exception e) {
sb.append(strValue);
}
} else if (isValidJsonArray(strValue)) {
try {
List<Object> jsonList = objectMapper.readValue(strValue, List.class);
appendValue(sb, jsonList);
} catch (Exception e) {
sb.append(strValue);
}
} else {
sb.append(strValue);
}
} else if (value instanceof Boolean) {
sb.append(((Boolean) value) ? "true" : "false");
} else if (value instanceof Integer || value instanceof Long) {
sb.append(value);
} else if (value instanceof BigDecimal) {
sb.append(((BigDecimal) value).toPlainString());
} else if (value instanceof Double || value instanceof Float) {
sb.append(value);
} else {
sb.append(value.toString());
}
}
private boolean isValidJsonObject(String str) {
if (str == null || str.trim().isEmpty()) {
return false;
}
String trimmed = str.trim();
return trimmed.startsWith("{") && trimmed.endsWith("}");
}
private boolean isValidJsonArray(String str) {
if (str == null || str.trim().isEmpty()) {
return false;
}
String trimmed = str.trim();
return trimmed.startsWith("[") && trimmed.endsWith("]");
}
@SuppressWarnings("unchecked")
private String getFlagValue(TaobaoResponse response) {
try {
Map<String, Object> map = objectMapper.readValue(objectMapper.writeValueAsString(response), Map.class);
return (String) map.get("flag");
} catch (Exception e) {
return null;
}
}
@SuppressWarnings("unchecked")
private String getMessageValue(TaobaoResponse response) {
try {
Map<String, Object> map = objectMapper.readValue(objectMapper.writeValueAsString(response), Map.class);
Object message = map.get("message");
return message != null ? message.toString() : "";
} catch (Exception e) {
return "";
}
}
@SuppressWarnings("unchecked")
private String getSubMessageValue(TaobaoResponse response) {
try {
Map<String, Object> map = objectMapper.readValue(objectMapper.writeValueAsString(response), Map.class);
Object subMessage = map.get("subMessage");
return subMessage != null ? subMessage.toString() : "";
} catch (Exception e) {
return "";
}
}
@SuppressWarnings("unchecked")
private String getBodyFlagValue(TaobaoResponse response) {
try {
Map<String, Object> map = objectMapper.readValue(objectMapper.writeValueAsString(response), Map.class);
Object body = map.get("body");
if (body != null) {
Map<String, Object> bodyMap = objectMapper.readValue(objectMapper.writeValueAsString(body), Map.class);
Object responseObj = bodyMap.get("response");
if (responseObj instanceof Map) {
Map<String, Object> responseMap = (Map<String, Object>) responseObj;
Object flag = responseMap.get("flag");
return flag != null ? flag.toString() : null;
}
}
} catch (Exception e) {
logger.debug("获取body flag失败", e);
}
return null;
}
@SuppressWarnings("unchecked")
private String getBodyMessageValue(TaobaoResponse response) {
try {
Map<String, Object> map = objectMapper.readValue(objectMapper.writeValueAsString(response), Map.class);
Object body = map.get("body");
if (body != null) {
Map<String, Object> bodyMap = objectMapper.readValue(objectMapper.writeValueAsString(body), Map.class);
Object responseObj = bodyMap.get("response");
if (responseObj instanceof Map) {
Map<String, Object> responseMap = (Map<String, Object>) responseObj;
Object message = responseMap.get("message");
return message != null ? message.toString() : "";
}
}
} catch (Exception e) {
logger.debug("获取body message失败", e);
}
return "";
}
public static int calculateTotalPage(int totalCount, int pageSize) {
return totalCount / pageSize + (totalCount % pageSize > 0 ? 1 : 0);
}
}
}
\ No newline at end of file
package com.sfa.job.jobhandler;
import com.sfa.job.service.stock.IWdtOtherStockSyncService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
* 旺店通其他出入库单同步 XXL-Job 任务
*
* @Author: DouXinYu
* @Date: 2026-04-23
*/
@Slf4j
@Component
public class WdtOtherStockSyncJobHandler {
@Autowired
private IWdtOtherStockSyncService wdtOtherStockSyncService;
private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* 同步昨日其他出库单(XXL-Job 任务)
* 任务调度建议:0 0 1 * * ? 每天凌晨1点
*/
@XxlJob("wdtSyncLastDayOtherStockOutJob")
public void syncLastDayOtherStockOutJob() {
log.info("===== XXL-Job 开始执行:同步昨日旺店通其他出库单 =====");
XxlJobHelper.log("XXL-Job 开始执行:同步昨日旺店通其他出库单");
LocalDateTime now = LocalDateTime.now();
LocalDateTime yesterdayStart = now.minusDays(1).withHour(0).withMinute(0).withSecond(0);
LocalDateTime yesterdayEnd = now.minusDays(1).withHour(23).withMinute(59).withSecond(59);
String startTime = yesterdayStart.format(FORMATTER);
String endTime = yesterdayEnd.format(FORMATTER);
log.info("同步时间范围:{} ~ {}", startTime, endTime);
XxlJobHelper.log("同步时间范围:{} ~ {}", startTime, endTime);
long start = System.currentTimeMillis();
try {
wdtOtherStockSyncService.syncLastDayOtherStockOut(startTime, endTime);
log.info("===== XXL-Job 同步昨日其他出库单完成,耗时:{}ms =====", System.currentTimeMillis() - start);
XxlJobHelper.log("同步完成,耗时:{}ms", System.currentTimeMillis() - start);
XxlJobHelper.handleSuccess("同步昨日其他出库单成功");
} catch (Exception e) {
log.error("===== XXL-Job 同步昨日其他出库单异常 =====", e);
XxlJobHelper.log("同步异常:%s", e.getMessage());
XxlJobHelper.handleFail("同步昨日其他出库单失败:" + e.getMessage());
}
}
/**
* 同步昨日其他入库单(XXL-Job 任务)
* 任务调度建议:0 10 1 * * ? 每天凌晨1点10分
*/
@XxlJob("wdtSyncLastDayOtherStockInJob")
public void syncLastDayOtherStockInJob() {
log.info("===== XXL-Job 开始执行:同步昨日旺店通其他入库单 =====");
XxlJobHelper.log("XXL-Job 开始执行:同步昨日旺店通其他入库单");
LocalDateTime now = LocalDateTime.now();
LocalDateTime yesterdayStart = now.minusDays(1).withHour(0).withMinute(0).withSecond(0);
LocalDateTime yesterdayEnd = now.minusDays(1).withHour(23).withMinute(59).withSecond(59);
String startTime = yesterdayStart.format(FORMATTER);
String endTime = yesterdayEnd.format(FORMATTER);
log.info("同步时间范围:{} ~ {}", startTime, endTime);
XxlJobHelper.log("同步时间范围:{} ~ {}", startTime, endTime);
long start = System.currentTimeMillis();
try {
wdtOtherStockSyncService.syncLastDayOtherStockIn(startTime, endTime);
log.info("===== XXL-Job 同步昨日其他入库单完成,耗时:{}ms =====", System.currentTimeMillis() - start);
XxlJobHelper.log("同步完成,耗时:{}ms", System.currentTimeMillis() - start);
XxlJobHelper.handleSuccess("同步昨日其他入库单成功");
} catch (Exception e) {
log.error("===== XXL-Job 同步昨日其他入库单异常 =====", e);
XxlJobHelper.log("同步异常:%s", e.getMessage());
XxlJobHelper.handleFail("同步昨日其他入库单失败:" + e.getMessage());
}
}
}
\ No newline at end of file
<?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.sfa.job.domain.stock.mapper.WdtQimenOtherStockInOrderDetailMapper">
<!-- 批量插入或更新其他入库单明细 -->
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
INSERT INTO wdt_qimen_other_stock_in_order_detail (
rec_id,
other_in_id,
barcode,
base_unit_id,
base_unit_name,
batch_no,
batch_remark,
brand_id,
brand_name,
created_date,
defect,
expire_date,
goods_id,
goods_name,
goods_no,
modified_date,
num,
num2,
in_num,
production_date,
remark,
short_name,
spec_code,
spec_id,
spec_name,
spec_no
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.recId},
#{item.otherInId},
#{item.barcode},
#{item.baseUnitId},
#{item.baseUnitName},
#{item.batchNo},
#{item.batchRemark},
#{item.brandId},
#{item.brandName},
#{item.createdDate},
#{item.defect},
#{item.expireDate},
#{item.goodsId},
#{item.goodsName},
#{item.goodsNo},
#{item.modifiedDate},
#{item.num},
#{item.num2},
#{item.inNum},
#{item.productionDate},
#{item.remark},
#{item.shortName},
#{item.specCode},
#{item.specId},
#{item.specName},
#{item.specNo}
)
</foreach>
ON DUPLICATE KEY UPDATE
other_in_id = VALUES(other_in_id),
barcode = VALUES(barcode),
base_unit_id = VALUES(base_unit_id),
base_unit_name = VALUES(base_unit_name),
batch_no = VALUES(batch_no),
batch_remark = VALUES(batch_remark),
brand_id = VALUES(brand_id),
brand_name = VALUES(brand_name),
created_date = VALUES(created_date),
defect = VALUES(defect),
expire_date = VALUES(expire_date),
goods_id = VALUES(goods_id),
goods_name = VALUES(goods_name),
goods_no = VALUES(goods_no),
modified_date = VALUES(modified_date),
num = VALUES(num),
num2 = VALUES(num2),
in_num = VALUES(in_num),
production_date = VALUES(production_date),
remark = VALUES(remark),
short_name = VALUES(short_name),
spec_code = VALUES(spec_code),
spec_id = VALUES(spec_id),
spec_name = VALUES(spec_name),
spec_no = VALUES(spec_no)
</insert>
</mapper>
<?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.sfa.job.domain.stock.mapper.WdtQimenOtherStockInOrderMapper">
<!-- 插入或更新其他入库单 -->
<insert id="insertOrUpdate" parameterType="com.sfa.job.domain.stock.entity.WdtQimenOtherStockInOrder">
INSERT INTO wdt_qimen_other_stock_in_order (
rec_id,
other_in_no,
outer_no,
warehouse_no,
warehouse_name,
created,
creator_id,
employee_name,
warehouse_type,
actual_num,
expect_num,
logistics_no,
logistics_id,
logistics_name,
reason,
remark,
status,
modified,
check_time,
note_count,
warehouse_id
) VALUES (
#{recId},
#{otherInNo},
#{outerNo},
#{warehouseNo},
#{warehouseName},
#{created},
#{creatorId},
#{employeeName},
#{warehouseType},
#{actualNum},
#{expectNum},
#{logisticsNo},
#{logisticsId},
#{logisticsName},
#{reason},
#{remark},
#{status},
#{modified},
#{checkTime},
#{noteCount},
#{warehouseId}
)
ON DUPLICATE KEY UPDATE
other_in_no = VALUES(other_in_no),
outer_no = VALUES(outer_no),
warehouse_no = VALUES(warehouse_no),
warehouse_name = VALUES(warehouse_name),
created = VALUES(created),
creator_id = VALUES(creator_id),
employee_name = VALUES(employee_name),
warehouse_type = VALUES(warehouse_type),
actual_num = VALUES(actual_num),
expect_num = VALUES(expect_num),
logistics_no = VALUES(logistics_no),
logistics_id = VALUES(logistics_id),
logistics_name = VALUES(logistics_name),
reason = VALUES(reason),
remark = VALUES(remark),
status = VALUES(status),
modified = VALUES(modified),
check_time = VALUES(check_time),
note_count = VALUES(note_count),
warehouse_id = VALUES(warehouse_id)
</insert>
<!-- 批量插入或更新其他入库单 -->
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
INSERT INTO wdt_qimen_other_stock_in_order (
rec_id,
other_in_no,
outer_no,
warehouse_no,
warehouse_name,
created,
creator_id,
employee_name,
warehouse_type,
actual_num,
expect_num,
logistics_no,
logistics_id,
logistics_name,
reason,
remark,
status,
modified,
check_time,
note_count,
warehouse_id
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.recId},
#{item.otherInNo},
#{item.outerNo},
#{item.warehouseNo},
#{item.warehouseName},
#{item.created},
#{item.creatorId},
#{item.employeeName},
#{item.warehouseType},
#{item.actualNum},
#{item.expectNum},
#{item.logisticsNo},
#{item.logisticsId},
#{item.logisticsName},
#{item.reason},
#{item.remark},
#{item.status},
#{item.modified},
#{item.checkTime},
#{item.noteCount},
#{item.warehouseId}
)
</foreach>
ON DUPLICATE KEY UPDATE
other_in_no = VALUES(other_in_no),
outer_no = VALUES(outer_no),
warehouse_no = VALUES(warehouse_no),
warehouse_name = VALUES(warehouse_name),
created = VALUES(created),
creator_id = VALUES(creator_id),
employee_name = VALUES(employee_name),
warehouse_type = VALUES(warehouse_type),
actual_num = VALUES(actual_num),
expect_num = VALUES(expect_num),
logistics_no = VALUES(logistics_no),
logistics_id = VALUES(logistics_id),
logistics_name = VALUES(logistics_name),
reason = VALUES(reason),
remark = VALUES(remark),
status = VALUES(status),
modified = VALUES(modified),
check_time = VALUES(check_time),
note_count = VALUES(note_count),
warehouse_id = VALUES(warehouse_id)
</insert>
</mapper>
<?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.sfa.job.domain.stock.mapper.WdtQimenOtherStockOutOrderDetailMapper">
<!-- 批量插入或更新其他出库单明细 -->
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
INSERT INTO wdt_qimen_other_stock_out_order_detail (
rec_id,
other_out_id,
barcode,
base_unit_id,
base_unit_name,
batch_no,
batch_remark,
brand_id,
brand_name,
created_date,
defect,
expire_date,
goods_id,
goods_name,
goods_no,
modified_date,
num,
num2,
out_num,
production_date,
remark,
short_name,
spec_code,
spec_id,
spec_name,
spec_no
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.recId},
#{item.otherOutId},
#{item.barcode},
#{item.baseUnitId},
#{item.baseUnitName},
#{item.batchNo},
#{item.batchRemark},
#{item.brandId},
#{item.brandName},
#{item.createdDate},
#{item.defect},
#{item.expireDate},
#{item.goodsId},
#{item.goodsName},
#{item.goodsNo},
#{item.modifiedDate},
#{item.num},
#{item.num2},
#{item.outNum},
#{item.productionDate},
#{item.remark},
#{item.shortName},
#{item.specCode},
#{item.specId},
#{item.specName},
#{item.specNo}
)
</foreach>
ON DUPLICATE KEY UPDATE
other_out_id = VALUES(other_out_id),
barcode = VALUES(barcode),
base_unit_id = VALUES(base_unit_id),
base_unit_name = VALUES(base_unit_name),
batch_no = VALUES(batch_no),
batch_remark = VALUES(batch_remark),
brand_id = VALUES(brand_id),
brand_name = VALUES(brand_name),
created_date = VALUES(created_date),
defect = VALUES(defect),
expire_date = VALUES(expire_date),
goods_id = VALUES(goods_id),
goods_name = VALUES(goods_name),
goods_no = VALUES(goods_no),
modified_date = VALUES(modified_date),
num = VALUES(num),
num2 = VALUES(num2),
out_num = VALUES(out_num),
production_date = VALUES(production_date),
remark = VALUES(remark),
short_name = VALUES(short_name),
spec_code = VALUES(spec_code),
spec_id = VALUES(spec_id),
spec_name = VALUES(spec_name),
spec_no = VALUES(spec_no)
</insert>
</mapper>
<?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.sfa.job.domain.stock.mapper.WdtQimenOtherStockOutOrderMapper">
<!-- 插入或更新其他出库单 -->
<insert id="insertOrUpdate" parameterType="com.sfa.job.domain.stock.entity.WdtQimenOtherStockOutOrder">
INSERT INTO wdt_qimen_other_stock_out_order (
rec_id,
other_out_no,
outer_no,
warehouse_no,
warehouse_name,
created,
creator_id,
employee_name,
warehouse_type,
actual_num,
expect_num,
logistics_no,
logistics_id,
logistics_name,
receiver_name,
receiver_province,
receiver_city,
receiver_district,
receiver_mobile,
receiver_address,
reason,
remark,
status,
modified,
check_time,
note_count,
is_reserved,
prop1,
prop2,
prop3,
prop4,
prop5,
prop6,
warehouse_id
) VALUES (
#{recId},
#{otherOutNo},
#{outerNo},
#{warehouseNo},
#{warehouseName},
#{created},
#{creatorId},
#{employeeName},
#{warehouseType},
#{actualNum},
#{expectNum},
#{logisticsNo},
#{logisticsId},
#{logisticsName},
#{receiverName},
#{receiverProvince},
#{receiverCity},
#{receiverDistrict},
#{receiverMobile},
#{receiverAddress},
#{reason},
#{remark},
#{status},
#{modified},
#{checkTime},
#{noteCount},
#{isReserved},
#{prop1},
#{prop2},
#{prop3},
#{prop4},
#{prop5},
#{prop6},
#{warehouseId}
)
ON DUPLICATE KEY UPDATE
other_out_no = VALUES(other_out_no),
outer_no = VALUES(outer_no),
warehouse_no = VALUES(warehouse_no),
warehouse_name = VALUES(warehouse_name),
created = VALUES(created),
creator_id = VALUES(creator_id),
employee_name = VALUES(employee_name),
warehouse_type = VALUES(warehouse_type),
actual_num = VALUES(actual_num),
expect_num = VALUES(expect_num),
logistics_no = VALUES(logistics_no),
logistics_id = VALUES(logistics_id),
logistics_name = VALUES(logistics_name),
receiver_name = VALUES(receiver_name),
receiver_province = VALUES(receiver_province),
receiver_city = VALUES(receiver_city),
receiver_district = VALUES(receiver_district),
receiver_mobile = VALUES(receiver_mobile),
receiver_address = VALUES(receiver_address),
reason = VALUES(reason),
remark = VALUES(remark),
status = VALUES(status),
modified = VALUES(modified),
check_time = VALUES(check_time),
note_count = VALUES(note_count),
is_reserved = VALUES(is_reserved),
prop1 = VALUES(prop1),
prop2 = VALUES(prop2),
prop3 = VALUES(prop3),
prop4 = VALUES(prop4),
prop5 = VALUES(prop5),
prop6 = VALUES(prop6),
warehouse_id = VALUES(warehouse_id)
</insert>
<!-- 批量插入或更新其他出库单 -->
<insert id="insertOrUpdateBatch" parameterType="java.util.List">
INSERT INTO wdt_qimen_other_stock_out_order (
rec_id,
other_out_no,
outer_no,
warehouse_no,
warehouse_name,
created,
creator_id,
employee_name,
warehouse_type,
actual_num,
expect_num,
logistics_no,
logistics_id,
logistics_name,
receiver_name,
receiver_province,
receiver_city,
receiver_district,
receiver_mobile,
receiver_address,
reason,
remark,
status,
modified,
check_time,
note_count,
is_reserved,
prop1,
prop2,
prop3,
prop4,
prop5,
prop6,
warehouse_id
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.recId},
#{item.otherOutNo},
#{item.outerNo},
#{item.warehouseNo},
#{item.warehouseName},
#{item.created},
#{item.creatorId},
#{item.employeeName},
#{item.warehouseType},
#{item.actualNum},
#{item.expectNum},
#{item.logisticsNo},
#{item.logisticsId},
#{item.logisticsName},
#{item.receiverName},
#{item.receiverProvince},
#{item.receiverCity},
#{item.receiverDistrict},
#{item.receiverMobile},
#{item.receiverAddress},
#{item.reason},
#{item.remark},
#{item.status},
#{item.modified},
#{item.checkTime},
#{item.noteCount},
#{item.isReserved},
#{item.prop1},
#{item.prop2},
#{item.prop3},
#{item.prop4},
#{item.prop5},
#{item.prop6},
#{item.warehouseId}
)
</foreach>
ON DUPLICATE KEY UPDATE
other_out_no = VALUES(other_out_no),
outer_no = VALUES(outer_no),
warehouse_no = VALUES(warehouse_no),
warehouse_name = VALUES(warehouse_name),
created = VALUES(created),
creator_id = VALUES(creator_id),
employee_name = VALUES(employee_name),
warehouse_type = VALUES(warehouse_type),
actual_num = VALUES(actual_num),
expect_num = VALUES(expect_num),
logistics_no = VALUES(logistics_no),
logistics_id = VALUES(logistics_id),
logistics_name = VALUES(logistics_name),
receiver_name = VALUES(receiver_name),
receiver_province = VALUES(receiver_province),
receiver_city = VALUES(receiver_city),
receiver_district = VALUES(receiver_district),
receiver_mobile = VALUES(receiver_mobile),
receiver_address = VALUES(receiver_address),
reason = VALUES(reason),
remark = VALUES(remark),
status = VALUES(status),
modified = VALUES(modified),
check_time = VALUES(check_time),
note_count = VALUES(note_count),
is_reserved = VALUES(is_reserved),
prop1 = VALUES(prop1),
prop2 = VALUES(prop2),
prop3 = VALUES(prop3),
prop4 = VALUES(prop4),
prop5 = VALUES(prop5),
prop6 = VALUES(prop6),
warehouse_id = VALUES(warehouse_id)
</insert>
</mapper>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论