增加查询上游的菜单

This commit is contained in:
wuweihua
2026-10-13 09:29:26 +08:00
parent 3456a0bf7f
commit 26bdd3ba87
9 changed files with 665 additions and 0 deletions
@@ -0,0 +1,28 @@
package com.bms.price.domain.vo;
import java.io.Serializable;
import java.util.List;
import lombok.Data;
/**
* 订单数据源(TAB_ORDER)监控查询条件。
* 必须传客户 + 提货时间范围,避免全表扫描。
*/
@Data
public class TabOrderMonitorQuery implements Serializable
{
private static final long serialVersionUID = 1L;
/** 客户代码列表 */
private List<String> customerCodes;
/** 提货时间起(yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) */
private String beginTime;
/** 提货时间止(yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss) */
private String endTime;
/** 客户订单号 ORDER_ID */
private String orderId;
/** 运单号 ORG_ORDER_ID */
private String orgOrderId;
/** 转单号 TRANSFER_ORDER_ID */
private String transferOrderId;
}
@@ -0,0 +1,50 @@
package com.bms.price.domain.vo;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
/** 订单数据源(TAB_ORDER)列表行。 */
@Data
public class TabOrderMonitorVo implements Serializable
{
private static final long serialVersionUID = 1L;
/** 客户订单号 */
private String orderId;
/** 运单号 */
private String orgOrderId;
/** 转单号 */
private String transferOrderId;
/** 轨迹ID */
private String trackId;
/** 客户代码 */
private String customerCode;
/** 客户名称 */
private String customerName;
/** 产品代码 */
private String productCode;
/** 产品名称 */
private String productName;
/** 产品底级代码 */
private String productFloorCode;
/** 国家代码 */
private String country;
/** 国家名称 */
private String countryName;
/** 收件人邮编 */
private String consigneePostcode;
/** 材积系数/计费重 */
private BigDecimal dimensionalWeightFactor;
/** 体积重 */
private BigDecimal volumeWeight;
/** 实重 */
private BigDecimal weight;
/** 订单状态 ORDER_STATUS */
private Integer orderStatus;
/** 提货时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date pickupDate;
}
@@ -1,7 +1,9 @@
package com.bms.price.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import com.bms.price.domain.vo.TabOrderMonitorQuery;
/** Read upstream main order from Oracle (SLAVE datasource). */
public interface OracleUpstreamOrderMapper
@@ -17,4 +19,12 @@ public interface OracleUpstreamOrderMapper
Map<String, Object> selectByBarcode(@Param("orderTable") String orderTable, @Param("trackingNo") String trackingNo);
Map<String, Object> selectByCustomerTrackId(@Param("orderTable") String orderTable, @Param("trackingNo") String trackingNo);
long countTabOrderMonitor(@Param("orderTable") String orderTable, @Param("query") TabOrderMonitorQuery query);
List<Map<String, Object>> selectTabOrderMonitorPage(
@Param("orderTable") String orderTable,
@Param("query") TabOrderMonitorQuery query,
@Param("startRow") long startRow,
@Param("endRow") long endRow);
}
@@ -0,0 +1,292 @@
package com.bms.price.oracle;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.bms.common.annotation.DataSource;
import com.bms.common.enums.DataSourceType;
import com.bms.common.exception.ServiceException;
import com.bms.common.utils.StringUtils;
import com.bms.price.config.BillingProperties;
import com.bms.price.domain.vo.TabOrderMonitorQuery;
import com.bms.price.domain.vo.TabOrderMonitorVo;
import com.bms.price.mapper.OracleUpstreamOrderMapper;
/**
* 订单数据源:从 Oracle TAB_ORDER 分页查询(SLAVE)。
*/
@Service
public class TabOrderMonitorService
{
private static final Logger log = LoggerFactory.getLogger(TabOrderMonitorService.class);
@Autowired
private OracleUpstreamOrderMapper oracleUpstreamOrderMapper;
@Autowired
private BillingProperties billingProperties;
@DataSource(DataSourceType.SLAVE)
public long count(TabOrderMonitorQuery query)
{
validate(query);
String table = resolveTable();
try
{
PageHelper.clearPage();
return oracleUpstreamOrderMapper.countTabOrderMonitor(table, query);
}
catch (RuntimeException e)
{
throw new ServiceException("Oracle TAB_ORDER count failed: " + e.getMessage());
}
finally
{
PageHelper.clearPage();
}
}
@DataSource(DataSourceType.SLAVE)
public List<TabOrderMonitorVo> selectPage(TabOrderMonitorQuery query, int pageNum, int pageSize)
{
validate(query);
String table = resolveTable();
int pn = pageNum < 1 ? 1 : pageNum;
int ps = pageSize < 1 ? 10 : pageSize;
if (ps > 200)
{
ps = 200;
}
long endRow = (long) pn * ps;
long startRow = endRow - ps;
try
{
PageHelper.clearPage();
long t0 = System.currentTimeMillis();
List<Map<String, Object>> rows = oracleUpstreamOrderMapper.selectTabOrderMonitorPage(table, query, startRow, endRow);
log.info("oracle tab_order page customerSize={} begin={} end={} page={}/{} rows={} costMs={}",
query.getCustomerCodes() == null ? 0 : query.getCustomerCodes().size(),
query.getBeginTime(), query.getEndTime(), pn, ps,
rows == null ? 0 : rows.size(), System.currentTimeMillis() - t0);
if (rows == null || rows.isEmpty())
{
return Collections.emptyList();
}
List<TabOrderMonitorVo> list = new ArrayList<TabOrderMonitorVo>(rows.size());
for (Map<String, Object> row : rows)
{
list.add(toVo(row));
}
return list;
}
catch (RuntimeException e)
{
throw new ServiceException("Oracle TAB_ORDER list failed: " + e.getMessage());
}
finally
{
PageHelper.clearPage();
}
}
private void validate(TabOrderMonitorQuery query)
{
if (query == null)
{
throw new ServiceException("请先选择客户和提货时间");
}
List<String> codes = query.getCustomerCodes();
if (codes == null || codes.isEmpty())
{
throw new ServiceException("请选择客户");
}
List<String> cleaned = new ArrayList<String>();
for (String c : codes)
{
if (StringUtils.isNotEmpty(c))
{
cleaned.add(c.trim());
}
}
if (cleaned.isEmpty())
{
throw new ServiceException("请选择客户");
}
query.setCustomerCodes(cleaned);
String begin = normalizeTime(query.getBeginTime(), true);
String end = normalizeTime(query.getEndTime(), false);
if (begin == null || end == null)
{
throw new ServiceException("请选择提货时间范围");
}
query.setBeginTime(begin);
query.setEndTime(end);
query.setOrderId(trimToNull(query.getOrderId()));
query.setOrgOrderId(trimToNull(query.getOrgOrderId()));
query.setTransferOrderId(trimToNull(query.getTransferOrderId()));
}
private static String trimToNull(String s)
{
if (StringUtils.isEmpty(s))
{
return null;
}
String t = s.trim();
return t.isEmpty() ? null : t;
}
private String resolveTable()
{
String table = billingProperties.getOracle().getOrderTable();
if (StringUtils.isEmpty(table))
{
throw new ServiceException("bms.billing.oracle.order-table is empty");
}
if (!table.matches("[A-Za-z0-9_\\.]+"))
{
throw new ServiceException("invalid oracle order table name");
}
return table;
}
private static String normalizeTime(String raw, boolean begin)
{
if (StringUtils.isEmpty(raw))
{
return null;
}
String s = raw.trim();
if (s.length() == 10)
{
return begin ? (s + " 00:00:00") : (s + " 23:59:59");
}
if (s.length() >= 19)
{
return s.substring(0, 19);
}
return s;
}
private static TabOrderMonitorVo toVo(Map<String, Object> row)
{
TabOrderMonitorVo vo = new TabOrderMonitorVo();
vo.setOrderId(str(row, "ORDER_ID"));
vo.setOrgOrderId(str(row, "ORG_ORDER_ID"));
vo.setTransferOrderId(str(row, "TRANSFER_ORDER_ID"));
vo.setTrackId(str(row, "TRACK_ID"));
vo.setCustomerCode(str(row, "CUSTOMER_CODE"));
vo.setCustomerName(str(row, "CUSTOMER_NAME"));
vo.setProductCode(str(row, "PRODUCT_CODE"));
vo.setProductName(str(row, "PRODUCT_NAME"));
vo.setProductFloorCode(str(row, "PRODUCT_FLOOR_CODE"));
vo.setCountry(str(row, "COUNTRY"));
vo.setCountryName(str(row, "COUNTRY_NAME"));
vo.setConsigneePostcode(str(row, "CONSIGNEE_POSTCODE"));
vo.setDimensionalWeightFactor(decimal(row, "DIMENSIONAL_WEIGHT_FACTOR"));
vo.setVolumeWeight(decimal(row, "VOLUME_WEIGHT"));
vo.setWeight(decimal(row, "WEIGHT"));
vo.setOrderStatus(integer(row, "ORDER_STATUS"));
vo.setPickupDate(date(row, "PICKUP_DATE"));
return vo;
}
private static String str(Map<String, Object> row, String key)
{
Object v = value(row, key);
return v == null ? null : String.valueOf(v).trim();
}
private static Integer integer(Map<String, Object> row, String key)
{
Object v = value(row, key);
if (v == null)
{
return null;
}
if (v instanceof Number)
{
return Integer.valueOf(((Number) v).intValue());
}
try
{
return Integer.valueOf(String.valueOf(v).trim());
}
catch (Exception e)
{
return null;
}
}
private static BigDecimal decimal(Map<String, Object> row, String key)
{
Object v = value(row, key);
if (v == null)
{
return null;
}
if (v instanceof BigDecimal)
{
return (BigDecimal) v;
}
if (v instanceof Number)
{
return BigDecimal.valueOf(((Number) v).doubleValue());
}
try
{
return new BigDecimal(String.valueOf(v).trim());
}
catch (Exception e)
{
return null;
}
}
private static Date date(Map<String, Object> row, String key)
{
Object v = value(row, key);
if (v == null)
{
return null;
}
if (v instanceof Timestamp)
{
return new Date(((Timestamp) v).getTime());
}
if (v instanceof Date)
{
return (Date) v;
}
return null;
}
private static Object value(Map<String, Object> row, String key)
{
if (row == null || key == null)
{
return null;
}
if (row.containsKey(key))
{
return row.get(key);
}
for (Map.Entry<String, Object> e : row.entrySet())
{
if (e.getKey() != null && e.getKey().equalsIgnoreCase(key))
{
return e.getValue();
}
}
return null;
}
}
@@ -44,4 +44,67 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
SELECT * FROM ${orderTable} WHERE CUSTOMER_TRACK_ID = #{trackingNo}
) WHERE ROWNUM &lt;= 1
</select>
<sql id="tabOrderMonitorWhere">
o.BL_PICKUP = 1
AND o.ORDER_STATUS IN (3, 4, 5, 6, 7, 8, 11)
AND o.CUSTOMER_CODE IN
<foreach collection="query.customerCodes" item="code" open="(" separator="," close=")">
#{code}
</foreach>
AND o.PICKUP_DATE &gt;= TO_TIMESTAMP(#{query.beginTime}, 'YYYY-MM-DD HH24:MI:SS')
AND o.PICKUP_DATE &lt;= TO_TIMESTAMP(#{query.endTime}, 'YYYY-MM-DD HH24:MI:SS')
<if test="query.orderId != null and query.orderId != ''">
AND o.ORDER_ID = #{query.orderId}
</if>
<if test="query.orgOrderId != null and query.orgOrderId != ''">
AND o.ORG_ORDER_ID = #{query.orgOrderId}
</if>
<if test="query.transferOrderId != null and query.transferOrderId != ''">
AND o.TRANSFER_ORDER_ID = #{query.transferOrderId}
</if>
</sql>
<sql id="tabOrderMonitorColumns">
o.ORDER_ID,
o.ORG_ORDER_ID,
o.TRANSFER_ORDER_ID,
o.TRACK_ID,
o.CUSTOMER_CODE,
o.CUSTOMER_NAME,
o.PRODUCT_CODE,
o.PRODUCT_NAME,
o.PRODUCT_FLOOR_CODE,
o.COUNTRY,
o.COUNTRY_NAME,
o.CONSIGNEE_POSTCODE,
o.DIMENSIONAL_WEIGHT_FACTOR,
o.VOLUME_WEIGHT,
o.WEIGHT,
o.ORDER_STATUS,
o.PICKUP_DATE
</sql>
<select id="countTabOrderMonitor" resultType="long">
SELECT COUNT(1)
FROM ${orderTable} o
WHERE
<include refid="tabOrderMonitorWhere"/>
</select>
<select id="selectTabOrderMonitorPage" resultType="java.util.HashMap">
SELECT * FROM (
SELECT inner_q.*, ROWNUM AS rn FROM (
SELECT
<include refid="tabOrderMonitorColumns"/>
FROM ${orderTable} o
WHERE
<include refid="tabOrderMonitorWhere"/>
ORDER BY o.PICKUP_DATE DESC, o.ORDER_ID DESC
) inner_q
WHERE ROWNUM &lt;= #{endRow}
)
WHERE rn &gt; #{startRow}
</select>
</mapper>