生成单据号逻辑修改
线程池线程数修改
This commit is contained in:
@@ -1116,6 +1116,9 @@ public class ExcelUtil<T>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加单元格
|
||||
*/
|
||||
/**
|
||||
* 添加单元格
|
||||
*/
|
||||
@@ -1126,11 +1129,13 @@ public class ExcelUtil<T>
|
||||
{
|
||||
// 设置行高
|
||||
row.setHeight(maxHeight);
|
||||
// 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列.
|
||||
|
||||
// 根据Excel中设置情况决定是否导出
|
||||
if (attr.isExport())
|
||||
{
|
||||
// 创建cell
|
||||
cell = row.createCell(column);
|
||||
|
||||
if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
|
||||
{
|
||||
if (subMergedLastRowNum >= subMergedFirstRowNum)
|
||||
@@ -1138,14 +1143,45 @@ public class ExcelUtil<T>
|
||||
sheet.addMergedRegion(new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column));
|
||||
}
|
||||
}
|
||||
|
||||
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType(), attr.wrapText())));
|
||||
|
||||
// 用于读取对象中的属性
|
||||
Object value = getTargetValue(vo, field, attr);
|
||||
|
||||
// =========================
|
||||
// ✅ BigDecimal:按“实际几位显示几位”,去掉末尾0(核心修改点)
|
||||
// =========================
|
||||
if (value instanceof BigDecimal)
|
||||
{
|
||||
BigDecimal bd = (BigDecimal) value;
|
||||
|
||||
if (-1 != attr.scale())
|
||||
{
|
||||
bd = bd.setScale(attr.scale(), attr.roundingMode());
|
||||
}
|
||||
|
||||
// 去掉末尾0:1.000000 -> 1,1.2300 -> 1.23
|
||||
String text = bd.stripTrailingZeros().toPlainString();
|
||||
|
||||
// 强制按字符串写入,避免 Excel 数值格式导致显示成固定小数位
|
||||
cell.setCellType(CellType.STRING);
|
||||
cell.setCellValue(StringUtils.isEmpty(text) ? attr.defaultValue() : text + attr.suffix());
|
||||
|
||||
// 统计
|
||||
addStatisticsData(column, text, attr);
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
// =========================
|
||||
// 原有逻辑(非 BigDecimal)保持不变
|
||||
// =========================
|
||||
String dateFormat = attr.dateFormat();
|
||||
String readConverterExp = attr.readConverterExp();
|
||||
String separator = attr.separator();
|
||||
String dictType = attr.dictType();
|
||||
|
||||
if (StringUtils.isNotEmpty(dateFormat) && StringUtils.isNotNull(value))
|
||||
{
|
||||
cell.getCellStyle().setDataFormat(this.wb.getCreationHelper().createDataFormat().getFormat(dateFormat));
|
||||
@@ -1164,10 +1200,6 @@ public class ExcelUtil<T>
|
||||
}
|
||||
cell.setCellValue(sysDictMap.get(dictType + value));
|
||||
}
|
||||
else if (value instanceof BigDecimal && -1 != attr.scale())
|
||||
{
|
||||
cell.setCellValue((((BigDecimal) value).setScale(attr.scale(), attr.roundingMode())).doubleValue());
|
||||
}
|
||||
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
||||
{
|
||||
cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell));
|
||||
@@ -1177,6 +1209,7 @@ public class ExcelUtil<T>
|
||||
// 设置列类型
|
||||
setCellVo(value, attr, cell);
|
||||
}
|
||||
|
||||
addStatisticsData(column, Convert.toStr(value), attr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,16 +18,16 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
public class ThreadPoolConfig
|
||||
{
|
||||
// 核心线程池大小
|
||||
private int corePoolSize = 50;
|
||||
private int corePoolSize = 16;
|
||||
|
||||
// 最大可创建的线程数
|
||||
private int maxPoolSize = 200;
|
||||
private int maxPoolSize = 32;
|
||||
|
||||
// 队列最大长度
|
||||
private int queueCapacity = 1000;
|
||||
|
||||
// 线程池维护线程所允许的空闲时间
|
||||
private int keepAliveSeconds = 300;
|
||||
private int keepAliveSeconds = 120;
|
||||
|
||||
@Bean(name = "threadPoolTaskExecutor")
|
||||
public ThreadPoolTaskExecutor threadPoolTaskExecutor()
|
||||
|
||||
@@ -80,11 +80,13 @@ public class AgvTaskResultController extends BaseController {
|
||||
*/
|
||||
@PostMapping("/upGoods")
|
||||
public AjaxResult upGoods(@RequestBody OutGoodsDTO dto) {
|
||||
|
||||
if (StringUtils.isBlank(dto.getTaskNo())) {
|
||||
throw new ServiceException("taskNo 不能为空");
|
||||
}
|
||||
// 返回 taskId
|
||||
String taskId = agvTaskResultService.handleUpGoods(dto.getTaskNo(), dto.getMaterialStatus());
|
||||
|
||||
return AjaxResult.success("上架任务已提交至WCS").put("taskId", taskId);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,13 +71,14 @@ public class RkInfoController extends BaseController
|
||||
@PostMapping("/pageStatistics")
|
||||
public Map<String, Object> pageStatistics(@RequestBody RkInfoQueryDTO dto) {
|
||||
|
||||
// 使用 PageHelper 分页
|
||||
// 分页(如果这里不需要总数,后面你可以改成 startPage(..., false))
|
||||
PageHelper.startPage(dto.getPageNum(), dto.getPageSize());
|
||||
List<RkInfo> list = rkInfoService.selectAllRkInfo(dto);
|
||||
Map<String,Object> dataInfo = new HashMap<>();
|
||||
dataInfo.put("dataList",getDataTable(list));
|
||||
return dataInfo;
|
||||
|
||||
List<RkInfo> list = rkInfoService.selectAllRkInfo(dto);
|
||||
|
||||
Map<String, Object> dataInfo = new HashMap<>();
|
||||
dataInfo.put("dataList", getDataTable(list));
|
||||
return dataInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -193,6 +193,10 @@ public class RkInfo extends BaseEntity {
|
||||
@Excel(name = "实际入库数量")
|
||||
private BigDecimal realQty;
|
||||
|
||||
/** 总金额 = 合同单价 × 实际入库数量(导出专用) */
|
||||
@Excel(name = "总金额")
|
||||
private BigDecimal totalAmount;
|
||||
|
||||
/** 库位码(编码) */
|
||||
@Excel(name = "库位码")
|
||||
private String pcode;
|
||||
@@ -488,6 +492,14 @@ public class RkInfo extends BaseEntity {
|
||||
public String getFycde2() { return fycde2; }
|
||||
public void setFycde2(String fycde2) { this.fycde2 = fycde2; }
|
||||
|
||||
public BigDecimal getTotalAmount() {
|
||||
return totalAmount;
|
||||
}
|
||||
|
||||
public void setTotalAmount(BigDecimal totalAmount) {
|
||||
this.totalAmount = totalAmount;
|
||||
}
|
||||
|
||||
public String getIsDelete() { return isDelete; }
|
||||
public void setIsDelete(String isDelete) { this.isDelete = isDelete; }
|
||||
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package com.zg.project.wisdom.domain.dto;
|
||||
|
||||
import com.zg.framework.aspectj.lang.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class OutGoodsDTO {
|
||||
private String taskNo;
|
||||
private Integer materialStatus; // 0=空托,1=有货(影响是否传物料信息)
|
||||
/**
|
||||
* 调度模式
|
||||
* 1 = 仅立库(WCS)
|
||||
* 2 = 立库 + AGV
|
||||
*/
|
||||
@Excel(name = "调度模式", readConverterExp = "1=仅立库,2=立库+AGV")
|
||||
private Integer dispatchMode;
|
||||
}
|
||||
@@ -135,8 +135,12 @@ public class AgvTaskResultServiceImpl implements IAgvTaskResultService {
|
||||
* 货物上架
|
||||
* @param
|
||||
*/
|
||||
/**
|
||||
* 货物上架
|
||||
*/
|
||||
@Override
|
||||
public String handleUpGoods(String taskNo, Integer materialStatus) {
|
||||
|
||||
Date now = DateUtils.getNowDate();
|
||||
|
||||
// 1. 查询调度任务
|
||||
@@ -172,13 +176,11 @@ public class AgvTaskResultServiceImpl implements IAgvTaskResultService {
|
||||
|
||||
// 3. 发起调用
|
||||
String wcsResp = OkHttpUtils.postJson(wcsJobCreateUrl, wcsParam.toJSONString());
|
||||
|
||||
if (StringUtils.isBlank(wcsResp)) {
|
||||
throw new ServiceException("WCS 接口无响应");
|
||||
}
|
||||
|
||||
JSONObject json = JSON.parseObject(wcsResp);
|
||||
|
||||
if (!json.containsKey("result")) {
|
||||
throw new ServiceException("WCS 返回格式异常:" + wcsResp);
|
||||
}
|
||||
@@ -203,12 +205,19 @@ public class AgvTaskResultServiceImpl implements IAgvTaskResultService {
|
||||
wcs.setUpdateTime(now);
|
||||
wcsTaskResultMapper.insertWcsTaskResult(wcs);
|
||||
|
||||
log.info("[上架] 执行成功,任务 {} 状态已更新为已完成", taskNo);
|
||||
// ✅ 5. 根据 dispatchMode 判断:仅立库(WCS)模式,WCS成功即任务完成
|
||||
if (ddTask.getDispatchMode() != null && ddTask.getDispatchMode() == 1) {
|
||||
ddTaskMapper.updateTaskStatusByTaskNo(taskNo, 2); // 2=已完成
|
||||
log.info("[上架] dispatchMode=1,仅立库模式:任务 {} 已更新为已完成(task_status=2)", taskNo);
|
||||
} else {
|
||||
log.info("[上架] dispatchMode!=1,非仅立库模式:任务 {} 不在此处置完成,后续流程继续", taskNo);
|
||||
}
|
||||
|
||||
// ✅ 返回 taskId
|
||||
return taskId;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 货物下架
|
||||
* @param
|
||||
|
||||
@@ -32,12 +32,15 @@ import com.zg.project.wisdom.utils.BillNoUtil;
|
||||
import com.zg.project.wisdom.utils.CodeConvertUtil;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.zg.project.wisdom.mapper.RkInfoMapper;
|
||||
import com.zg.project.wisdom.domain.RkInfo;
|
||||
import com.zg.project.wisdom.service.IRkInfoService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static com.zg.common.utils.SecurityUtils.getUsername;
|
||||
|
||||
/**
|
||||
@@ -91,43 +94,19 @@ public class RkInfoServiceImpl implements IRkInfoService
|
||||
* @return 库存单据主
|
||||
*/
|
||||
@Override
|
||||
public List<RkInfo> selectRkInfoList(RkInfo rkInfo) {
|
||||
public List<RkInfo> selectRkInfoList(RkInfo rkInfo)
|
||||
{
|
||||
boolean needAudit = "1".equals(configService.selectConfigByKey("rk.audit.enabled"));
|
||||
|
||||
List<RkInfo> list = rkInfoMapper.selectRkInfoList(rkInfo);
|
||||
LocalDate today = LocalDate.now();
|
||||
|
||||
for (RkInfo info : list) {
|
||||
// 计算库龄
|
||||
if (info.getRkTime() != null) {
|
||||
LocalDate rkDate = info.getRkTime().toInstant()
|
||||
.atZone(ZoneId.systemDefault())
|
||||
.toLocalDate();
|
||||
long days = ChronoUnit.DAYS.between(rkDate, today);
|
||||
info.setStockAge(days);
|
||||
}
|
||||
|
||||
// 查询现场图片 + 审核结果
|
||||
AuditSignature signature = auditSignatureMapper.selectPhotoUrlByRkId(info.getId());
|
||||
if (signature != null) {
|
||||
info.setScenePhotoUrl(signature.getSignUrl());
|
||||
info.setAuditResult(signature.getAuditResult());
|
||||
info.setApproverId(signature.getApproverId());
|
||||
} else {
|
||||
info.setScenePhotoUrl(null);
|
||||
info.setAuditResult(null);
|
||||
info.setApproverId(null);
|
||||
}
|
||||
}
|
||||
|
||||
// 审核开启,过滤掉审核结果不是“通过” 且 审核人不为空(说明是审核失败)
|
||||
if (needAudit) {
|
||||
// 审核开启时,过滤掉“审核失败”的数据
|
||||
if (needAudit)
|
||||
{
|
||||
list = list.stream()
|
||||
.filter(info ->
|
||||
// ① 未审核过(approverId 为空)或
|
||||
info.getApproverId() == null ||
|
||||
// ② 审核通过
|
||||
"1".equals(info.getAuditResult())
|
||||
info.getApproverId() == null
|
||||
|| "1".equals(info.getAuditResult())
|
||||
)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
@@ -1380,18 +1359,7 @@ public class RkInfoServiceImpl implements IRkInfoService
|
||||
|
||||
@Override
|
||||
public List<RkInfo> selectAllRkInfo(RkInfo query) {
|
||||
|
||||
List<RkInfo> list = rkInfoMapper.selectAllRkInfo(query);
|
||||
|
||||
Instant now = Instant.now();
|
||||
for (RkInfo ri : list) {
|
||||
Date rkTime = ri.getRkTime();
|
||||
if (rkTime != null) {
|
||||
long days = Duration.between(rkTime.toInstant(), now).toDays();
|
||||
ri.setStockAge(days);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
return rkInfoMapper.selectAllRkInfo(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -4,45 +4,63 @@ import com.zg.project.wisdom.mapper.RkInfoMapper;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 单据号生成工具类
|
||||
*
|
||||
* 目标:
|
||||
* 1) 每次业务操作都生成全新单据号(不依赖历史,不查DB)
|
||||
* 2) 单号短、可读
|
||||
* 3) 避免串单:不同出库操作绝不复用同一个 billNo
|
||||
*
|
||||
* 推荐格式:
|
||||
* CK24011315384227
|
||||
* 前缀 + yyMMdd + HHmmss + 2位随机数
|
||||
*/
|
||||
public class BillNoUtil {
|
||||
|
||||
// 内存缓存:key = prefix + yyyyMMdd
|
||||
private static final Map<String, AtomicInteger> DAILY_SEQUENCE_MAP = new ConcurrentHashMap<>();
|
||||
private static final String DEFAULT_PREFIX = "RK";
|
||||
|
||||
/**
|
||||
* 生成当天单据号(格式:RK20251222_1)
|
||||
* 生成单据号(短号,不查数据库)
|
||||
* 格式:PREFIX + yyMMdd + HHmmss + 2位随机数
|
||||
* 示例:CK24011315384227
|
||||
*
|
||||
* @param prefix 单据前缀:RK/CK/...
|
||||
* @param rkInfoMapper 兼容旧签名(不再使用,可传 null)
|
||||
*/
|
||||
public static synchronized String generateTodayBillNo(String prefix, RkInfoMapper rkInfoMapper) {
|
||||
|
||||
// ✅ 先得到最终前缀(不要让 lambda 捕获一个会被重新赋值的变量)
|
||||
final String finalPrefix = (prefix == null || prefix.trim().isEmpty()) ? "RK" : prefix.trim();
|
||||
// 前缀处理
|
||||
final String p = (prefix == null || prefix.trim().isEmpty())
|
||||
? DEFAULT_PREFIX
|
||||
: prefix.trim().toUpperCase();
|
||||
|
||||
// ✅ today / key 也用 final,确保 lambda 可用
|
||||
final String today = new SimpleDateFormat("yyyyMMdd").format(new Date());
|
||||
final String key = finalPrefix + today;
|
||||
final String likePrefix = finalPrefix + today + "_";
|
||||
// 时间到秒:yyMMddHHmmss(12位)
|
||||
String time = new SimpleDateFormat("yyMMddHHmmss").format(new Date());
|
||||
|
||||
// 如果当天还没初始化,从数据库取最大号
|
||||
AtomicInteger counter = DAILY_SEQUENCE_MAP.computeIfAbsent(key, k -> {
|
||||
// 2位随机数:10~99(避免同一秒内多次点击撞号)
|
||||
int rnd = ThreadLocalRandom.current().nextInt(10, 100);
|
||||
|
||||
String maxBillNo = rkInfoMapper.selectMaxBillNo(likePrefix);
|
||||
return p + time + rnd;
|
||||
}
|
||||
|
||||
int start = 1;
|
||||
if (maxBillNo != null) {
|
||||
try {
|
||||
String seqStr = maxBillNo.substring(maxBillNo.lastIndexOf("_") + 1);
|
||||
start = Integer.parseInt(seqStr) + 1;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
return new AtomicInteger(start);
|
||||
});
|
||||
/**
|
||||
* 需要更短的版本(可选)
|
||||
* 格式:PREFIX + yyMMdd + 4位随机数
|
||||
* 示例:CK2401134837
|
||||
*
|
||||
* 注意:比带秒的版本更短,但理论碰撞概率略高(一般够用)
|
||||
*/
|
||||
public static synchronized String generateShortBillNo(String prefix) {
|
||||
final String p = (prefix == null || prefix.trim().isEmpty())
|
||||
? DEFAULT_PREFIX
|
||||
: prefix.trim().toUpperCase();
|
||||
|
||||
int seq = counter.getAndIncrement();
|
||||
return finalPrefix + today + "_" + seq;
|
||||
String day = new SimpleDateFormat("yyMMdd").format(new Date());
|
||||
int rnd4 = ThreadLocalRandom.current().nextInt(1000, 10000);
|
||||
|
||||
return p + day + rnd4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,10 @@
|
||||
<result property="fycde1" column="fycde_1"/>
|
||||
<result property="fycde2" column="fycde_2"/>
|
||||
<result property="isDelivery" column="is_delivery"/>
|
||||
<!-- ✅ 库龄(天) -->
|
||||
<result property="stockAge" column="stock_age"/>
|
||||
<!-- 总金额 -->
|
||||
<result property="totalAmount" column="total_amount"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 明细查询SQL(包含多表JOIN,用于普通明细分页等) -->
|
||||
@@ -79,37 +83,85 @@
|
||||
ri.wl_type, mt.type_name AS wl_type_name,
|
||||
|
||||
ri.cangku,
|
||||
wh.warehouse_name AS cangku_name,
|
||||
wh.warehouse_name AS cangku_name,
|
||||
|
||||
-- 新增:大仓/小仓编码和名称
|
||||
wh.parent_warehouse_code AS parent_warehouse_code,
|
||||
wh.parent_warehouse_name AS parent_warehouse_name,
|
||||
wh.warehouse_code AS warehouse_code,
|
||||
wh.warehouse_name AS warehouse_name,
|
||||
wh.parent_warehouse_code AS parent_warehouse_code,
|
||||
wh.parent_warehouse_name AS parent_warehouse_name,
|
||||
wh.warehouse_code AS warehouse_code,
|
||||
wh.warehouse_name AS warehouse_name,
|
||||
|
||||
ri.rk_time,
|
||||
ri.lihuo_y,
|
||||
ri.is_chuku,
|
||||
ri.is_borrowed,
|
||||
ri.is_delivery,
|
||||
ri.remark,
|
||||
|
||||
ri.ck_lihuo_y,
|
||||
ri.ck_type,
|
||||
sot.type_name AS ck_type_name,
|
||||
|
||||
ri.team_code,
|
||||
ct.team_name,
|
||||
|
||||
ri.rk_time, ri.lihuo_y, ri.is_chuku, ri.is_borrowed, ri.is_delivery,ri.remark,
|
||||
ri.ck_lihuo_y, ri.ck_type, sot.type_name AS ck_type_name,
|
||||
ri.team_code, ct.team_name,
|
||||
ri.ck_remark,
|
||||
ri.ly_time,
|
||||
ri.fycde_1, ri.fycde_2,
|
||||
ri.borrow_time, ri.return_time,
|
||||
ri.xj, ri.xm_no, ri.xm_ms, ri.wl_no, ri.wl_ms, ri.xm_no_ck, ri.xm_ms_ck,
|
||||
ri.gys_no, ri.gys_mc, ri.jh_amt, ri.ht_dj, ri.sap_no, ri.xh, ri.gys_jh_id,
|
||||
ri.jh_qty, ri.ht_qty, ri.dw, ri.real_qty,
|
||||
ri.pcode, ri.pcode_id, ri.tray_code, ri.entity_id,
|
||||
ri.status, ri.has_moved,
|
||||
ri.create_by, ri.create_time, ri.update_by, ri.update_time, ri.is_delete,
|
||||
u.user_name AS lihuo_y_name
|
||||
ri.borrow_time,
|
||||
ri.return_time,
|
||||
|
||||
ri.xj,
|
||||
ri.xm_no,
|
||||
ri.xm_ms,
|
||||
ri.xm_no_ck,
|
||||
ri.xm_ms_ck,
|
||||
|
||||
ri.wl_no,
|
||||
ri.wl_ms,
|
||||
ri.gys_no,
|
||||
ri.gys_mc,
|
||||
|
||||
ri.jh_amt,
|
||||
ri.ht_dj,
|
||||
ri.sap_no,
|
||||
ri.xh,
|
||||
ri.gys_jh_id,
|
||||
|
||||
ri.jh_qty,
|
||||
ri.ht_qty,
|
||||
ri.dw,
|
||||
ri.real_qty,
|
||||
|
||||
ri.pcode,
|
||||
ri.pcode_id,
|
||||
ri.tray_code,
|
||||
ri.entity_id,
|
||||
|
||||
ri.status,
|
||||
ri.has_moved,
|
||||
|
||||
ri.create_by,
|
||||
ri.create_time,
|
||||
ri.update_by,
|
||||
ri.update_time,
|
||||
ri.is_delete,
|
||||
|
||||
u.user_name AS lihuo_y_name,
|
||||
|
||||
-- ✅ 库龄(天)
|
||||
DATEDIFF(CURDATE(), ri.rk_time) AS stock_age,
|
||||
|
||||
-- 总金额 = 单价 × 实际数量
|
||||
COALESCE(ri.ht_dj, 0) * COALESCE(ri.real_qty, 0) AS total_amount
|
||||
FROM rk_info ri
|
||||
LEFT JOIN stock_in_type st ON ri.rk_type = st.type_code
|
||||
LEFT JOIN material_type mt ON ri.wl_type = mt.type_code
|
||||
LEFT JOIN warehouse_info wh ON ri.cangku = wh.warehouse_code
|
||||
LEFT JOIN stock_out_type sot ON ri.ck_type = sot.type_code
|
||||
LEFT JOIN stock_in_type st ON ri.rk_type = st.type_code
|
||||
LEFT JOIN material_type mt ON ri.wl_type = mt.type_code
|
||||
LEFT JOIN warehouse_info wh ON ri.cangku = wh.warehouse_code
|
||||
LEFT JOIN stock_out_type sot ON ri.ck_type = sot.type_code
|
||||
LEFT JOIN construction_team ct ON ri.team_code = ct.team_code
|
||||
LEFT JOIN sys_user u ON ri.lihuo_y = u.user_id
|
||||
LEFT JOIN sys_user u ON ri.lihuo_y = u.user_id
|
||||
</sql>
|
||||
|
||||
|
||||
<!-- 轻量分组专用SQL:仅rk_info字段,不做JOIN(供按单据分组内层使用) -->
|
||||
<sql id="selectRkInfoForGroup">
|
||||
SELECT
|
||||
|
||||
Reference in New Issue
Block a user