Merge remote-tracking branch 'gitee/0.8.X' into 0.8.X
This commit is contained in:
@@ -116,4 +116,16 @@ public class SysDeptController extends BaseController {
|
|||||||
deptService.checkDeptDataScope(deptId);
|
deptService.checkDeptDataScope(deptId);
|
||||||
return toAjax(deptService.deleteDeptById(deptId));
|
return toAjax(deptService.deleteDeptById(deptId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询部门及其所有子部门
|
||||||
|
*
|
||||||
|
* @param deptId 部门ID
|
||||||
|
*/
|
||||||
|
@SaCheckPermission("system:dept:list")
|
||||||
|
@GetMapping("/list/{deptId}")
|
||||||
|
public R<List<SysDept>> listWithChildren(@PathVariable Long deptId) {
|
||||||
|
List<SysDept> depts = deptService.selectChildDeptsById(deptId);
|
||||||
|
return R.ok(depts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,4 +113,12 @@ public interface ISysDeptService {
|
|||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
int deleteDeptById(Long deptId);
|
int deleteDeptById(Long deptId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据部门ID查询所有子部门(递归)
|
||||||
|
*
|
||||||
|
* @param deptId 部门ID
|
||||||
|
* @return 所有子部门列表
|
||||||
|
*/
|
||||||
|
List<SysDept> selectChildDeptsById(Long deptId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,6 +270,16 @@ public class SysDeptServiceImpl implements ISysDeptService, DeptService {
|
|||||||
.in(SysDept::getDeptId, Arrays.asList(deptIds)));
|
.in(SysDept::getDeptId, Arrays.asList(deptIds)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SysDept> selectChildDeptsById(Long deptId) {
|
||||||
|
// 创建查询条件,查找祖先列表中包含指定部门ID的所有部门
|
||||||
|
LambdaQueryWrapper<SysDept> lqw = new LambdaQueryWrapper<>();
|
||||||
|
lqw.eq(SysDept::getDelFlag, "0")
|
||||||
|
.apply(DataBaseHelper.findInSet(deptId, "ancestors"));
|
||||||
|
|
||||||
|
return baseMapper.selectList(lqw);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改子元素关系
|
* 修改子元素关系
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -58,3 +58,13 @@ export function treeselect() {
|
|||||||
method: 'get'
|
method: 'get'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function listDeptWithChildren(deptId) {
|
||||||
|
if (!deptId) {
|
||||||
|
return Promise.reject(new Error('deptId is required'))
|
||||||
|
}
|
||||||
|
return request({
|
||||||
|
url: '/system/dept/list/' + deptId,
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -227,64 +227,74 @@
|
|||||||
<el-button size="mini" icon="el-icon-refresh" @click="getStepSplitList">刷新</el-button>
|
<el-button size="mini" icon="el-icon-refresh" @click="getStepSplitList">刷新</el-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="stepSpilt.list.length > 0" style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
<div v-if="stepSpilt.list.length > 0" style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||||
<div v-for="(item, index) in stepSpilt.list" :key="item.coilId || index" class="coil-card"
|
<div v-for="(item, index) in stepSpilt.list" :key="item.coilId || index"
|
||||||
style="border: 1px solid #e4e7ed; border-radius: 8px; padding: 16px; margin-bottom: 12px; background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); box-shadow: 0 2px 8px rgba(0,0,0,0.05);">
|
style="width: 18rem; background-color: #ffffff; border-bottom-left-radius: 0.5rem; border-bottom-right-radius: 0.5rem; border-top: 4px solid #2bf; padding-left: 1rem; padding-right: 1rem; padding-top: 1.25rem; padding-bottom: 1.25rem; display: flex; flex-direction: column; justify-content: space-around; box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);">
|
||||||
|
<p
|
||||||
<!-- 主标题区域 - 突出显示currentCoilNo -->
|
style="font-size: 1.125rem; line-height: 1.75rem; font-weight: 700; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';">
|
||||||
<div class="card-header" style="margin-bottom: 16px; text-align: center;">
|
{{ item.currentCoilNo || 'N/A' }}
|
||||||
<div style="display: inline-block; position: relative;">
|
</p>
|
||||||
<!-- <div style="font-size: 12px; color: #909399; margin-bottom: 4px;">卷号</div> -->
|
<div style="padding-top: 0.75rem; padding-bottom: 0.75rem;">
|
||||||
<div class="coil-no" style="font-size: 28px; font-weight: 800; color: #409eff; letter-spacing: 1px;
|
<p style="color: #9ca3af; font-size: 0.875rem; line-height: 1.25rem;">
|
||||||
padding: 4px 16px; background: linear-gradient(135deg, #ecf5ff 0%, #d9ecff 100%);
|
<div class="info-item">
|
||||||
border-radius: 6px; display: inline-block; border: 2px solid #a0cfff;">
|
<span class="info-label">入场:</span>
|
||||||
{{ item.currentCoilNo || 'N/A' }}
|
<span class="info-value" :title="item.enterCoilNo">{{ item.enterCoilNo || '—' }}</span>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="info-label">厂家:</span>
|
||||||
|
<span class="info-value" :title="item.supplierCoilNo">{{ item.supplierCoilNo || '—' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="info-item">
|
||||||
|
<span class="info-label">品名:</span>
|
||||||
|
<span class="info-value">
|
||||||
|
<el-popover placement="top" width="280" trigger="hover"
|
||||||
|
popper-class="material-params-popover">
|
||||||
|
<div class="material-params-content">
|
||||||
|
<div class="params-list">
|
||||||
|
<div class="param-item">
|
||||||
|
<div class="param-row" v-if="item.specification">
|
||||||
|
<span class="param-label">规格:</span>
|
||||||
|
<span class="param-value">{{ item.specification }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="param-row" v-if="item.material">
|
||||||
|
<span class="param-label">材质:</span>
|
||||||
|
<span class="param-value">{{ item.material }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="param-row" v-if="item.surfaceTreatment">
|
||||||
|
<span class="param-label">表面处理:</span>
|
||||||
|
<span class="param-value">{{ item.surfaceTreatment }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="param-row" v-if="item.zincLayer">
|
||||||
|
<span class="param-label">镀层质量:</span>
|
||||||
|
<span class="param-value">{{ item.zincLayer }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="param-row" v-if="item.manufacturer">
|
||||||
|
<span class="param-label">厂家:</span>
|
||||||
|
<span class="param-value">{{ item.manufacturer }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span slot="reference" style="cursor: pointer; color: #2bf;">{{ item.itemName || '—' }}</span>
|
||||||
|
</el-popover>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="display: flex; justify-content: space-between;">
|
||||||
<!-- 详细信息区域 -->
|
<svg-icon icon-class="coil" style="width: 1.5rem; height: 1.5rem;"></svg-icon>
|
||||||
<!-- <div class="card-content" style="margin-bottom: 16px;">
|
<div style="font-size: 0.875rem; line-height: 1.25rem; display: flex; gap: 0.5rem;">
|
||||||
|
<el-button type="primary" size="mini" @click="handleContinueSplit(item)"
|
||||||
<div class="info-row" style="display: flex; justify-content: space-between; margin-bottom: 10px;">
|
style="min-width: 80px; padding: 5px 15px;">
|
||||||
<div class="info-item" style="flex: 1; text-align: center;">
|
查看
|
||||||
<div style="font-size: 11px; color: #909399; margin-bottom: 2px;">仓库</div>
|
</el-button>
|
||||||
<div style="font-size: 14px; font-weight: 600; color: #303133;">
|
<el-button size="mini" @click="handleCancelSplit(item)"
|
||||||
{{ item.warehouseName || '-' }}
|
style="min-width: 80px; padding: 5px 15px; margin-left: 12px; border-color: #f56c6c; color: #f56c6c;"
|
||||||
</div>
|
:plain="true">
|
||||||
</div>
|
取消
|
||||||
|
</el-button>
|
||||||
<div style="width: 1px; background: #e4e7ed; margin: 0 8px;"></div>
|
|
||||||
|
|
||||||
<div class="info-item" style="flex: 1; text-align: center;">
|
|
||||||
<div style="font-size: 11px; color: #909399; margin-bottom: 2px;">实际仓库</div>
|
|
||||||
<div style="font-size: 14px; font-weight: 600; color: #303133;">
|
|
||||||
{{ item.actualWarehouseName || '-' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="weight-info" style="background: linear-gradient(135deg, #f0f9eb 0%, #e1f3d8 100%);
|
|
||||||
border-radius: 6px; padding: 8px; margin-top: 8px; text-align: center;">
|
|
||||||
<div style="display: inline-block;">
|
|
||||||
<div style="font-size: 12px; color: #67c23a; margin-bottom: 2px;">净重</div>
|
|
||||||
<div style="font-size: 18px; font-weight: 700; color: #67c23a;">
|
|
||||||
{{ item.netWeight ? `${item.netWeight} kg` : '-' }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- 操作按钮区域 -->
|
|
||||||
<div class="card-actions" style="text-align: center; border-top: 1px solid #ebeef5; padding-top: 12px;">
|
|
||||||
<el-button type="primary" size="mini" @click="handleContinueSplit(item)"
|
|
||||||
style="min-width: 80px; padding: 5px 15px;">
|
|
||||||
查看
|
|
||||||
</el-button>
|
|
||||||
<el-button size="mini" @click="handleCancelSplit(item)"
|
|
||||||
style="min-width: 80px; padding: 5px 15px; margin-left: 12px; border-color: #f56c6c; color: #f56c6c;"
|
|
||||||
:plain="true">
|
|
||||||
取消
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<el-descriptions-item label="厂家原料卷号">{{ coilInfo.supplierCoilNo || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="厂家原料卷号">{{ coilInfo.supplierCoilNo || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="所在库位">{{ coilInfo.warehouseName || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="所在库位">{{ coilInfo.warehouseName || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="材料类型">{{ coilInfo.materialType || '-' }}</el-descriptions-item>
|
<el-descriptions-item label="材料类型">{{ coilInfo.materialType || '-' }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="净重">{{ coilInfo.netWeight || '-' }} kg</el-descriptions-item>
|
<el-descriptions-item label="净重">{{ coilInfo.netWeight || '-' }} T</el-descriptions-item>
|
||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
<!-- 已分条钢卷列表 -->
|
<!-- 已分条钢卷列表 -->
|
||||||
|
|
||||||
|
|||||||
@@ -43,13 +43,12 @@
|
|||||||
<el-empty description="请选择发货单查看明细" />
|
<el-empty description="请选择发货单查看明细" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- 添加或修改发货单明细对话框 -->
|
<!-- 添加或修改发货单明细对话框 -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||||
<el-form ref="form" :model="form" label-width="80px">
|
<el-form ref="form" :model="form" label-width="80px">
|
||||||
<el-form-item label="发货钢卷" prop="coilId">
|
<el-form-item label="发货钢卷" prop="coilId">
|
||||||
<div style="display: flex; gap: 10px;">
|
<div style="display: flex; gap: 10px;">
|
||||||
<coil-selector v-model="form.coilId" :use-trigger="true" @select="handleSelect" :rangeMode="true" :rangeData="coilList" />
|
<coil-selector v-model="form.coilId" :use-trigger="true" :filters="{ selectType: 'product', status: 0, excludeBound: true }" @select="handleSelect" />
|
||||||
<el-checkbox v-model="autoFillForm" label="自动填写表单信息" />
|
<el-checkbox v-model="autoFillForm" label="自动填写表单信息" />
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryYear" />
|
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryYear" />
|
||||||
<span class="label date-label">年</span>
|
<span class="label date-label">年</span>
|
||||||
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryMonth" />
|
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryMonth" />
|
||||||
<span class="label date-label">月</span>
|
<span class="label date-label">月</span>
|
||||||
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryDay" />
|
<input type="text" class="editable-input date-input transparent-input" v-model="localWaybill.deliveryDay" />
|
||||||
<span class="label date-label">日</span>
|
<span class="label date-label">日</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="waybill-header">
|
<div class="waybill-header">
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<span class="label">负责人:</span>
|
<span class="label">负责人:</span>
|
||||||
<input type="text" class="editable-input transparent-input" v-model="localWaybill.principal" />
|
<input type="text" class="editable-input transparent-input" v-model="localWaybill.principal" />
|
||||||
@@ -44,13 +44,14 @@
|
|||||||
<th>品名</th>
|
<th>品名</th>
|
||||||
<th>切边</th>
|
<th>切边</th>
|
||||||
<th>包装</th>
|
<th>包装</th>
|
||||||
|
<th>仓库位置</th>
|
||||||
<th>结算</th>
|
<th>结算</th>
|
||||||
<th>原料厂家</th>
|
<th>原料厂家</th>
|
||||||
<th>卷号</th>
|
<th>卷号</th>
|
||||||
<th>规格</th>
|
<th>规格</th>
|
||||||
<th>材质</th>
|
<th>材质</th>
|
||||||
<th>数量(件)</th>
|
<th>数量(件)</th>
|
||||||
<th>重量(kg)</th>
|
<th>重量(T)</th>
|
||||||
<th>单价</th>
|
<th>单价</th>
|
||||||
<th>备注</th>
|
<th>备注</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -58,7 +59,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<!-- 无明细提示 -->
|
<!-- 无明细提示 -->
|
||||||
<tr v-if="localWaybillDetails.length === 0">
|
<tr v-if="localWaybillDetails.length === 0">
|
||||||
<td colspan="12" class="no-data">
|
<td colspan="13" class="no-data">
|
||||||
<div class="no-data-content">
|
<div class="no-data-content">
|
||||||
<el-empty description="暂无发货单明细" />
|
<el-empty description="暂无发货单明细" />
|
||||||
</div>
|
</div>
|
||||||
@@ -71,6 +72,8 @@
|
|||||||
</td>
|
</td>
|
||||||
<td><input type="text" class="table-input transparent-input" v-model="item.packageType" />
|
<td><input type="text" class="table-input transparent-input" v-model="item.packageType" />
|
||||||
</td>
|
</td>
|
||||||
|
<td><input type="text" class="table-input transparent-input" v-model="item.actualWarehouseName" />
|
||||||
|
</td>
|
||||||
<td><input type="text" class="table-input transparent-input" v-model="item.settlementType" />
|
<td><input type="text" class="table-input transparent-input" v-model="item.settlementType" />
|
||||||
</td>
|
</td>
|
||||||
<td><input type="text" class="table-input transparent-input" v-model="item.rawMaterialFactory" />
|
<td><input type="text" class="table-input transparent-input" v-model="item.rawMaterialFactory" />
|
||||||
@@ -98,13 +101,15 @@
|
|||||||
|
|
||||||
<!-- 备注说明 -->
|
<!-- 备注说明 -->
|
||||||
<div class="waybill-remarks">
|
<div class="waybill-remarks">
|
||||||
<p>1、品名:冷硬钢卷(酸连轧)、冷轧钢卷(脱脂退火火拉矫)、镀锌卷板,镀锌管料(镀锌分剪料);2、切边:净边/毛边;3、包装:裸包:周三径四;简包1:周三径四内外护角;简包2:周三径四+防锈纸;普包:周三径四+内外护角+防锈纸+端护板;精包1:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板;精包2:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板+木托。</p>
|
<p>
|
||||||
|
1、品名:冷硬钢卷(酸连轧)、冷轧钢卷(脱脂退火火拉矫)、镀锌卷板,镀锌管料(镀锌分剪料);2、切边:净边/毛边;3、包装:裸包:周三径四;简包1:周三径四内外护角;简包2:周三径四+防锈纸;普包:周三径四+内外护角+防锈纸+端护板;精包1:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板;精包2:周三径四+内外护角+防锈纸+薄膜+端护板+内外护板+木托。
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="waybill-pickup-location">
|
<div class="waybill-pickup-location">
|
||||||
<!-- <div class="pickup-location-item inline"> -->
|
<!-- <div class="pickup-location-item inline"> -->
|
||||||
<span class="label">取货地点:</span>
|
<span class="label">取货地点:</span>
|
||||||
<input type="text" class="editable-input full-input transparent-input" v-model="localWaybill.pickupLocation" />
|
<input type="text" class="editable-input full-input transparent-input" v-model="localWaybill.pickupLocation" />
|
||||||
<!-- </div> -->
|
<!-- </div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -134,7 +139,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import domtoimage from 'dom-to-image';
|
import domtoimage from 'dom-to-image';
|
||||||
import printJS from 'print-js';
|
import { PDFDocument } from 'pdf-lib';
|
||||||
|
import html2canvas from 'html2canvas';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@@ -231,15 +237,15 @@ export default {
|
|||||||
// 确保容器在保存图片时能完整显示所有内容
|
// 确保容器在保存图片时能完整显示所有内容
|
||||||
const originalWidth = node.style.width;
|
const originalWidth = node.style.width;
|
||||||
const originalOverflow = node.style.overflow;
|
const originalOverflow = node.style.overflow;
|
||||||
|
|
||||||
// 临时调整容器样式,确保所有内容可见
|
// 临时调整容器样式,确保所有内容可见
|
||||||
node.style.width = 'auto';
|
node.style.width = 'auto';
|
||||||
node.style.overflow = 'visible';
|
node.style.overflow = 'visible';
|
||||||
|
|
||||||
// 获取实际内容宽度
|
// 获取实际内容宽度
|
||||||
const contentWidth = node.scrollWidth;
|
const contentWidth = node.scrollWidth;
|
||||||
const contentHeight = node.scrollHeight;
|
const contentHeight = node.scrollHeight;
|
||||||
|
|
||||||
domtoimage.toPng(node, {
|
domtoimage.toPng(node, {
|
||||||
width: contentWidth,
|
width: contentWidth,
|
||||||
height: contentHeight,
|
height: contentHeight,
|
||||||
@@ -266,32 +272,73 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
// 打印发货单
|
// 打印发货单
|
||||||
printWaybill() {
|
async printWaybill() {
|
||||||
const node = this.$refs.waybillRef;
|
const node = this.$refs.waybillRef;
|
||||||
// 确保容器在打印时能完整显示所有内容
|
// 确保容器在打印时能完整显示所有内容
|
||||||
const originalWidth = node.style.width;
|
const originalWidth = node.style.width;
|
||||||
|
const originalHeight = node.style.height;
|
||||||
|
const paperWidthMm = 297;
|
||||||
|
const paperHeightMm = 180;
|
||||||
const originalOverflow = node.style.overflow;
|
const originalOverflow = node.style.overflow;
|
||||||
|
|
||||||
// 临时调整容器样式,确保所有内容可见
|
// 临时调整容器样式,确保所有内容可见
|
||||||
node.style.width = 'auto';
|
node.style.width = 'auto';
|
||||||
node.style.overflow = 'visible';
|
node.style.overflow = 'visible';
|
||||||
|
|
||||||
// 获取实际内容宽度
|
// 获取实际内容宽度
|
||||||
const contentWidth = node.scrollWidth;
|
const contentWidth = node.scrollWidth;
|
||||||
|
const contentHeight = node.scrollHeight;
|
||||||
printJS({
|
|
||||||
printable: node,
|
// console.log('contentWidth', contentWidth, originalWidth, originalHeight);
|
||||||
maxWidth: contentWidth,
|
// 改用html2canvas + pdf-lib打印pdf
|
||||||
type: 'html',
|
const canvas = await html2canvas(node, {
|
||||||
scanStyles: true,
|
backgroundColor: '#ffffff',
|
||||||
style: `
|
scale: 3,
|
||||||
@page { size: A4 landscape; margin: 1cm; }
|
useCORS: true,
|
||||||
.waybill-container { width: 100%; max-width: none; overflow: visible; }
|
// 让 html2canvas 为频繁读回优化 Canvas(与批量导出一致)
|
||||||
.waybill-table { width: 100%; table-layout: auto; }
|
willReadFrequently: true,
|
||||||
`,
|
// 确保按元素尺寸截图,明确指定宽高
|
||||||
targetStyles: ['*']
|
width: contentWidth,
|
||||||
|
height: contentHeight,
|
||||||
|
windowWidth: contentWidth,
|
||||||
|
windowHeight: contentHeight,
|
||||||
});
|
});
|
||||||
|
// 5. 使用 pdf-lib 生成单页 PDF(占满整张纸,无边距)
|
||||||
|
const mmToPt = 72 / 25.4;
|
||||||
|
const pageWidthPt = paperWidthMm * mmToPt;
|
||||||
|
const pageHeightPt = paperHeightMm * mmToPt;
|
||||||
|
|
||||||
|
const pdfDoc = await PDFDocument.create();
|
||||||
|
console.log('canvas', canvas);
|
||||||
|
const png = canvas.toDataURL('image/png');
|
||||||
|
const imgPng = await pdfDoc.embedPng(png);
|
||||||
|
// 确保页面尺寸正确:宽100mm,高80mm(横向)
|
||||||
|
const page = pdfDoc.addPage([pageWidthPt, pageHeightPt]);
|
||||||
|
|
||||||
|
// 直接拉伸填充整个PDF页面,不留边距,确保占满整张纸
|
||||||
|
// 从(0,0)开始,直接填充整个页面尺寸
|
||||||
|
page.drawImage(imgPng, {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: pageWidthPt,
|
||||||
|
height: pageHeightPt
|
||||||
|
});
|
||||||
|
|
||||||
|
const pdfBytes = await pdfDoc.save();
|
||||||
|
const blob = new Blob([pdfBytes], { type: 'application/pdf' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
|
const win = window.open(url, '_blank');
|
||||||
|
if (!win) {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = `标签_${new Date().getTime()}.pdf`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// 恢复原始样式
|
// 恢复原始样式
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
node.style.width = originalWidth;
|
node.style.width = originalWidth;
|
||||||
@@ -304,7 +351,7 @@ export default {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.waybill-container {
|
.waybill-container {
|
||||||
width: 850px;
|
width: 960px;
|
||||||
max-width: none;
|
max-width: none;
|
||||||
min-width: 850px;
|
min-width: 850px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
@@ -407,62 +454,80 @@ export default {
|
|||||||
/* 表格列宽设置 */
|
/* 表格列宽设置 */
|
||||||
.waybill-table th:nth-child(1),
|
.waybill-table th:nth-child(1),
|
||||||
.waybill-table td:nth-child(1) {
|
.waybill-table td:nth-child(1) {
|
||||||
width: 80px; /* 品名 */
|
width: 80px;
|
||||||
|
/* 品名 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(2),
|
.waybill-table th:nth-child(2),
|
||||||
.waybill-table td:nth-child(2) {
|
.waybill-table td:nth-child(2) {
|
||||||
width: 40px; /* 切边 */
|
width: 40px;
|
||||||
|
/* 切边 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(3),
|
.waybill-table th:nth-child(3),
|
||||||
.waybill-table td:nth-child(3) {
|
.waybill-table td:nth-child(3) {
|
||||||
width: 40px; /* 包装 */
|
width: 40px;
|
||||||
|
/* 包装 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(4),
|
.waybill-table th:nth-child(4),
|
||||||
.waybill-table td:nth-child(4) {
|
.waybill-table td:nth-child(4) {
|
||||||
width: 40px; /* 结算 */
|
width: 80px;
|
||||||
|
/* 仓库位置 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(5),
|
.waybill-table th:nth-child(5),
|
||||||
.waybill-table td:nth-child(5) {
|
.waybill-table td:nth-child(5) {
|
||||||
width: 80px; /* 原料厂家 */
|
width: 40px;
|
||||||
|
/* 结算 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(6),
|
.waybill-table th:nth-child(6),
|
||||||
.waybill-table td:nth-child(6) {
|
.waybill-table td:nth-child(6) {
|
||||||
width: 100px; /* 卷号 */
|
width: 80px;
|
||||||
|
/* 原料厂家 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(7),
|
.waybill-table th:nth-child(7),
|
||||||
.waybill-table td:nth-child(7) {
|
.waybill-table td:nth-child(7) {
|
||||||
width: 80px; /* 规格 */
|
width: 100px;
|
||||||
|
/* 卷号 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(8),
|
.waybill-table th:nth-child(8),
|
||||||
.waybill-table td:nth-child(8) {
|
.waybill-table td:nth-child(8) {
|
||||||
width: 40px; /* 材质 */
|
width: 80px;
|
||||||
|
/* 规格 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(9),
|
.waybill-table th:nth-child(9),
|
||||||
.waybill-table td:nth-child(9) {
|
.waybill-table td:nth-child(9) {
|
||||||
width: 60px; /* 数量(件) */
|
width: 40px;
|
||||||
|
/* 材质 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(10),
|
.waybill-table th:nth-child(10),
|
||||||
.waybill-table td:nth-child(10) {
|
.waybill-table td:nth-child(10) {
|
||||||
width: 60px; /* 重量(kg) */
|
width: 60px;
|
||||||
|
/* 数量(件) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(11),
|
.waybill-table th:nth-child(11),
|
||||||
.waybill-table td:nth-child(11) {
|
.waybill-table td:nth-child(11) {
|
||||||
width: 40px; /* 单价 */
|
width: 80px;
|
||||||
|
/* 重量(kg) */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th:nth-child(12),
|
.waybill-table th:nth-child(12),
|
||||||
.waybill-table td:nth-child(12) {
|
.waybill-table td:nth-child(12) {
|
||||||
width: 100px; /* 备注 */
|
width: 40px;
|
||||||
|
/* 单价 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.waybill-table th:nth-child(13),
|
||||||
|
.waybill-table td:nth-child(13) {
|
||||||
|
width: 100px;
|
||||||
|
/* 备注 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th {
|
.waybill-table th {
|
||||||
@@ -594,23 +659,23 @@ export default {
|
|||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-header {
|
.waybill-header {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-footer {
|
.waybill-footer {
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-actions {
|
.waybill-actions {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@@ -623,26 +688,26 @@ export default {
|
|||||||
gap: 15px;
|
gap: 15px;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table {
|
.waybill-table {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-table th,
|
.waybill-table th,
|
||||||
.waybill-table td {
|
.waybill-table td {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.waybill-footer {
|
.waybill-footer {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-item.inline {
|
.footer-item.inline {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.label {
|
||||||
width: auto;
|
width: auto;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|||||||
@@ -67,10 +67,10 @@
|
|||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button size="mini" type="text" icon="el-icon-view"
|
<el-button size="mini" type="text" icon="el-icon-view"
|
||||||
@click.stop="handlePrint(scope.row)">打印发货单</el-button>
|
@click.stop="handlePrint(scope.row)">打印发货单</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-edit"
|
<el-button size="mini" type="text" icon="el-icon-edit" :disabled="scope.row.status === 1"
|
||||||
@click.stop="handleUpdate(scope.row)">修改</el-button>
|
title="已发货的发货单不能修改" @click.stop="handleUpdate(scope.row)">修改</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-delete"
|
<el-button size="mini" type="text" icon="el-icon-delete" :disabled="scope.row.status === 1"
|
||||||
@click.stop="handleDelete(scope.row)">删除</el-button>
|
title="已发货的发货单不能删除" @click.stop="handleDelete(scope.row)">删除</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -80,13 +80,13 @@
|
|||||||
|
|
||||||
<el-divider style="margin: 20px 0;" />
|
<el-divider style="margin: 20px 0;" />
|
||||||
|
|
||||||
<DeliveryWaybillDetail ref="detailTable" :waybillId="waybillId" :coilList="coilList" @add="refreshCoilList" @update="refreshCoilList" @delete="refreshCoilList" />
|
<DeliveryWaybillDetail v-if="canEdit" ref="detailTable" :waybillId="waybillId" :coilList="coilList"
|
||||||
|
@add="refreshCoilList" @update="refreshCoilList" @delete="refreshCoilList" />
|
||||||
|
<el-empty v-else description="已发货,不可修改,点击打印查看详情" />
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- 添加或修改发货单对话框 -->
|
<!-- 添加或修改发货单对话框 -->
|
||||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||||
@@ -107,12 +107,6 @@
|
|||||||
placeholder="请选择发货时间">
|
placeholder="请选择发货时间">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="磅房" prop="weighbridge">
|
|
||||||
<el-input v-model="form.weighbridge" placeholder="请输入磅房" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="销售" prop="salesPerson">
|
|
||||||
<el-input v-model="form.salesPerson" placeholder="请输入销售" />
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item label="负责人" prop="principal">
|
<el-form-item label="负责人" prop="principal">
|
||||||
<el-input v-model="form.principal" placeholder="请输入负责人" />
|
<el-input v-model="form.principal" placeholder="请输入负责人" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -130,7 +124,7 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 打印发货单对话框 -->
|
<!-- 打印发货单对话框 -->
|
||||||
<el-dialog title="打印发货单" :visible.sync="printDialogVisible" width="900px" append-to-body center>
|
<el-dialog title="打印发货单" :visible.sync="printDialogVisible" width="1000px" append-to-body center>
|
||||||
<WayBill :waybill="currentWaybill" :waybillDetails="currentWaybillDetails" />
|
<WayBill :waybill="currentWaybill" :waybillDetails="currentWaybillDetails" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -217,7 +211,8 @@ export default {
|
|||||||
planType: 0,
|
planType: 0,
|
||||||
// auditStatus: 1,
|
// auditStatus: 1,
|
||||||
},
|
},
|
||||||
coilList: []
|
coilList: [],
|
||||||
|
canEdit: true,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@@ -330,6 +325,13 @@ export default {
|
|||||||
this.getList();
|
this.getList();
|
||||||
},
|
},
|
||||||
handleRowClick(row) {
|
handleRowClick(row) {
|
||||||
|
if (row.status === 1) {
|
||||||
|
this.canEdit = false;
|
||||||
|
this.waybillId = row.waybillId;
|
||||||
|
// this.$modal.msgWarning("已发货的发货单不能操作");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.canEdit = true;
|
||||||
this.waybillId = row.waybillId;
|
this.waybillId = row.waybillId;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -431,19 +433,30 @@ export default {
|
|||||||
remark: item.remark
|
remark: item.remark
|
||||||
}));
|
}));
|
||||||
const coils = this.currentWaybillDetails.map(item => item.coilId).join(',');
|
const coils = this.currentWaybillDetails.map(item => item.coilId).join(',');
|
||||||
listCoilByIds(coils).then(response => {
|
if (coils) {
|
||||||
// 取前三位, 然后去抽后用;连接
|
listCoilByIds(coils).then(response => {
|
||||||
// 设置当前发货单
|
// 取前三位, 然后去抽后用;连接
|
||||||
const actualWahouseNames = [...new Set(response.rows.filter(item => Boolean(item.actualWarehouseName)).map(item => item.actualWarehouseName.slice(0, 3)))].join(';');
|
// 设置当前发货单
|
||||||
this.currentWaybill = {
|
const actualWahouseNames = [...new Set(response.rows.filter(item => Boolean(item.actualWarehouseName)).map(item => item.actualWarehouseName.slice(0, 3)))].join(';');
|
||||||
...row,
|
this.currentWaybill = {
|
||||||
pickupLocation: actualWahouseNames || '',
|
...row,
|
||||||
};
|
pickupLocation: actualWahouseNames || '',
|
||||||
});
|
};
|
||||||
|
this.currentWaybillDetails = this.currentWaybillDetails.map(item => {
|
||||||
// 打开打印对话框
|
const actualWarehouseName = response.rows.find(detail => detail.coilId === item.coilId)?.actualWarehouseName || '';
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
actualWarehouseName: actualWarehouseName,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.currentWaybill = {
|
||||||
|
...row,
|
||||||
|
};
|
||||||
this.printDialogVisible = true;
|
this.printDialogVisible = true;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error('获取发货单明细失败:', error);
|
console.error('获取发货单明细失败:', error);
|
||||||
this.$modal.msgError('获取发货单明细失败');
|
this.$modal.msgError('获取发货单明细失败');
|
||||||
|
|||||||
@@ -119,7 +119,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getOutRequest, addOutRequest, updateOutRequest } from "@/api/wms/outRequest";
|
import { getOutRequest, addOutRequest, updateOutRequest } from "@/api/wms/outRequest";
|
||||||
import { listApproval, updateApproval } from "@/api/wms/approval"
|
import { listApproval, updateApproval } from "@/api/wms/approval"
|
||||||
import { listDept } from "@/api/system/dept"
|
import { listDeptWithChildren } from "@/api/system/dept"
|
||||||
import FileUpload from '@/components/FileUpload'
|
import FileUpload from '@/components/FileUpload'
|
||||||
import DictSelect from '@/components/DictSelect'
|
import DictSelect from '@/components/DictSelect'
|
||||||
import OutLabelPrinter from '../components/outLabelPrinter'
|
import OutLabelPrinter from '../components/outLabelPrinter'
|
||||||
@@ -183,7 +183,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getDeptList() {
|
getDeptList() {
|
||||||
listDept().then(response => {
|
listDeptWithChildren("2009923867307630594").then(response => {
|
||||||
this.deptOptions = response.data
|
this.deptOptions = response.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -145,7 +145,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { getLeaveRequest, addLeaveRequest, updateLeaveRequest } from "@/api/wms/leaveRequest";
|
import { getLeaveRequest, addLeaveRequest, updateLeaveRequest } from "@/api/wms/leaveRequest";
|
||||||
import { listApproval, updateApproval } from "@/api/wms/approval"
|
import { listApproval, updateApproval } from "@/api/wms/approval"
|
||||||
import { listDept } from "@/api/system/dept"
|
import { listDeptWithChildren } from "@/api/system/dept"
|
||||||
import FileUpload from '@/components/FileUpload'
|
import FileUpload from '@/components/FileUpload'
|
||||||
import DictSelect from '@/components/DictSelect'
|
import DictSelect from '@/components/DictSelect'
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
getDeptList() {
|
getDeptList() {
|
||||||
listDept().then(response => {
|
listDeptWithChildren("2009923867307630594").then(response => {
|
||||||
this.deptOptions = response.data
|
this.deptOptions = response.data
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -189,6 +189,17 @@ public class WmsMaterialCoilBo extends BaseEntity {
|
|||||||
|
|
||||||
private Boolean onlyUnshippedAndUnplanned;
|
private Boolean onlyUnshippedAndUnplanned;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否排除已被发货单明细绑定的钢卷(true=列表不返回已绑定钢卷)
|
||||||
|
*/
|
||||||
|
private Boolean excludeBound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否在列表中返回“发货单明细绑定信息”(true=返回 bound + 绑定来源信息)
|
||||||
|
* 默认不返回,避免不需要的场景变慢。
|
||||||
|
*/
|
||||||
|
private Boolean includeBindInfo;
|
||||||
|
|
||||||
//销售id
|
//销售id
|
||||||
private Long saleId;
|
private Long saleId;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.klp.domain.vo;
|
||||||
|
|
||||||
|
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 钢卷绑定信息(发货单明细 -> 发货单 -> 发货计划)
|
||||||
|
* 用于快速标记钢卷是否已被发货单明细占用,并返回占用来源信息。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class WmsCoilBindInfoVo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private Long coilId;
|
||||||
|
|
||||||
|
private Long detailId;
|
||||||
|
|
||||||
|
private Long waybillId;
|
||||||
|
private String waybillNo;
|
||||||
|
private String waybillName;
|
||||||
|
|
||||||
|
private Long planId;
|
||||||
|
private String planName;
|
||||||
|
private Date planDate;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -333,5 +333,24 @@ public class WmsMaterialCoilVo extends BaseEntity {
|
|||||||
* 独占状态(0=未独占,1=特殊分卷中)
|
* 独占状态(0=未独占,1=特殊分卷中)
|
||||||
*/
|
*/
|
||||||
private Integer exclusiveStatus;
|
private Integer exclusiveStatus;
|
||||||
|
|
||||||
|
// ========== 发货绑定信息(由发货单明细占用) ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否已被发货单明细绑定(true=不可再次绑定)
|
||||||
|
*/
|
||||||
|
private Boolean bound;
|
||||||
|
|
||||||
|
private Long bindDetailId;
|
||||||
|
|
||||||
|
private Long bindWaybillId;
|
||||||
|
private String bindWaybillNo;
|
||||||
|
private String bindWaybillName;
|
||||||
|
|
||||||
|
private Long bindPlanId;
|
||||||
|
private String bindPlanName;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date bindPlanDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
package com.klp.mapper;
|
package com.klp.mapper;
|
||||||
|
|
||||||
import com.klp.domain.WmsDeliveryWaybillDetail;
|
import com.klp.domain.WmsDeliveryWaybillDetail;
|
||||||
|
import com.klp.domain.vo.WmsCoilBindInfoVo;
|
||||||
import com.klp.domain.vo.WmsDeliveryWaybillDetailVo;
|
import com.klp.domain.vo.WmsDeliveryWaybillDetailVo;
|
||||||
import com.klp.common.core.mapper.BaseMapperPlus;
|
import com.klp.common.core.mapper.BaseMapperPlus;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发货单明细Mapper接口
|
* 发货单明细Mapper接口
|
||||||
@@ -12,4 +17,13 @@ import com.klp.common.core.mapper.BaseMapperPlus;
|
|||||||
*/
|
*/
|
||||||
public interface WmsDeliveryWaybillDetailMapper extends BaseMapperPlus<WmsDeliveryWaybillDetailMapper, WmsDeliveryWaybillDetail, WmsDeliveryWaybillDetailVo> {
|
public interface WmsDeliveryWaybillDetailMapper extends BaseMapperPlus<WmsDeliveryWaybillDetailMapper, WmsDeliveryWaybillDetail, WmsDeliveryWaybillDetailVo> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钢卷ID批量查询绑定来源信息(明细->发货单->发货计划)
|
||||||
|
*/
|
||||||
|
List<WmsCoilBindInfoVo> selectBindInfoByCoilIds(@Param("coilIds") Collection<Long> coilIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按钢卷ID查询绑定来源信息(明细->发货单->发货计划)
|
||||||
|
*/
|
||||||
|
WmsCoilBindInfoVo selectBindInfoByCoilId(@Param("coilId") Long coilId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,13 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.klp.common.utils.StringUtils;
|
import com.klp.common.utils.StringUtils;
|
||||||
|
import com.klp.common.exception.ServiceException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import com.klp.domain.bo.WmsDeliveryWaybillDetailBo;
|
import com.klp.domain.bo.WmsDeliveryWaybillDetailBo;
|
||||||
import com.klp.domain.vo.WmsDeliveryWaybillDetailVo;
|
import com.klp.domain.vo.WmsDeliveryWaybillDetailVo;
|
||||||
import com.klp.domain.WmsDeliveryWaybillDetail;
|
import com.klp.domain.WmsDeliveryWaybillDetail;
|
||||||
|
import com.klp.domain.vo.WmsCoilBindInfoVo;
|
||||||
import com.klp.mapper.WmsDeliveryWaybillDetailMapper;
|
import com.klp.mapper.WmsDeliveryWaybillDetailMapper;
|
||||||
import com.klp.service.IWmsDeliveryWaybillDetailService;
|
import com.klp.service.IWmsDeliveryWaybillDetailService;
|
||||||
|
|
||||||
@@ -105,7 +107,32 @@ public class WmsDeliveryWaybillDetailServiceImpl implements IWmsDeliveryWaybillD
|
|||||||
* 保存前的数据校验
|
* 保存前的数据校验
|
||||||
*/
|
*/
|
||||||
private void validEntityBeforeSave(WmsDeliveryWaybillDetail entity){
|
private void validEntityBeforeSave(WmsDeliveryWaybillDetail entity){
|
||||||
//TODO 做一些数据校验,如唯一约束
|
if (entity == null || entity.getCoilId() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同一个钢卷只能被一个发货单明细绑定(排除当前记录)
|
||||||
|
LambdaQueryWrapper<WmsDeliveryWaybillDetail> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(WmsDeliveryWaybillDetail::getCoilId, entity.getCoilId());
|
||||||
|
lqw.eq(WmsDeliveryWaybillDetail::getDelFlag, 0);
|
||||||
|
lqw.ne(entity.getDetailId() != null, WmsDeliveryWaybillDetail::getDetailId, entity.getDetailId());
|
||||||
|
lqw.last("LIMIT 1");
|
||||||
|
WmsDeliveryWaybillDetail exists = baseMapper.selectOne(lqw);
|
||||||
|
if (exists == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拼接提示:在哪个计划/发货单下已被绑定
|
||||||
|
WmsCoilBindInfoVo bindInfo = baseMapper.selectBindInfoByCoilId(entity.getCoilId());
|
||||||
|
if (bindInfo != null) {
|
||||||
|
throw new ServiceException(
|
||||||
|
"该钢卷已被绑定,不能重复选择;" +
|
||||||
|
"发货计划:" + bindInfo.getPlanName() +
|
||||||
|
",发货单:" + bindInfo.getWaybillNo() +
|
||||||
|
"(" + bindInfo.getWaybillName() + ")"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
throw new ServiceException("该钢卷已被绑定,不能重复选择");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -95,6 +95,12 @@ public class WmsDeliveryWaybillServiceImpl implements IWmsDeliveryWaybillService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Boolean updateByBo(WmsDeliveryWaybillBo bo) {
|
public Boolean updateByBo(WmsDeliveryWaybillBo bo) {
|
||||||
|
// 现根据bo.getWaybillId()查询出数据库中的数据
|
||||||
|
// 如果这条数据的status是1 则抛异常为不允许修改
|
||||||
|
WmsDeliveryWaybill db = baseMapper.selectById(bo.getWaybillId());
|
||||||
|
if (db.getStatus() == 1) {
|
||||||
|
throw new RuntimeException("已发货的发货单不能修改");
|
||||||
|
}
|
||||||
WmsDeliveryWaybill update = BeanUtil.toBean(bo, WmsDeliveryWaybill.class);
|
WmsDeliveryWaybill update = BeanUtil.toBean(bo, WmsDeliveryWaybill.class);
|
||||||
validEntityBeforeSave(update);
|
validEntityBeforeSave(update);
|
||||||
return baseMapper.updateById(update) > 0;
|
return baseMapper.updateById(update) > 0;
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
private final WmsDeliveryPlanMapper deliveryPlanMapper;
|
private final WmsDeliveryPlanMapper deliveryPlanMapper;
|
||||||
private final WmsProductMapper productMapper;
|
private final WmsProductMapper productMapper;
|
||||||
private final WmsRawMaterialMapper rawMaterialMapper;
|
private final WmsRawMaterialMapper rawMaterialMapper;
|
||||||
|
private final WmsDeliveryWaybillDetailMapper deliveryWaybillDetailMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询钢卷物料表
|
* 查询钢卷物料表
|
||||||
@@ -305,6 +306,47 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
return TableDataInfo.build(result);
|
return TableDataInfo.build(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量查询当前页钢卷的“发货单明细绑定”信息(用于禁选/置灰/提示来源)
|
||||||
|
// 仅当前端明确需要时才查询,避免不必要的性能开销
|
||||||
|
if (Boolean.TRUE.equals(bo.getIncludeBindInfo())) {
|
||||||
|
try {
|
||||||
|
List<Long> coilIds = records.stream()
|
||||||
|
.map(WmsMaterialCoilVo::getCoilId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (!coilIds.isEmpty()) {
|
||||||
|
Map<Long, WmsCoilBindInfoVo> bindMap = deliveryWaybillDetailMapper
|
||||||
|
.selectBindInfoByCoilIds(coilIds)
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
WmsCoilBindInfoVo::getCoilId,
|
||||||
|
v -> v,
|
||||||
|
(a, b) -> a
|
||||||
|
));
|
||||||
|
|
||||||
|
for (WmsMaterialCoilVo vo : records) {
|
||||||
|
WmsCoilBindInfoVo bind = bindMap.get(vo.getCoilId());
|
||||||
|
if (bind != null) {
|
||||||
|
vo.setBound(Boolean.TRUE);
|
||||||
|
vo.setBindDetailId(bind.getDetailId());
|
||||||
|
vo.setBindWaybillId(bind.getWaybillId());
|
||||||
|
vo.setBindWaybillNo(bind.getWaybillNo());
|
||||||
|
vo.setBindWaybillName(bind.getWaybillName());
|
||||||
|
vo.setBindPlanId(bind.getPlanId());
|
||||||
|
vo.setBindPlanName(bind.getPlanName());
|
||||||
|
vo.setBindPlanDate(bind.getPlanDate());
|
||||||
|
} else {
|
||||||
|
vo.setBound(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
// 绑定信息属于增强字段,查询失败时不影响钢卷列表主流程
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Set<String> userNames = records.stream()
|
Set<String> userNames = records.stream()
|
||||||
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy(), v.getExportBy()))
|
.flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy(), v.getExportBy()))
|
||||||
.filter(StringUtils::isNotBlank)
|
.filter(StringUtils::isNotBlank)
|
||||||
@@ -408,6 +450,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
qw.in("mc.quality_status", java.util.Arrays.asList("C+", "C", "C-", "D+", "D", "D-"));
|
qw.in("mc.quality_status", java.util.Arrays.asList("C+", "C", "C-", "D+", "D", "D-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 排除已被发货单明细绑定的钢卷(SQL级过滤,分页总数准确)
|
||||||
|
if (Boolean.TRUE.equals(bo.getExcludeBound())) {
|
||||||
|
qw.apply("NOT EXISTS (SELECT 1 FROM wms_delivery_waybill_detail d WHERE d.del_flag = 0 AND d.coil_id = mc.coil_id)");
|
||||||
|
}
|
||||||
|
|
||||||
// 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN
|
// 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN
|
||||||
boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType());
|
boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType());
|
||||||
boolean hasAnyItemFilter = StringUtils.isNotBlank(bo.getItemMaterial())
|
boolean hasAnyItemFilter = StringUtils.isNotBlank(bo.getItemMaterial())
|
||||||
@@ -505,16 +552,16 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
qw.in("mc.coil_id", coilIdList);
|
qw.in("mc.coil_id", coilIdList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 仅查询未发货且未绑定在发货计划里的钢卷
|
// // 仅查询未发货且未绑定在发货计划里的钢卷
|
||||||
if (Boolean.TRUE.equals(bo.getOnlyUnshippedAndUnplanned())) {
|
// if (Boolean.TRUE.equals(bo.getOnlyUnshippedAndUnplanned())) {
|
||||||
// 未发货:排除状态=1(已出库/已发货)
|
// // 未发货:排除状态=1(已出库/已发货)
|
||||||
qw.ne("mc.status", 1);
|
// qw.ne("mc.status", 1);
|
||||||
// 未绑定在任一有效发货计划:计划未删除,coil 字段包含当前 coil_id
|
// // 未绑定在任一有效发货计划:计划未删除,coil 字段包含当前 coil_id
|
||||||
// 这里使用 NOT EXISTS + FIND_IN_SET,避免将所有计划加载到内存
|
// // 这里使用 NOT EXISTS + FIND_IN_SET,避免将所有计划加载到内存
|
||||||
qw.apply("NOT EXISTS (SELECT 1 FROM wms_delivery_plan dp " +
|
// qw.apply("NOT EXISTS (SELECT 1 FROM wms_delivery_plan dp " +
|
||||||
"WHERE dp.del_flag = 0 AND dp.coil IS NOT NULL AND dp.coil <> '' " +
|
// "WHERE dp.del_flag = 0 AND dp.coil IS NOT NULL AND dp.coil <> '' " +
|
||||||
"AND FIND_IN_SET(CAST(mc.coil_id AS CHAR), dp.coil))");
|
// "AND FIND_IN_SET(CAST(mc.coil_id AS CHAR), dp.coil))");
|
||||||
}
|
// }
|
||||||
//逻辑删除
|
//逻辑删除
|
||||||
qw.eq("mc.del_flag", 0);
|
qw.eq("mc.del_flag", 0);
|
||||||
//把team字段作为筛选条件
|
//把team字段作为筛选条件
|
||||||
|
|||||||
@@ -27,5 +27,53 @@
|
|||||||
<result property="updateBy" column="update_by"/>
|
<result property="updateBy" column="update_by"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
|
<resultMap type="com.klp.domain.vo.WmsCoilBindInfoVo" id="WmsCoilBindInfoResult">
|
||||||
|
<result property="coilId" column="coil_id"/>
|
||||||
|
<result property="detailId" column="detail_id"/>
|
||||||
|
<result property="waybillId" column="waybill_id"/>
|
||||||
|
<result property="waybillNo" column="waybill_no"/>
|
||||||
|
<result property="waybillName" column="waybill_name"/>
|
||||||
|
<result property="planId" column="plan_id"/>
|
||||||
|
<result property="planName" column="plan_name"/>
|
||||||
|
<result property="planDate" column="plan_date"/>
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<select id="selectBindInfoByCoilIds" resultMap="WmsCoilBindInfoResult">
|
||||||
|
SELECT
|
||||||
|
d.coil_id,
|
||||||
|
d.detail_id,
|
||||||
|
w.waybill_id,
|
||||||
|
w.waybill_no,
|
||||||
|
w.waybill_name,
|
||||||
|
p.plan_id,
|
||||||
|
p.plan_name,
|
||||||
|
p.plan_date
|
||||||
|
FROM wms_delivery_waybill_detail d
|
||||||
|
INNER JOIN wms_delivery_waybill w ON w.waybill_id = d.waybill_id AND w.del_flag = 0
|
||||||
|
INNER JOIN wms_delivery_plan p ON p.plan_id = w.plan_id AND p.del_flag = 0
|
||||||
|
WHERE d.del_flag = 0
|
||||||
|
AND d.coil_id IN
|
||||||
|
<foreach collection="coilIds" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectBindInfoByCoilId" resultMap="WmsCoilBindInfoResult">
|
||||||
|
SELECT
|
||||||
|
d.coil_id,
|
||||||
|
d.detail_id,
|
||||||
|
w.waybill_id,
|
||||||
|
w.waybill_no,
|
||||||
|
w.waybill_name,
|
||||||
|
p.plan_id,
|
||||||
|
p.plan_name,
|
||||||
|
p.plan_date
|
||||||
|
FROM wms_delivery_waybill_detail d
|
||||||
|
INNER JOIN wms_delivery_waybill w ON w.waybill_id = d.waybill_id AND w.del_flag = 0
|
||||||
|
INNER JOIN wms_delivery_plan p ON p.plan_id = w.plan_id AND p.del_flag = 0
|
||||||
|
WHERE d.del_flag = 0
|
||||||
|
AND d.coil_id = #{coilId}
|
||||||
|
LIMIT 1
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
mc.temper_grade,
|
mc.temper_grade,
|
||||||
mc.exclusive_status,
|
mc.exclusive_status,
|
||||||
su.nick_name AS saleName,
|
su.nick_name AS saleName,
|
||||||
|
w.warehouse_name AS warehouseName,
|
||||||
aw.actual_warehouse_name AS actualWarehouseName,
|
aw.actual_warehouse_name AS actualWarehouseName,
|
||||||
CASE WHEN mc.item_type = 'raw_material' THEN rm.specification
|
CASE WHEN mc.item_type = 'raw_material' THEN rm.specification
|
||||||
WHEN mc.item_type = 'product' THEN p.specification
|
WHEN mc.item_type = 'product' THEN p.specification
|
||||||
|
|||||||
Reference in New Issue
Block a user