Compare commits
53 Commits
test.X
...
8f1e8c9381
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f1e8c9381 | ||
|
|
60576864bf | ||
|
|
f4be9312c3 | ||
| 56b05a02a1 | |||
| 64d1d4683b | |||
| 93e3a71c50 | |||
| bfba3ce49a | |||
|
|
3e9a08308f | ||
| e589bb6496 | |||
| db8696f9e7 | |||
| 2b213f7475 | |||
| 0abec84a2e | |||
|
|
223a745991 | ||
| 5f8ec04a17 | |||
| ae410d85e5 | |||
|
|
016e5dc246 | ||
|
|
c766904b45 | ||
|
|
3c96211cc5 | ||
|
|
5b6286326b | ||
|
|
f561b4eb0b | ||
| 30a06d297b | |||
| 70b9d620b2 | |||
| 71c7876bf9 | |||
|
|
fb96148d1f | ||
|
|
8d73342e9e | ||
| b61cea837a | |||
| 09c8b9cc4a | |||
|
|
aa286d66f2 | ||
|
|
6f6acf0c3c | ||
| 18bffc4325 | |||
| 12207aa421 | |||
| 7679b0475a | |||
|
|
b6add4e739 | ||
|
|
e1fbb7805f | ||
| ba6b2e201f | |||
| 7133ac4225 | |||
| 3afc296e40 | |||
|
|
a6efe02046 | ||
| 1862908eb1 | |||
| 9e5e7cf0af | |||
| 927cbf9586 | |||
|
|
da2caa1c46 | ||
|
|
6e909212bf | ||
| e937ff50f6 | |||
| 891ec659de | |||
|
|
730148e966 | ||
| 8927760eb1 | |||
| 328c46b8b8 | |||
| c21f5dc813 | |||
| c5089faaea | |||
| f5017443d5 | |||
|
|
f5904fa7f3 | ||
|
|
3f4ee0fce3 |
@@ -7,10 +7,13 @@ import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
@@ -32,7 +35,7 @@ import java.util.concurrent.TimeUnit;
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@Component
|
||||
public class AcidOeeMonthTask {
|
||||
public class AcidOeeMonthTask implements ApplicationRunner {
|
||||
|
||||
/** Redis 缓存 key 模板:当月 OEE 汇总(酸轧线) */
|
||||
private static final String SUMMARY_KEY_PATTERN = "oee:report:month:summary:%s:SY";
|
||||
@@ -48,10 +51,13 @@ public class AcidOeeMonthTask {
|
||||
private final StringRedisTemplate stringRedisTemplate;
|
||||
|
||||
/**
|
||||
* 项目启动完成后立即计算一次当月酸轧 OEE 汇总并写入 Redis。
|
||||
* 项目启动完成后计算一次当月酸轧 OEE 汇总并写入 Redis。
|
||||
* 使用 ApplicationRunner 在 Spring Boot 启动完成后执行。
|
||||
* 使用 @Async 异步执行,不阻塞项目启动。
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
@Async
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
try {
|
||||
computeCurrentMonth("startup");
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = MES一体化平台
|
||||
VUE_APP_TITLE = 科伦普冷轧涂镀数智运营一体化平台
|
||||
|
||||
# 开发环境配置
|
||||
ENV = 'development'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = MES一体化平台
|
||||
VUE_APP_TITLE = 科伦普冷轧涂镀数智运营一体化平台
|
||||
|
||||
# 生产环境配置
|
||||
ENV = 'production'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = MES一体化平台
|
||||
VUE_APP_TITLE = 科伦普冷轧涂镀数智运营一体化平台
|
||||
|
||||
# 开发环境配置
|
||||
ENV = 'development'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.png">
|
||||
<title><%= webpackConfig.name %></title>
|
||||
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
|
||||
<style>
|
||||
|
||||
@@ -27,3 +27,16 @@ export function delOss(ossId) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件
|
||||
*/
|
||||
export function uploadFile(file) {
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
return request({
|
||||
url: '/system/oss/upload',
|
||||
method: 'post',
|
||||
data: form,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -42,3 +42,16 @@ export function delApproval(approvalId) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销审批
|
||||
*/
|
||||
export function withdrawApproval(approvalId) {
|
||||
return request({
|
||||
url: '/wms/approval/cancel',
|
||||
method: 'post',
|
||||
params: {
|
||||
approvalId: approvalId
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import request from '@/utils/request'
|
||||
import { tansParams } from "@/utils/klp";
|
||||
|
||||
// 查询钢卷物料表列表
|
||||
export function listMaterialCoil(query) {
|
||||
@@ -202,13 +203,14 @@ export function cancelExportCoil(coilId) {
|
||||
}
|
||||
|
||||
// 检查入场钢卷号或当前钢卷号是否合法(是否存在)
|
||||
export function checkCoilNo({ currentCoilNo, enterCoilNo, coilId }) {
|
||||
export function checkCoilNo({ currentCoilNo, enterCoilNo, coilId, supplierCoilNo }) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/checkCoilNoDuplicate',
|
||||
method: 'get',
|
||||
params: {
|
||||
currentCoilNo,
|
||||
enterCoilNo,
|
||||
supplierCoilNo,
|
||||
coilId
|
||||
}
|
||||
})
|
||||
@@ -252,15 +254,19 @@ export function restoreMaterialCoil(coilId) {
|
||||
/**
|
||||
* 开始分条,锁定钢卷
|
||||
*/
|
||||
export function startSpecialSplit(coilId) {
|
||||
export function startSpecialSplit(coilId, actionType) {
|
||||
if (!coilId) {
|
||||
return Promise.reject(new Error('coilId is required'))
|
||||
}
|
||||
if (!actionType) {
|
||||
return Promise.reject(new Error('actionType is required'))
|
||||
}
|
||||
return request({
|
||||
url: '/wms/materialCoil/specialSplit/start',
|
||||
method: 'post',
|
||||
params: {
|
||||
coilId
|
||||
coilId,
|
||||
actionType
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -345,4 +351,18 @@ export function categoryWidthStatistics() {
|
||||
url: '/wms/materialCoil/statistics/categoryWidthStatistics',
|
||||
method: 'get',
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出钢卷的全部字段
|
||||
*/
|
||||
export function exportCoilWithAll(data) {
|
||||
return request({
|
||||
url: '/wms/materialCoil/exportAll',
|
||||
method: 'post',
|
||||
data: data,
|
||||
transformRequest: [(params) => { return tansParams(params) }],
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
responseType: 'blob'
|
||||
})
|
||||
}
|
||||
@@ -42,3 +42,16 @@ export function delCoilStatisticsSummary(summaryId) {
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 检查今天是否已经创建过该类型的透视表
|
||||
// 如果已经创建过,返回该透视表的id
|
||||
// 如果没有创建过,返回null
|
||||
export function checkCoilStatisticsSummaryExist(statType) {
|
||||
return request({
|
||||
url: '/wms/coilStatisticsSummary/checkToday',
|
||||
method: 'get',
|
||||
params: {
|
||||
statType
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
function parseDate(date) {
|
||||
// 修复1:参数名和内部变量名冲突,改用tempDate
|
||||
// 修复2:如果传入的date为空/无效,默认使用当前时间
|
||||
const tempDate = date ? new Date(date) : new Date();
|
||||
|
||||
// 获取年、月、日、时、分、秒(补零处理,确保是两位数)
|
||||
const year = tempDate.getFullYear();
|
||||
// 月份从0开始,所以要+1,不足两位补0
|
||||
const month = String(tempDate.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(tempDate.getDate()).padStart(2, '0');
|
||||
const hours = String(tempDate.getHours()).padStart(2, '0');
|
||||
const minutes = String(tempDate.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(tempDate.getSeconds()).padStart(2, '0');
|
||||
|
||||
// 格式化为YYYY-mm-dd HH:mm:ss并返回
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
}
|
||||
|
||||
// 查询钢卷待操作列表
|
||||
export function listPendingAction(query) {
|
||||
return request({
|
||||
@@ -9,6 +27,31 @@ export function listPendingAction(query) {
|
||||
})
|
||||
}
|
||||
|
||||
// 查询钢卷待操作列表(包含已删除记录)
|
||||
// includeDeleted: 0=不包含已删除(默认), 1=包含已删除记录, 2=仅查询已删除记录
|
||||
export function listPendingActionWithDeleted(query) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/list',
|
||||
method: 'get',
|
||||
params: {
|
||||
...query,
|
||||
includeDeleted: 1
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 仅查询已删除的钢卷待操作列表
|
||||
export function listDeletedPendingAction(query) {
|
||||
return request({
|
||||
url: '/wms/coilPendingAction/list',
|
||||
method: 'get',
|
||||
params: {
|
||||
...query,
|
||||
includeDeleted: 2
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 查询钢卷待操作详细
|
||||
export function getPendingAction(actionId) {
|
||||
return request({
|
||||
@@ -19,19 +62,33 @@ export function getPendingAction(actionId) {
|
||||
|
||||
// 新增钢卷待操作
|
||||
export function addPendingAction(data) {
|
||||
const payload = { ...data }
|
||||
if (payload.processTime) {
|
||||
payload.processTime = parseDate(payload.processTime)
|
||||
}
|
||||
if (payload.completeTime) {
|
||||
payload.completeTime = parseDate(payload.completeTime)
|
||||
}
|
||||
return request({
|
||||
url: '/wms/coilPendingAction',
|
||||
method: 'post',
|
||||
data: data
|
||||
data: payload
|
||||
})
|
||||
}
|
||||
|
||||
// 修改钢卷待操作
|
||||
export function updatePendingAction(data) {
|
||||
const payload = { ...data }
|
||||
if (payload.processTime) {
|
||||
payload.processTime = parseDate(payload.processTime)
|
||||
}
|
||||
if (payload.completeTime) {
|
||||
payload.completeTime = parseDate(payload.completeTime)
|
||||
}
|
||||
return request({
|
||||
url: '/wms/coilPendingAction',
|
||||
method: 'put',
|
||||
data: data
|
||||
data: payload
|
||||
})
|
||||
}
|
||||
|
||||
@@ -84,3 +141,12 @@ export function exportPendingAction(query) {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原被删除的钢卷
|
||||
*/
|
||||
export function restorePendingAction(actionId) {
|
||||
return request({
|
||||
url: `/wms/coilPendingAction/restore/${actionId}`,
|
||||
method: 'put'
|
||||
})
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 19 KiB |
@@ -18,9 +18,9 @@
|
||||
</div>
|
||||
|
||||
<el-dialog title="选择钢卷" :visible.sync="dialogVisible" :width="dialogWidth" :close-on-click-modal="false"
|
||||
@close="handleClose" append-to-body>
|
||||
@close="handleClose" append-to-body :fullscreen="orderBy">
|
||||
<!-- 搜索区域 -->
|
||||
<el-form v-if="!rangeMode" :model="queryParams" class="search-form">
|
||||
<el-form v-if="!rangeMode" inline :model="queryParams" class="search-form">
|
||||
<!-- <el-form-item label="类型">
|
||||
<el-select v-model="queryParams.selectType" placeholder="请选择类型" size="small">
|
||||
<el-option label="成品" value="product" />
|
||||
@@ -62,12 +62,13 @@
|
||||
</el-form-item>
|
||||
<el-form-item label="实际库区" v-if="orderBy">
|
||||
<actual-warehouse-select v-model="queryParams.actualWarehouseId" placeholder="请选择实际库区" canSelectLevel2
|
||||
canSelectDisabled />
|
||||
canSelectDisabled :clearInput="false" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
|
||||
<el-checkbox style="margin-left: 10px;" v-model="showCoilMap" size="small">显示钢卷地图</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -77,6 +78,7 @@
|
||||
<!-- 自定义列 -->
|
||||
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align" :prop="column.prop"
|
||||
:width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
|
||||
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
|
||||
</el-table>
|
||||
@@ -93,6 +95,7 @@
|
||||
<!-- 自定义列 -->
|
||||
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align"
|
||||
:prop="column.prop" :width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
|
||||
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="切边" prop="trimmingRequirement"></el-table-column>
|
||||
<el-table-column v-if="orderBy" label="包装" prop="packagingRequirement"></el-table-column>
|
||||
</el-table>
|
||||
@@ -105,6 +108,7 @@
|
||||
<el-table v-if="multiple && selectedCoils.length > 0" :data="selectedCoils">
|
||||
<el-table-column v-for="column in renderColumns" :label="column.label" :align="column.align" :prop="column.prop"
|
||||
:width="column.width" :show-overflow-tooltip="column.showOverflowTooltip" />
|
||||
<el-table-column v-if="orderBy" label="品质" prop="qualityStatus"></el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="50">
|
||||
<template slot-scope="scope">
|
||||
@@ -117,23 +121,42 @@
|
||||
<el-button type="primary" @click="handleConfirm">确认选择</el-button>
|
||||
<el-button @click="handleClose">取消</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 一个可以拖拽和调节大小的浮层 -->
|
||||
<DragResizeBox v-if="showCoilMap" @size-change="handleSizeChange" storageKey="coil-map">
|
||||
<div style="height: 100%; width: 100%; overflow-y: scroll; display: flex; background-color: #fff;">
|
||||
<div style="min-width: 150px; position: sticky; top: 0;" v-loading="treeLoading">
|
||||
<el-tree ref="warehouseTreeRef" :data="warehouseTree" :props="treeProps" node-key="actualWarehouseId"
|
||||
@node-click="handleNodeClick" :expand-on-click-node="false" highlight-current class="warehouse-tree">
|
||||
</el-tree>
|
||||
</div>
|
||||
<warehouse-bird-mini ref="warehouseBirdMini" v-loading="warehouseLoading" :warehouseList="warehouseList" :id="selectedNodeId"
|
||||
:canToggle="false" :canRelease="false" />
|
||||
</div>
|
||||
</DragResizeBox>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMaterialCoil } from '@/api/wms/coil';
|
||||
import { listActualWarehouse } from "@/api/wms/actualWarehouse";
|
||||
import { treeActualWarehouseTwoLevel } from "@/api/wms/actualWarehouse";
|
||||
import MemoInput from '@/components/MemoInput/index.vue';
|
||||
import MutiSelect from '@/components/MutiSelect/index.vue';
|
||||
import { defaultColumns } from './data';
|
||||
import ActualWarehouseSelect from '@/components/KLPService/ActualWarehouseSelect/index.vue';
|
||||
import WarehouseBirdMini from '@/views/wms/warehouse/components/WarehouseBirdMini.vue';
|
||||
import DragResizeBox from '@/components/DragResizeBox/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'CoilSelector',
|
||||
components: {
|
||||
MemoInput,
|
||||
MutiSelect,
|
||||
ActualWarehouseSelect
|
||||
ActualWarehouseSelect,
|
||||
WarehouseBirdMini,
|
||||
DragResizeBox
|
||||
},
|
||||
dicts: ['coil_itemname', 'coil_material', 'coil_manufacturer'],
|
||||
props: {
|
||||
@@ -200,6 +223,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showCoilMap: false,
|
||||
loading: false,
|
||||
coilList: [],
|
||||
total: 0,
|
||||
@@ -223,6 +247,12 @@ export default {
|
||||
columns: defaultColumns,
|
||||
currentTab: 'my',
|
||||
selectedCoils: [],
|
||||
warehouseList: [],
|
||||
selectedNodeId: null,
|
||||
warehouseLoading: false,
|
||||
warehouseTree: [],
|
||||
treeProps: { label: "actualWarehouseName", children: "children" },
|
||||
treeLoading: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -304,8 +334,56 @@ export default {
|
||||
if (this.initialCoil) {
|
||||
this.selectedCoil = this.initialCoil;
|
||||
}
|
||||
if (this.orderBy) {
|
||||
this.getWarehouseTree();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取库位列表
|
||||
getWarehouseList(parentId) {
|
||||
this.warehouseLoading = true;
|
||||
return listActualWarehouse({ parentId })
|
||||
.then((res) => { this.warehouseList = res.data || []; this.warehouseLoading = false; })
|
||||
.catch((err) => {
|
||||
this.$message.error("获取库位数据失败:" + err.message);
|
||||
this.warehouseList = [];
|
||||
this.warehouseLoading = false;
|
||||
});
|
||||
},
|
||||
handleNodeClick(data) {
|
||||
console.log('data', data);
|
||||
if (data.actualWarehouseType != 2) {
|
||||
return;
|
||||
}
|
||||
this.selectedNodeId = data.actualWarehouseId;
|
||||
this.getWarehouseList(data.actualWarehouseId);
|
||||
},
|
||||
// 获取树形数据
|
||||
getWarehouseTree() {
|
||||
this.treeLoading = true;
|
||||
treeActualWarehouseTwoLevel()
|
||||
.then((res) => { this.warehouseTree = res.data || []; })
|
||||
.catch((err) => { this.$message.error("获取仓库树形数据失败:" + err.message); })
|
||||
.finally(() => { this.treeLoading = false; });
|
||||
},
|
||||
// 处理大小变化
|
||||
handleSizeChange(size) {
|
||||
console.log('size', size);
|
||||
this.$refs.warehouseBirdMini.resize();
|
||||
},
|
||||
// 处理实际库区选择变化
|
||||
handleWarehouseChange(val) {
|
||||
console.log('val', val);
|
||||
if (!val) {
|
||||
this.selectedNodeId = null;
|
||||
this.warehouseList = [];
|
||||
return;
|
||||
}
|
||||
if (val.pathIds.length == 2) {
|
||||
this.selectedNodeId = val;
|
||||
this.getWarehouseList(val.id);
|
||||
}
|
||||
},
|
||||
// 动态生成表格行类名 - 综合处理选中、禁用等状态
|
||||
getRowClassName({ row }) {
|
||||
const classNames = [];
|
||||
@@ -539,13 +617,6 @@ export default {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
::v-deep .el-dialog__body {
|
||||
padding: 20px;
|
||||
max-height: calc(100vh - 200px);
|
||||
|
||||
301
klp-ui/src/components/DragResizeBox/index.vue
Normal file
301
klp-ui/src/components/DragResizeBox/index.vue
Normal file
@@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<div class="drag-resize-container" ref="containerRef">
|
||||
<!-- 可拖拽调整的元素 -->
|
||||
<div
|
||||
class="draggable-element"
|
||||
ref="elementRef"
|
||||
:style="{
|
||||
left: `${position.x}px`,
|
||||
top: `${position.y}px`,
|
||||
width: `${size.width}px`,
|
||||
height: `${size.height}px`
|
||||
}"
|
||||
@mousedown="startDrag"
|
||||
>
|
||||
<!-- 元素内容区 -->
|
||||
<div class="element-content">
|
||||
<slot>可拖拽调整的元素</slot>
|
||||
</div>
|
||||
<!-- 右下角调整大小的控制点 -->
|
||||
<div class="resize-handle" @mousedown="startResize"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'DragResizeBox',
|
||||
props: {
|
||||
// 初始位置
|
||||
initPosition: {
|
||||
type: Object,
|
||||
default: () => ({ x: 100, y: 100 })
|
||||
},
|
||||
// 初始尺寸
|
||||
initSize: {
|
||||
type: Object,
|
||||
default: () => ({ width: 200, height: 150 })
|
||||
},
|
||||
// 移除容器尺寸限制(保留prop但默认值改为屏幕尺寸)
|
||||
containerSize: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
})
|
||||
},
|
||||
// 元素最小尺寸
|
||||
minSize: {
|
||||
type: Object,
|
||||
default: () => ({ width: 100, height: 80 })
|
||||
},
|
||||
// 用于localStorage存储的唯一标识
|
||||
storageKey: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 当前位置
|
||||
position: { x: 0, y: 0 },
|
||||
// 当前尺寸
|
||||
size: { width: 0, height: 0 },
|
||||
// 拖拽状态
|
||||
isDragging: false,
|
||||
// 调整大小状态
|
||||
isResizing: false,
|
||||
// 鼠标初始位置
|
||||
startMouse: { x: 0, y: 0 },
|
||||
// 元素初始状态
|
||||
startState: { x: 0, y: 0, width: 0, height: 0 }
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
// 初始化位置和尺寸(优先从localStorage读取)
|
||||
this.initFromStorage();
|
||||
// 监听全局鼠标移动和松开事件
|
||||
document.addEventListener('mousemove', this.handleMouseMove);
|
||||
document.addEventListener('mouseup', this.handleMouseUp);
|
||||
// 监听窗口大小变化,更新屏幕尺寸
|
||||
window.addEventListener('resize', this.updateScreenSize);
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 移除全局事件监听,防止内存泄漏
|
||||
document.removeEventListener('mousemove', this.handleMouseMove);
|
||||
document.removeEventListener('mouseup', this.handleMouseUp);
|
||||
window.removeEventListener('resize', this.updateScreenSize);
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 从localStorage初始化位置和尺寸
|
||||
* 有key时优先读取存储值,无则使用props传入的初始值
|
||||
*/
|
||||
initFromStorage() {
|
||||
if (this.storageKey) {
|
||||
try {
|
||||
const storageKey = `dnd-ps-${this.storageKey}`;
|
||||
const storedData = localStorage.getItem(storageKey);
|
||||
|
||||
if (storedData) {
|
||||
const { position, size } = JSON.parse(storedData);
|
||||
// 验证存储的数据是否合法,防止异常值
|
||||
const isValidPosition = position && typeof position.x === 'number' && typeof position.y === 'number';
|
||||
const isValidSize = size && typeof size.width === 'number' && typeof size.height === 'number';
|
||||
|
||||
if (isValidPosition && isValidSize) {
|
||||
// 使用存储的位置和尺寸(确保不小于最小尺寸)
|
||||
this.position = {
|
||||
x: Math.max(0, position.x),
|
||||
y: Math.max(0, position.y)
|
||||
};
|
||||
this.size = {
|
||||
width: Math.max(this.minSize.width, size.width),
|
||||
height: Math.max(this.minSize.height, size.height)
|
||||
};
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('读取拖拽元素存储数据失败,使用默认值:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 无存储数据或存储异常时,使用props初始值
|
||||
this.position = { ...this.initPosition };
|
||||
this.size = { ...this.initSize };
|
||||
},
|
||||
|
||||
/**
|
||||
* 将当前位置和尺寸保存到localStorage
|
||||
*/
|
||||
saveToStorage() {
|
||||
if (this.storageKey) {
|
||||
try {
|
||||
const storageKey = `dnd-ps-${this.storageKey}`;
|
||||
const saveData = {
|
||||
position: { ...this.position },
|
||||
size: { ...this.size },
|
||||
updateTime: new Date().getTime()
|
||||
};
|
||||
console.log('saveData', saveData);
|
||||
localStorage.setItem(storageKey, JSON.stringify(saveData));
|
||||
// 触发存储成功事件
|
||||
this.$emit('save-success', saveData);
|
||||
} catch (error) {
|
||||
console.error('保存拖拽元素数据失败:', error);
|
||||
this.$emit('save-fail', error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新屏幕尺寸(窗口大小变化时)
|
||||
*/
|
||||
updateScreenSize() {
|
||||
this.containerSize = {
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 开始拖拽(移动位置)
|
||||
*/
|
||||
startDrag(e) {
|
||||
// 阻止事件冒泡,避免和调整大小冲突
|
||||
if (e.target.classList.contains('resize-handle')) return;
|
||||
|
||||
this.isDragging = true;
|
||||
// 记录鼠标初始位置
|
||||
this.startMouse = { x: e.clientX, y: e.clientY };
|
||||
// 记录元素初始位置
|
||||
this.startState = {
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
width: this.size.width,
|
||||
height: this.size.height
|
||||
};
|
||||
// 更改鼠标样式
|
||||
document.body.style.cursor = 'move';
|
||||
},
|
||||
|
||||
/**
|
||||
* 开始调整大小
|
||||
*/
|
||||
startResize(e) {
|
||||
e.stopPropagation(); // 阻止事件冒泡
|
||||
this.isResizing = true;
|
||||
// 记录鼠标初始位置
|
||||
this.startMouse = { x: e.clientX, y: e.clientY };
|
||||
// 记录元素初始尺寸
|
||||
this.startState = {
|
||||
x: this.position.x,
|
||||
y: this.position.y,
|
||||
width: this.size.width,
|
||||
height: this.size.height
|
||||
};
|
||||
// 更改鼠标样式
|
||||
document.body.style.cursor = 'se-resize';
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理鼠标移动
|
||||
*/
|
||||
handleMouseMove(e) {
|
||||
if (this.isDragging) {
|
||||
// 计算鼠标移动的偏移量
|
||||
const dx = e.clientX - this.startMouse.x;
|
||||
const dy = e.clientY - this.startMouse.y;
|
||||
|
||||
// 核心修改:移除容器边界限制,仅限制不超出屏幕左侧/顶部(右侧/底部可任意移动)
|
||||
this.position.x = Math.max(0, this.startState.x + dx);
|
||||
this.position.y = Math.max(0, this.startState.y + dy);
|
||||
|
||||
// 触发位置变化事件
|
||||
this.$emit('position-change', { ...this.position });
|
||||
}
|
||||
|
||||
if (this.isResizing) {
|
||||
// 计算鼠标移动的偏移量
|
||||
const dx = e.clientX - this.startMouse.x;
|
||||
const dy = e.clientY - this.startMouse.y;
|
||||
|
||||
// 调整大小仅限制最小尺寸,不限制屏幕边界
|
||||
this.size.width = Math.max(this.minSize.width, this.startState.width + dx);
|
||||
this.size.height = Math.max(this.minSize.height, this.startState.height + dy);
|
||||
|
||||
// 触发尺寸变化事件
|
||||
this.$emit('size-change', { ...this.size });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理鼠标松开
|
||||
*/
|
||||
handleMouseUp() {
|
||||
// 重置状态
|
||||
this.isDragging = false;
|
||||
this.isResizing = false;
|
||||
// 恢复鼠标样式
|
||||
document.body.style.cursor = 'default';
|
||||
|
||||
// 保存当前状态到localStorage(有key时)
|
||||
this.saveToStorage();
|
||||
|
||||
// 触发结束事件
|
||||
this.$emit('drag-end', { position: { ...this.position }, size: { ...this.size } });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 容器样式:改为全屏且无视觉样式 */
|
||||
.drag-resize-container {
|
||||
position: fixed; /* 固定定位覆盖整个屏幕 */
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
pointer-events: none; /* 容器不拦截鼠标事件,不影响页面其他元素 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 可拖拽元素样式:fixed定位确保基于屏幕移动 */
|
||||
.draggable-element {
|
||||
position: fixed;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
user-select: none; /* 禁止文本选中 */
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
pointer-events: auto; /* 元素本身响应鼠标事件 */
|
||||
z-index: 9999; /* 确保元素在最上层 */
|
||||
background-color: #ffffff; /* 添加背景色,提升可视性 */
|
||||
}
|
||||
|
||||
/* 元素内容区 */
|
||||
.element-content {
|
||||
height: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
/* 调整大小控制点 */
|
||||
.resize-handle {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #1e88e5;
|
||||
cursor: se-resize;
|
||||
border-top-left-radius: 4px;
|
||||
}
|
||||
|
||||
/* 控制点hover效果 */
|
||||
.resize-handle:hover {
|
||||
background-color: #1976d2;
|
||||
}
|
||||
</style>
|
||||
119
klp-ui/src/components/FileList/index.vue
Normal file
119
klp-ui/src/components/FileList/index.vue
Normal file
@@ -0,0 +1,119 @@
|
||||
<template>
|
||||
<div class="file-list-container">
|
||||
<el-table
|
||||
:data="fileList"
|
||||
border
|
||||
size="small"
|
||||
v-loading="loading"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-table-column
|
||||
label="文件名"
|
||||
prop="originalName"
|
||||
min-width="200"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<i class="el-icon-document" style="margin-right: 8px;"></i>
|
||||
{{ scope.row.originalName }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="操作"
|
||||
width="100"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="el-icon-download"
|
||||
@click="downloadFile(scope.row)"
|
||||
size="small"
|
||||
>
|
||||
下载
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 空数据提示 -->
|
||||
<div v-if="fileList.length === 0 && !loading" class="empty-tip">
|
||||
<el-empty description="暂无文件数据"></el-empty>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listByIds } from "@/api/system/oss";
|
||||
|
||||
export default {
|
||||
name: "FileList",
|
||||
props: {
|
||||
ossIds: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
fileList: [],
|
||||
loading: false // 加载状态
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
ossIds: {
|
||||
handler(val) {
|
||||
if (val) {
|
||||
this.getFileList();
|
||||
} else {
|
||||
this.fileList = []; // 清空文件列表
|
||||
}
|
||||
},
|
||||
immediate: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getFileList() {
|
||||
if (!this.ossIds) return;
|
||||
|
||||
this.loading = true;
|
||||
try {
|
||||
let res = await listByIds(this.ossIds);
|
||||
this.fileList = res.data || [];
|
||||
} catch (error) {
|
||||
this.$message.error('获取文件列表失败:' + (error.message || '未知错误'));
|
||||
this.fileList = [];
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 文件下载方法
|
||||
downloadFile(file) {
|
||||
if (!file || !file.ossId) {
|
||||
this.$message.warning('文件下载地址不存在');
|
||||
return;
|
||||
}
|
||||
this.$download.oss(file.ossId);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.file-list-container {
|
||||
width: 100%;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
::v-deep .el-table {
|
||||
--el-table-header-text-color: #606266;
|
||||
--el-table-row-hover-bg-color: #f5f7fa;
|
||||
}
|
||||
</style>
|
||||
@@ -30,6 +30,18 @@
|
||||
<span class="label">净重:</span>
|
||||
<span class="value">{{ netWeight }}</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="length">
|
||||
<span class="label">长度:</span>
|
||||
<span class="value">{{ length }}</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="actualLength">
|
||||
<span class="label">实测长度:</span>
|
||||
<span class="value">{{ actualLength }}</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="actualWidth">
|
||||
<span class="label">实测宽度:</span>
|
||||
<span class="value">{{ actualWidth }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">厂家卷号:</span>
|
||||
<span class="value">{{ supplierCoilNo }}</span>
|
||||
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: 'MES一体化平台',
|
||||
title: '科伦普一体化平台',
|
||||
logo: logoImg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<img :src="avatar" class="user-avatar" alt="头像" />
|
||||
<div class="greeting-text">
|
||||
<div class="greeting-title">{{ greeting }},{{ name }}</div>
|
||||
<div class="greeting-desc">欢迎使用MES数智一体化平台</div>
|
||||
<div class="greeting-desc">欢迎使用科伦普冷轧涂渡数智一体化平台</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -12,10 +12,10 @@ export default {
|
||||
components: { Home },
|
||||
mounted() {
|
||||
// 确保容器DOM已渲染后,对容器执行全屏
|
||||
// this.$nextTick(() => {
|
||||
// this.enterFullscreen()
|
||||
// this.addFullscreenListener()
|
||||
// })
|
||||
this.$nextTick(() => {
|
||||
this.enterFullscreen()
|
||||
this.addFullscreenListener()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 移除监听,避免内存泄漏
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
!document.mozFullScreenElement &&
|
||||
!document.webkitFullscreenElement &&
|
||||
!document.msFullscreenElement
|
||||
|
||||
|
||||
if (isExit) {
|
||||
// 退出全屏后返回上一页
|
||||
this.$router.back()
|
||||
@@ -91,4 +91,4 @@ export default {
|
||||
height: 100%;
|
||||
/* 可根据需要添加其他样式(如背景色等) */
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,71 +1,68 @@
|
||||
<template>
|
||||
<!-- <div class="dashboard-editor-container">-->
|
||||
<!-- <img src="http://kelunpuzhonggong.com/upload/img/20250427091033.jpg" alt="">-->
|
||||
<!-- -->
|
||||
<!-- <div class="aboutus">-->
|
||||
<!-- <el-row :gutter="30">-->
|
||||
<!-- <!– 左栏 –>-->
|
||||
<!-- <el-col :span="12" :xs="24">-->
|
||||
<!-- <div class="aboutus-title">-->
|
||||
<!-- <h2>关于我们</h2>-->
|
||||
<!-- <p>ABOUT US</p>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="aboutus-left">-->
|
||||
<!-- <p class="aboutus-desc">-->
|
||||
<!-- MES一体化平台是面向制造企业车间执行层的生产信息化管理系统,为企业提供包括制造数据管理、计划排程管理、生产调度管理、库存管理、质量管理、人力资源管理、工作中心管理等多项企业管理功能。-->
|
||||
<!-- </p>-->
|
||||
<!-- <p class="aboutus-desc">-->
|
||||
<!-- 平台通过互联网技术实现企业数字化转型,提高生产效率、降低成本、提升产品质量,实现精益化生产管理,帮助企业实现智能制造目标。-->
|
||||
<!-- </p>-->
|
||||
<!-- </div>-->
|
||||
<div class="dashboard-editor-container">
|
||||
<img src="http://kelunpuzhonggong.com/upload/img/20250427091033.jpg" alt="">
|
||||
|
||||
<div class="aboutus">
|
||||
<el-row :gutter="30">
|
||||
<!-- 左栏 -->
|
||||
<el-col :span="12" :xs="24">
|
||||
<div class="aboutus-title">
|
||||
<h2>关于我们</h2>
|
||||
<p>ABOUT US</p>
|
||||
</div>
|
||||
<div class="aboutus-left">
|
||||
<p class="aboutus-desc">
|
||||
嘉祥科伦普重工有限公司是山东省重点工程项目,是济宁市工程之一,也是科伦普产品结构调整重要的工程项目。工程采用了外方技术总负责、关键设备整体引进、点采集成、国内技术总成、自主创新、单体设备引进等多种建设方案,保证了技术先进和人才的培养,确保工程投产后达产达效。
|
||||
</p>
|
||||
<p class="aboutus-desc">
|
||||
科伦普冷轧重工有限公司是设计年产量150万吨,能向广大用户提供热轧酸洗、热轧镀锌、冷硬、罩式退火、冷轧镀锌、铝锌合金、锌铝合金、锌铝镁、镀铬等各大类产品。产品覆盖东北、华北、华东、华南等地区。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- <statistic-group />-->
|
||||
<!-- </el-col>-->
|
||||
<statistic-group />
|
||||
</el-col>
|
||||
|
||||
<!-- <!– 右栏 –>-->
|
||||
<!-- <el-col :span="12" :xs="24">-->
|
||||
<!-- <img src="http://kelunpuzhonggong.com/upload/img/20251015103934.jpg" alt="">-->
|
||||
<!-- <!– <div class="aboutus-right">-->
|
||||
<!-- <p class="aboutus-detail">-->
|
||||
<!-- 嘉祥科伦普重工有限公司成立于2017年8月,注册资金33100万元,主要经营高铁设备、配件制造与销售,模具制造与销售,新材料技术研发,高性能有色金属及合金材料销售,机械零件、零部件加工与销售,金属材料制造与销售,锌铝镁新材料等。目前公司拥有10余项具有自主知识产权的发明专利技术,综合技术水平达国内领先,2024年公司主导产品国内市场占有率约占85%。2024年总资产5.98亿元,净资产4.49亿元,收入3.95亿元,公司现有员工238人,研究与试验发展人员57人,其中专职研究与试验发展人员52人,外聘专家5人。-->
|
||||
<!-- </p>-->
|
||||
<!-- <p class="aboutus-detail">-->
|
||||
<!-- 2024年公司新建科伦普合金新材料研发项目,占地290亩,采用国内先进的镀层核心技术和热处理工艺,专业生产锌铝镁板材和镀铬板材。致力于打造国内工艺链条最完善、产品型号最丰富的涂镀新材料生产企业。全部投产后可实现新增销售收入80亿元,利税4.7亿元,带动就业约500人。项目主要生产的冷轧板、锌铝镁涂层板、镀铬涂层板、镀锡涂层板等产品,涵盖0.08MM-6.0MM区间60多种产品,是国内单个企业产品种类最多的项目。产品因其防锈、耐氧化、耐腐蚀、高电导、高稳定的优秀特性,广泛应用于建筑结构件、汽车制造、轻工家电、食品包装、医疗器械、电子通讯、航空航天领域。-->
|
||||
<!-- </p>-->
|
||||
<!-- </div> –>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row>-->
|
||||
<!-- </div>-->
|
||||
<!-- 右栏 -->
|
||||
<el-col :span="12" :xs="24">
|
||||
<img src="http://kelunpuzhonggong.com/upload/img/20251015103934.jpg" alt="">
|
||||
<!-- <div class="aboutus-right">
|
||||
<p class="aboutus-detail">
|
||||
嘉祥科伦普重工有限公司成立于2017年8月,注册资金33100万元,主要经营高铁设备、配件制造与销售,模具制造与销售,新材料技术研发,高性能有色金属及合金材料销售,机械零件、零部件加工与销售,金属材料制造与销售,锌铝镁新材料等。目前公司拥有10余项具有自主知识产权的发明专利技术,综合技术水平达国内领先,2024年公司主导产品国内市场占有率约占85%。2024年总资产5.98亿元,净资产4.49亿元,收入3.95亿元,公司现有员工238人,研究与试验发展人员57人,其中专职研究与试验发展人员52人,外聘专家5人。
|
||||
</p>
|
||||
<p class="aboutus-detail">
|
||||
2024年公司新建科伦普合金新材料研发项目,占地290亩,采用国内先进的镀层核心技术和热处理工艺,专业生产锌铝镁板材和镀铬板材。致力于打造国内工艺链条最完善、产品型号最丰富的涂镀新材料生产企业。全部投产后可实现新增销售收入80亿元,利税4.7亿元,带动就业约500人。项目主要生产的冷轧板、锌铝镁涂层板、镀铬涂层板、镀锡涂层板等产品,涵盖0.08MM-6.0MM区间60多种产品,是国内单个企业产品种类最多的项目。产品因其防锈、耐氧化、耐腐蚀、高电导、高稳定的优秀特性,广泛应用于建筑结构件、汽车制造、轻工家电、食品包装、医疗器械、电子通讯、航空航天领域。
|
||||
</p>
|
||||
</div> -->
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- <!– <div>-->
|
||||
<!-- <statistic-group />-->
|
||||
<!-- </div> –>-->
|
||||
<!-- -->
|
||||
<!-- <!– <AllApplications /> -->
|
||||
<!-- <el-row :gutter="10">-->
|
||||
<!-- <el-col :span="18">-->
|
||||
<!-- <el-empty description="办公模块定制开发中"></el-empty>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="6">-->
|
||||
<!-- <mini-calendar />-->
|
||||
<!-- </el-col>-->
|
||||
<!-- </el-row> –>-->
|
||||
<!-- </div>-->
|
||||
<Dashboard />
|
||||
<!-- <div>
|
||||
<statistic-group />
|
||||
</div> -->
|
||||
|
||||
<!-- <AllApplications />
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="18">
|
||||
<el-empty description="办公模块定制开发中"></el-empty>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<mini-calendar />
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import StatisticGroup from '@/components/HomeModules/StatisticGroup.vue'
|
||||
// import AllApplications from '@/components/HomeModules/AllApplications.vue'
|
||||
// import MiniCalendar from '@/components/HomeModules/MiniCalendar.vue'
|
||||
import Dashboard from '@/views/dashboard/demo.vue'
|
||||
|
||||
export default {
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
// PanelGroup,
|
||||
StatisticGroup,
|
||||
Dashboard,
|
||||
// AllApplications,
|
||||
// MiniCalendar,
|
||||
},
|
||||
@@ -196,4 +193,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -3,14 +3,15 @@
|
||||
<div class="login-box">
|
||||
<div class="login-left">
|
||||
<div class="login-title-welcome">
|
||||
<!-- <img src="../assets/logo/logo.png" alt="logo" class="logo-img" />-->
|
||||
<span class="login-title">欢迎使用MES一体化平台</span>
|
||||
<img src="../assets/logo/logo.png" alt="logo" class="logo-img" />
|
||||
<span class="login-title">欢迎使用科伦普冷轧涂镀数智一体化平台</span>
|
||||
</div>
|
||||
<p>
|
||||
MES一体化平台是面向制造企业车间执行层的生产信息化管理系统,为企业提供包括制造数据管理、计划排程管理、生产调度管理、库存管理、质量管理、人力资源管理、工作中心管理等多项企业管理功能。
|
||||
嘉祥科伦普重工有限公司是山东省重点工程项目,是济宁市工程之一,也是科伦普产品结构调整重要的工程项目。工程采用了外方技术总负责、关键设备整体引进、点采集成、国内技术总成、自主创新、单体设备引进等多种建设方
|
||||
案,保证了技术先进和人才的培养,确保工程投产后达产达效。
|
||||
</p>
|
||||
<p>
|
||||
平台通过互联网技术实现企业数字化转型,提高生产效率、降低成本、提升产品质量,实现精益化生产管理。
|
||||
科伦普冷轧重工有限公司是设计年产量150万 吨,能向广大用户提供热轧酸洗、热轧镀锌、冷硬、罩式退火、冷轧镀锌、铝锌合金、锌铝合金、锌铝镁、镀铬等各大类产品。产品覆盖东北、华北、华东、华南等地区。
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -299,4 +300,4 @@ $--metal-gradient-light: linear-gradient(145deg, #f5f5f550, #ffffff50);
|
||||
color: $--color-text-secondary; // 浅灰色文字
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -15,6 +15,16 @@
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<el-form :model="materialQueryParams" ref="materialQueryForm" size="small" :inline="true" class="query-form">
|
||||
<el-form-item label="钢卷类型" prop="dataType">
|
||||
<el-select v-model="coilType" placeholder="请选择钢卷类型">
|
||||
<el-option label="全部" value="all" />
|
||||
<el-option label="当前钢卷" value="now" />
|
||||
<el-option label="历史钢卷" value="history" />
|
||||
<el-option label="已发货钢卷" value="trans" />
|
||||
<el-option label="未入库钢卷" value="unIn" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||||
<el-input v-model="materialQueryParams.enterCoilNo" placeholder="请输入入场钢卷号" clearable
|
||||
@keyup.enter.native="handleMaterialQuery" style="width: 150px;" />
|
||||
@@ -26,6 +36,7 @@
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleMaterialQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetMaterialQuery">重置</el-button>
|
||||
<el-button type="success" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@@ -135,6 +146,14 @@
|
||||
<span class="param-label">长度:</span>
|
||||
<span class="param-value">{{ item.length }}</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="item.actualLength">
|
||||
<span class="param-label">实测长度:</span>
|
||||
<span class="param-value">{{ item.actualLength }}</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="item.actualWidth">
|
||||
<span class="param-label">实测宽度:</span>
|
||||
<span class="param-value">{{ item.actualWidth }}</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="item.temperGrade">
|
||||
<span class="param-label">调制度:</span>
|
||||
<span class="param-value">{{ item.temperGrade }}</span>
|
||||
@@ -197,9 +216,13 @@
|
||||
style="position: absolute; bottom: 10px; right: 10px;" type="success" icon="el-icon-refresh"
|
||||
size="mini" @click="handleRestoreMaterial(item)" :loading="item.cancelling"
|
||||
class="action-btn">回滚</el-button>
|
||||
<el-button v-if="item.dataType == 10 && item.status == 0"
|
||||
style="position: absolute; bottom: 10px; right: 10px;" type="success" icon="el-icon-refresh"
|
||||
size="mini" @click="handleForceInMaterial(item)" :loading="item.cancelling"
|
||||
class="action-btn">强制入库</el-button>
|
||||
</div>
|
||||
|
||||
<div class="card-footer" v-if="item.dataType != 10">
|
||||
<div class="card-footer">
|
||||
<el-button type="primary" icon="el-icon-check" size="mini" @click="handleCorrectMaterial(item)"
|
||||
:loading="item.picking" class="action-btn">修正</el-button>
|
||||
<el-button type="danger" icon="el-icon-delete" size="mini" @click="hanleDeleteMaterial(item)"
|
||||
@@ -259,7 +282,7 @@
|
||||
<label-render :content="labelRender.data" :labelType="labelRender.type" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="钢卷信息修正" :visible.sync="correctVisible" width="600px">
|
||||
<el-dialog :title="title" :visible.sync="correctVisible" width="600px">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||||
<el-input v-model="form.enterCoilNo" placeholder="请输入入场钢卷号" :disabled="form.coilId" />
|
||||
@@ -331,6 +354,14 @@
|
||||
<el-form-item label="长度" prop="length">
|
||||
<el-input v-model="form.length" placeholder="请输入长度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||||
<el-input-number :controls="false" v-model="form.actualLength" placeholder="请输入实测长度" type="number"
|
||||
:step="0.01" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实测宽度(m)" prop="actualWidth">
|
||||
<el-input-number :controls="false" v-model="form.actualWidth" placeholder="请输入实测宽度" type="number"
|
||||
:step="0.01" />
|
||||
</el-form-item>
|
||||
<el-form-item label="调制度" prop="temperGrade">
|
||||
<el-input v-model="form.temperGrade" placeholder="请输入调制度" />
|
||||
</el-form-item>
|
||||
@@ -340,11 +371,11 @@
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="createTime">
|
||||
<el-form-item label="创建时间" prop="createTime" v-if="form.coilId">
|
||||
<el-date-picker v-model="form.createTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="请选择创建时间" style="width: 100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="创建人" prop="createBy">
|
||||
<el-form-item label="创建人" prop="createBy" v-if="form.coilId">
|
||||
<el-select v-model="form.createBy" placeholder="请选择创建人" style="width: 100%;" clearable filterable>
|
||||
<el-option v-for="item in userList" :key="item.userName" :label="item.nickName" :value="item.userName" />
|
||||
</el-select>
|
||||
@@ -360,7 +391,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listMaterialCoil, updateMaterialCoilSimple, checkCoilNo, delMaterialCoil, restoreMaterialCoil } from '@/api/wms/coil'
|
||||
import { listMaterialCoil, updateMaterialCoilSimple, checkCoilNo, delMaterialCoil, restoreMaterialCoil, addMaterialCoil } from '@/api/wms/coil'
|
||||
import { listUser } from '@/api/system/user'
|
||||
import { listPendingAction, startProcess, cancelAction, delPendingAction } from '@/api/wms/pendingAction'
|
||||
import { parseTime } from '@/utils/klp'
|
||||
@@ -397,6 +428,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
coilType: 'all',
|
||||
title: '钢卷信息修正',
|
||||
// 物料列表相关
|
||||
materialLoading: false,
|
||||
materialCoilList: [],
|
||||
@@ -591,6 +624,44 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
parseTime,
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.correctVisible = true;
|
||||
this.title = "添加钢卷物料";
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
coilId: undefined,
|
||||
enterCoilNo: undefined,
|
||||
currentCoilNo: undefined,
|
||||
supplierCoilNo: undefined,
|
||||
dataType: 1,
|
||||
warehouseId: undefined,
|
||||
nextWarehouseId: undefined,
|
||||
qrcodeRecordId: undefined,
|
||||
actualWarehouseId: undefined,
|
||||
team: undefined,
|
||||
hasMergeSplit: undefined,
|
||||
parentCoilNos: undefined,
|
||||
itemId: undefined,
|
||||
itemType: undefined,
|
||||
status: undefined,
|
||||
remark: undefined,
|
||||
delFlag: undefined,
|
||||
createTime: undefined,
|
||||
createBy: undefined,
|
||||
updateTime: undefined,
|
||||
updateBy: undefined,
|
||||
materialType: '原料',
|
||||
temperGrade: undefined,
|
||||
coatingType: undefined,
|
||||
actualLength: undefined,
|
||||
actualWidth: undefined,
|
||||
};
|
||||
this.resetForm("form");
|
||||
},
|
||||
getBorderStyle(row) {
|
||||
// console.log(row);
|
||||
// 已发货
|
||||
@@ -675,9 +746,39 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
handleForceInMaterial(row) {
|
||||
this.$modal.confirm('是否要强制入库改钢卷?').then(_ => {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: '处理中...',
|
||||
spinner: 'el-icon-loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
updateMaterialCoilSimple({
|
||||
...row,
|
||||
dataType: 1,
|
||||
}).then(_ => {
|
||||
this.$modal.msgSuccess("强制入库成功");
|
||||
this.getMaterialCoil();
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
})
|
||||
})
|
||||
},
|
||||
getMaterialCoil() {
|
||||
this.materialLoading = true
|
||||
listMaterialCoil(this.materialQueryParams).then(response => {
|
||||
const payload = { ...this.materialQueryParams }
|
||||
if (this.coilType == 'now') {
|
||||
payload.dataType = 1;
|
||||
payload.status = 0;
|
||||
} else if (this.coilType == 'history') {
|
||||
payload.dataType = 0;
|
||||
} else if (this.coilType == 'trans') {
|
||||
payload.status = 1;
|
||||
} else if (this.coilType == 'unIn') {
|
||||
payload.dataType = 10;
|
||||
}
|
||||
listMaterialCoil(payload).then(response => {
|
||||
this.materialCoilList = response.rows || []
|
||||
this.materialTotal = response.total || 0
|
||||
this.materialLoading = false
|
||||
@@ -727,7 +828,8 @@ export default {
|
||||
handleCorrectMaterial(row) {
|
||||
this.form = {
|
||||
...row,
|
||||
}
|
||||
};
|
||||
this.title = "钢卷信息修正";
|
||||
this.correctVisible = true
|
||||
},
|
||||
cancel() {
|
||||
@@ -741,13 +843,25 @@ export default {
|
||||
return
|
||||
}
|
||||
this.buttonLoading = true;
|
||||
updateMaterialCoilSimple(this.form).then(_ => {
|
||||
this.$modal.msgSuccess("修正成功");
|
||||
this.correctVisible = false;
|
||||
this.getMaterialCoil();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
if (this.form.coilId) {
|
||||
// 更新
|
||||
updateMaterialCoilSimple(this.form).then(_ => {
|
||||
this.$modal.msgSuccess("修正成功");
|
||||
this.correctVisible = false;
|
||||
this.getMaterialCoil();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
} else {
|
||||
// 新增
|
||||
addMaterialCoil(this.form).then(_ => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.correctVisible = false;
|
||||
this.getMaterialCoil();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
'镀锌工序': [
|
||||
{value: '1988150263284953089', label: '镀锌原料库'},
|
||||
{value: '1988150323162836993', label: '镀锌成品库'},
|
||||
{value: '1988150487185289217', label: '镀锌纵剪分条原料库'},
|
||||
],
|
||||
'脱脂工序': [
|
||||
{value: '1988150545175736322', label: '脱脂原料库'},
|
||||
@@ -53,9 +54,16 @@
|
||||
{value: '1988151076996706306', label: '镀铬原料库'},
|
||||
{value: '1988151132361519105', label: '镀铬成品库'},
|
||||
],
|
||||
'纵剪分条工序': [
|
||||
{value: '', label: '原料库'},
|
||||
{value: '1988150210872930306', label: '酸连轧分条成品'},
|
||||
{value: '1988150800092950529', label: '退火分条成品'},
|
||||
{value: '1988150380649967617', label: '镀锌分条成品'},
|
||||
{value: '1988151027466170370', label: '拉矫分条成品'},
|
||||
],
|
||||
}
|
||||
|
||||
if (this.actionType === '镀锌工序') {
|
||||
if (this.actionType === '镀锌工序' || this.actionType === '脱脂工序' || this.actionType === '拉矫平整工序' || this.actionType === '双机架工序' || this.actionType === '镀铬工序' || this.actionType === '纵剪分条工序') {
|
||||
this.useSpecialSplit = true
|
||||
}
|
||||
// 从map中获取默认的查询参数
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item v-if="!form.coilId" label="厂家原料卷号" prop="supplierCoilNo">
|
||||
<el-form-item label="厂家原料卷号" prop="supplierCoilNo">
|
||||
<el-input v-model="form.supplierCoilNo" placeholder="请输入厂家原料卷号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -457,6 +457,29 @@ export default {
|
||||
// }, trigger: 'blur'
|
||||
// },
|
||||
],
|
||||
supplierCoilNo: [
|
||||
{ required: true, message: "厂家原料卷号不能为空", trigger: "blur" },
|
||||
// 远程校验,检查钢卷号是否存在
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.form.coilId) {
|
||||
// 新增时触发校验
|
||||
console.log('编辑时不触发校验');
|
||||
callback();
|
||||
} else {
|
||||
checkCoilNo({ supplierCoilNo: value }).then(res => {
|
||||
const { duplicateType } = res.data;
|
||||
if (duplicateType === 'supplier' || duplicateType === 'both') {
|
||||
// alert('厂家原料卷号重复,请重新输入');
|
||||
callback(new Error('厂家原料卷号重复,请重新输入'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
})
|
||||
}
|
||||
}, trigger: 'blur'
|
||||
},
|
||||
],
|
||||
materialType: [
|
||||
{ required: true, message: "材料类型不能为空", trigger: "change" }
|
||||
],
|
||||
@@ -724,11 +747,11 @@ export default {
|
||||
}
|
||||
delPendingAction(row.actionId).then(response => {
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
delCoilWarehouseOperationLogByCoilId({
|
||||
coilId: row.coilId,
|
||||
operationType: 1,
|
||||
inOutType: 1
|
||||
})
|
||||
// delCoilWarehouseOperationLogByCoilId({
|
||||
// coilId: row.coilId,
|
||||
// operationType: 1,
|
||||
// inOutType: 1
|
||||
// })
|
||||
this.getList();
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
|
||||
759
klp-ui/src/views/wms/coil/docorrent.vue
Normal file
759
klp-ui/src/views/wms/coil/docorrent.vue
Normal file
@@ -0,0 +1,759 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索栏 -->
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
|
||||
<el-form-item label="钢卷号" prop="currentCoilNo">
|
||||
<el-input v-model="queryParams.currentCoilNo" placeholder="请输入钢卷号" clearable
|
||||
@keyup.enter.native="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型" prop="actionType">
|
||||
<el-select v-model="queryParams.actionType" placeholder="请选择操作类型" clearable filterable>
|
||||
<el-option v-for="item in dict.type.action_type" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="只看待操作" prop="actionStatus">
|
||||
<el-switch @change="switchActionStatus" v-model="queryParams.actionSwitch" />
|
||||
</el-form-item> -->
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
|
||||
@click="handleDelete">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="el-icon-refresh" size="mini" @click="handleRefresh"
|
||||
:disabled="buttonLoading" v-loading="buttonLoading">刷新</el-button>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-checkbox v-model="rubbish" label="1" @change="getList">查看被删除操作</el-checkbox>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table v-loading="loading" :data="actionList" @selection-change="handleSelectionChange"
|
||||
:row-class-name="tableRowClassName">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<!-- <el-table-column label="序号" type="index" width="60" align="center" /> -->
|
||||
|
||||
<el-table-column label="钢卷号" align="center" prop="currentCoilNo">
|
||||
<template slot-scope="scope">
|
||||
<coil-no :coil-no="scope.row.currentCoilNo"></coil-no>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作类型" align="center" prop="actionType" width="160">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.actionType === 401">入库/收货操作</span>
|
||||
<span v-else-if="scope.row.actionType === 402">发货操作</span>
|
||||
<span v-else-if="scope.row.actionType === 403">移库操作</span>
|
||||
<span v-else-if="scope.row.actionType === 404">通过库区编辑钢卷</span>
|
||||
<span v-else-if="scope.row.actionType === 405">钢卷打包</span>
|
||||
<dict-tag v-else :options='dict.type.action_type' :value="scope.row.actionType"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作状态" align="center" prop="actionStatus" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.actionStatus" placeholder="请选择操作状态" @change="handleStatusChange(scope.row)">
|
||||
<el-option label="待处理" :value="0" />
|
||||
<el-option label="处理中" :value="1" />
|
||||
<el-option label="已完成" :value="2" />
|
||||
<el-option label="已取消" :value="3" />
|
||||
</el-select>
|
||||
<!-- <el-tag v-if="scope.row.actionStatus === 0" type="info" size="small">待处理</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 1" type="warning" size="small">处理中</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 2" type="success" size="small">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.actionStatus === 3" type="danger" size="small">已取消</el-tag> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="优先级" align="center" prop="priority" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.priority === 0" type="info" size="mini">普通</el-tag>
|
||||
<el-tag v-else-if="scope.row.priority === 1" type="warning" size="mini">重要</el-tag>
|
||||
<el-tag v-else-if="scope.row.priority === 2" type="danger" size="mini">紧急</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="来源" align="center" prop="sourceType" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-tag v-if="scope.row.sourceType === 'scan'" type="success" size="mini">
|
||||
<i class="el-icon-mobile"></i> 扫码
|
||||
</el-tag>
|
||||
<el-tag v-else type="info" size="mini">
|
||||
<i class="el-icon-edit-outline"></i> 手动
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="新增时间" align="center" prop="createTime" width="155" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="创建人" align="center" prop="createByName" width="100" />
|
||||
<el-table-column label="操作人" align="center" prop="updateBy" width="100" />
|
||||
|
||||
<el-table-column label="完成时间" align="center" prop="completeTime" width="220" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<el-date-picker @change="handleProcessTimeChange(scope.row)" value-format="yyyy-MM-dd HH:mm:ss" style="width: 200px" v-model="scope.row.completeTime" type="datetime" placeholder="选择完成时间" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" />
|
||||
|
||||
<el-table-column label="操作" align="center" width="200" class-name="small-padding fixed-width" fixed="right">
|
||||
<template slot-scope="scope">
|
||||
<!-- 待处理状态显示操作按钮 -->
|
||||
<!-- <template v-if="scope.row.actionStatus === 0">
|
||||
<el-button size="mini" type="primary" icon="el-icon-edit" @click="handleProcess(scope.row)"
|
||||
v-loading="buttonLoading" :disabled="buttonLoading">操作</el-button>
|
||||
<el-button size="mini" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template> -->
|
||||
<!-- 处理中状态显示继续按钮 -->
|
||||
<!-- <template v-else-if="scope.row.actionStatus === 1">
|
||||
<el-button size="mini" type="warning" icon="el-icon-edit" @click="handleProcess(scope.row)"
|
||||
:disabled="buttonLoading" v-loading="buttonLoading">继续</el-button>
|
||||
<el-button size="mini" type="info" icon="el-icon-close" @click="handleCancel(scope.row)">取消</el-button>
|
||||
</template> -->
|
||||
<!-- 已完成或已取消状态显示删除按钮 -->
|
||||
<template v-if="scope.row.actionStatus === 2 || scope.row.actionStatus === 3">
|
||||
<el-button v-if="scope.row.delFlag == 0" size="mini" type="danger" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
|
||||
<el-button v-if="scope.row.delFlag == 2" size="mini" type="success" icon="el-icon-refresh" @click="handleRestore(scope.row)">还原</el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
|
||||
<!-- 添加或修改对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="1200px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
|
||||
<el-form-item label="钢卷" prop="coilId">
|
||||
<coil-selector v-model="form.coilId" :use-trigger="true" @select="handleCoilSelect" />
|
||||
</el-form-item>
|
||||
<el-form-item label="操作类型" prop="actionType">
|
||||
<div class="action-type-cards">
|
||||
<!-- 分条操作区 -->
|
||||
<div class="card-section" v-if="splitTypes.length > 0">
|
||||
<div class="section-title">分条操作</div>
|
||||
<div class="action-cards-row">
|
||||
<div v-for="item in splitTypes" :key="item.value" class="action-card split-card"
|
||||
:class="{ 'active': form.actionType == item.value }" @click="form.actionType = parseInt(item.value)">
|
||||
<div class="card-icon">
|
||||
<i :class="getActionIcon(item.value)"></i>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="card-title">{{ item.label }}</div>
|
||||
<div class="card-desc">{{ item.remark || '钢卷分条操作' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 其他操作区 -->
|
||||
<div class="card-section" v-if="otherTypes.length > 0">
|
||||
<div class="section-title">其他操作</div>
|
||||
<div class="action-cards-row">
|
||||
<div v-for="item in otherTypes" :key="item.value" class="action-card"
|
||||
:class="{ 'active': form.actionType == item.value }" @click="form.actionType = parseInt(item.value)">
|
||||
<div class="card-icon">
|
||||
<i :class="getActionIcon(item.value)"></i>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="card-title">{{ item.label }}</div>
|
||||
<div class="card-desc">{{ item.remark || '钢卷操作' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="优先级" prop="priority">
|
||||
<el-select v-model="form.priority" placeholder="请选择优先级">
|
||||
<el-option label="普通" :value="0" />
|
||||
<el-option label="重要" :value="1" />
|
||||
<el-option label="紧急" :value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm" :disabled="buttonLoading" v-loading="buttonLoading">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listPendingAction,
|
||||
getPendingAction,
|
||||
delPendingAction,
|
||||
addPendingAction,
|
||||
updatePendingAction,
|
||||
startProcess,
|
||||
cancelAction,
|
||||
restorePendingAction,
|
||||
} from '@/api/wms/pendingAction';
|
||||
import CoilSelector from '@/components/CoilSelector';
|
||||
import CoilNo from '@/components/KLPService/Renderer/CoilNo.vue';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'CoilActflow',
|
||||
dicts: ['action_type'],
|
||||
components: {
|
||||
CoilSelector,
|
||||
CoilNo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 遮罩层
|
||||
loading: true,
|
||||
buttonLoading: false,
|
||||
rubbish: false,
|
||||
// 选中数组
|
||||
ids: [],
|
||||
// 非单个禁用
|
||||
single: true,
|
||||
// 非多个禁用
|
||||
multiple: true,
|
||||
// 显示搜索条件
|
||||
showSearch: true,
|
||||
// 总条数
|
||||
total: 0,
|
||||
// 待操作列表数据
|
||||
actionList: [],
|
||||
// 弹出层标题
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
currentCoilNo: null,
|
||||
actionType: null,
|
||||
actionStatus: null, // 默认查询待处理
|
||||
priority: null
|
||||
},
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
coilId: [
|
||||
{ required: true, message: '请选择钢卷', trigger: 'blur' }
|
||||
],
|
||||
actionType: [
|
||||
{ required: true, message: '请选择操作类型', trigger: 'change' }
|
||||
]
|
||||
},
|
||||
// 钢卷选择器可见性
|
||||
coilSelectorVisible: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 分条操作列表(100-199)
|
||||
splitTypes() {
|
||||
if (!this.dict.type.action_type) return [];
|
||||
return this.dict.type.action_type.filter(item => {
|
||||
const value = parseInt(item.value);
|
||||
return value >= 100 && value <= 199;
|
||||
});
|
||||
},
|
||||
// 其他操作列表(200-299等)
|
||||
otherTypes() {
|
||||
if (!this.dict.type.action_type) return [];
|
||||
return this.dict.type.action_type.filter(item => {
|
||||
const value = parseInt(item.value);
|
||||
return value < 100 || value > 199;
|
||||
});
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
// 设置定时刷新(可选,用于移动端扫码后自动刷新)
|
||||
this.startAutoRefresh();
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 清除定时器
|
||||
if (this.refreshTimer) {
|
||||
clearInterval(this.refreshTimer);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 查询待操作列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
this.buttonLoading = true;
|
||||
const payload = {
|
||||
...this.queryParams,
|
||||
includeDeleted: this.rubbish ? 2 : 0
|
||||
}
|
||||
listPendingAction(payload).then(response => {
|
||||
console.log('response.rows', response.rows);
|
||||
this.actionList = response.rows;
|
||||
this.total = response.total;
|
||||
this.buttonLoading = false;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
switchActionStatus(value) {
|
||||
console.log(value)
|
||||
if (!value) {
|
||||
this.queryParams.actionStatus = null;
|
||||
} else {
|
||||
this.queryParams.actionStatus = '-1';
|
||||
}
|
||||
this.getList()
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
// 表单重置
|
||||
reset() {
|
||||
this.form = {
|
||||
actionId: null,
|
||||
coilId: null,
|
||||
currentCoilNo: null,
|
||||
actionType: null,
|
||||
actionStatus: null,
|
||||
priority: 0,
|
||||
sourceType: 'manual',
|
||||
remark: null
|
||||
};
|
||||
this.resetForm('form');
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryForm');
|
||||
this.handleQuery();
|
||||
},
|
||||
handleStatusChange(row) {
|
||||
// console.log(row)
|
||||
updatePendingAction(row).then(response => {
|
||||
this.$message.success('操作状态更新成功');
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
/** 还原按钮操作 */
|
||||
handleRestore(row) {
|
||||
const actionId = row.actionId;
|
||||
this.$modal.confirm('是否确认还原该待操作记录?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
restorePendingAction(actionId).then(response => {
|
||||
this.$message.success('还原成功');
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.actionId);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = '添加待操作';
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const actionId = row.actionId || this.ids;
|
||||
getPendingAction(actionId).then(response => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = '修改待操作';
|
||||
});
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs['form'].validate(valid => {
|
||||
if (valid) {
|
||||
this.buttonLoading = true;
|
||||
if (this.form.actionId != null) {
|
||||
updatePendingAction(this.form).then(response => {
|
||||
this.$message.success('修改成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
} else {
|
||||
addPendingAction(this.form).then(response => {
|
||||
this.$message.success('新增成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/** 完成时间改变时触发 */
|
||||
handleProcessTimeChange(row) {
|
||||
console.log('完成时间改变:', row);
|
||||
updatePendingAction(row).then(response => {
|
||||
this.$message.success('更新成功');
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const actionIds = row.actionId || this.ids;
|
||||
this.$confirm('是否确认删除该待操作记录?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
return delPendingAction(actionIds);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$message.success('删除成功');
|
||||
}).catch(() => { });
|
||||
},
|
||||
/** 处理操作 - 跳转到对应页面 */
|
||||
handleProcess(row) {
|
||||
console.log('=== 开始处理操作 ===');
|
||||
console.log('待操作记录:', row);
|
||||
console.log('操作类型:', row.actionType);
|
||||
console.log('钢卷ID:', row.coilId);
|
||||
|
||||
this.buttonLoading = true;
|
||||
this.$forceUpdate();
|
||||
const actionType = parseInt(row.actionType);
|
||||
|
||||
// 特殊处理:发货和移库操作不需要跳转
|
||||
if (actionType === 4 || actionType === 5 || actionType === 401 || actionType === 402) {
|
||||
this.$message.info(actionType === 4 ? '发货操作已在移动端完成' : '移库操作已在移动端完成');
|
||||
this.buttonLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 根据操作类型跳转到不同页面
|
||||
let path = '';
|
||||
|
||||
// 分条操作:100-199
|
||||
if (actionType >= 100 && actionType <= 199) {
|
||||
path = '/wms/split';
|
||||
}
|
||||
// 合卷操作:200-299
|
||||
else if (actionType == 200) {
|
||||
path = '/wms/merge';
|
||||
}
|
||||
else if (actionType < 100) {
|
||||
path = '/wms/typing';
|
||||
}
|
||||
// 其他操作类型
|
||||
else {
|
||||
this.$message.error('特殊操作请到专门的页面进行处理');
|
||||
this.buttonLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
this.$message.error('未知的操作类型: ' + row.actionType);
|
||||
this.buttonLoading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新状态为处理中
|
||||
console.log('调用startProcess,actionId:', row.actionId);
|
||||
startProcess(row.actionId).then(response => {
|
||||
console.log('开始处理响应:', response);
|
||||
|
||||
if (response.code !== 200) {
|
||||
this.$message.error(response.msg || '更新状态失败');
|
||||
return;
|
||||
}
|
||||
|
||||
// 跳转并传递参数
|
||||
console.log('准备跳转到:', path, '参数:', { coilId: row.coilId, actionId: row.actionId });
|
||||
this.$router.push({
|
||||
path: path,
|
||||
query: {
|
||||
coilId: row.coilId,
|
||||
actionId: row.actionId
|
||||
}
|
||||
});
|
||||
this.buttonLoading = false;
|
||||
}).catch(error => {
|
||||
console.error('更新状态失败:', error);
|
||||
this.$message.error('更新状态失败: ' + (error.message || error));
|
||||
}).finally(() => {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
},
|
||||
/** 取消操作 */
|
||||
handleCancel(row) {
|
||||
this.$confirm('是否确认取消该操作?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
return cancelAction(row.actionId);
|
||||
}).then(() => {
|
||||
this.$message.success('操作已取消');
|
||||
this.getList();
|
||||
}).catch(() => { });
|
||||
},
|
||||
/** 刷新列表 */
|
||||
handleRefresh() {
|
||||
this.getList();
|
||||
this.$message.success('刷新成功');
|
||||
},
|
||||
/** 自动刷新 */
|
||||
startAutoRefresh() {
|
||||
// 每30秒自动刷新一次(用于移动端扫码后自动更新列表)
|
||||
this.refreshTimer = setInterval(() => {
|
||||
|
||||
// 只在查看待处理状态时自动刷新
|
||||
this.getList();
|
||||
}, 30000);
|
||||
},
|
||||
/** 表格行样式 */
|
||||
tableRowClassName({ row }) {
|
||||
if (row.priority === 2) {
|
||||
return 'urgent-row';
|
||||
} else if (row.priority === 1) {
|
||||
return 'important-row';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
/** 显示钢卷选择器 */
|
||||
showCoilSelector() {
|
||||
this.coilSelectorVisible = true;
|
||||
},
|
||||
/** 钢卷选择回调 */
|
||||
handleCoilSelect(coil) {
|
||||
this.form.coilId = coil.coilId;
|
||||
this.form.currentCoilNo = coil.currentCoilNo;
|
||||
},
|
||||
|
||||
/** 获取状态文本 */
|
||||
getStatusText(status) {
|
||||
const statusMap = {
|
||||
0: '待处理',
|
||||
1: '处理中',
|
||||
2: '已完成',
|
||||
3: '已取消'
|
||||
};
|
||||
return statusMap[status] || '未知';
|
||||
},
|
||||
/** 根据操作类型获取图标 */
|
||||
getActionIcon(actionType) {
|
||||
const value = parseInt(actionType);
|
||||
const iconMap = {
|
||||
1: 'el-icon-connection', // 合卷
|
||||
2: 'el-icon-s-operation', // 分条
|
||||
3: 'el-icon-edit', // 更新
|
||||
4: 'el-icon-truck', // 发货
|
||||
5: 'el-icon-s-grid', // 移库
|
||||
101: 'el-icon-scissors', // 纵剪分条
|
||||
102: 'el-icon-s-operation', // 横切分条
|
||||
103: 'el-icon-s-unfold' // 开卷分条
|
||||
};
|
||||
return iconMap[value] || 'el-icon-s-operation';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.app-container {
|
||||
::v-deep .urgent-row {
|
||||
background: #fef0f0 !important;
|
||||
}
|
||||
|
||||
::v-deep .important-row {
|
||||
background: #fdf6ec !important;
|
||||
}
|
||||
|
||||
// 优化按钮文字颜色
|
||||
// 实心按钮:白色文字(在深色背景上清晰可见)
|
||||
::v-deep .el-button--primary.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--danger.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--warning.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--info.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--success.el-button--mini:not(.is-plain) {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
// plain按钮:同色系深色文字(在浅色背景上)
|
||||
::v-deep .el-button--primary.el-button--mini.is-plain {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
::v-deep .el-button--danger.el-button--mini.is-plain {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
::v-deep .el-button--warning.el-button--mini.is-plain {
|
||||
color: #e6a23c;
|
||||
}
|
||||
}
|
||||
|
||||
/* 操作类型卡片样式 */
|
||||
.action-type-cards {
|
||||
width: 100%;
|
||||
|
||||
.card-section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 12px;
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
|
||||
// 分条操作区域的特殊样式
|
||||
.card-section:first-child .section-title {
|
||||
border-left-color: #e6a23c;
|
||||
}
|
||||
|
||||
.action-cards-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.action-card {
|
||||
min-width: 0;
|
||||
padding: 16px;
|
||||
border: 2px solid #dcdfe6;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
&.active {
|
||||
border-color: #409eff;
|
||||
background: linear-gradient(135deg, #e3f2fd 0%, #f0f7ff 100%);
|
||||
box-shadow: 0 2px 12px 0 rgba(64, 158, 255, 0.3);
|
||||
|
||||
.card-icon {
|
||||
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: #409eff;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&.split-card {
|
||||
&.active {
|
||||
background: linear-gradient(135deg, #fff3e0 0%, #fff8f0 100%);
|
||||
border-color: #e6a23c;
|
||||
|
||||
.card-icon {
|
||||
background: linear-gradient(135deg, #e6a23c 0%, #f0ad4e 100%);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
color: #e6a23c;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: #e6a23c;
|
||||
box-shadow: 0 2px 12px 0 rgba(230, 162, 60, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 8px;
|
||||
background: #f5f7fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
color: #909399;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
margin-bottom: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card-desc {
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -50,10 +50,16 @@ export const actionStrategies = {
|
||||
handler: async (coil, action) => {
|
||||
// 更新操作记录状态 actionStatus: 2
|
||||
// 并行执行更新操作记录和更新钢卷状态
|
||||
// 将日期格式化为yyyy-MM-dd HH:mm:ss
|
||||
const completeTime = new Date()
|
||||
function parseDate(date) {
|
||||
return date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()
|
||||
}
|
||||
await Promise.all([
|
||||
updatePendingAction({
|
||||
...action,
|
||||
actionStatus: 2,
|
||||
completeTime: parseDate(completeTime),
|
||||
}),
|
||||
updateMaterialCoilSimple({
|
||||
...coil,
|
||||
|
||||
@@ -189,6 +189,18 @@
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||||
<el-input-number :controls="false" v-model="targetCoil.actualLength" placeholder="请输入实测长度" type="number"
|
||||
:step="0.01" :disabled="readonly">
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="实测宽度(m)" prop="actualWidth">
|
||||
<el-input-number :controls="false" v-model="targetCoil.actualWidth" placeholder="请输入实测宽度" type="number"
|
||||
:step="0.01" :disabled="readonly">
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="调制度" prop="temperGrade">
|
||||
<el-input v-model="targetCoil.temperGrade" placeholder="请输入调制度" />
|
||||
</el-form-item>
|
||||
@@ -263,6 +275,8 @@ export default {
|
||||
length: null,
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
actualLength: undefined,
|
||||
actualWidth: undefined,
|
||||
},
|
||||
buttonLoading: false,
|
||||
loading: false,
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
Jiaxiang County,Jining City,Shandong Province</span>
|
||||
<br />
|
||||
<span>
|
||||
TEL:0537-6625068 0537-6625067
|
||||
TEL:19053728822 19053728835
|
||||
</span>
|
||||
</div>
|
||||
<div class="contact-timestamp">
|
||||
|
||||
291
klp-ui/src/views/wms/coil/panels/LabelRender/TuoZhiTag.vue
Normal file
291
klp-ui/src/views/wms/coil/panels/LabelRender/TuoZhiTag.vue
Normal file
@@ -0,0 +1,291 @@
|
||||
<template>
|
||||
<div class="label-container" :style="{ '--print-scale': printScale }">
|
||||
<div class="material-label-grid">
|
||||
<!-- 公司名称行 -->
|
||||
<div class="grid-cell company-cell">嘉祥科伦普重工有限公司</div>
|
||||
|
||||
<!-- 第一行:冷卷号、热卷号 -->
|
||||
<div class="grid-cell label-cell">冷卷号</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.currentCoilNo || '' }}</div>
|
||||
</div>
|
||||
<div class="grid-cell label-cell">热卷号</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.enterCoilNo || '' }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 第二行:规格、钢种 -->
|
||||
<div class="grid-cell label-cell">规格</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.specification || '' }}</div>
|
||||
</div>
|
||||
<div class="grid-cell label-cell">钢种</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.material || '' }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 第三行:净重、下工序 -->
|
||||
<div class="grid-cell label-cell">净重</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.netWeight || '' }}</div>
|
||||
</div>
|
||||
<div class="grid-cell label-cell">下工序</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.nextProcess || '冷轧' }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 第四行:包装要求、切边要求 -->
|
||||
<div class="grid-cell label-cell">包装要求</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.packagingRequirement || '' }}</div>
|
||||
</div>
|
||||
<div class="grid-cell label-cell">切边要求</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.trimmingRequirement || '' }}</div>
|
||||
</div>
|
||||
|
||||
<!-- 第五行:班组、代码(二维码) -->
|
||||
<div class="grid-cell label-cell">班组</div>
|
||||
<div class="grid-cell value-cell">
|
||||
<div class="nob" contenteditable>{{ content.team || '' }}</div>
|
||||
</div>
|
||||
<div class="grid-cell label-cell">代码</div>
|
||||
<div class="grid-cell qrcode-cell">
|
||||
<!-- 二维码容器 -->
|
||||
<QRCode :content="content.qrcodeRecordId" :size="80"/>
|
||||
</div>
|
||||
|
||||
<!-- 第六行:生产日期 -->
|
||||
<div class="grid-cell label-cell">生产日期</div>
|
||||
<div class="grid-cell value-cell date-cell">
|
||||
<div class="nob" contenteditable>{{ content.createTime || '' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QRCode from '@/components/QRCode/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'ZincRawTag',
|
||||
components: {
|
||||
QRCode
|
||||
},
|
||||
props: {
|
||||
content: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
currentCoilNo: '',
|
||||
entryCoilNo: '',
|
||||
specification: '',
|
||||
material: '',
|
||||
netWeight: '',
|
||||
nextProcess: '',
|
||||
packagingRequirements: '',
|
||||
trimmingRequirements: '',
|
||||
team: '',
|
||||
createTime: '',
|
||||
qrcodeRecordId: '',
|
||||
})
|
||||
},
|
||||
paperWidthMm: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
paperHeightMm: {
|
||||
type: Number,
|
||||
default: 80
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
printScale: 1,
|
||||
printMediaQuery: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.printMediaQuery = window.matchMedia('print');
|
||||
this.printMediaQuery.addListener(this.handlePrintMediaChange);
|
||||
window.addEventListener('beforeprint', this.handleBeforePrint);
|
||||
window.addEventListener('afterprint', this.handleAfterPrint);
|
||||
this.$nextTick(() => {
|
||||
this.calculatePrintScale();
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.printMediaQuery) {
|
||||
this.printMediaQuery.removeListener(this.handlePrintMediaChange);
|
||||
}
|
||||
window.removeEventListener('beforeprint', this.handleBeforePrint);
|
||||
window.removeEventListener('afterprint', this.handleAfterPrint);
|
||||
},
|
||||
methods: {
|
||||
handlePrintMediaChange(mq) {
|
||||
mq.matches ? this.calculatePrintScale() : this.resetPrintScale();
|
||||
},
|
||||
handleBeforePrint() {
|
||||
setTimeout(() => this.calculatePrintScale(), 100);
|
||||
},
|
||||
handleAfterPrint() {
|
||||
this.resetPrintScale();
|
||||
},
|
||||
calculatePrintScale() {
|
||||
this.$nextTick(() => {
|
||||
const container = this.$el;
|
||||
if (!container) return;
|
||||
|
||||
const dpi = 96;
|
||||
const mmToPx = dpi / 25.4;
|
||||
const paperWidthPx = this.paperWidthMm * mmToPx;
|
||||
const paperHeightPx = this.paperHeightMm * mmToPx;
|
||||
const marginPx = 2 * mmToPx;
|
||||
|
||||
const rect = container.getBoundingClientRect();
|
||||
const contentWidth = rect.width || container.scrollWidth;
|
||||
const contentHeight = rect.height || container.scrollHeight;
|
||||
|
||||
const availableWidth = paperWidthPx - marginPx * 2;
|
||||
const availableHeight = paperHeightPx - marginPx * 2;
|
||||
|
||||
const scaleX = contentWidth > 0 ? availableWidth / contentWidth : 1;
|
||||
const scaleY = contentHeight > 0 ? availableHeight / contentHeight : 1;
|
||||
|
||||
this.printScale = Math.min(scaleX, scaleY, 1);
|
||||
container.style.setProperty('--print-scale', this.printScale);
|
||||
container.style.setProperty('--paper-width', `${this.paperWidthMm}mm`);
|
||||
container.style.setProperty('--paper-height', `${this.paperHeightMm}mm`);
|
||||
});
|
||||
},
|
||||
resetPrintScale() {
|
||||
this.printScale = 1;
|
||||
if (this.$el) {
|
||||
this.$el.style.setProperty('--print-scale', 1);
|
||||
this.$el.style.removeProperty('--paper-width');
|
||||
this.$el.style.removeProperty('--paper-height');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.label-container {
|
||||
width: 45em;
|
||||
height: 25em;
|
||||
padding: 16px;
|
||||
font-family: "SimSun", serif;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 核心Grid布局 */
|
||||
.material-label-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr); /* 4列等宽 */
|
||||
grid-auto-rows: 1fr; /* 行高自适应 */
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid #333;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.grid-cell {
|
||||
border: 1px solid #333;
|
||||
padding: 4px;
|
||||
font-size: 20px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
overflow-wrap: break-word;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 公司名称单元格 */
|
||||
.company-cell {
|
||||
grid-column: span 4; /* 跨4列 */
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
/* background-color: #f5f5f5; */
|
||||
}
|
||||
|
||||
/* 标签单元格(左) */
|
||||
.label-cell {
|
||||
/* background-color: #f5f5f5; */
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 值单元格 */
|
||||
.value-cell {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.date-cell {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
/* 二维码单元格(跨2列+2行) */
|
||||
.qrcode-cell {
|
||||
grid-row: span 2; /* 跨2行 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.qrcode-container {
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
border: 1px dashed #999; /* 占位虚线 */
|
||||
}
|
||||
|
||||
/* 内容可编辑区域 */
|
||||
.nob {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
text-align: center;
|
||||
font-size: inherit;
|
||||
word-break: break-all;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 打印样式 */
|
||||
@media print {
|
||||
@page {
|
||||
size: 100mm 80mm;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
* {
|
||||
-webkit-print-color-adjust: exact !important;
|
||||
print-color-adjust: exact !important;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
body>*:not(.label-container) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.label-container {
|
||||
page-break-inside: avoid !important;
|
||||
break-inside: avoid !important;
|
||||
transform: scale(var(--print-scale, 1)) !important;
|
||||
transform-origin: top left !important;
|
||||
max-width: var(--paper-width, 100mm) !important;
|
||||
max-height: var(--paper-height, 80mm) !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -36,7 +36,13 @@
|
||||
v-if="tagType === 'ge'"
|
||||
:content="content"
|
||||
:paperWidthMm="180"
|
||||
:paperHeightMm="80"
|
||||
:paperHeightMm="100"
|
||||
/>
|
||||
<TuoZhiTag
|
||||
v-if="tagType === '6'"
|
||||
:content="content"
|
||||
:paperWidthMm="180"
|
||||
:paperHeightMm="100"
|
||||
/>
|
||||
<!-- <SampleTagPreview v-if="labelType === '4'" :content="content" />
|
||||
<ForgeTagPreview v-if="labelType === '5'" :content="content" />
|
||||
@@ -61,6 +67,8 @@ import GalvanizedTag from './GalvanizedTag.vue';
|
||||
import WhereTag from './WhereTag.vue';
|
||||
import ZincRawTag from './ZincRawTag.vue';
|
||||
import DuGeTag from './DuGeTag.vue';
|
||||
import TuoZhiTag from './TuoZhiTag.vue';
|
||||
|
||||
|
||||
// import SampleTagPreview from './SampleTagPreview.vue';
|
||||
// import ForgeTagPreview from './ForgeTagPreview.vue';
|
||||
@@ -75,6 +83,7 @@ export default {
|
||||
WhereTag,
|
||||
ZincRawTag,
|
||||
DuGeTag,
|
||||
TuoZhiTag,
|
||||
// SampleTagPreview,
|
||||
// ForgeTagPreview,
|
||||
// SaltSprayTagPreview,
|
||||
@@ -107,6 +116,10 @@ export default {
|
||||
width: 180,
|
||||
height: 100,
|
||||
},
|
||||
'6': {
|
||||
width: 180,
|
||||
height: 100,
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -141,8 +154,12 @@ export default {
|
||||
handler(newVal) {
|
||||
const { itemName, itemType, warehouseId } = newVal;
|
||||
// 在镀锌颜料库的卷使用镀锌原料标签
|
||||
if (itemType == 'raw_material' && warehouseId == '1988150263284953089') {
|
||||
if (itemType == 'raw_material' && (warehouseId == '1988150263284953089' || warehouseId == '1988150487185289217')) {
|
||||
this.labelType = '5';
|
||||
}
|
||||
// 脱脂原料库
|
||||
else if (itemType == 'raw_material' && (warehouseId == '1988150545175736322')) {
|
||||
this.labelType = '6';
|
||||
} else if (itemType == 'raw_material') {
|
||||
this.labelType = '2';
|
||||
} else if (itemType == 'product' && itemName == '冷硬卷') {
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div class="hot-zha-raw">
|
||||
<!-- 使用 el-table 展示数据 -->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="processedData"
|
||||
border
|
||||
style="width: 100%;"
|
||||
:header-cell-style="{background: '#f2f2f2', fontWeight: 600}"
|
||||
>
|
||||
<!-- 类别列 -->
|
||||
<el-table-column
|
||||
label="类别"
|
||||
prop="category"
|
||||
min-width="180"
|
||||
align="left"
|
||||
/>
|
||||
|
||||
<!-- 合并的净边表头 -->
|
||||
<el-table-column
|
||||
label="净边"
|
||||
align="center"
|
||||
>
|
||||
<el-table-column
|
||||
label="1000"
|
||||
prop="width1000"
|
||||
min-width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="1200"
|
||||
prop="width1200"
|
||||
min-width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="1220"
|
||||
prop="width1220"
|
||||
min-width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="1250"
|
||||
prop="width1250"
|
||||
min-width="100"
|
||||
align="center"
|
||||
/>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 其他宽度及毛边列 -->
|
||||
<el-table-column
|
||||
label="其他宽度及毛边"
|
||||
prop="otherWidth"
|
||||
min-width="120"
|
||||
align="center"
|
||||
/>
|
||||
|
||||
<!-- 合计列 -->
|
||||
<el-table-column
|
||||
label="合计"
|
||||
prop="total"
|
||||
min-width="100"
|
||||
align="center"
|
||||
:cell-style="{fontWeight: 600, color: '#1890ff'}"
|
||||
/>
|
||||
</el-table>
|
||||
|
||||
<!-- 无数据提示(el-table 自带空数据提示,这里可保留统一样式) -->
|
||||
<div v-if="!data || data.length === 0" class="empty-data">
|
||||
暂无数据
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HotZhaRaw',
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false // 可根据实际需求控制加载状态
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
processedData() {
|
||||
if (!this.data || !Array.isArray(this.data)) {
|
||||
return [];
|
||||
}
|
||||
console.log(this.data);
|
||||
// 深拷贝避免修改原数据
|
||||
return this.data;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// el-table 专用的数字格式化方法
|
||||
formatTableNumber(row, column) {
|
||||
const num = row[column.prop];
|
||||
if (num === null || num === undefined || num === '') return '0.000';
|
||||
return Number(num).toFixed(3);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hot-zha-raw {
|
||||
width: 100%;
|
||||
min-height: 200px;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.empty-data {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* 覆盖 el-table 样式,保持视觉统一 */
|
||||
:deep(.el-table) {
|
||||
--el-table-header-text-color: #303133;
|
||||
--el-table-row-hover-bg-color: #f8f9fa;
|
||||
}
|
||||
|
||||
:deep(.el-table th) {
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
:deep(.el-table td) {
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
</style>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="trim-statistics-table">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
:data="filteredTableData"
|
||||
border
|
||||
stripe
|
||||
:span-method="objectSpanMethod"
|
||||
@@ -15,7 +15,7 @@
|
||||
align="center"
|
||||
/>
|
||||
|
||||
<!-- 冷硬卷板净边料现货库存 表头组 -->
|
||||
<!-- 冷硬卷板净边料现货库存 独立表头组 -->
|
||||
<el-table-column
|
||||
label="冷硬卷板净边料现货库存"
|
||||
align="center"
|
||||
@@ -27,18 +27,19 @@
|
||||
<el-table-column label="数量(件)" prop="trimmedTotalCount" width="80" align="center" />
|
||||
<el-table-column label="重量(吨)" prop="trimmedTotalWeight" width="80" align="center" />
|
||||
</el-table-column>
|
||||
<!-- 净边料独立宽度列(合并后的分组) -->
|
||||
<el-table-column
|
||||
v-for="width in widthList"
|
||||
:key="'trimmed-' + width"
|
||||
:label="width"
|
||||
v-for="group in trimmedWidthGroups"
|
||||
:key="'trimmed-' + group.key"
|
||||
:label="group.label"
|
||||
align="center"
|
||||
>
|
||||
<el-table-column label="数量(件)" :prop="`trimmed_${width}_count`" width="80" align="center" />
|
||||
<el-table-column label="重量(吨)" :prop="`trimmed_${width}_weight`" width="80" align="center" />
|
||||
<el-table-column label="数量(件)" :prop="`trimmed_${group.key}_count`" width="80" align="center" />
|
||||
<el-table-column label="重量(吨)" :prop="`trimmed_${group.key}_weight`" width="80" align="center" />
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 冷硬卷板毛边料现货库存 表头组 -->
|
||||
<!-- 冷硬卷板毛边料现货库存 独立表头组 -->
|
||||
<el-table-column
|
||||
label="冷硬卷板毛边料现货库存"
|
||||
align="center"
|
||||
@@ -50,14 +51,15 @@
|
||||
<el-table-column label="数量(件)" prop="untrimmedTotalCount" width="80" align="center" />
|
||||
<el-table-column label="重量(吨)" prop="untrimmedTotalWeight" width="80" align="center" />
|
||||
</el-table-column>
|
||||
<!-- 毛边料独立宽度列(合并后的分组) -->
|
||||
<el-table-column
|
||||
v-for="width in widthList"
|
||||
:key="'untrimmed-' + width"
|
||||
:label="width"
|
||||
v-for="group in untrimmedWidthGroups"
|
||||
:key="'untrimmed-' + group.key"
|
||||
:label="group.label"
|
||||
align="center"
|
||||
>
|
||||
<el-table-column label="数量(件)" :prop="`untrimmed_${width}_count`" width="80" align="center" />
|
||||
<el-table-column label="重量(吨)" :prop="`untrimmed_${width}_weight`" width="80" align="center" />
|
||||
<el-table-column label="数量(件)" :prop="`untrimmed_${group.key}_count`" width="80" align="center" />
|
||||
<el-table-column label="重量(吨)" :prop="`untrimmed_${group.key}_weight`" width="80" align="center" />
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -71,69 +73,202 @@ export default {
|
||||
data: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
// 可配置的宽度分组规则(支持自定义)
|
||||
widthGroupRules: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
'1000系列': ['1000', '1000~1005', '1010/1015'],
|
||||
'1200基础系列': ['1200/1202', '1200~1215'],
|
||||
'1218基础系列': ['1218/1220', '1218~1235', '1210/1215'],
|
||||
'1240系列': ['1240/1252'],
|
||||
'1225系列': ['1225/1235'],
|
||||
'1250+系列': ['1250~1265', '1260-1265']
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 定义表格中需要展示的宽度规格(与图片中一致)
|
||||
widthList() {
|
||||
return [
|
||||
'1000', '1200/1202', '1218/1220', '1240/1252',
|
||||
'1010/1015', '1210/1215', '1225/1235', '1260-1265',
|
||||
'1000~1005', '1200~1215', '1218~1235', '1250~1265'
|
||||
];
|
||||
// ========== 净边料相关计算 ==========
|
||||
// 提取净边料所有原始宽度
|
||||
rawTrimmedWidths() {
|
||||
const widthSet = new Set();
|
||||
this.data?.forEach(item => {
|
||||
item.trimmedList?.forEach(trimmed => {
|
||||
if (trimmed.width) widthSet.add(trimmed.width);
|
||||
});
|
||||
});
|
||||
return Array.from(widthSet);
|
||||
},
|
||||
// 处理后的数据(适配表格列结构)
|
||||
// 净边料宽度分组(合并相近宽度)
|
||||
trimmedWidthGroups() {
|
||||
return this.generateWidthGroups(this.rawTrimmedWidths);
|
||||
},
|
||||
|
||||
// ========== 毛边料相关计算 ==========
|
||||
// 提取毛边料所有原始宽度
|
||||
rawUntrimmedWidths() {
|
||||
const widthSet = new Set();
|
||||
this.data?.forEach(item => {
|
||||
item.untrimmedList?.forEach(untrimmed => {
|
||||
if (untrimmed.width) widthSet.add(untrimmed.width);
|
||||
});
|
||||
});
|
||||
return Array.from(widthSet);
|
||||
},
|
||||
// 毛边料宽度分组(合并相近宽度)
|
||||
untrimmedWidthGroups() {
|
||||
return this.generateWidthGroups(this.rawUntrimmedWidths);
|
||||
},
|
||||
|
||||
// 处理后的原始表格数据
|
||||
tableData() {
|
||||
return this.data.map(item => {
|
||||
const row = {
|
||||
thickness: item.thickness,
|
||||
trimmedTotalCount: 0, // 净边料总计数量
|
||||
trimmedTotalWeight: 0, // 净边料总计重量
|
||||
untrimmedTotalCount: 0, // 毛边料总计数量
|
||||
untrimmedTotalWeight: 0 // 毛边料总计重量
|
||||
trimmedTotalCount: 0,
|
||||
trimmedTotalWeight: 0,
|
||||
untrimmedTotalCount: 0,
|
||||
untrimmedTotalWeight: 0
|
||||
};
|
||||
|
||||
// 初始化所有宽度的数量和重量为0
|
||||
this.widthList.forEach(width => {
|
||||
row[`trimmed_${width}_count`] = 0;
|
||||
row[`trimmed_${width}_weight`] = 0;
|
||||
row[`untrimmed_${width}_count`] = 0;
|
||||
row[`untrimmed_${width}_weight`] = 0;
|
||||
// 初始化净边料分组数据
|
||||
this.trimmedWidthGroups?.forEach(group => {
|
||||
row[`trimmed_${group.key}_count`] = 0;
|
||||
row[`trimmed_${group.key}_weight`] = 0;
|
||||
});
|
||||
|
||||
// 处理净边料数据
|
||||
item.trimmedList.forEach(trimmed => {
|
||||
const widthKey = trimmed.width;
|
||||
if (this.widthList.includes(widthKey)) {
|
||||
row[`trimmed_${widthKey}_count`] = trimmed.coilCount;
|
||||
row[`trimmed_${widthKey}_weight`] = trimmed.totalWeight;
|
||||
// 累加总计
|
||||
row.trimmedTotalCount += trimmed.coilCount;
|
||||
row.trimmedTotalWeight = (Number(row.trimmedTotalWeight) + Number(trimmed.totalWeight)).toFixed(3);
|
||||
}
|
||||
// 初始化毛边料分组数据
|
||||
this.untrimmedWidthGroups?.forEach(group => {
|
||||
row[`untrimmed_${group.key}_count`] = 0;
|
||||
row[`untrimmed_${group.key}_weight`] = 0;
|
||||
});
|
||||
|
||||
// 处理毛边料数据
|
||||
item.untrimmedList.forEach(untrimmed => {
|
||||
const widthKey = untrimmed.width;
|
||||
if (this.widthList.includes(widthKey)) {
|
||||
row[`untrimmed_${widthKey}_count`] = untrimmed.coilCount;
|
||||
row[`untrimmed_${widthKey}_weight`] = untrimmed.totalWeight;
|
||||
// 累加总计
|
||||
row.untrimmedTotalCount += untrimmed.coilCount;
|
||||
row.untrimmedTotalWeight = (Number(row.untrimmedTotalWeight) + Number(untrimmed.totalWeight)).toFixed(3);
|
||||
}
|
||||
// 处理净边料数据(按分组求和)
|
||||
item.trimmedList?.forEach(trimmed => {
|
||||
const width = trimmed.width;
|
||||
const count = Number(trimmed.coilCount) || 0;
|
||||
const weight = Number(trimmed.totalWeight) || 0;
|
||||
|
||||
// 找到宽度所属的分组并累加
|
||||
this.trimmedWidthGroups?.forEach(group => {
|
||||
if (group.includesWidth(width)) {
|
||||
row[`trimmed_${group.key}_count`] += count;
|
||||
row[`trimmed_${group.key}_weight`] = (row[`trimmed_${group.key}_weight`] + weight).toFixed(3);
|
||||
}
|
||||
});
|
||||
|
||||
// 累加总计
|
||||
row.trimmedTotalCount += count;
|
||||
row.trimmedTotalWeight = (Number(row.trimmedTotalWeight) + weight).toFixed(3);
|
||||
});
|
||||
|
||||
// 处理毛边料数据(按分组求和)
|
||||
item.untrimmedList?.forEach(untrimmed => {
|
||||
const width = untrimmed.width;
|
||||
const count = Number(untrimmed.coilCount) || 0;
|
||||
const weight = Number(untrimmed.totalWeight) || 0;
|
||||
|
||||
// 找到宽度所属的分组并累加
|
||||
this.untrimmedWidthGroups?.forEach(group => {
|
||||
if (group.includesWidth(width)) {
|
||||
row[`untrimmed_${group.key}_count`] += count;
|
||||
row[`untrimmed_${group.key}_weight`] = (row[`untrimmed_${group.key}_weight`] + weight).toFixed(3);
|
||||
}
|
||||
});
|
||||
|
||||
// 累加总计
|
||||
row.untrimmedTotalCount += count;
|
||||
row.untrimmedTotalWeight = (Number(row.untrimmedTotalWeight) + weight).toFixed(3);
|
||||
});
|
||||
|
||||
return row;
|
||||
});
|
||||
},
|
||||
|
||||
// 过滤掉全0的行
|
||||
filteredTableData() {
|
||||
return this.tableData.filter(row => {
|
||||
let hasNonZeroData = false;
|
||||
|
||||
// 检查净边料总计
|
||||
if (Number(row.trimmedTotalCount) > 0 || Number(row.trimmedTotalWeight) > 0) {
|
||||
hasNonZeroData = true;
|
||||
}
|
||||
|
||||
// 检查毛边料总计
|
||||
if (Number(row.untrimmedTotalCount) > 0 || Number(row.untrimmedTotalWeight) > 0) {
|
||||
hasNonZeroData = true;
|
||||
}
|
||||
|
||||
// 检查净边料分组列
|
||||
if (!hasNonZeroData) {
|
||||
this.trimmedWidthGroups?.forEach(group => {
|
||||
if (Number(row[`trimmed_${group.key}_count`]) > 0 || Number(row[`trimmed_${group.key}_weight`]) > 0) {
|
||||
hasNonZeroData = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 检查毛边料分组列
|
||||
if (!hasNonZeroData) {
|
||||
this.untrimmedWidthGroups?.forEach(group => {
|
||||
if (Number(row[`untrimmed_${group.key}_count`]) > 0 || Number(row[`untrimmed_${group.key}_weight`]) > 0) {
|
||||
hasNonZeroData = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return hasNonZeroData;
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 合并表头的跨度方法(可选,若需要合并行/列可扩展)
|
||||
// 生成宽度分组(核心方法)
|
||||
generateWidthGroups(rawWidths) {
|
||||
const groups = [];
|
||||
const usedWidths = new Set();
|
||||
|
||||
// 遍历分组规则,匹配原始宽度
|
||||
Object.entries(this.widthGroupRules)?.forEach(([groupLabel, widthList]) => {
|
||||
// 筛选出当前分组包含的原始宽度
|
||||
const matchedWidths = rawWidths.filter(width => widthList.includes(width));
|
||||
if (matchedWidths.length === 0) return;
|
||||
|
||||
// 创建分组对象
|
||||
const groupKey = groupLabel.replace(/[^a-zA-Z0-9]/g, '_');
|
||||
groups.push({
|
||||
key: groupKey,
|
||||
label: groupLabel,
|
||||
widths: matchedWidths,
|
||||
includesWidth: function(width) {
|
||||
return this.widths.includes(width);
|
||||
}
|
||||
});
|
||||
|
||||
// 标记已使用的宽度
|
||||
matchedWidths?.forEach(width => usedWidths.add(width));
|
||||
});
|
||||
|
||||
// 处理未匹配到分组的宽度(单独成组)
|
||||
rawWidths?.forEach(width => {
|
||||
if (!usedWidths.has(width)) {
|
||||
const groupKey = width.replace(/[^a-zA-Z0-9]/g, '_');
|
||||
groups.push({
|
||||
key: groupKey,
|
||||
label: width,
|
||||
widths: [width],
|
||||
includesWidth: function(width) {
|
||||
return this.widths.includes(width);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return groups;
|
||||
},
|
||||
|
||||
// 合并表头的跨度方法
|
||||
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
|
||||
// 可根据需求实现行/列合并逻辑,例如合并重复的厚度行
|
||||
// 示例:若需合并相同厚度的行,可在此处返回 { rowspan: n, colspan: m }
|
||||
return { rowspan: 1, colspan: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,13 +51,14 @@
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
<el-button icon="el-icon-download" size="mini" @click="handleNewExport" v-if="showNewExport">导出</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8" v-if="showControl">
|
||||
<el-col :span="1.5">
|
||||
<!-- <el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
|
||||
</el-col>
|
||||
</el-col> -->
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single"
|
||||
@click="handleCheck">修正</el-button>
|
||||
@@ -73,6 +74,10 @@
|
||||
<el-button type="info" plain icon="el-icon-printer" size="mini" :disabled="multiple"
|
||||
@click="handleBatchPrintLabel">批量打印标签</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5" v-if="showOrderBy">
|
||||
<el-checkbox v-model="queryParams.orderBy" v-loading="loading" @change="getList"
|
||||
label="orderBy">按实际库区排序</el-checkbox>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
@@ -177,7 +182,8 @@
|
||||
|
||||
<el-table-column label="关联订单" align="center" prop="relatedToOrder" v-if="showRelatedToOrder" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-switch @change="handleRelatedToOrderChange(scope.row)" v-model="scope.row.isRelatedToOrder" :active-value="1" :inactive-value="0" />
|
||||
<el-switch @change="handleRelatedToOrderChange(scope.row)" v-model="scope.row.isRelatedToOrder"
|
||||
:active-value="1" :inactive-value="0" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
@@ -334,6 +340,14 @@
|
||||
<el-form-item label="长度" prop="length" v-if="showLength">
|
||||
<el-input v-model="form.length" placeholder="请输入长度" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||||
<el-input-number :controls="false" v-model="form.actualLength" placeholder="请输入实测长度" type="number"
|
||||
:step="0.01" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实测宽度(m)" prop="actualWidth">
|
||||
<el-input-number :controls="false" v-model="form.actualWidth" placeholder="请输入实测宽度" type="number"
|
||||
:step="0.01" />
|
||||
</el-form-item>
|
||||
<el-form-item label="调制度" prop="temperGrade">
|
||||
<el-input v-model="form.temperGrade" placeholder="请输入调制度" />
|
||||
</el-form-item>
|
||||
@@ -404,9 +418,10 @@ import {
|
||||
exportCoil,
|
||||
cancelExportCoil,
|
||||
checkCoilNo,
|
||||
returnCoil
|
||||
returnCoil,
|
||||
} from "@/api/wms/coil";
|
||||
import { listBoundCoil } from "@/api/wms/deliveryWaybillDetail";
|
||||
import { addPendingAction } from "@/api/wms/pendingAction";
|
||||
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
|
||||
import QRCode from "../../print/components/QRCode.vue";
|
||||
import * as XLSX from 'xlsx'
|
||||
@@ -529,6 +544,14 @@ export default {
|
||||
showRelatedToOrder: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showOrderBy: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showNewExport: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -577,6 +600,7 @@ export default {
|
||||
itemIds: undefined,
|
||||
status: undefined,
|
||||
updateTime: undefined,
|
||||
orderBy: false,
|
||||
...this.querys,
|
||||
},
|
||||
// 表单参数
|
||||
@@ -689,7 +713,9 @@ export default {
|
||||
{ label: '包装要求', prop: 'packagingRequirement' },
|
||||
{ label: '厂家', prop: 'itemManufacturer' },
|
||||
{ label: '调制度', prop: 'temperGrade' },
|
||||
{ label: '镀层种类', prop: 'coatingType' }
|
||||
{ label: '镀层种类', prop: 'coatingType' },
|
||||
{ label: '实测长度(m)', prop: 'actualLength' },
|
||||
{ label: '实测宽度(m)', prop: 'actualWidth' },
|
||||
],
|
||||
title: '详细信息'
|
||||
},
|
||||
@@ -787,8 +813,31 @@ export default {
|
||||
handlePrintLabel(row) {
|
||||
const item = row.itemType === 'product' ? row.product : row.rawMaterial;
|
||||
const itemName = row.itemType === 'product' ? item?.productName || '' : item?.rawMaterialName || '';
|
||||
|
||||
this.labelRender.type = row.itemType === 'product' ? '3' : '2';
|
||||
const itemType = row.itemType || '';
|
||||
const warehouseId = row.warehouseId || '';
|
||||
// 在镀锌颜料库的卷使用镀锌原料标签
|
||||
if (itemType == 'raw_material' && (warehouseId == '1988150263284953089' || warehouseId == '1988150487185289217')) {
|
||||
this.labelRender.type = '5';
|
||||
}
|
||||
// 脱脂原料库
|
||||
else if (itemType == 'raw_material' && (warehouseId == '1988150545175736322')) {
|
||||
this.labelRender.type = '6';
|
||||
}
|
||||
else if (itemType == 'raw_material') {
|
||||
this.labelRender.type = '2';
|
||||
} else if (itemType == 'product' && itemName == '冷硬卷') {
|
||||
this.labelRender.type = '3';
|
||||
} else if (itemType == 'product' && itemName == '热轧卷板') {
|
||||
this.labelRender.type = '3';
|
||||
} else if (itemType == 'product' && itemName == '镀锌卷') {
|
||||
this.labelRender.type = '4';
|
||||
} else if (itemType == 'product' && itemName == '冷轧卷') {
|
||||
this.labelRender.type = '3';
|
||||
} else if (itemType == 'product' && itemName == '镀铬卷') {
|
||||
this.labelRender.type = 'ge';
|
||||
} else {
|
||||
this.labelRender.type = '3';
|
||||
}
|
||||
this.labelRender.data = {
|
||||
...row,
|
||||
itemName: itemName,
|
||||
@@ -898,12 +947,6 @@ export default {
|
||||
}
|
||||
},
|
||||
handleAbnormal(row) {
|
||||
// this.$router.push({
|
||||
// path: '/quality/detail',
|
||||
// query: {
|
||||
// coilId: row.coilId,
|
||||
// }
|
||||
// })
|
||||
this.currentCoilId = row.coilId;
|
||||
this.abnormalOpen = true;
|
||||
},
|
||||
@@ -1015,11 +1058,50 @@ export default {
|
||||
handleExportCoil(row) {
|
||||
exportCoil(row.coilId).then(response => {
|
||||
this.$modal.msgSuccess("发货成功");
|
||||
// 2. 插入一条已完成的待操作记录
|
||||
addPendingAction({
|
||||
coilId: row.coilId,
|
||||
currentCoilNo: row.currentCoilNo,
|
||||
actionType: 402, // 402=发货
|
||||
actionStatus: 2, // 直接标记为完成状态
|
||||
scanTime: new Date(),
|
||||
// scanDevice: ,
|
||||
priority: 0, // 0=普通
|
||||
sourceType: 'scan',
|
||||
warehouseId: row.warehouseId,
|
||||
processTime: new Date(),
|
||||
completeTime: new Date()
|
||||
});
|
||||
this.getList();
|
||||
}).catch(error => {
|
||||
this.$modal.msgError("发货失败");
|
||||
});
|
||||
},
|
||||
async handleNewExport(row) {
|
||||
this.loading = true
|
||||
let coilIds = ''
|
||||
const query = {
|
||||
...this.queryParams,
|
||||
selectType: 'product',
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
}
|
||||
if (this.showWaybill) {
|
||||
const res = await listBoundCoil(query)
|
||||
coilIds = res.rows.map(item => item.coilId).join(',')
|
||||
this.loading = false
|
||||
this.download('/wms/materialCoil/exportDelivery', {
|
||||
coilIds,
|
||||
}, 'coil.xlsx')
|
||||
} else {
|
||||
const { rows: coils } = await listMaterialCoil(query)
|
||||
coilIds = coils.map(item => item.coilId).join(',')
|
||||
this.loading = false
|
||||
this.download('wms/materialCoil/exportAll', {
|
||||
coilIds,
|
||||
}, 'coil.xlsx')
|
||||
}
|
||||
},
|
||||
handleCheck(row) {
|
||||
this.isCheck = true;
|
||||
this.loading = true;
|
||||
@@ -1153,7 +1235,6 @@ export default {
|
||||
...this.queryParams
|
||||
}, `materialCoil_${new Date().getTime()}.xlsx`)
|
||||
},
|
||||
|
||||
/** 批量打印标签按钮 */
|
||||
handleBatchPrintLabel() {
|
||||
if (!this.ids || this.ids.length === 0) {
|
||||
|
||||
@@ -135,6 +135,14 @@
|
||||
<span class="param-label">长度:</span>
|
||||
<span class="param-value">{{ item.length }}米</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="item.actualLength">
|
||||
<span class="param-label">实测长度:</span>
|
||||
<span class="param-value">{{ item.actualLength }}米</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="item.actualWidth">
|
||||
<span class="param-label">实测宽度:</span>
|
||||
<span class="param-value">{{ item.actualWidth }}米</span>
|
||||
</div>
|
||||
<div class="param-row" v-if="item.temperGrade">
|
||||
<span class="param-label">调制度:</span>
|
||||
<span class="param-value">{{ item.temperGrade }}</span>
|
||||
@@ -199,7 +207,7 @@
|
||||
</div>
|
||||
|
||||
<div class="card-footer">
|
||||
<el-button v-if="useSpecialSplit" type="success" icon="el-icon-scissors" size="mini"
|
||||
<el-button v-if="useSpecialSplit" :style="splitButtonStyle" icon="el-icon-scissors" size="mini"
|
||||
@click="handleStartSplit(item)" :loading="buttonLoading" class="action-btn">加工</el-button>
|
||||
<el-button v-else type="primary" icon="el-icon-check" size="mini" @click="handlePickMaterial(item)"
|
||||
:loading="buttonLoading" class="action-btn">领料</el-button>
|
||||
@@ -223,7 +231,7 @@
|
||||
<div class="section-card action-section" v-if="useSpecialSplit" style="margin-bottom: 20px;"
|
||||
v-loading="stepSpilt.loading">
|
||||
<div class="section-header ">
|
||||
<h3 class="section-title">进行中的镀锌工序</h3>
|
||||
<h3 class="section-title">进行中的{{ label }}</h3>
|
||||
<el-button size="mini" icon="el-icon-refresh" @click="getStepSplitList">刷新</el-button>
|
||||
</div>
|
||||
<div v-if="stepSpilt.list.length > 0" style="display: flex; align-items: center; gap: 10px; flex-wrap: wrap;">
|
||||
@@ -298,7 +306,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-empty description="暂无进行中的镀锌工序" />
|
||||
<el-empty :description="`暂无进行中的${label}`" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -552,7 +560,7 @@ export default {
|
||||
degree: null,
|
||||
remark: null
|
||||
},
|
||||
tagSizeMap: {
|
||||
tagSizeMap: {
|
||||
'2': {
|
||||
width: 100,
|
||||
height: 80,
|
||||
@@ -577,6 +585,10 @@ export default {
|
||||
width: 180,
|
||||
height: 100,
|
||||
},
|
||||
'6': {
|
||||
width: 180,
|
||||
height: 100,
|
||||
},
|
||||
},
|
||||
stepSpilt: {
|
||||
list: [],
|
||||
@@ -598,6 +610,48 @@ export default {
|
||||
})
|
||||
return acidAction ? parseInt(acidAction.value) : null
|
||||
},
|
||||
splitButtonStyle() {
|
||||
if (this.acidRollingActionType == 501) {
|
||||
return {
|
||||
backgroundColor: '#2cb867',
|
||||
border: '1px solid #2cb867',
|
||||
color: '#111'
|
||||
}
|
||||
} else if (this.acidRollingActionType == 502) {
|
||||
return {
|
||||
backgroundColor: 'purple',
|
||||
border: '1px solid purple',
|
||||
color: '#fff'
|
||||
}
|
||||
} else if (this.acidRollingActionType == 503) {
|
||||
return {
|
||||
backgroundColor: '#f56c6c',
|
||||
border: '1px solid #f56c6c',
|
||||
color: '#fff'
|
||||
}
|
||||
} else if (this.acidRollingActionType == 504) {
|
||||
return {
|
||||
backgroundColor: 'orange',
|
||||
border: '1px solid orange',
|
||||
color: '#111'
|
||||
}
|
||||
} else if (this.acidRollingActionType == 505) {
|
||||
return {
|
||||
// 青色
|
||||
backgroundColor: 'blue',
|
||||
border: '1px solid blue',
|
||||
color: '#fff'
|
||||
}
|
||||
} else if (this.acidRollingActionType == 506) {
|
||||
return {
|
||||
backgroundColor: '#2bf',
|
||||
border: '1px solid #2bf',
|
||||
color: '#fff'
|
||||
}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// 监听字典数据加载,当acidRollingActionType有值时自动加载待操作列表
|
||||
@@ -623,9 +677,12 @@ export default {
|
||||
},
|
||||
currentTab: {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
if (newVal && newVal != 0) {
|
||||
this.materialQueryParams.warehouseId = newVal
|
||||
} else {
|
||||
this.materialQueryParams.warehouseId = ''
|
||||
}
|
||||
|
||||
this.getMaterialCoil()
|
||||
},
|
||||
immediate: true
|
||||
@@ -639,9 +696,11 @@ export default {
|
||||
if (this.acidRollingActionType) {
|
||||
this.actionQueryParams.actionType = this.acidRollingActionType
|
||||
this.getPendingAction()
|
||||
if (this.useSpecialSplit) {
|
||||
this.getStepSplitList()
|
||||
}
|
||||
}
|
||||
})
|
||||
this.getStepSplitList()
|
||||
},
|
||||
mounted() {
|
||||
// 确保在mounted时也尝试加载(字典数据可能此时才加载完成)
|
||||
@@ -661,9 +720,14 @@ export default {
|
||||
const itemType = row.itemType || '';
|
||||
const warehouseId = row.warehouseId || '';
|
||||
// 在镀锌颜料库的卷使用镀锌原料标签
|
||||
if (itemType == 'raw_material' && warehouseId == '1988150263284953089') {
|
||||
if (itemType == 'raw_material' && (warehouseId == '1988150263284953089' || warehouseId == '1988150487185289217')) {
|
||||
this.labelRender.type = '5';
|
||||
} else if (itemType == 'raw_material') {
|
||||
}
|
||||
// 脱脂原料库
|
||||
else if (itemType == 'raw_material' && (warehouseId == '1988150545175736322')) {
|
||||
this.labelRender.type = '6';
|
||||
}
|
||||
else if (itemType == 'raw_material') {
|
||||
this.labelRender.type = '2';
|
||||
} else if (itemType == 'product' && itemName == '冷硬卷') {
|
||||
this.labelRender.type = '3';
|
||||
@@ -690,7 +754,11 @@ export default {
|
||||
|
||||
getStepSplitList() {
|
||||
this.stepSpilt.loading = true
|
||||
listPendingAction({ actionType: 501, actionStatus: 0 }).then(response => {
|
||||
if (!this.acidRollingActionType) {
|
||||
this.$message.error(`未找到${this.label}操作类型,请检查字典配置`)
|
||||
return
|
||||
}
|
||||
listPendingAction({ actionType: this.acidRollingActionType, actionStatus: 0 }).then(response => {
|
||||
this.stepSpilt.list = response.rows || []
|
||||
this.stepSpilt.loading = false
|
||||
})
|
||||
@@ -955,7 +1023,7 @@ export default {
|
||||
try {
|
||||
await this.$modal.confirm('是否确认领料开始分步加工操作?')
|
||||
this.stepSpilt.loading = true
|
||||
await startSpecialSplit(row.coilId);
|
||||
await startSpecialSplit(row.coilId, this.acidRollingActionType);
|
||||
// await addPendingAction({
|
||||
// coilId: row.coilId,
|
||||
// currentCoilNo: row.currentCoilNo,
|
||||
|
||||
@@ -135,6 +135,14 @@
|
||||
<el-form-item label="长度" prop="length">
|
||||
<el-input v-model="splitForm.length" placeholder="请输入长度" type="number" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||||
<el-input-number :controls="false" v-model="splitForm.actualLength" placeholder="请输入实测长度" type="number"
|
||||
:step="0.01" />
|
||||
</el-form-item>
|
||||
<el-form-item label="实测宽度(m)" prop="actualWidth">
|
||||
<el-input-number :controls="false" v-model="splitForm.actualWidth" placeholder="请输入实测宽度" type="number"
|
||||
:step="0.01" />
|
||||
</el-form-item>
|
||||
<el-form-item label="调制度" prop="temperGrade">
|
||||
<el-input v-model="splitForm.temperGrade" placeholder="请输入调制度" />
|
||||
</el-form-item>
|
||||
@@ -251,6 +259,8 @@ export default {
|
||||
grossWeight: '',
|
||||
netWeight: '',
|
||||
length: '',
|
||||
actualLength: '',
|
||||
actualWidth: '',
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
remark: '',
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" class="add-btn">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button type="primary" plain icon="el-icon-refresh" size="mini" @click="getList" class="add-btn">
|
||||
刷新
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 自定义列表(替代表格) -->
|
||||
@@ -32,11 +35,16 @@
|
||||
<!-- 内容区域 -->
|
||||
<div class="item-content">
|
||||
<el-tag type="info">{{ item.statType }}</el-tag>
|
||||
<div style="display: flex;">
|
||||
<div style="display: flex; flex-direction: column;">
|
||||
<!-- 双击后变成输入框,输入框失去焦点触发更新 -->
|
||||
<div class="value">{{ item.title }}</div>
|
||||
<!-- <span class="value">{{ item.createTime }}</span>
|
||||
<span class="value">{{ item.createBy }}</span> -->
|
||||
<div class="value">
|
||||
{{ item.title }}
|
||||
<el-icons title="本次汇总保存了汇总时使用的钢卷明细" v-if="item.attachmentInfo" class="el-icon-link"></el-icons>
|
||||
</div>
|
||||
<div>
|
||||
<span class="value" style="margin-right: 5px;">{{ item.createBy }}</span>
|
||||
<span class="value">{{ item.createTime }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -55,12 +63,10 @@
|
||||
|
||||
<!-- 添加或修改钢卷生产统计对话框 -->
|
||||
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<div v-for="item in tableType" :key="item.statType" @click="handleCreate(item)" class="type-item">
|
||||
<div class="type-title">{{ item.title }}</div>
|
||||
<div class="type-desc">{{ item.description }}</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<div v-for="item in tableType" :key="item.statType" @click="handleCreate(item)" class="type-item">
|
||||
<div class="type-title">{{ item.title }}</div>
|
||||
<div class="type-desc">{{ item.description }}</div>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
@@ -263,6 +269,7 @@ export default {
|
||||
.item-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,32 +5,53 @@
|
||||
<LeftList ref="leftList" @add="handleAdd" @select="handleSelect" />
|
||||
</el-col>
|
||||
|
||||
<el-col :span="18">
|
||||
<el-col :span="18" style="position: relative;">
|
||||
<ul style="float: right; position: absolute; right: 0; top: 0; z-index: 100;">
|
||||
<li v-show="currentRow.attachmentInfo" @click="handleDownload(currentRow)"><el-button
|
||||
icon="el-icon-download">下载明细</el-button></li>
|
||||
</ul>
|
||||
<div style="height: calc(100vh - 124px); overflow-y: scroll; overflow-x: hidden;">
|
||||
<div v-if="currentRow.summaryId">
|
||||
<Preview :data="currentRow.statJson" :statType="currentRow.statType" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>钢卷生产统计详情</div>
|
||||
<div>
|
||||
<el-empty description="请点击左侧列表查看或创建透视表" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-dialog v-loading="previewLoading" title="效果预览" :visible.sync="previewOpen" width="100vw" fullscreen append-to-body>
|
||||
<Preview :data="liveData" :statType="form.statType" />
|
||||
<el-button type="primary" @click="handleSave">保存</el-button>
|
||||
<el-dialog v-loading="previewLoading" title="效果预览" :visible.sync="previewOpen" width="80vw" append-to-body>
|
||||
<div>
|
||||
<el-button type="primary" @click="handleSave" :loading="buttonLoading">保存</el-button>
|
||||
<!-- <el-button type="primary" @click="handleDetail" :loading="buttonLoading">查看明细</el-button> -->
|
||||
<el-checkbox style="margin-left: 10px;" v-model="saveDetail"
|
||||
label="orderBy">保存透视表时保存明细,勾选后在保存时会消耗更长的时间且会占用更多内存和存储</el-checkbox>
|
||||
</div>
|
||||
<div style="height: calc(100vh - 300px); overflow-y: scroll; overflow-x: hidden;">
|
||||
<div v-if="liveData">
|
||||
<Preview :data="liveData" :statType="form.statType" />
|
||||
</div>
|
||||
<div v-else>
|
||||
<div>
|
||||
<el-empty description="未知的透视表" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getCoilStatisticsSummary, delCoilStatisticsSummary, addCoilStatisticsSummary, updateCoilStatisticsSummary } from "@/api/wms/coilStatisticsSummary";
|
||||
import { getCoilStatisticsSummary, delCoilStatisticsSummary, addCoilStatisticsSummary, updateCoilStatisticsSummary, checkCoilStatisticsSummaryExist } from "@/api/wms/coilStatisticsSummary";
|
||||
import LeftList from "./components/LeftList.vue";
|
||||
import Preview from "@/views/wms/coil/panels/Perspective/index.vue";
|
||||
|
||||
import { listRawMaterialPerspective } from "@/api/wms/rawMaterial";
|
||||
import { listCoilTrimStatistics, categoryWidthStatistics } from "@/api/wms/coil";
|
||||
import { uploadFile } from "@/api/system/oss";
|
||||
import { listCoilTrimStatistics, categoryWidthStatistics, listMaterialCoil, exportCoilWithAll } from "@/api/wms/coil";
|
||||
|
||||
export default {
|
||||
name: "CoilStatisticsSummary",
|
||||
@@ -67,6 +88,7 @@ export default {
|
||||
title: undefined,
|
||||
statType: undefined,
|
||||
},
|
||||
saveDetail: false,
|
||||
// 表单参数
|
||||
form: {},
|
||||
// 表单校验
|
||||
@@ -78,19 +100,7 @@ export default {
|
||||
currentRow: {},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
/** 查询钢卷生产统计列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listCoilStatisticsSummary(this.queryParams).then(response => {
|
||||
this.coilStatisticsSummaryList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 取消按钮
|
||||
cancel() {
|
||||
this.open = false;
|
||||
@@ -130,9 +140,39 @@ export default {
|
||||
};
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd(form) {
|
||||
this.previewOpen = true;
|
||||
async handleAdd(form) {
|
||||
this.form = form;
|
||||
// 先检查今天是否已经创建过该类型的透视表
|
||||
const {data: existingSummary} = await checkCoilStatisticsSummaryExist(form.statType);
|
||||
// 如果已经创建过
|
||||
if (existingSummary) {
|
||||
// 先提示是否继续创建
|
||||
try {
|
||||
await this.$confirm('该类型已存在透视表,是否继续创建?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
});
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
// 如果要继续创建,则提示是否要覆盖已经存在的透视表
|
||||
try {
|
||||
await this.$confirm('是否覆盖已存在的透视表?', '提示', {
|
||||
confirmButtonText: '删除并重新创建',
|
||||
cancelButtonText: '保留已有透视表',
|
||||
type: 'warning'
|
||||
});
|
||||
delCoilStatisticsSummary(existingSummary).then(() => {
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
this.getList();
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
this.previewOpen = true;
|
||||
|
||||
if (form.statType == '热轧原料') {
|
||||
this.previewLoading = true;
|
||||
listRawMaterialPerspective().then(response => {
|
||||
@@ -183,19 +223,97 @@ export default {
|
||||
}
|
||||
this.previewLoading = false;
|
||||
},
|
||||
handleSave() {
|
||||
addCoilStatisticsSummary({
|
||||
...this.form,
|
||||
statJson: JSON.stringify(this.liveData)
|
||||
}).then(response => {
|
||||
async handleSave() {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: '保存中...',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
try {
|
||||
this.buttonLoading = true;
|
||||
|
||||
const { data: summary } = await addCoilStatisticsSummary({
|
||||
...this.form,
|
||||
statJson: JSON.stringify(this.liveData)
|
||||
})
|
||||
|
||||
if (this.saveDetail) {
|
||||
// 获取原始数据,组装coilIds,
|
||||
let coilIds = ''
|
||||
if (this.form.statType == '热轧原料') {
|
||||
const { rows: coils } = await listMaterialCoil({
|
||||
pageNum: 1,
|
||||
pageSize: 9999,
|
||||
selectType: 'raw_material',
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
itemName: '热轧卷板',
|
||||
itemType: 'raw_material',
|
||||
})
|
||||
coilIds = coils.map(item => item.coilId).join(',')
|
||||
} else if (this.form.statType == '冷硬卷板') {
|
||||
const { rows: coils1 } = await listMaterialCoil({
|
||||
pageNum: 1,
|
||||
pageSize: 9999,
|
||||
selectType: 'raw_material',
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
itemName: '冷硬卷',
|
||||
itemType: 'raw_material',
|
||||
})
|
||||
const { rows: coils2 } = await listMaterialCoil({
|
||||
pageNum: 1,
|
||||
pageSize: 9999,
|
||||
selectType: 'product',
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
itemName: '冷硬卷',
|
||||
itemType: 'product',
|
||||
})
|
||||
coilIds = coils1.concat(coils2).map(item => item.coilId).join(',')
|
||||
} else if (this.form.statType == '汇总') {
|
||||
const { rows: coils } = await listMaterialCoil({
|
||||
pageNum: 1,
|
||||
pageSize: 9999,
|
||||
dataType: 1,
|
||||
status: 0,
|
||||
})
|
||||
coilIds = coils.map(item => item.coilId).join(',')
|
||||
}
|
||||
|
||||
// 使用exportCoilWithAll接口传入coilIds获取二进制文件数据
|
||||
const response = await exportCoilWithAll({
|
||||
coilIds: coilIds,
|
||||
})
|
||||
const file = new Blob([response], { type: 'application/vnd.ms-excel' })
|
||||
const fileName = this.form.statType + '明细.xlsx'
|
||||
// 通过new File构建出excel文件
|
||||
const excelFile = new File([file], fileName, { type: 'application/vnd.ms-excel' })
|
||||
|
||||
console.log(excelFile)
|
||||
// 上传文件到minio
|
||||
const uploadResponse = await uploadFile(excelFile)
|
||||
console.log(uploadResponse)
|
||||
|
||||
// 关联附件信息
|
||||
await updateCoilStatisticsSummary({
|
||||
...summary,
|
||||
attachmentInfo: uploadResponse.data.ossId,
|
||||
});
|
||||
}
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
this.open = false;
|
||||
this.previewOpen = false;
|
||||
this.liveData = [];
|
||||
this.form = {};
|
||||
this.$refs.leftList.getList();
|
||||
}).finally(() => {
|
||||
} finally {
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
loading.close();
|
||||
}
|
||||
},
|
||||
handleDownload(row) {
|
||||
this.$download.oss(row.attachmentInfo)
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
|
||||
@@ -29,7 +29,8 @@ export default {
|
||||
showStatus: true,
|
||||
hideType: true,
|
||||
showLength: true,
|
||||
canExportAll: true
|
||||
canExportAll: true,
|
||||
showOrderBy: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +193,18 @@
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||||
<el-input-number :controls="false" v-model="item.actualLength" placeholder="请输入实测长度" type="number"
|
||||
:step="0.01" :disabled="readonly">
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="实测宽度(m)" prop="actualWidth">
|
||||
<el-input-number :controls="false" v-model="item.actualWidth" placeholder="请输入实测宽度" type="number"
|
||||
:step="0.01" :disabled="readonly">
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="调制度" prop="temperGrade">
|
||||
<el-input v-model="item.temperGrade" placeholder="请输入调制度" />
|
||||
</el-form-item>
|
||||
@@ -275,6 +287,8 @@ export default {
|
||||
length: undefined,
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
actualLength: undefined,
|
||||
actualWidth: undefined,
|
||||
}
|
||||
],
|
||||
loading: false,
|
||||
@@ -459,6 +473,8 @@ export default {
|
||||
trimmingRequirement: '',
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
actualLength: undefined,
|
||||
actualWidth: undefined,
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -157,14 +157,21 @@
|
||||
|
||||
<el-form-item label="净重(t)" prop="netWeight">
|
||||
<el-input-number :precision="3" :controls="false" v-model="updateForm.netWeight" placeholder="请输入净重"
|
||||
type="number" :step="0.01">
|
||||
type="number" :step="0.001">
|
||||
<template slot="append">吨</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="长度(m)" prop="length">
|
||||
<el-input-number :controls="false" v-model="updateForm.length" placeholder="请输入长度" type="number"
|
||||
:step="0.01">
|
||||
<el-form-item label="实测长度(m)" prop="actualLength">
|
||||
<el-input-number :controls="false" v-model="updateForm.actualLength" placeholder="请输入实测长度" type="number"
|
||||
:step="0.001">
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="实测宽度(m)" prop="actualWidth">
|
||||
<el-input-number :controls="false" v-model="updateForm.actualWidth" placeholder="请输入实测宽度" type="number"
|
||||
:step="0.001">
|
||||
<template slot="append">米</template>
|
||||
</el-input-number>
|
||||
</el-form-item>
|
||||
@@ -283,6 +290,8 @@ export default {
|
||||
length: undefined,
|
||||
temperGrade: '',
|
||||
coatingType: '',
|
||||
actualLength: undefined,
|
||||
actualWidth: undefined,
|
||||
},
|
||||
rules: {
|
||||
currentCoilNo: [
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
|
||||
:hideType="hideType" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="次品" name="third">
|
||||
<BasePage :qrcode="qrcode" :querys="query3" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
|
||||
:hideType="hideType" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
||||
@@ -34,6 +38,10 @@ export default {
|
||||
nextWarehouseId: '2019583429955104769', // 废品仓
|
||||
// materialType: '废品'
|
||||
},
|
||||
query3: {
|
||||
dataType: 1,
|
||||
OnlyScrap: true,
|
||||
},
|
||||
hideWarehouseQuery: true,
|
||||
showAbnormal: true,
|
||||
labelType: '2',
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<BasePage
|
||||
:qrcode="qrcode"
|
||||
:showWaybill="showWaybill"
|
||||
:showNewExport="showNewExport"
|
||||
:querys="querys" :labelType="labelType" :showStatus="showStatus" :hideType="hideType" :showControl="showControl" :showExportTime="showExportTime" />
|
||||
</template>
|
||||
|
||||
@@ -27,6 +28,7 @@ export default {
|
||||
hideType: false,
|
||||
showExportTime: false,
|
||||
showWaybill: true,
|
||||
showNewExport: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
klp-ui/src/views/wms/delivery/canuse/index.vue
Normal file
38
klp-ui/src/views/wms/delivery/canuse/index.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<BasePage :qrcode="qrcode"
|
||||
:querys="querys"
|
||||
:labelType="labelType"
|
||||
:showStatus="showStatus"
|
||||
:hideType="hideType"
|
||||
:showLength="showLength"
|
||||
:canExportAll="canExportAll"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasePage from '@/views/wms/coil/panels/base.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BasePage
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
qrcode: false,
|
||||
querys: {
|
||||
dataType: 1,
|
||||
materialType: '成品',
|
||||
itemType: 'product',
|
||||
status: 0,
|
||||
orderBy: true
|
||||
},
|
||||
labelType: '3',
|
||||
showStatus: true,
|
||||
hideType: true,
|
||||
showLength: true,
|
||||
canExportAll: true,
|
||||
showOrderBy: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -34,8 +34,8 @@
|
||||
<div class="editable-input transparent-input" contenteditable>{{ localWaybill.principal }}</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<span class="label">电话:</span>
|
||||
<div class="editable-input transparent-input" contenteditable>{{ localWaybill.principalPhone }}</div>
|
||||
<span class="label">订单号:</span>
|
||||
<div class="editable-input transparent-input" contenteditable>{{ localWaybill.orderId ? localWaybill.orderCode : localWaybill.principalPhone }}</div>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<span class="label">合同号:</span>
|
||||
@@ -239,6 +239,8 @@ export default {
|
||||
handler(newVal) {
|
||||
if (newVal) {
|
||||
this.localWaybill = {
|
||||
orderId: newVal.orderId || '',
|
||||
orderCode: newVal.orderCode || '',
|
||||
consigneeUnit: newVal.consigneeUnit || '',
|
||||
senderUnit: newVal.senderUnit || '',
|
||||
deliveryYear: this.getYearFromDate(newVal.deliveryTime) || '',
|
||||
@@ -499,12 +501,12 @@ export default {
|
||||
[
|
||||
`负责人:${this.localWaybill.principal || ''}`,
|
||||
undefined, undefined,
|
||||
`电话:${this.localWaybill.principalPhone || ''}`,
|
||||
`订单号:${this.localWaybill.orderId ? this.localWaybill.orderCode : this.localWaybill.principalPhone || ''}`,
|
||||
undefined, undefined,
|
||||
`合同号:${this.localWaybill.contractCode || ''}`,
|
||||
undefined, undefined,
|
||||
`车牌:${this.localWaybill.licensePlate || ''}`
|
||||
], // 负责人/电话/合同号/车牌行(r=2)
|
||||
], // 负责人/订单号/合同号/车牌行(r=2)
|
||||
["品名", '切边', '包装', '仓库位置', '结算', '原料厂家', '卷号', '规格', '材质', '重量(t)', '单价', '备注'], // 表格表头(r=3)
|
||||
];
|
||||
|
||||
@@ -558,7 +560,7 @@ export default {
|
||||
{ s: { c: 4, r: headerRow1Idx }, e: { c: 7, r: headerRow1Idx } }, // 日期(E2-H2)
|
||||
{ s: { c: 8, r: headerRow1Idx }, e: { c: 11, r: headerRow1Idx } }, // 发货单位(I2-L2)
|
||||
{ s: { c: 0, r: headerRow2Idx }, e: { c: 2, r: headerRow2Idx } }, // 负责人(A3-C3)
|
||||
{ s: { c: 3, r: headerRow2Idx }, e: { c: 5, r: headerRow2Idx } }, // 电话(D3-F3)
|
||||
{ s: { c: 3, r: headerRow2Idx }, e: { c: 5, r: headerRow2Idx } }, // 订单号(D3-F3)
|
||||
{ s: { c: 6, r: headerRow2Idx }, e: { c: 8, r: headerRow2Idx } }, // 合同号(G3-I3)
|
||||
{ s: { c: 9, r: headerRow2Idx }, e: { c: 11, r: headerRow2Idx } }, // 车牌(J3-L3)
|
||||
{ s: { c: 0, r: remarkRowIdx }, e: { c: 11, r: remarkRowIdx } }, // 备注跨列合并(A*_L*)
|
||||
@@ -747,9 +749,9 @@ export default {
|
||||
date: `${this.localWaybill.deliveryYear || ''}年${this.localWaybill.deliveryMonth || ''}月${this.localWaybill.deliveryDay || ''}日`,
|
||||
sender: `发货单位:${this.localWaybill.senderUnit || ''}`
|
||||
};
|
||||
const header2 = { // 负责人+电话+合同号+车牌
|
||||
const header2 = { // 负责人+订单号+合同号+车牌
|
||||
principal: `负责人:${this.localWaybill.principal || ''}`,
|
||||
phone: `电话:${this.localWaybill.principalPhone || ''}`,
|
||||
phone: `订单号:${this.localWaybill.orderId ? this.localWaybill.orderCode : this.localWaybill.principalPhone || ''}`,
|
||||
contract: `合同号:${this.localWaybill.contractCode || ''}`,
|
||||
license: `车牌:${this.localWaybill.licensePlate || ''}`
|
||||
};
|
||||
@@ -797,7 +799,7 @@ export default {
|
||||
worksheet.getCell(`G${rowIdx}`).value = header2.contract;
|
||||
worksheet.getCell(`J${rowIdx}`).value = header2.license;
|
||||
worksheet.mergeCells(`A${rowIdx}:C${rowIdx}`); // 负责人:A3-C3
|
||||
worksheet.mergeCells(`D${rowIdx}:F${rowIdx}`); // 电话:D3-F3
|
||||
worksheet.mergeCells(`D${rowIdx}:F${rowIdx}`); // 订单号:D3-F3
|
||||
worksheet.mergeCells(`G${rowIdx}:I${rowIdx}`); // 合同号:G3-I3
|
||||
worksheet.mergeCells(`J${rowIdx}:L${rowIdx}`); // 车牌:J3-L3
|
||||
// 3.4 表格表头(第4行)
|
||||
|
||||
1391
klp-ui/src/views/wms/delivery/components/wayBill2.vue
Normal file
1391
klp-ui/src/views/wms/delivery/components/wayBill2.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -43,13 +43,20 @@
|
||||
<el-table-column label="车牌" align="center" prop="licensePlate" width="100" />
|
||||
<el-table-column label="收货单位" align="center" prop="consigneeUnit" />
|
||||
<!-- <el-table-column label="发货单位" align="center" prop="senderUnit" /> -->
|
||||
<el-table-column label="订单编号" align="center" prop="orderNo" />
|
||||
<el-table-column label="订单编号" align="center" prop="orderNo">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.orderId">{{ scope.row.orderCode }}</span>
|
||||
<span v-else>{{ scope.row.principalPhone }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="发货时间" align="center" prop="deliveryTime" width="100">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.deliveryTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="负责人" align="center" prop="principal" width="60" />
|
||||
<el-table-column label="备注" align="center" prop="remark" width="100" show-overflow-tooltip/>
|
||||
|
||||
<!-- <el-table-column label="负责人电话" align="center" prop="principalPhone" width="100" /> -->
|
||||
<el-table-column label="完成状态" align="center" prop="status" width="120">
|
||||
<template slot-scope="scope">
|
||||
@@ -65,6 +72,8 @@
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" type="text" icon="el-icon-view"
|
||||
@click.stop="handlePrint(scope.row)">打印发货单</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-view"
|
||||
@click.stop="handlePrintSimple(scope.row)">简单打印</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-copy"
|
||||
@click.stop="handleCopy(scope.row)">复制新增</el-button>
|
||||
<el-button size="mini" type="text" icon="el-icon-edit" :disabled="scope.row.status === 1"
|
||||
@@ -109,9 +118,12 @@
|
||||
<el-form-item label="负责人" prop="principal">
|
||||
<el-input v-model="form.principal" placeholder="请输入负责人" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="负责人电话" prop="principalPhone">
|
||||
<el-input v-model="form.principalPhone" placeholder="请输入负责人电话" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="订单编号" prop="principalPhone" v-if="!form.orderId">
|
||||
<el-input v-model="form.principalPhone" placeholder="请输入订单编号"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="订单编号" prop="principalPhone" v-else title="当前发货单已绑定订单">
|
||||
<el-input v-model="form.orderCode" placeholder="请输入订单编号" readonly disabled/>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
@@ -124,7 +136,8 @@
|
||||
|
||||
<!-- 打印发货单对话框 -->
|
||||
<el-dialog title="打印发货单" :visible.sync="printDialogVisible" width="1000px" append-to-body center>
|
||||
<WayBill :waybill="currentWaybill" :waybillDetails="currentWaybillDetails" />
|
||||
<WayBill v-if="printType === 0" :waybill="currentWaybill" :waybillDetails="currentWaybillDetails" />
|
||||
<WayBill2 v-else :waybill="currentWaybill" :waybillDetails="currentWaybillDetails" />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
@@ -138,6 +151,8 @@ import MemoInput from "@/components/MemoInput";
|
||||
import DeliveryWaybillDetail from "../components/detailTable.vue";
|
||||
import WayBill from "../components/wayBill.vue";
|
||||
import PlanList from "../components/planList.vue";
|
||||
import WayBill2 from "../components/wayBill2.vue";
|
||||
|
||||
|
||||
export default {
|
||||
name: "DeliveryWaybill",
|
||||
@@ -145,7 +160,8 @@ export default {
|
||||
MemoInput,
|
||||
DeliveryWaybillDetail,
|
||||
WayBill,
|
||||
PlanList
|
||||
PlanList,
|
||||
WayBill2
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -172,6 +188,8 @@ export default {
|
||||
currentWaybillDetails: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
// 打印类型
|
||||
printType: 0,
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 查询参数
|
||||
@@ -338,7 +356,10 @@ export default {
|
||||
const waybillId = row.waybillId || this.ids
|
||||
getDeliveryWaybill(waybillId).then(response => {
|
||||
this.loading = false;
|
||||
this.form = response.data;
|
||||
this.form = {
|
||||
...response.data,
|
||||
orderCode: row.orderCode
|
||||
};
|
||||
this.open = true;
|
||||
this.title = "修改发货单";
|
||||
});
|
||||
@@ -409,6 +430,65 @@ export default {
|
||||
/** 打印发货单 */
|
||||
handlePrint(row) {
|
||||
this.loading = true;
|
||||
this.printType = 0;
|
||||
// 获取发货单明细
|
||||
listDeliveryWaybillDetail({
|
||||
waybillId: row.waybillId,
|
||||
pageNum: 1,
|
||||
pageSize: 1000 // 获取所有明细
|
||||
}).then(response => {
|
||||
// 处理字段映射,确保与wayBill组件使用的字段名一致
|
||||
this.currentWaybillDetails = response.rows.map(item => ({
|
||||
coilId: item.coilId,
|
||||
productName: item.productName,
|
||||
edgeType: item.edgeType,
|
||||
packageType: item.packaging, // 映射packaging到packageType
|
||||
settlementType: item.settlementType,
|
||||
rawMaterialFactory: item.rawMaterialFactory,
|
||||
coilNumber: item.coilNo, // 映射coilNo到coilNumber
|
||||
specification: item.specification,
|
||||
material: item.material,
|
||||
quantity: item.quantity,
|
||||
weight: item.weight,
|
||||
unitPrice: item.unitPrice || '',
|
||||
// 单价为空时,显示为空字符串
|
||||
remark: item.remark
|
||||
}));
|
||||
const coils = this.currentWaybillDetails.map(item => item.coilId).join(',');
|
||||
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 = {
|
||||
...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.loading = false;
|
||||
|
||||
}).catch(error => {
|
||||
console.error('获取发货单明细失败:', error);
|
||||
this.$modal.msgError('获取发货单明细失败');
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 打印发货单 */
|
||||
handlePrintSimple(row) {
|
||||
this.loading = true;
|
||||
this.printType = 1;
|
||||
// 获取发货单明细
|
||||
listDeliveryWaybillDetail({
|
||||
waybillId: row.waybillId,
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</template>
|
||||
<!-- 左侧是新增表单 -->
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
|
||||
<el-form-item label="审批部门" prop="deptId">
|
||||
<el-form-item v-if="!form.outId" label="审批部门" prop="deptId">
|
||||
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="getDeptLeader">
|
||||
<el-option v-for="item in deptOptions" :key="item.deptId"
|
||||
:label="item.deptName + '(' + (item.leaderNickName || '无负责人') + ')'" :value="item.deptId"></el-option>
|
||||
@@ -63,13 +63,13 @@
|
||||
<el-button style="float: right;" icon="el-icon-refresh" @click="getList">刷新</el-button>
|
||||
</template>
|
||||
<el-table v-loading="loading" :data="leaveRequestList">
|
||||
<!-- <el-table-column prop="approvalStatus" label="审批状态" align="center">
|
||||
<el-table-column prop="approvalStatus" label="审批状态" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getStatusTagType(scope.row.approvalStatus)">
|
||||
{{ getStatusText(scope.row.approvalStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table-column>
|
||||
<el-table-column label="外出类型" align="center" prop="outType">
|
||||
<template slot-scope="scope">
|
||||
<dict-tag :options="dict.type.hrm_out_type" :value="scope.row.outType" />
|
||||
@@ -104,8 +104,8 @@
|
||||
@click="handlePrint(scope.row)">打印</el-button>
|
||||
<el-button icon="el-icon-edit" size="mini" @click="handleEdit(scope.row)"
|
||||
v-if="scope.row.approvalStatus === '待审批'">修改</el-button>
|
||||
<!-- <el-button icon="el-icon-delete" size="mini" @click="handleWithdraw(scope.row)"
|
||||
v-if="scope.row.approvalStatus === '待审批'">撤回</el-button> -->
|
||||
<el-button icon="el-icon-delete" size="mini" @click="handleWithdraw(scope.row)"
|
||||
v-if="scope.row.approvalStatus === '待审批'">撤回</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
<script>
|
||||
import { getOutRequest, addOutRequest, updateOutRequest } from "@/api/wms/outRequest";
|
||||
import { listApproval, updateApproval } from "@/api/wms/approval"
|
||||
import { listApproval, updateApproval, withdrawApproval } from "@/api/wms/approval"
|
||||
import { listDept } from "@/api/wms/dept"
|
||||
import FileUpload from '@/components/FileUpload'
|
||||
import EmployeeSelector from '@/components/EmployeeSelector'
|
||||
@@ -324,10 +324,8 @@ export default {
|
||||
handleWithdraw(row) {
|
||||
this.$modal.confirm('是否确认撤回外出申请编号为"' + row.applyId + '"的数据项?').then(() => {
|
||||
this.loading = true;
|
||||
return updateApproval({
|
||||
approvalId: row.approvalId,
|
||||
approvalStatus: '已撤销'
|
||||
});
|
||||
// 撤销审批
|
||||
return withdrawApproval(row.approvalId)
|
||||
}).then(() => {
|
||||
this.loading = false;
|
||||
this.getList();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</template>
|
||||
<!-- 左侧是新增表单 -->
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px" v-loading="loading">
|
||||
<el-form-item label="审批部门" prop="deptId">
|
||||
<el-form-item label="审批部门" prop="deptId" v-if="!form.leaveId">
|
||||
<el-select v-model="form.deptId" placeholder="请选择审批部门" filterable @change="getDeptLeader">
|
||||
<el-option v-for="item in deptOptions" :key="item.deptId"
|
||||
:label="item.deptName + '(' + (item.leaderNickName || '无负责人') + ')'" :value="item.deptId"></el-option>
|
||||
@@ -29,14 +29,8 @@
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||
<span style="font-weight: 600;">请假时段 {{ index + 1 }}</span>
|
||||
<!-- 只有多行时显示删除按钮 -->
|
||||
<el-button
|
||||
v-if="form.list.length > 1"
|
||||
type="text"
|
||||
icon="el-icon-delete"
|
||||
size="mini"
|
||||
@click="removeLeaveItem(index)"
|
||||
style="color: #f56c6c;"
|
||||
>删除</el-button>
|
||||
<el-button v-if="form.list.length > 1" type="text" icon="el-icon-delete" size="mini"
|
||||
@click="removeLeaveItem(index)" style="color: #f56c6c;">删除</el-button>
|
||||
</div>
|
||||
<!-- 注意:prop需要指定数组索引,支持嵌套校验 -->
|
||||
<el-form-item label="开始时间" :prop="`list[${index}].startTime`" :rules="rules.listItem.startTime">
|
||||
@@ -79,7 +73,9 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="text-align: center;">
|
||||
<el-button type="primary" @click="handleSubmit" v-loading="buttonLoading">{{ form.leaveId ? '更新申请' : '批量提交申请' }}</el-button>
|
||||
<el-button type="primary" @click="handleSubmit" v-loading="buttonLoading">{{ form.leaveId ? '更新申请' :
|
||||
'批量提交申请'
|
||||
}}</el-button>
|
||||
<el-button @click="handleReset">重置表单</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -107,7 +103,8 @@
|
||||
<el-table-column label="审批情况" align="center" prop="approverName">
|
||||
<template slot-scope="scope">
|
||||
<!-- 每行一个,不要出现换行,将英文映射成中文 -->
|
||||
<el-tag v-for="task in scope.row.tasks" :key="task.taskId" :type="getTaskStatusTagType(task.taskStatus)" style="margin-right: 8px;">
|
||||
<el-tag v-for="task in scope.row.tasks" :key="task.taskId" :type="getTaskStatusTagType(task.taskStatus)"
|
||||
style="margin-right: 8px;">
|
||||
<!-- taskStatus包括pending, approved, rejected, 根据状态设置不同的标签类型 -->
|
||||
{{ task.approverName }} {{ getTaskStatusText(task.taskStatus) }}
|
||||
</el-tag>
|
||||
@@ -133,7 +130,7 @@
|
||||
<el-table-column label="操作" align="center" width="160">
|
||||
<template slot-scope="scope" v-if="scope.row.approvalStatus === '待审批'">
|
||||
<el-button icon="el-icon-edit" size="mini" @click="handleEdit(scope.row)">修改</el-button>
|
||||
<!-- <el-button icon="el-icon-delete" size="mini" @click="handleWithdraw(scope.row)">撤回</el-button> -->
|
||||
<el-button icon="el-icon-delete" size="mini" @click="handleWithdraw(scope.row)">撤回</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -147,7 +144,7 @@
|
||||
|
||||
<script>
|
||||
import { getLeaveRequest, addLeaveRequest, updateLeaveRequest } from "@/api/wms/leaveRequest";
|
||||
import { listApproval, updateApproval } from "@/api/wms/approval"
|
||||
import { listApproval, updateApproval, withdrawApproval } from "@/api/wms/approval"
|
||||
import { listDept } from "@/api/wms/dept"
|
||||
import FileUpload from '@/components/FileUpload'
|
||||
import EmployeeSelector from '@/components/EmployeeSelector'
|
||||
@@ -307,7 +304,8 @@ export default {
|
||||
endTime: data.endTime,
|
||||
leaveShift: data.leaveShift,
|
||||
leaveDays: data.leaveDays,
|
||||
leaveReason: data.leaveReason
|
||||
leaveReason: data.leaveReason,
|
||||
oldApprovalType: data.approvalType,
|
||||
}]
|
||||
};
|
||||
});
|
||||
@@ -327,7 +325,7 @@ export default {
|
||||
this.buttonLoading = true;
|
||||
const { list, ...commonFields } = this.form; // 拆分公共字段和时段列表
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
let failCount = 0;
|
||||
const failReasons = [];
|
||||
|
||||
// 2. 循环处理每个时段,逐个发送请求
|
||||
@@ -342,21 +340,23 @@ export default {
|
||||
leaveDays: item.leaveDays,
|
||||
leaveReason: item.leaveReason,
|
||||
// 生成单条记录的标题
|
||||
leaveTitle: `${commonFields.applicantName}-${commonFields.leaveType}-时段${i+1}-${item.startTime}-${item.leaveReason || ''}`,
|
||||
leaveTitle: `${commonFields.applicantName}-${commonFields.leaveType}-时段${i + 1}-${item.startTime}-${item.leaveReason || ''}`,
|
||||
approvalType: approvalType,
|
||||
};
|
||||
|
||||
try {
|
||||
if (commonFields.leaveId != null) {
|
||||
if (singleRequestData.oldApprovalType !== approvalType) {
|
||||
this.$message.warning('请假时长变动过大,请撤销后重新发起');
|
||||
failCount++;
|
||||
continue;
|
||||
}
|
||||
await updateLeaveRequest({ ...singleRequestData, leaveId: commonFields.leaveId });
|
||||
successCount++;
|
||||
// 编辑模式:仅支持修改单条(因为后端是单条记录)
|
||||
if (list.length > 1) {
|
||||
this.$message.warning('编辑模式仅支持单条修改,已自动取第一行数据');
|
||||
await updateLeaveRequest({ ...singleRequestData, leaveId: commonFields.leaveId });
|
||||
successCount++;
|
||||
break; // 编辑时只处理第一条
|
||||
} else {
|
||||
await updateLeaveRequest({ ...singleRequestData, leaveId: commonFields.leaveId });
|
||||
successCount++;
|
||||
}
|
||||
} else {
|
||||
// 新增模式:批量提交多条
|
||||
@@ -365,19 +365,23 @@ export default {
|
||||
}
|
||||
} catch (error) {
|
||||
failCount++;
|
||||
failReasons.push(`时段${i+1}提交失败:${error.message || '未知错误'}`);
|
||||
failReasons.push(`时段${i + 1}提交失败:${error.message || '未知错误'}`);
|
||||
// 失败后继续提交下一条,不中断批量操作
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 提交完成后反馈结果
|
||||
if (failCount === 0) {
|
||||
this.$modal.msgSuccess(`批量提交成功!共提交${successCount}条请假申请`);
|
||||
} else {
|
||||
this.$modal.msgWarning(`批量提交完成!成功${successCount}条,失败${failCount}条\n失败原因:${failReasons.join(';')}`);
|
||||
console.log(commonFields.leaveId);
|
||||
if (commonFields.leaveId == null) {
|
||||
if (failCount === 0) {
|
||||
this.$modal.msgSuccess(`批量提交成功!共提交${successCount}条请假申请`);
|
||||
} else {
|
||||
this.$modal.msgWarning(`批量提交完成!成功${successCount}条,失败${failCount}条\n失败原因:${failReasons.join(';')}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. 刷新列表并重置表单
|
||||
this.getList();
|
||||
this.reset();
|
||||
@@ -390,10 +394,8 @@ export default {
|
||||
handleWithdraw(row) {
|
||||
this.$modal.confirm('是否确认撤回请假申请编号为"' + row.applyId + '"的数据项?').then(() => {
|
||||
this.loading = true;
|
||||
return updateApproval({
|
||||
approvalId: row.approvalId,
|
||||
approvalStatus: '已撤销'
|
||||
});
|
||||
// 撤销审批
|
||||
return withdrawApproval(row.approvalId)
|
||||
}).then(() => {
|
||||
this.loading = false;
|
||||
this.getList();
|
||||
|
||||
@@ -40,39 +40,32 @@
|
||||
<div class="custom-tabs-nav">
|
||||
<div
|
||||
class="custom-tabs-item"
|
||||
:class="{ active: queryParams.approvalStatus === undefined || queryParams.approvalStatus === '' }"
|
||||
@click="handleTabClick('approvalStatus', '')"
|
||||
:class="{ active: queryParams.taskStatus === undefined || queryParams.taskStatus === '' }"
|
||||
@click="handleTabClick('taskStatus', '')"
|
||||
>
|
||||
全部
|
||||
</div>
|
||||
<div
|
||||
class="custom-tabs-item"
|
||||
:class="{ active: queryParams.approvalStatus === '待审批' }"
|
||||
@click="handleTabClick('approvalStatus', '待审批')"
|
||||
:class="{ active: queryParams.taskStatus === 'pending' }"
|
||||
@click="handleTabClick('taskStatus', 'pending')"
|
||||
>
|
||||
待审批
|
||||
</div>
|
||||
<div
|
||||
class="custom-tabs-item"
|
||||
:class="{ active: queryParams.approvalStatus === '已同意' }"
|
||||
@click="handleTabClick('approvalStatus', '已同意')"
|
||||
:class="{ active: queryParams.taskStatus === 'approved' }"
|
||||
@click="handleTabClick('taskStatus', 'approved')"
|
||||
>
|
||||
已同意
|
||||
</div>
|
||||
<div
|
||||
class="custom-tabs-item"
|
||||
:class="{ active: queryParams.approvalStatus === '已驳回' }"
|
||||
@click="handleTabClick('approvalStatus', '已驳回')"
|
||||
:class="{ active: queryParams.taskStatus === 'rejected' }"
|
||||
@click="handleTabClick('taskStatus', 'rejected')"
|
||||
>
|
||||
已驳回
|
||||
</div>
|
||||
<div
|
||||
class="custom-tabs-item"
|
||||
:class="{ active: queryParams.approvalStatus === '已撤销' }"
|
||||
@click="handleTabClick('approvalStatus', '已撤销')"
|
||||
>
|
||||
已撤回
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -110,6 +103,13 @@
|
||||
{{ scope.row.endTime ? formatTime(scope.row.endTime) : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="taskStatus" label="整体状态" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getInstStatusTagType(scope.row.approvalStatus)">
|
||||
{{ getInstStatusText(scope.row.approvalStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="taskStatus" label="审批状态" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-tag :type="getStatusTagType(scope.row.taskStatus)">
|
||||
@@ -127,7 +127,7 @@
|
||||
详情
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.approvalStatus === '待审批'"
|
||||
v-if="scope.row.taskStatus === 'pending'"
|
||||
size="small"
|
||||
icon="el-icon-check"
|
||||
@click="handleApprove(scope.row)"
|
||||
@@ -136,7 +136,7 @@
|
||||
同意
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="scope.row.approvalStatus === '待审批'"
|
||||
v-if="scope.row.taskStatus === 'pending'"
|
||||
size="small"
|
||||
icon="el-icon-close"
|
||||
@click="handleReject(scope.row)"
|
||||
@@ -182,6 +182,9 @@
|
||||
<el-descriptions-item label="请假天数">{{ currentDetail.leaveDays || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="请假原因">{{ currentDetail.leaveReason || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注">{{ currentDetail.remark || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="附件">
|
||||
<FileList :ossIds="currentDetail.attachmentUrls" />
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
@@ -196,6 +199,9 @@
|
||||
<el-descriptions-item label="外出地点">{{ currentDetail.outPlace || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="外出原因">{{ currentDetail.outReason || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="备注">{{ currentDetail.remark || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="附件">
|
||||
<FileList :ossIds="currentDetail.attachmentUrls" />
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
@@ -208,9 +214,14 @@
|
||||
|
||||
<script>
|
||||
import { listApprovalTask, rejectApprovalTask, resolveApprovalTask } from '@/api/wms/approvalTask'
|
||||
import FileList from '@/components/FileList/index.vue'
|
||||
|
||||
|
||||
export default {
|
||||
name: 'TodoList',
|
||||
components: {
|
||||
FileList,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 查询参数
|
||||
@@ -369,6 +380,27 @@ export default {
|
||||
return this.parseTime(time, '{y}-{m}-{d} {h}')
|
||||
},
|
||||
|
||||
// 获取审批状态对应的标签类型
|
||||
getInstStatusTagType(status) {
|
||||
const typeMap = {
|
||||
'待审批': 'warning',
|
||||
'已同意': 'success',
|
||||
'已驳回': 'danger',
|
||||
'已撤销': 'info',
|
||||
}
|
||||
return typeMap[status] || 'default'
|
||||
},
|
||||
// 获取审批状态的中文文本
|
||||
getInstStatusText(status) {
|
||||
const textMap = {
|
||||
'待审批': '待审批',
|
||||
'已同意': '已同意',
|
||||
'已驳回': '已驳回',
|
||||
'已撤销': '已撤销',
|
||||
}
|
||||
return textMap[status] || '未知状态'
|
||||
},
|
||||
|
||||
// 获取审批状态对应的标签类型
|
||||
getStatusTagType(status) {
|
||||
const typeMap = {
|
||||
|
||||
@@ -318,7 +318,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 11, // 酸轧工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -328,7 +328,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -339,7 +339,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 11, // 酸轧工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -349,7 +349,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -394,7 +394,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 11, // 酸轧工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -404,7 +404,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -323,7 +323,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 11, // 酸轧工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -333,7 +333,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -186,7 +186,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 11, // 酸轧工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -196,7 +196,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -304,7 +304,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 501, // 镀锌工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -314,7 +314,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -325,7 +325,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 501, // 镀锌工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -335,7 +335,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -381,7 +381,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 501, // 镀锌工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -391,7 +391,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -307,7 +307,7 @@ export default {
|
||||
const res1 = await listPendingAction({
|
||||
actionStatus: 2,
|
||||
actionType: 501, // 镀锌工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -317,7 +317,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
@@ -186,7 +186,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 501, // 镀锌工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
@@ -196,7 +196,7 @@ export default {
|
||||
warehouseId: this.queryParams.planId,
|
||||
// actionType: 401,
|
||||
actionType: 120, // 分条工序
|
||||
pageSize: 999,
|
||||
pageSize: 9999,
|
||||
pageNum: 1,
|
||||
startTime: this.queryParams.byCreateTimeStart,
|
||||
endTime: this.queryParams.byCreateTimeEnd,
|
||||
|
||||
405
klp-ui/src/views/wms/warehouse/components/WarehouseBirdMini.vue
Normal file
405
klp-ui/src/views/wms/warehouse/components/WarehouseBirdMini.vue
Normal file
@@ -0,0 +1,405 @@
|
||||
<template>
|
||||
<div class="bird-container">
|
||||
<!-- 图例 -->
|
||||
<div class="legend-container">
|
||||
<div class="legend-item">
|
||||
<div class="legend-color layer-1"></div>
|
||||
<span class="legend-text">一层</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color layer-2"></div>
|
||||
<span class="legend-text">二层</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color occupied"></div>
|
||||
<span class="legend-text">已占用</span>
|
||||
</div>
|
||||
<div class="legend-item">
|
||||
<div class="legend-color error"></div>
|
||||
<span class="legend-text">异常</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分列库位容器 -->
|
||||
<div class="layers-container">
|
||||
<!-- 无数据提示 -->
|
||||
<div class="empty-tip" v-if="Object.keys(columns).length === 0 && warehouseList.length > 0">
|
||||
暂无解析到有效的库位分列数据
|
||||
</div>
|
||||
<div class="empty-tip" v-else-if="warehouseList.length === 0">
|
||||
<el-empty description="暂无库位数据"></el-empty>
|
||||
</div>
|
||||
<warehouse-interlaced ref="warehouseInterlaced" v-else="warehouseList.length" :id="id" :columns="columns" :canToggle="canToggle"
|
||||
:canRelease="canRelease" @split-warehouse="handleSplitWarehouse" @merge-warehouse="handleMergeWarehouse"
|
||||
@release-warehouse="handleReleaseWarehouse" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WarehouseInterlaced from './WarehouseInterlaced.vue';
|
||||
|
||||
export default {
|
||||
name: "WarehouseBirdMini",
|
||||
components: { WarehouseInterlaced },
|
||||
props: {
|
||||
// 原始库位列表
|
||||
warehouseList: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
canToggle: {
|
||||
default: true,
|
||||
type: Boolean
|
||||
},
|
||||
canRelease: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 分列库位数据(核心修改:从layers改为columns)
|
||||
columns: {},
|
||||
// 统计信息(适配分列逻辑)
|
||||
statistics: {
|
||||
total: 0,
|
||||
columnCount: 0,
|
||||
columnDetail: {},
|
||||
// 占用情况
|
||||
// 每一列每一层的总数和已占用数量
|
||||
layerDetail: {}
|
||||
},
|
||||
tableData: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
// 监听库位列表变化,重新构建分列数据
|
||||
warehouseList: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.buildWarehouseBox(newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理分列数据调整
|
||||
resize() {
|
||||
this.$refs.warehouseInterlaced?.handleResize();
|
||||
},
|
||||
handleSplitWarehouse(warehouse) {
|
||||
this.$emit('split-warehouse', warehouse);
|
||||
},
|
||||
|
||||
// 1. 转换layerDetail为表格所需的数组格式
|
||||
formatTableData() {
|
||||
const layerDetail = this.statistics.layerDetail;
|
||||
this.tableData = Object.keys(layerDetail).map(column => {
|
||||
const layer1 = layerDetail[column].layer1;
|
||||
const layer2 = layerDetail[column].layer2;
|
||||
return {
|
||||
column: column, // 列号
|
||||
// 第一层数据
|
||||
layer1_total: layer1.total,
|
||||
layer1_occupied: layer1.occupied,
|
||||
layer1_free: layer1.free,
|
||||
// 第二层数据
|
||||
layer2_total: layer2.total,
|
||||
layer2_occupied: layer2.occupied,
|
||||
layer2_free: layer2.free,
|
||||
// 该列总计
|
||||
column_total: layer1.total + layer2.total,
|
||||
column_occupied: layer1.occupied + layer2.occupied,
|
||||
column_free: layer1.free + layer2.free
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
handleMergeWarehouse(warehouse) {
|
||||
this.$emit('merge-warehouse', warehouse);
|
||||
},
|
||||
|
||||
handleReleaseWarehouse(warehouse) {
|
||||
this.$emit('release-warehouse', warehouse);
|
||||
},
|
||||
/**
|
||||
* 解析第三级库位编码
|
||||
* 新规则:
|
||||
* 1. 前三位:数字或字母的任意组合
|
||||
* 2. column:从第五位开始到第一个"-"为止(支持多位数)
|
||||
* 3. 保留 row(两位数字)、layer(数字)的解析规则
|
||||
*/
|
||||
parseWarehouseCode(code) {
|
||||
if (!code) return null;
|
||||
|
||||
// 新正则表达式解析规则
|
||||
// ^([A-Za-z0-9]{3}) :匹配前3位(数字/字母)
|
||||
// . :匹配第4位(任意单个字符)
|
||||
// ([^-]+) :匹配column(到第一个"-"为止,至少1位)
|
||||
// -(\d{2}) :匹配row(两位数字)
|
||||
// -(\d+) :匹配layer(一位或多位数字)
|
||||
const reg = /^([A-Za-z0-9]{3})([^-]+)-(\d{2})-(\d+)$/;
|
||||
const match = code.match(reg);
|
||||
|
||||
if (!match) {
|
||||
console.warn(`库位编码解析失败:${code},格式不符合规范`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
level: 3,
|
||||
warehousePrefix: match[1], // 前三位(数字/字母),替代原warehouseFirst/warehouseSecond
|
||||
warehouseFirst: match[1].slice(0, 2), // 前三位的前两个字符
|
||||
warehouseSecond: match[1].slice(2, 3), // 前三位的第三个字符
|
||||
column: Number(match[2]), // 第五位到第一个"-"的内容(多位数)
|
||||
row: Number(match[3]), // 两位数字的行号
|
||||
layer: match[4] // 层级数字(可多位数)
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* 解析第四级库位编码,格式为F2A1-X01-1
|
||||
*/
|
||||
parseWarehouseCodeFourth(code) {
|
||||
if (!code) return null;
|
||||
const reg = /^([A-Za-z0-9]{3})([^-]+)-X(\d{2})-(\d+)$/;
|
||||
const match = code.match(reg);
|
||||
|
||||
if (!match) {
|
||||
console.warn(`库位编码解析失败:${code},格式不符合规范`);
|
||||
return null;
|
||||
}
|
||||
|
||||
// console.log('match:', match);
|
||||
|
||||
return {
|
||||
level: 4,
|
||||
warehousePrefix: match[1],
|
||||
warehouseFirst: match[1].slice(0, 2), // 前三位的前两个字符
|
||||
warehouseSecond: match[1].slice(2, 3), // 前三位的第三个字符
|
||||
// warehouseSecond: match[2],
|
||||
column: Number(match[2]),
|
||||
row: Number(match[3]),
|
||||
layer: match[4],
|
||||
};
|
||||
},
|
||||
|
||||
buildWarehouseBox(list) {
|
||||
const columnMap = {}; // 按列分组的核心对象
|
||||
const statistics = {
|
||||
total: list.length,
|
||||
columnCount: 0,
|
||||
columnDetail: {},
|
||||
// 占用情况:每一列每一层的总数、已占用、未占用数量
|
||||
layerDetail: {}
|
||||
};
|
||||
|
||||
// 1. 按列分组,每列内部分为layer1和layer2两个数组
|
||||
list.forEach((warehouse) => {
|
||||
let codeInfo = {}
|
||||
if (warehouse.actualWarehouseType == 4) {
|
||||
codeInfo = this.parseWarehouseCodeFourth(warehouse.actualWarehouseCode);
|
||||
} else {
|
||||
codeInfo = this.parseWarehouseCode(warehouse.actualWarehouseCode);
|
||||
}
|
||||
if (!codeInfo) return;
|
||||
|
||||
const { layer, row, column } = codeInfo;
|
||||
warehouse.parsedInfo = codeInfo;
|
||||
|
||||
// 初始化列数据结构:每列包含layer1、layer2数组,以及最大行号
|
||||
if (!columnMap[column]) {
|
||||
columnMap[column] = {
|
||||
maxRow: 0,
|
||||
layer1: [], // 第一层库位数组
|
||||
layer2: [], // 第二层库位数组
|
||||
total: 0 // 该列总库位数
|
||||
};
|
||||
}
|
||||
|
||||
// 更新列的最大行号
|
||||
columnMap[column].maxRow = Math.max(columnMap[column].maxRow, row);
|
||||
|
||||
// 根据层数将库位放入对应数组
|
||||
if (layer === '1' || layer === 1) {
|
||||
columnMap[column].layer1.push(warehouse);
|
||||
} else if (layer === '2' || layer === 2) {
|
||||
columnMap[column].layer2.push(warehouse);
|
||||
}
|
||||
|
||||
// 更新该列总库位数
|
||||
columnMap[column].total = columnMap[column].layer1.length + columnMap[column].layer2.length;
|
||||
});
|
||||
|
||||
// 2. 对每列的两层数据分别按行号排序
|
||||
Object.keys(columnMap).forEach((column) => {
|
||||
const columnData = columnMap[column];
|
||||
|
||||
// 按行号排序(保证展示顺序正确)
|
||||
columnData.layer1.sort((a, b) => a.parsedInfo.row - b.parsedInfo.row);
|
||||
columnData.layer2.sort((a, b) => a.parsedInfo.row - b.parsedInfo.row);
|
||||
});
|
||||
|
||||
// 3. 更新统计信息(适配分列逻辑)
|
||||
statistics.columnCount = Object.keys(columnMap).length;
|
||||
Object.keys(columnMap).forEach((column) => {
|
||||
const columnData = columnMap[column];
|
||||
// 列维度总数量
|
||||
statistics.columnDetail[column] = columnData.total;
|
||||
|
||||
// ========== 新增:layerDetail 层级统计逻辑 ==========
|
||||
// 初始化当前列的层级统计结构
|
||||
statistics.layerDetail[column] = {
|
||||
layer1: {
|
||||
total: 0, // 该层总库位数
|
||||
occupied: 0, // 已占用(isEnabled=0)
|
||||
free: 0 // 未占用(isEnabled=1)
|
||||
},
|
||||
layer2: {
|
||||
total: 0,
|
||||
occupied: 0,
|
||||
free: 0
|
||||
}
|
||||
};
|
||||
|
||||
// 统计第一层
|
||||
const layer1Data = columnData.layer1;
|
||||
statistics.layerDetail[column].layer1.total = layer1Data.length;
|
||||
statistics.layerDetail[column].layer1.occupied = layer1Data.filter(item => item.isEnabled === 0).length;
|
||||
statistics.layerDetail[column].layer1.free = layer1Data.filter(item => item.isEnabled === 1).length;
|
||||
|
||||
// 统计第二层
|
||||
const layer2Data = columnData.layer2;
|
||||
statistics.layerDetail[column].layer2.total = layer2Data.length;
|
||||
statistics.layerDetail[column].layer2.occupied = layer2Data.filter(item => item.isEnabled === 0).length;
|
||||
statistics.layerDetail[column].layer2.free = layer2Data.filter(item => item.isEnabled === 1).length;
|
||||
});
|
||||
|
||||
// 4. 赋值到响应式数据
|
||||
this.columns = columnMap;
|
||||
this.statistics = statistics;
|
||||
this.formatTableData();
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开初始化弹窗(透传至根组件)
|
||||
*/
|
||||
openInitDialog() {
|
||||
this.$emit('open-init-dialog');
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.bird-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 统计卡片样式
|
||||
.statistics-card {
|
||||
margin-bottom: 16px;
|
||||
|
||||
.statistics-item {
|
||||
margin-bottom: 8px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 图例样式
|
||||
.legend-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 8px 12px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 4px;
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.legend-color {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
margin-right: 8px;
|
||||
border: 1px solid #e6e6e6;
|
||||
}
|
||||
|
||||
.normal {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.layer-1 {
|
||||
background-color: #fff3e0;
|
||||
}
|
||||
|
||||
.layer-2 {
|
||||
background-color: #e8f5e9;
|
||||
}
|
||||
|
||||
.occupied {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: #fdecea;
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分列容器样式
|
||||
.layers-container {
|
||||
display: flex;
|
||||
|
||||
.layer-section {
|
||||
flex: 1;
|
||||
max-width: 50%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
text-align: center;
|
||||
padding: 32px;
|
||||
color: #909399;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
|
||||
.empty-text {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -125,7 +125,7 @@ export default {
|
||||
canRelease: {
|
||||
default: false,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
@@ -224,4 +224,17 @@ public class WmsActualWarehouseController extends BaseController {
|
||||
return AjaxResult.error("库区释放失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修正已生成库位的排序号(交错排序)
|
||||
*
|
||||
* @param parentId 父库位ID
|
||||
*/
|
||||
@Log(title = "修正库位排序号", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/fixSortNo/{parentId}")
|
||||
public R<Integer> fixSortNo(@PathVariable Long parentId) {
|
||||
int count = iWmsActualWarehouseService.fixSortNoByParentId(parentId);
|
||||
return R.ok(count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -142,4 +142,18 @@ public class WmsApprovalController extends BaseController {
|
||||
public R<List<WmsApprovalTaskVo>> getTasks(@PathVariable Long approvalId) {
|
||||
return R.ok(iWmsApprovalTaskService.queryByApprovalId(approvalId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 撤销审批
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
*/
|
||||
@Log(title = "撤销审批", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/cancel")
|
||||
public R<Map<String, Object>> cancelApproval(
|
||||
@NotNull(message = "审批ID不能为空")
|
||||
@RequestParam Long approvalId) {
|
||||
return R.ok(iWmsApprovalService.cancelApproval(approvalId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ public class WmsCoilPendingActionController extends BaseController {
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/status/{actionId}/{status}")
|
||||
public R<Void> updateStatus(@PathVariable("actionId") Long actionId,
|
||||
public R<Void> updateStatus(@PathVariable("actionId") Long actionId,
|
||||
@PathVariable("status") Integer status) {
|
||||
return toAjax(iWmsCoilPendingActionService.updateStatus(actionId, status));
|
||||
}
|
||||
@@ -138,6 +138,15 @@ public class WmsCoilPendingActionController extends BaseController {
|
||||
return toAjax(iWmsCoilPendingActionService.cancelAction(actionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原操作(将已删除的记录恢复为正常状态)
|
||||
*/
|
||||
@Log(title = "钢卷待操作", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/restore/{actionId}")
|
||||
public R<Void> restoreAction(@PathVariable("actionId")@NotNull Long actionId) {
|
||||
return toAjax(iWmsCoilPendingActionService.restoreAction(actionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算理论节拍回归(默认近6个月),并返回散点+拟合线
|
||||
*/
|
||||
|
||||
@@ -71,8 +71,8 @@ public class WmsCoilStatisticsSummaryController extends BaseController {
|
||||
@Log(title = "钢卷生产统计汇总(数据透视结果持久化)", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody WmsCoilStatisticsSummaryBo bo) {
|
||||
return toAjax(iWmsCoilStatisticsSummaryService.insertByBo(bo));
|
||||
public R<WmsCoilStatisticsSummaryVo> add(@Validated(AddGroup.class) @RequestBody WmsCoilStatisticsSummaryBo bo) {
|
||||
return R.ok(iWmsCoilStatisticsSummaryService.insertByBo(bo));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -96,4 +96,15 @@ public class WmsCoilStatisticsSummaryController extends BaseController {
|
||||
@PathVariable Long[] summaryIds) {
|
||||
return toAjax(iWmsCoilStatisticsSummaryService.deleteWithValidByIds(Arrays.asList(summaryIds), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当天是否存在指定类型的统计记录
|
||||
*
|
||||
* @param statType 统计类型
|
||||
* @return 存在的记录ID,不存在则返回null
|
||||
*/
|
||||
@GetMapping("/checkToday")
|
||||
public R<Long> checkTodayExists(@RequestParam String statType) {
|
||||
return R.ok(iWmsCoilStatisticsSummaryService.checkExistsByStatTypeToday(statType));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
package com.klp.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.klp.domain.vo.WmsMaterialCoilExportVo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilDeliveryExportVo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilLocationGridVo;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.klp.domain.vo.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.constraints.*;
|
||||
@@ -22,7 +24,6 @@ import com.klp.common.core.validate.AddGroup;
|
||||
import com.klp.common.core.validate.EditGroup;
|
||||
import com.klp.common.enums.BusinessType;
|
||||
import com.klp.common.utils.poi.ExcelUtil;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import com.klp.domain.bo.WmsMaterialCoilBo;
|
||||
import com.klp.domain.vo.dashboard.CoilTrimStatisticsVo;
|
||||
import com.klp.domain.vo.dashboard.CategoryWidthStatisticsVo;
|
||||
@@ -66,7 +67,7 @@ public class WmsMaterialCoilController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出钢卷物料表列表(完整字段版本)
|
||||
* 导出钢卷物料表列表(精简字段版本)
|
||||
*/
|
||||
@Log(title = "钢卷物料表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@@ -74,6 +75,16 @@ public class WmsMaterialCoilController extends BaseController {
|
||||
List<WmsMaterialCoilExportVo> list = iWmsMaterialCoilService.queryExportList(bo);
|
||||
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilExportVo.class, response);
|
||||
}
|
||||
/**
|
||||
* 导出钢卷物料表列表(完整字段版本)
|
||||
* 导出全部字段
|
||||
*/
|
||||
@Log(title = "钢卷物料表", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/exportAll")
|
||||
public void exportSimple(WmsMaterialCoilBo bo, HttpServletResponse response) {
|
||||
List<WmsMaterialCoilAllExportVo> list = iWmsMaterialCoilService.queryExportListAll(bo);
|
||||
ExcelUtil.exportExcel(list, "钢卷物料表", WmsMaterialCoilAllExportVo.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出发货报表(按 coilIds,联查发货单明细/主表/发货计划)
|
||||
@@ -285,19 +296,23 @@ public class WmsMaterialCoilController extends BaseController {
|
||||
* 检查钢卷号是否重复
|
||||
* 前端传入入场钢卷号和当前钢卷号,返回哪个钢卷号重复
|
||||
*
|
||||
* @param coilId 钢卷ID(修改时传入,用于排除自身)
|
||||
* @param enterCoilNo 入场钢卷号
|
||||
* @param currentCoilNo 当前钢卷号
|
||||
* @param supplierCoilNo 厂家原料卷号
|
||||
* @return 返回结果,包含:
|
||||
* - duplicateType: "enter" (入场钢卷号重复), "current" (当前钢卷号重复), "both" (都重复), "none" (都不重复)
|
||||
* - duplicateType: "enter" (入场钢卷号重复), "current" (当前钢卷号重复), "supplier" (厂家原料卷号重复), "both" (都重复), "none" (都不重复)
|
||||
* - enterCoilNoDuplicate: 入场钢卷号是否重复
|
||||
* - currentCoilNoDuplicate: 当前钢卷号是否重复
|
||||
* - supplierCoilNoDuplicate: 厂家原料卷号是否重复
|
||||
*/
|
||||
@GetMapping("/checkCoilNoDuplicate")
|
||||
public R<Map<String, Object>> checkCoilNoDuplicate(
|
||||
@RequestParam(required = false) Long coilId,
|
||||
@RequestParam(required = false) String enterCoilNo,
|
||||
@RequestParam(required = false) String currentCoilNo) {
|
||||
Map<String, Object> result = iWmsMaterialCoilService.checkCoilNoDuplicate(coilId,enterCoilNo, currentCoilNo);
|
||||
@RequestParam(required = false) String currentCoilNo,
|
||||
@RequestParam(required = false) String supplierCoilNo) {
|
||||
Map<String, Object> result = iWmsMaterialCoilService.checkCoilNoDuplicate(coilId, enterCoilNo, currentCoilNo, supplierCoilNo);
|
||||
return R.ok(result);
|
||||
}
|
||||
|
||||
@@ -360,9 +375,12 @@ public class WmsMaterialCoilController extends BaseController {
|
||||
@PostMapping("/specialSplit/start")
|
||||
public R<Long> startSpecialSplit(
|
||||
@NotNull(message = "钢卷ID不能为空")
|
||||
@RequestParam Long coilId) {
|
||||
@RequestParam Long coilId,
|
||||
@NotNull(message = "操作类型不能为空")
|
||||
@RequestParam Integer actionType
|
||||
) {
|
||||
try {
|
||||
Boolean result = iWmsMaterialCoilService.startSpecialSplit(coilId);
|
||||
Boolean result = iWmsMaterialCoilService.startSpecialSplit(coilId, actionType);
|
||||
if (Boolean.TRUE.equals(result)) {
|
||||
return R.ok();
|
||||
}
|
||||
|
||||
@@ -46,4 +46,7 @@ public class WmsCoilStatisticsSummary extends BaseEntity {
|
||||
@TableLogic
|
||||
private Long delFlag;
|
||||
|
||||
// 新增附件字段
|
||||
private String attachmentInfo;
|
||||
|
||||
}
|
||||
|
||||
@@ -82,6 +82,10 @@ public class WmsEmployeeInfo extends BaseEntity {
|
||||
* 紧急联系人电话
|
||||
*/
|
||||
private String emergencyContactPhone;
|
||||
/**
|
||||
* 社保类型(三险/五险)
|
||||
*/
|
||||
private String socialInsuranceType;
|
||||
/**
|
||||
* 逻辑删除标识:0=正常,1=已删
|
||||
*/
|
||||
|
||||
@@ -160,5 +160,15 @@ public class WmsMaterialCoil extends BaseEntity {
|
||||
|
||||
// 父钢卷id
|
||||
private String parentCoilId;
|
||||
|
||||
/**
|
||||
* 实测长度
|
||||
*/
|
||||
private BigDecimal actualLength;
|
||||
|
||||
/**
|
||||
* 实测宽度
|
||||
*/
|
||||
private BigDecimal actualWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -89,13 +89,13 @@ public class WmsCoilPendingActionBo extends BaseEntity {
|
||||
/**
|
||||
* 处理时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date processTime;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX", timezone = "GMT+8")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date completeTime;
|
||||
|
||||
//开始时间和结束时间
|
||||
@@ -109,5 +109,10 @@ public class WmsCoilPendingActionBo extends BaseEntity {
|
||||
|
||||
//备注
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否包含已删除记录(0=不包含,1=包含已删除,2=仅查询已删除)
|
||||
*/
|
||||
private Integer includeDeleted;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,5 +42,8 @@ public class WmsCoilStatisticsSummaryBo extends BaseEntity {
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
// 新增附件字段
|
||||
private String attachmentInfo;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -94,6 +94,11 @@ public class WmsEmployeeInfoBo extends BaseEntity {
|
||||
*/
|
||||
private String emergencyContactPhone;
|
||||
|
||||
/**
|
||||
* 社保类型(三险/五险)
|
||||
*/
|
||||
private String socialInsuranceType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@@ -260,5 +260,15 @@ public class WmsMaterialCoilBo extends BaseEntity {
|
||||
// 已绑定钢卷列表中,未发货(status=0)的排在前面
|
||||
@TableField(exist = false)
|
||||
private Boolean statusFirst;
|
||||
|
||||
/**
|
||||
* 实测长度
|
||||
*/
|
||||
private BigDecimal actualLength;
|
||||
|
||||
/**
|
||||
* 实测宽度
|
||||
*/
|
||||
private BigDecimal actualWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,7 +200,6 @@ public class WmsCoilPendingActionVo extends BaseEntity implements Serializable {
|
||||
|
||||
private String actualWarehouseName;
|
||||
|
||||
|
||||
|
||||
private Integer delFlag;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import com.klp.common.core.domain.BaseEntity;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
@@ -15,7 +16,7 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsCoilStatisticsSummaryVo {
|
||||
public class WmsCoilStatisticsSummaryVo extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@@ -52,5 +53,7 @@ public class WmsCoilStatisticsSummaryVo {
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
// 新增附件字段
|
||||
private String attachmentInfo;
|
||||
|
||||
}
|
||||
|
||||
@@ -112,6 +112,11 @@ public class WmsEmployeeInfoVo {
|
||||
@ExcelProperty(value = "紧急联系人电话")
|
||||
private String emergencyContactPhone;
|
||||
|
||||
/**
|
||||
* 社保类型(三险/五险)
|
||||
*/
|
||||
private String socialInsuranceType;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
package com.klp.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.Excel;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 钢卷物料导出VO
|
||||
*
|
||||
* @author klp
|
||||
* @date 2025-11-27
|
||||
*/
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class WmsMaterialCoilAllExportVo {
|
||||
|
||||
/**
|
||||
* 类型(成品/原料)
|
||||
*/
|
||||
@ExcelProperty(value = "类型")
|
||||
private String itemTypeDesc;
|
||||
|
||||
/**
|
||||
* 逻辑库区
|
||||
*/
|
||||
@ExcelProperty(value = "逻辑库区")
|
||||
private String warehouseName;
|
||||
|
||||
/**
|
||||
* 实际库区
|
||||
*/
|
||||
@ExcelProperty(value = "实际库区")
|
||||
private String actualWarehouseName;
|
||||
|
||||
/**
|
||||
* 入场卷号
|
||||
*/
|
||||
@ExcelProperty(value = "入场卷号")
|
||||
private String enterCoilNo;
|
||||
|
||||
/**
|
||||
* 厂家卷号
|
||||
*/
|
||||
@ExcelProperty(value = "厂家卷号")
|
||||
private String supplierCoilNo;
|
||||
|
||||
/**
|
||||
* 成品卷号
|
||||
*/
|
||||
@ExcelProperty(value = "成品卷号")
|
||||
private String currentCoilNo;
|
||||
|
||||
/**
|
||||
* 日期
|
||||
*/
|
||||
@ExcelProperty(value = "日期")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 发货时间(仅临时存储,不导出)
|
||||
*/
|
||||
@ExcelProperty(value = "发货时间")
|
||||
private Date exportTime;
|
||||
|
||||
// 发货人
|
||||
@ExcelProperty(value = "发货人")
|
||||
private String exportBy;
|
||||
|
||||
/**
|
||||
* 重量(kg)
|
||||
*/
|
||||
@ExcelProperty(value = "重量")
|
||||
private BigDecimal netWeight;
|
||||
|
||||
// 班组
|
||||
private String team;
|
||||
|
||||
/**
|
||||
* 用途
|
||||
*/
|
||||
@ExcelProperty(value = "用途")
|
||||
private String purpose;
|
||||
|
||||
/**
|
||||
* 切边要求
|
||||
*/
|
||||
@ExcelProperty(value = "切边要求")
|
||||
private String trimmingRequirement;
|
||||
|
||||
/**
|
||||
* 包装种类
|
||||
*/
|
||||
@ExcelProperty(value = "包装种类")
|
||||
private String packagingRequirement;
|
||||
|
||||
/**
|
||||
* 产品状态
|
||||
*/
|
||||
@ExcelProperty(value = "产品质量")
|
||||
private String qualityStatus;
|
||||
|
||||
/**
|
||||
* 打包状态
|
||||
*/
|
||||
@ExcelProperty(value = "打包状态")
|
||||
private String packingStatus;
|
||||
|
||||
/**
|
||||
* 库存状态
|
||||
*/
|
||||
@ExcelProperty(value = "库存状态")
|
||||
private String statusDesc;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
@ExcelProperty(value = "名称")
|
||||
private String itemName;
|
||||
|
||||
|
||||
@ExcelProperty(value = "长度")
|
||||
private BigDecimal length;
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
@ExcelProperty(value = "规格")
|
||||
private String specification;
|
||||
/**
|
||||
* 材质
|
||||
*/
|
||||
@ExcelProperty(value = "材质")
|
||||
private String material;
|
||||
|
||||
/**
|
||||
* 厂家
|
||||
*/
|
||||
@ExcelProperty(value = "厂家")
|
||||
private String manufacturer;
|
||||
|
||||
/**
|
||||
* 表面处理
|
||||
*/
|
||||
@ExcelProperty(value = "表面处理")
|
||||
private String surfaceTreatmentDesc;
|
||||
|
||||
/**
|
||||
* 锌层
|
||||
*/
|
||||
@ExcelProperty(value = "锌层")
|
||||
private String zincLayer;
|
||||
|
||||
/**
|
||||
* 物品ID
|
||||
*/
|
||||
@ExcelProperty(value = "物品ID")
|
||||
private Long itemId;
|
||||
|
||||
|
||||
/**
|
||||
* 更新时间(仅临时存储,不导出,用于发货时间为空时兜底)
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
// 数据类型
|
||||
@Excel(name = "数据类型", readConverterExp = "0=历史,1=当前")
|
||||
private Integer dataType;
|
||||
|
||||
// 调制度
|
||||
@ExcelProperty(value = "调制度")
|
||||
private String temperGrade;
|
||||
// 镀层种类
|
||||
@ExcelProperty(value = "镀层种类")
|
||||
private String coatingType;
|
||||
|
||||
// 业务用途
|
||||
@ExcelProperty(value = "业务用途")
|
||||
private String businessPurpose;
|
||||
|
||||
// 是否与订单相关 readConverterExp
|
||||
@Excel(name = "是否与订单相关", readConverterExp = "0=否,1=是")
|
||||
private Integer isRelatedToOrder;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.klp.domain.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.klp.common.annotation.Excel;
|
||||
import com.klp.common.annotation.ExcelDictFormat;
|
||||
import com.klp.common.convert.ExcelDictConvert;
|
||||
import lombok.Data;
|
||||
@@ -174,4 +175,13 @@ public class WmsMaterialCoilExportVo {
|
||||
private String temperGrade;
|
||||
// 镀层种类
|
||||
private String coatingType;
|
||||
|
||||
// 班组
|
||||
private String team;
|
||||
|
||||
// 业务用途
|
||||
private String businessPurpose;
|
||||
|
||||
// 是否与订单相关 readConverterExp
|
||||
private Integer isRelatedToOrder;
|
||||
}
|
||||
|
||||
@@ -429,5 +429,17 @@ public class WmsMaterialCoilVo extends BaseEntity {
|
||||
* 明细单价
|
||||
*/
|
||||
private BigDecimal bindDetailUnitPrice;
|
||||
|
||||
/**
|
||||
* 实测长度
|
||||
*/
|
||||
@ExcelProperty(value = "实测长度")
|
||||
private BigDecimal actualLength;
|
||||
|
||||
/**
|
||||
* 实测宽度
|
||||
*/
|
||||
@ExcelProperty(value = "实测宽度")
|
||||
private BigDecimal actualWidth;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,5 +16,22 @@ import org.apache.ibatis.annotations.Param;
|
||||
public interface WmsCoilPendingActionMapper extends BaseMapperPlus<WmsCoilPendingActionMapper, WmsCoilPendingAction, WmsCoilPendingActionVo> {
|
||||
|
||||
Page<WmsCoilPendingActionVo> selectVoPagePlus(Page<Object> build,@Param("ew") QueryWrapper<WmsCoilPendingAction> lqw);
|
||||
|
||||
/**
|
||||
* 更新删除标志(绕过@TableLogic注解限制)
|
||||
* @param actionId 操作ID
|
||||
* @param delFlag 删除标志(0=正常,1=已删除)
|
||||
* @return 更新行数
|
||||
*/
|
||||
int updateDelFlag(@Param("actionId") Long actionId, @Param("delFlag") Integer delFlag);
|
||||
|
||||
|
||||
/**
|
||||
* 根据操作ID和删除标志查询记录(包含已删除记录)
|
||||
* @param actionId 操作ID
|
||||
* @param delFlag 删除标志(0=正常,1=已删除)
|
||||
* @return 待操作记录
|
||||
*/
|
||||
WmsCoilPendingAction selectByActionIdAndDelFlag(@Param("actionId") Long actionId, @Param("delFlag") Integer delFlag);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ public interface WmsMaterialCoilMapper extends BaseMapperPlus<WmsMaterialCoilMap
|
||||
|
||||
Page<WmsMaterialCoilVo> selectVoPagePlus(Page<Object> build,@Param("ew") QueryWrapper<WmsMaterialCoil> lqw);
|
||||
|
||||
/**
|
||||
* orderBy=true 时使用:包含库位排序辅助字段(aw_sort_key/aw_layer_key/aw_id_key)以及父库位 join
|
||||
*/
|
||||
Page<WmsMaterialCoilVo> selectVoPagePlusOrderBy(Page<Object> build, @Param("ew") QueryWrapper<WmsMaterialCoil> lqw);
|
||||
|
||||
List<WmsMaterialCoilVo> selectVoListWithDynamicJoin(@Param("ew")QueryWrapper<WmsMaterialCoil> lqw);
|
||||
|
||||
List<Map<String, Object>> getDistributionByActualWarehouse(@Param("itemType") String itemType, @Param("itemId") Long itemId);
|
||||
|
||||
@@ -84,4 +84,12 @@ public interface IWmsActualWarehouseService {
|
||||
* - 清空钢卷表中绑定此库区且为现存(data_type=1)、未删除(del_flag=0)的记录的 actual_warehouse_id
|
||||
*/
|
||||
void releaseActualWarehouse(Long actualWarehouseId);
|
||||
|
||||
/**
|
||||
* 修正已生成库位的排序号(交错排序)
|
||||
* @param parentId 父库位ID
|
||||
* @return 修正的记录数
|
||||
*/
|
||||
int fixSortNoByParentId(Long parentId);
|
||||
|
||||
}
|
||||
|
||||
@@ -65,4 +65,12 @@ public interface IWmsApprovalService {
|
||||
* @return 操作结果
|
||||
*/
|
||||
Map<String, Object> rejectTask(Long taskId, String approvalOpinion);
|
||||
|
||||
/**
|
||||
* 撤销审批
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
* @return 操作结果
|
||||
*/
|
||||
Map<String, Object> cancelApproval(Long approvalId);
|
||||
}
|
||||
|
||||
@@ -31,4 +31,12 @@ public interface IWmsApprovalTaskService {
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
List<WmsApprovalTaskVo> queryByApprovalId(Long approvalId);
|
||||
|
||||
/**
|
||||
* 根据审批ID删除所有相关任务
|
||||
*
|
||||
* @param approvalId 审批ID
|
||||
* @return 删除数量
|
||||
*/
|
||||
Integer deleteByApprovalId(Long approvalId);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,11 @@ public interface IWmsCoilPendingActionService {
|
||||
*/
|
||||
Boolean cancelAction(Long actionId);
|
||||
|
||||
/**
|
||||
* 还原操作(将已删除的记录恢复为正常状态)
|
||||
*/
|
||||
Boolean restoreAction(Long actionId);
|
||||
|
||||
/**
|
||||
* 计算理论节拍线性回归(默认近6个月),同时返回散点用于前端绘图并将结果缓存。
|
||||
*/
|
||||
|
||||
@@ -35,7 +35,7 @@ public interface IWmsCoilStatisticsSummaryService {
|
||||
/**
|
||||
* 新增钢卷生产统计汇总(数据透视结果持久化)
|
||||
*/
|
||||
Boolean insertByBo(WmsCoilStatisticsSummaryBo bo);
|
||||
WmsCoilStatisticsSummaryVo insertByBo(WmsCoilStatisticsSummaryBo bo);
|
||||
|
||||
/**
|
||||
* 修改钢卷生产统计汇总(数据透视结果持久化)
|
||||
@@ -46,4 +46,11 @@ public interface IWmsCoilStatisticsSummaryService {
|
||||
* 校验并批量删除钢卷生产统计汇总(数据透视结果持久化)信息
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||
|
||||
/**
|
||||
* 检查当天是否存在指定类型的统计记录
|
||||
* @param statType 统计类型
|
||||
* @return 存在的记录ID,不存在则返回null
|
||||
*/
|
||||
Long checkExistsByStatTypeToday(String statType);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.klp.service;
|
||||
|
||||
import com.klp.domain.vo.WmsMaterialCoilDeliveryExportVo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilLocationGridVo;
|
||||
import com.klp.domain.vo.WmsMaterialCoilVo;
|
||||
import com.klp.domain.vo.*;
|
||||
import com.klp.domain.bo.WmsMaterialCoilBo;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
@@ -141,16 +139,19 @@ public interface IWmsMaterialCoilService {
|
||||
|
||||
/**
|
||||
* 检查钢卷号是否重复
|
||||
* 根据入场钢卷号和当前钢卷号查询数据库,判断哪个钢卷号重复
|
||||
* 根据入场钢卷号、当前钢卷号和厂家原料卷号查询数据库,判断哪个钢卷号重复
|
||||
*
|
||||
* @param coilId 钢卷ID(修改时传入,用于排除自身)
|
||||
* @param enterCoilNo 入场钢卷号
|
||||
* @param currentCoilNo 当前钢卷号
|
||||
* @param supplierCoilNo 厂家原料卷号
|
||||
* @return 返回结果Map,包含:
|
||||
* - duplicateType: "enter" (入场钢卷号重复), "current" (当前钢卷号重复), "both" (都重复), "none" (都不重复)
|
||||
* - duplicateType: "enter" (入场钢卷号重复), "current" (当前钢卷号重复), "supplier" (厂家原料卷号重复), "both" (都重复), "none" (都不重复)
|
||||
* - enterCoilNoDuplicate: 入场钢卷号是否重复 (true/false)
|
||||
* - currentCoilNoDuplicate: 当前钢卷号是否重复 (true/false)
|
||||
* - supplierCoilNoDuplicate: 厂家原料卷号是否重复 (true/false)
|
||||
*/
|
||||
Map<String, Object> checkCoilNoDuplicate(Long coilId, String enterCoilNo, String currentCoilNo);
|
||||
Map<String, Object> checkCoilNoDuplicate(Long coilId, String enterCoilNo, String currentCoilNo, String supplierCoilNo);
|
||||
|
||||
/**
|
||||
* 根据入场钢卷号前缀查询最大的入场钢卷号
|
||||
@@ -191,7 +192,7 @@ public interface IWmsMaterialCoilService {
|
||||
* @param coilId 被分卷的钢卷ID
|
||||
* @return 待操作记录ID
|
||||
*/
|
||||
Boolean startSpecialSplit(@NotNull(message = "钢卷ID不能为空") Long coilId);
|
||||
Boolean startSpecialSplit(@NotNull(message = "钢卷ID不能为空") Long coilId, Integer actionType);
|
||||
|
||||
/**
|
||||
* 特殊分卷 - 第二步:逐个创建子钢卷
|
||||
@@ -231,5 +232,7 @@ public interface IWmsMaterialCoilService {
|
||||
String enterCoilNo,
|
||||
String currentCoilNo,
|
||||
String manufacturer);
|
||||
|
||||
List<WmsMaterialCoilAllExportVo> queryExportListAll(WmsMaterialCoilBo bo);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ import com.klp.domain.WmsMaterialCoil;
|
||||
import com.klp.mapper.WmsMaterialCoilMapper;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -799,5 +801,117 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int fixSortNoByParentId(Long parentId) {
|
||||
if (parentId == null) {
|
||||
throw new ServiceException("父库位ID不能为空");
|
||||
}
|
||||
|
||||
WmsActualWarehouse parent = baseMapper.selectById(parentId);
|
||||
if (parent == null) {
|
||||
throw new ServiceException("父库位不存在");
|
||||
}
|
||||
|
||||
Long l1SortNo = parent.getSortNo() != null ? parent.getSortNo() : 0L;
|
||||
int[] counter = {1}; // Global counter for sortNo
|
||||
|
||||
if (parent.getActualWarehouseType() != null && parent.getActualWarehouseType() == 1L) {
|
||||
List<WmsActualWarehouse> l2List = baseMapper.selectList(
|
||||
new LambdaQueryWrapper<WmsActualWarehouse>()
|
||||
.eq(WmsActualWarehouse::getParentId, parentId)
|
||||
.eq(WmsActualWarehouse::getDelFlag, 0)
|
||||
);
|
||||
|
||||
int totalCount = 0;
|
||||
for (WmsActualWarehouse l2 : l2List) {
|
||||
Long l2SortNo = l2.getSortNo() != null ? l2.getSortNo() : 0L;
|
||||
totalCount += fixLevel(l2.getActualWarehouseId(), l1SortNo, l2SortNo, counter);
|
||||
}
|
||||
return totalCount;
|
||||
} else {
|
||||
Long l2SortNo = 0L;
|
||||
if (parent.getParentId() != null) {
|
||||
WmsActualWarehouse l2 = baseMapper.selectById(parent.getParentId());
|
||||
l2SortNo = l2 != null && l2.getSortNo() != null ? l2.getSortNo() : 0L;
|
||||
}
|
||||
return fixLevel(parentId, l1SortNo, l2SortNo, counter);
|
||||
}
|
||||
}
|
||||
|
||||
private int fixLevel(Long parentId, Long l1SortNo, Long l2SortNo, int[] counter) {
|
||||
List<WmsActualWarehouse> list = baseMapper.selectList(
|
||||
new LambdaQueryWrapper<WmsActualWarehouse>()
|
||||
.eq(WmsActualWarehouse::getParentId, parentId)
|
||||
.eq(WmsActualWarehouse::getDelFlag, 0)
|
||||
);
|
||||
|
||||
if (list.isEmpty()) return 0;
|
||||
|
||||
// 需求调整:此处不再对四级(小库位)进行 sort_no 修正,只修正三级(大库位)即可
|
||||
boolean isFourthLevel = list.get(0).getActualWarehouseType() != null
|
||||
&& list.get(0).getActualWarehouseType() == 4L;
|
||||
if (isFourthLevel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Map<WmsActualWarehouse, int[]> sortKeyMap = new HashMap<>();
|
||||
Pattern pattern3 = Pattern.compile("(.*?)(\\d+)-(\\d+)-(\\d+)");
|
||||
|
||||
for (WmsActualWarehouse w : list) {
|
||||
String code = w.getActualWarehouseCode();
|
||||
if (StringUtils.isBlank(code)) continue;
|
||||
|
||||
Matcher m3 = pattern3.matcher(code);
|
||||
if (m3.matches()) {
|
||||
sortKeyMap.put(w, new int[]{
|
||||
Integer.parseInt(m3.group(2)),
|
||||
Integer.parseInt(m3.group(3)),
|
||||
Integer.parseInt(m3.group(4))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
List<WmsActualWarehouse> sorted = sortKeyMap.entrySet().stream()
|
||||
.sorted((e1, e2) -> {
|
||||
int[] k1 = e1.getValue();
|
||||
int[] k2 = e2.getValue();
|
||||
int c = Integer.compare(k1[0], k2[0]);
|
||||
if (c != 0) return c;
|
||||
c = Integer.compare(k1[1], k2[1]);
|
||||
if (c != 0) return c;
|
||||
return Integer.compare(k1[2], k2[2]);
|
||||
})
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<WmsActualWarehouse> updates = new ArrayList<>();
|
||||
int totalCount = 0;
|
||||
|
||||
for (WmsActualWarehouse w : sorted) {
|
||||
long currentSortNo = l1SortNo * 100000L + l2SortNo * 10000L + counter[0];
|
||||
// 仅修正三级排序号;四级交错排序已由钢卷查询排序逻辑处理
|
||||
totalCount += fixLevel(w.getActualWarehouseId(), l1SortNo, l2SortNo, counter);
|
||||
|
||||
WmsActualWarehouse update = new WmsActualWarehouse();
|
||||
update.setActualWarehouseId(w.getActualWarehouseId());
|
||||
update.setSortNo(currentSortNo);
|
||||
updates.add(update);
|
||||
|
||||
counter[0]++;
|
||||
totalCount++;
|
||||
|
||||
if (updates.size() >= 500) {
|
||||
baseMapper.updateBatchById(updates);
|
||||
updates.clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (!updates.isEmpty()) {
|
||||
baseMapper.updateBatchById(updates);
|
||||
}
|
||||
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public class WmsApprovalServiceImpl implements IWmsApprovalService {
|
||||
|
||||
private final WmsApprovalMapper baseMapper;
|
||||
private final WmsApprovalTaskMapper approvalTaskMapper;
|
||||
private final IWmsApprovalTaskService approvalTaskService;
|
||||
private final WmsLeaveRequestMapper leaveRequestMapper;
|
||||
private final WmsOutRequestMapper outRequestMapper;
|
||||
private final ISysUserService userService;
|
||||
@@ -225,6 +226,8 @@ public class WmsApprovalServiceImpl implements IWmsApprovalService {
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getApprovalStatus()), WmsApproval::getApprovalStatus, bo.getApprovalStatus());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getApprovalOpinion()), WmsApproval::getApprovalOpinion, bo.getApprovalOpinion());
|
||||
lqw.eq(bo.getApprovalTime() != null, WmsApproval::getApprovalTime, bo.getApprovalTime());
|
||||
// 根据创建人筛选
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), WmsApproval::getCreateBy, bo.getCreateBy());
|
||||
// 根据创建时间倒叙
|
||||
lqw.orderByDesc(WmsApproval::getCreateTime);
|
||||
return lqw;
|
||||
@@ -497,4 +500,53 @@ public class WmsApprovalServiceImpl implements IWmsApprovalService {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> cancelApproval(Long approvalId) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("success", false);
|
||||
|
||||
if (approvalId == null) {
|
||||
result.put("message", "审批ID不能为空");
|
||||
return result;
|
||||
}
|
||||
|
||||
WmsApproval approval = baseMapper.selectById(approvalId);
|
||||
if (approval == null) {
|
||||
result.put("message", "审批记录不存在");
|
||||
return result;
|
||||
}
|
||||
|
||||
if ("已撤销".equals(approval.getApprovalStatus())) {
|
||||
result.put("message", "该审批已被撤销");
|
||||
return result;
|
||||
}
|
||||
|
||||
if ("已同意".equals(approval.getApprovalStatus())) {
|
||||
result.put("message", "已通过的审批不能撤销");
|
||||
return result;
|
||||
}
|
||||
|
||||
List<WmsApprovalTaskVo> tasks = approvalTaskService.queryByApprovalId(approvalId);
|
||||
if (tasks != null && !tasks.isEmpty()) {
|
||||
for (WmsApprovalTaskVo task : tasks) {
|
||||
if (task.getTaskStatus() != null && !"pending".equals(task.getTaskStatus())) {
|
||||
result.put("message", "该审批已被审批,不能撤销(审批人:" + task.getApproverName() + ",状态:" + task.getTaskStatus() + ")");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Integer deletedCount = approvalTaskService.deleteByApprovalId(approvalId);
|
||||
|
||||
approval.setApprovalStatus("已撤销");
|
||||
approval.setFinalStatus("cancelled");
|
||||
baseMapper.updateById(approval);
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", "撤销成功");
|
||||
result.put("deletedTaskCount", deletedCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -201,4 +201,10 @@ public class WmsApprovalTaskServiceImpl implements IWmsApprovalTaskService {
|
||||
.eq(WmsApprovalTask::getApprovalId, approvalId)
|
||||
.orderByAsc(WmsApprovalTask::getCreateTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer deleteByApprovalId(Long approvalId) {
|
||||
return baseMapper.delete(Wrappers.<WmsApprovalTask>lambdaQuery()
|
||||
.eq(WmsApprovalTask::getApprovalId, approvalId));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,12 @@ package com.klp.service.impl;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.klp.common.core.domain.PageQuery;
|
||||
import com.klp.common.core.page.TableDataInfo;
|
||||
import com.klp.common.exception.ServiceException;
|
||||
import com.klp.common.helper.LoginHelper;
|
||||
import com.klp.common.utils.StringUtils;
|
||||
import com.klp.domain.WmsCoilPendingAction;
|
||||
@@ -108,12 +110,25 @@ public class WmsCoilPendingActionServiceImpl implements IWmsCoilPendingActionSer
|
||||
qw.orderByDesc("wcpa.create_time");
|
||||
qw.orderByDesc("wcpa.scan_time");
|
||||
//根据开始时间和结束时间筛选修改时间
|
||||
qw.ge(bo.getStartTime() != null, "wcpa.update_time", bo.getStartTime());
|
||||
qw.le(bo.getEndTime() != null, "wcpa.update_time", bo.getEndTime());
|
||||
qw.ge(bo.getStartTime() != null, "wcpa.complete_time", bo.getStartTime());
|
||||
qw.le(bo.getEndTime() != null, "wcpa.complete_time", bo.getEndTime());
|
||||
// 根据更新人查询
|
||||
qw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), "wcpa.update_by", bo.getUpdateBy());
|
||||
//逻辑删除
|
||||
qw.eq("wcpa.del_flag", 0);
|
||||
//逻辑删除 - 支持查询已删除记录
|
||||
if (bo.getIncludeDeleted() != null) {
|
||||
if (bo.getIncludeDeleted() == 1) {
|
||||
// 包含已删除记录:不添加del_flag过滤,查询所有记录
|
||||
} else if (bo.getIncludeDeleted() == 2) {
|
||||
// 仅查询已删除记录
|
||||
qw.eq("wcpa.del_flag", 2);
|
||||
} else {
|
||||
// 默认:仅查询正常记录
|
||||
qw.eq("wcpa.del_flag", 0);
|
||||
}
|
||||
} else {
|
||||
// 未传参数时默认仅查询正常记录
|
||||
qw.eq("wcpa.del_flag", 0);
|
||||
}
|
||||
return qw;
|
||||
}
|
||||
|
||||
@@ -268,6 +283,27 @@ public class WmsCoilPendingActionServiceImpl implements IWmsCoilPendingActionSer
|
||||
return baseMapper.updateById(action) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 还原操作(将已删除的记录恢复为正常状态)
|
||||
*/
|
||||
@Override
|
||||
public Boolean restoreAction(Long actionId) {
|
||||
// 参数校验
|
||||
if (actionId == null) {
|
||||
throw new ServiceException("操作ID不能为空");
|
||||
}
|
||||
|
||||
// 使用自定义查询方法检查记录是否存在且del_flag为1(已删除)
|
||||
WmsCoilPendingAction oldAction = baseMapper.selectByActionIdAndDelFlag(actionId, 2);
|
||||
if (oldAction == null) {
|
||||
throw new ServiceException("待操作记录不存在或未被删除");
|
||||
}
|
||||
|
||||
// 使用自定义更新方法更新del_flag,绕过@TableLogic注解限制
|
||||
int rows = baseMapper.updateDelFlag(actionId, 0);
|
||||
return rows > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TheoryCycleRegressionResultVo calcTheoryCycleRegression(Date startTime, Date endTime) {
|
||||
return calcTheoryCycleRegression(startTime, endTime, true, 2000);
|
||||
|
||||
@@ -71,14 +71,14 @@ public class WmsCoilStatisticsSummaryServiceImpl implements IWmsCoilStatisticsSu
|
||||
* 新增钢卷生产统计汇总(数据透视结果持久化)
|
||||
*/
|
||||
@Override
|
||||
public Boolean insertByBo(WmsCoilStatisticsSummaryBo bo) {
|
||||
public WmsCoilStatisticsSummaryVo insertByBo(WmsCoilStatisticsSummaryBo bo) {
|
||||
WmsCoilStatisticsSummary add = BeanUtil.toBean(bo, WmsCoilStatisticsSummary.class);
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
if (flag) {
|
||||
bo.setSummaryId(add.getSummaryId());
|
||||
}
|
||||
return flag;
|
||||
return queryById(add.getSummaryId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,4 +108,22 @@ public class WmsCoilStatisticsSummaryServiceImpl implements IWmsCoilStatisticsSu
|
||||
}
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查当天是否存在指定类型的统计记录
|
||||
*/
|
||||
@Override
|
||||
public Long checkExistsByStatTypeToday(String statType) {
|
||||
if (StringUtils.isBlank(statType)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<WmsCoilStatisticsSummary> lqw = Wrappers.lambdaQuery();
|
||||
lqw.eq(WmsCoilStatisticsSummary::getStatType, statType);
|
||||
lqw.eq(WmsCoilStatisticsSummary::getDelFlag, 0);
|
||||
lqw.apply("DATE(create_time) = CURDATE()");
|
||||
lqw.select(WmsCoilStatisticsSummary::getSummaryId);
|
||||
lqw.last("LIMIT 1");
|
||||
WmsCoilStatisticsSummary one = baseMapper.selectOne(lqw);
|
||||
return one != null ? one.getSummaryId() : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,7 @@ public class WmsEmployeeInfoServiceImpl implements IWmsEmployeeInfoService {
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getEmergencyContact()), WmsEmployeeInfo::getEmergencyContact, bo.getEmergencyContact());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getRelationship()), WmsEmployeeInfo::getRelationship, bo.getRelationship());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getEmergencyContactPhone()), WmsEmployeeInfo::getEmergencyContactPhone, bo.getEmergencyContactPhone());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getSocialInsuranceType()), WmsEmployeeInfo::getSocialInsuranceType, bo.getSocialInsuranceType());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +305,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
@Override
|
||||
public TableDataInfo<WmsMaterialCoilVo> queryPageList(WmsMaterialCoilBo bo, PageQuery pageQuery) {
|
||||
QueryWrapper<WmsMaterialCoil> qw = buildQueryWrapperPlus(bo);
|
||||
Page<WmsMaterialCoilVo> result = baseMapper.selectVoPagePlus(pageQuery.build(), qw);
|
||||
Page<WmsMaterialCoilVo> result;
|
||||
if (Boolean.TRUE.equals(bo.getOrderBy())) {
|
||||
result = baseMapper.selectVoPagePlusOrderBy(pageQuery.build(), qw);
|
||||
} else {
|
||||
result = baseMapper.selectVoPagePlus(pageQuery.build(), qw);
|
||||
}
|
||||
|
||||
List<WmsMaterialCoilVo> records = result.getRecords();
|
||||
if (records == null || records.isEmpty()) {
|
||||
@@ -469,6 +474,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
}
|
||||
// 新增长度
|
||||
qw.eq(bo.getLength() != null, "mc.length", bo.getLength());
|
||||
// 实测长度
|
||||
qw.eq(bo.getActualLength() != null, "mc.actual_length", bo.getActualLength());
|
||||
// 实测宽度
|
||||
qw.eq(bo.getActualWidth() != null, "mc.actual_width", bo.getActualWidth());
|
||||
// 如果actualWarehouseId不为空,则根据实际库区ID进行查询 如果为-1,则查询无库区的数据
|
||||
if (bo.getActualWarehouseId() != null) {
|
||||
if (bo.getActualWarehouseId() == -1) {
|
||||
@@ -663,11 +672,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
qw.orderByAsc("mc.status = 1");
|
||||
qw.orderByAsc("mc.status");
|
||||
} else if (Boolean.TRUE.equals(bo.getOrderBy())) {
|
||||
// 再按实际库位ID升序(库位ID为自增,升序即可满足“先生成的库位在前”)
|
||||
// - 否则:保持原有创建时间倒序
|
||||
// MySQL: false(0) < true(1),因此 "IS NULL" 升序可实现非空在前、空值在后
|
||||
// 按库位全局排序号排序
|
||||
qw.orderByAsc("mc.actual_warehouse_id IS NULL");
|
||||
qw.orderByAsc("mc.actual_warehouse_id");
|
||||
// 全局交错排序(仅三/四级):使用 SQL 中计算好的辅助字段,避免 MP 注入拦截
|
||||
qw.orderByAsc("aw_sort_key");
|
||||
qw.orderByAsc("aw_layer_key");
|
||||
qw.orderByAsc("aw_id_key");
|
||||
} else {
|
||||
//根据创建时间倒叙
|
||||
qw.orderByDesc("mc.create_time");
|
||||
@@ -1157,6 +1167,13 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
throw new RuntimeException("历史钢卷不允许占用实际库区!");
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 已发货的钢卷不能占用实际库区,给出提醒
|
||||
if (bo.getStatus() != null && bo.getStatus().equals(1)) {
|
||||
if (bo.getActualWarehouseId() != null && !bo.getActualWarehouseId().equals(-1L)) {
|
||||
throw new RuntimeException("已发货的钢卷不允许占用实际库区!");
|
||||
}
|
||||
}
|
||||
// 直接更新钢卷属性
|
||||
WmsMaterialCoil updateCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class);
|
||||
validEntityBeforeSave(updateCoil);
|
||||
@@ -1178,8 +1195,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
|
||||
// 更新实际库区的启用状态
|
||||
if (flag) {
|
||||
// 只有当新的库区ID不为空且与原库区ID不同时才更新库区状态
|
||||
if (bo.getActualWarehouseId() != null && !bo.getActualWarehouseId().equals(oldCoil.getActualWarehouseId())) {
|
||||
// 已发货的钢卷不能占用实际库区,释放旧库区
|
||||
if (bo.getStatus() != null && bo.getStatus().equals(1)) {
|
||||
if (oldCoil.getActualWarehouseId() != null) {
|
||||
updateActualWarehouseEnableStatus(oldCoil.getActualWarehouseId(), null);
|
||||
}
|
||||
} else if (bo.getActualWarehouseId() != null && !bo.getActualWarehouseId().equals(-1L)
|
||||
&& !bo.getActualWarehouseId().equals(oldCoil.getActualWarehouseId())) {
|
||||
// 只有当新的库区ID不为空(且不为-1)且与原库区ID不同时才更新库区状态
|
||||
updateActualWarehouseEnableStatus(oldCoil.getActualWarehouseId(), bo.getActualWarehouseId());
|
||||
}
|
||||
}
|
||||
@@ -2348,7 +2371,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
*/
|
||||
@Override
|
||||
public List<WmsMaterialCoilExportVo> queryExportList(WmsMaterialCoilBo bo) {
|
||||
QueryWrapper<WmsMaterialCoil> lqw = buildQueryWrapper(bo);
|
||||
QueryWrapper<WmsMaterialCoil> lqw = buildQueryWrapperPlus(bo);
|
||||
List<WmsMaterialCoilExportVo> wmsMaterialCoilExportVos = baseMapper.selectExportList(lqw);
|
||||
// 遍历数据,根据状态替换日期字段,并处理空值兜底
|
||||
wmsMaterialCoilExportVos.stream().forEach(vo -> {
|
||||
@@ -2379,7 +2402,25 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
});
|
||||
return wmsMaterialCoilExportVos;
|
||||
}
|
||||
/**
|
||||
* 查询钢卷导出数据列表(完整版)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public List<WmsMaterialCoilAllExportVo> queryExportListAll(WmsMaterialCoilBo bo) {
|
||||
QueryWrapper<WmsMaterialCoil> lqw = buildQueryWrapperPlus(bo);
|
||||
List<WmsMaterialCoilExportVo> wmsMaterialCoilVos = baseMapper.selectExportList(lqw);
|
||||
List<WmsMaterialCoilAllExportVo> exportVoList = BeanUtil.copyToList(wmsMaterialCoilVos, WmsMaterialCoilAllExportVo.class);
|
||||
if (CollectionUtils.isNotEmpty(exportVoList)) {
|
||||
for (WmsMaterialCoilAllExportVo vo : exportVoList) {
|
||||
if (Objects.equals(vo.getDataType(), 0)) {
|
||||
vo.setActualWarehouseName(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exportVoList;
|
||||
}
|
||||
/**
|
||||
* 发货报表导出:按 coilIds 查询钢卷 + 发货单明细/主表/计划联查数据
|
||||
*/
|
||||
@@ -2532,86 +2573,6 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建查询条件
|
||||
*/
|
||||
private QueryWrapper<WmsMaterialCoil> buildQueryWrapper(WmsMaterialCoilBo bo) {
|
||||
QueryWrapper<WmsMaterialCoil> lqw = Wrappers.query();
|
||||
|
||||
// 基础字段筛选
|
||||
lqw.eq(bo.getCoilId() != null, "mc.coil_id", bo.getCoilId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getEnterCoilNo()), "mc.enter_coil_no", bo.getEnterCoilNo());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getCurrentCoilNo()), "mc.current_coil_no", bo.getCurrentCoilNo());
|
||||
lqw.like(StringUtils.isNotBlank(bo.getSupplierCoilNo()), "mc.supplier_coil_no", bo.getSupplierCoilNo());
|
||||
lqw.eq(bo.getDataType() != null, "mc.data_type", bo.getDataType());
|
||||
lqw.eq(bo.getWarehouseId() != null, "mc.warehouse_id", bo.getWarehouseId());
|
||||
lqw.eq(bo.getActualWarehouseId() != null, "mc.actual_warehouse_id", bo.getActualWarehouseId());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getItemType()), "mc.item_type", bo.getItemType());
|
||||
lqw.eq(bo.getHasMergeSplit() != null, "mc.has_merge_split", bo.getHasMergeSplit());
|
||||
// 修改itemId筛选逻辑,支持逗号分隔的多个ID查询
|
||||
if (StringUtils.isNotBlank(bo.getItemIds())) {
|
||||
String[] itemIdArray = bo.getItemIds().split(",");
|
||||
List<Long> itemIdList = new ArrayList<>();
|
||||
for (String itemIdStr : itemIdArray) {
|
||||
if (StringUtils.isNotBlank(itemIdStr)) {
|
||||
try {
|
||||
itemIdList.add(Long.parseLong(itemIdStr.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效的ID格式
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!itemIdList.isEmpty()) {
|
||||
lqw.in("mc.item_id", itemIdList);
|
||||
}
|
||||
} else if (bo.getItemId() != null) {
|
||||
// 兼容原来的itemId单值查询
|
||||
lqw.eq("mc.item_id", bo.getItemId());
|
||||
}
|
||||
|
||||
// 添加coilIds查询条件,支持逗号分隔的多个coilId查询
|
||||
if (StringUtils.isNotBlank(bo.getCoilIds())) {
|
||||
String[] coilIdArray = bo.getCoilIds().split(",");
|
||||
List<Long> coilIdList = new ArrayList<>();
|
||||
for (String coilIdStr : coilIdArray) {
|
||||
if (StringUtils.isNotBlank(coilIdStr)) {
|
||||
try {
|
||||
coilIdList.add(Long.parseLong(coilIdStr.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
// 忽略无效的ID格式
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!coilIdList.isEmpty()) {
|
||||
lqw.in("mc.coil_id", coilIdList);
|
||||
}
|
||||
}
|
||||
lqw.eq(bo.getStatus() != null, "mc.status", bo.getStatus());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getMaterialType()), "mc.material_type", bo.getMaterialType());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getQualityStatus()), "mc.quality_status", bo.getQualityStatus());
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getPackingStatus()), "mc.packing_status", bo.getPackingStatus());
|
||||
|
||||
// 把team字段作为筛选条件
|
||||
lqw.eq(StringUtils.isNotBlank(bo.getTeam()), "mc.team", bo.getTeam());
|
||||
|
||||
// 根据开始时间和结束时间筛选修改时间
|
||||
lqw.ge(bo.getStartTime() != null, "mc.update_time", bo.getStartTime());
|
||||
lqw.le(bo.getEndTime() != null, "mc.update_time", bo.getEndTime());
|
||||
|
||||
// 根据发货开始和结束筛选发货时间
|
||||
lqw.ge(bo.getByExportTimeStart() != null, "mc.export_time", bo.getByExportTimeStart());
|
||||
lqw.le(bo.getByExportTimeEnd() != null, "mc.export_time", bo.getByExportTimeEnd());
|
||||
// 逻辑删除
|
||||
lqw.eq("mc.del_flag", 0);
|
||||
|
||||
// 根据创建时间倒序
|
||||
lqw.orderByDesc("mc.create_time");
|
||||
|
||||
return lqw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 批量更新钢卷发货状态
|
||||
*
|
||||
@@ -2846,11 +2807,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
|
||||
/**
|
||||
* 检查钢卷号是否重复
|
||||
* 根据入场钢卷号和当前钢卷号查询数据库,判断哪个钢卷号重复
|
||||
* 根据入场钢卷号、当前钢卷号和厂家原料卷号查询数据库,判断哪个钢卷号重复
|
||||
* 新增逻辑:修改历史记录时不检查重复
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> checkCoilNoDuplicate(Long coilId, String enterCoilNo, String currentCoilNo) {
|
||||
public Map<String, Object> checkCoilNoDuplicate(Long coilId, String enterCoilNo, String currentCoilNo, String supplierCoilNo) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 新增核心逻辑:先判断是否操作的是历史记录
|
||||
@@ -2862,12 +2823,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
result.put("duplicateType", "none");
|
||||
result.put("enterCoilNoDuplicate", false);
|
||||
result.put("currentCoilNoDuplicate", false);
|
||||
result.put("supplierCoilNoDuplicate", false);
|
||||
return result; // 直接返回,不执行后续检查
|
||||
}
|
||||
}
|
||||
|
||||
boolean enterCoilNoDuplicate = false;
|
||||
boolean currentCoilNoDuplicate = false;
|
||||
boolean supplierCoilNoDuplicate = false;
|
||||
|
||||
// 检查入场钢卷号是否重复
|
||||
if (StringUtils.isNotBlank(enterCoilNo)) {
|
||||
@@ -2898,14 +2861,31 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
currentCoilNoDuplicate = currentCount > 0;
|
||||
}
|
||||
|
||||
// 检查厂家原料卷号是否重复
|
||||
if (StringUtils.isNotBlank(supplierCoilNo)) {
|
||||
LambdaQueryWrapper<WmsMaterialCoil> supplierWrapper = Wrappers.lambdaQuery();
|
||||
supplierWrapper.eq(WmsMaterialCoil::getSupplierCoilNo, supplierCoilNo)
|
||||
.eq(WmsMaterialCoil::getDelFlag, 0)
|
||||
.eq(WmsMaterialCoil::getDataType, 1);
|
||||
// 如果是修改操作,排除自身
|
||||
if (coilId != null) {
|
||||
supplierWrapper.ne(WmsMaterialCoil::getCoilId, coilId);
|
||||
}
|
||||
|
||||
long supplierCount = baseMapper.selectCount(supplierWrapper);
|
||||
supplierCoilNoDuplicate = supplierCount > 0;
|
||||
}
|
||||
|
||||
// 判断重复类型
|
||||
String duplicateType;
|
||||
if (enterCoilNoDuplicate && currentCoilNoDuplicate) {
|
||||
if (enterCoilNoDuplicate && currentCoilNoDuplicate && supplierCoilNoDuplicate) {
|
||||
duplicateType = "both";
|
||||
} else if (enterCoilNoDuplicate) {
|
||||
duplicateType = "enter";
|
||||
} else if (currentCoilNoDuplicate) {
|
||||
duplicateType = "current";
|
||||
} else if (supplierCoilNoDuplicate) {
|
||||
duplicateType = "supplier";
|
||||
} else {
|
||||
duplicateType = "none";
|
||||
}
|
||||
@@ -2913,6 +2893,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
result.put("duplicateType", duplicateType);
|
||||
result.put("enterCoilNoDuplicate", enterCoilNoDuplicate);
|
||||
result.put("currentCoilNoDuplicate", currentCoilNoDuplicate);
|
||||
result.put("supplierCoilNoDuplicate", supplierCoilNoDuplicate);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -3272,6 +3253,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
actualWarehouseService.updateByBo(releaseBo);
|
||||
}
|
||||
|
||||
// 将被删除的合卷钢卷的二维码设置为失效
|
||||
if (currentCoil.getQrcodeRecordId() != null) {
|
||||
WmsGenerateRecordBo deleteQrBo = new WmsGenerateRecordBo();
|
||||
deleteQrBo.setRecordId(currentCoil.getQrcodeRecordId());
|
||||
deleteQrBo.setStatus(0); // 0=失效
|
||||
generateRecordService.updateByBo(deleteQrBo);
|
||||
}
|
||||
|
||||
// 删除当前合卷钢卷
|
||||
baseMapper.deleteById(currentCoil.getCoilId());
|
||||
|
||||
@@ -3390,6 +3379,13 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
releaseBo.setIsEnabled(1);
|
||||
actualWarehouseService.updateByBo(releaseBo);
|
||||
}
|
||||
// 将被删除的子钢卷的二维码设置为失效
|
||||
if (childCoil.getQrcodeRecordId() != null) {
|
||||
WmsGenerateRecordBo deleteQrBo = new WmsGenerateRecordBo();
|
||||
deleteQrBo.setRecordId(childCoil.getQrcodeRecordId());
|
||||
deleteQrBo.setStatus(0); // 0=失效
|
||||
generateRecordService.updateByBo(deleteQrBo);
|
||||
}
|
||||
baseMapper.deleteById(childCoil.getCoilId());
|
||||
}
|
||||
|
||||
@@ -3495,7 +3491,15 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
actualWarehouseService.updateByBo(releaseBo);
|
||||
}
|
||||
|
||||
// 2. 删除当前钢卷
|
||||
// 2. 将被删除的当前钢卷的二维码设置为失效
|
||||
if (currentCoil.getQrcodeRecordId() != null) {
|
||||
WmsGenerateRecordBo deleteQrBo = new WmsGenerateRecordBo();
|
||||
deleteQrBo.setRecordId(currentCoil.getQrcodeRecordId());
|
||||
deleteQrBo.setStatus(0); // 0=失效
|
||||
generateRecordService.updateByBo(deleteQrBo);
|
||||
}
|
||||
|
||||
// 3. 删除当前钢卷
|
||||
baseMapper.deleteById(currentCoil.getCoilId());
|
||||
|
||||
// 3. 删除操作记录
|
||||
@@ -3905,7 +3909,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean startSpecialSplit(Long coilId) {
|
||||
public Boolean startSpecialSplit(Long coilId, Integer actionType) {
|
||||
// 1. 查询钢卷信息
|
||||
WmsMaterialCoil coil = baseMapper.selectById(coilId);
|
||||
if (coil == null) {
|
||||
@@ -3942,7 +3946,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
||||
WmsCoilPendingActionBo pendingActionBo = new WmsCoilPendingActionBo();
|
||||
pendingActionBo.setCoilId(coilId);
|
||||
pendingActionBo.setCurrentCoilNo(coil.getCurrentCoilNo());
|
||||
pendingActionBo.setActionType(501); // 领料操作类型
|
||||
pendingActionBo.setActionType(actionType); // 领料操作类型
|
||||
pendingActionBo.setActionStatus(0); // 待处理
|
||||
pendingActionBo.setSourceType("manual"); // 手动创建
|
||||
pendingActionBo.setPriority(0); // 默认普通优先级
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
wcpa.process_time as processTime,
|
||||
wcpa.complete_time as completeTime,
|
||||
wcpa.remark as remark,
|
||||
wcpa.del_flag as delFlag,
|
||||
wcpa.create_time as createTime,
|
||||
wcpa.create_by as createBy,
|
||||
wcpa.update_time as updateTime,
|
||||
@@ -87,5 +88,23 @@
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
<!-- 根据操作ID和删除标志查询记录(包含已删除记录) -->
|
||||
<select id="selectByActionIdAndDelFlag" resultType="com.klp.domain.WmsCoilPendingAction">
|
||||
SELECT *
|
||||
FROM wms_coil_pending_action
|
||||
WHERE action_id = #{actionId}
|
||||
AND del_flag = #{delFlag}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<!-- 更新删除标志(绕过@TableLogic注解限制) -->
|
||||
<update id="updateDelFlag">
|
||||
UPDATE wms_coil_pending_action
|
||||
SET del_flag = #{delFlag}
|
||||
WHERE action_id = #{actionId}
|
||||
</update>
|
||||
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<result property="statType" column="stat_type"/>
|
||||
<result property="statJson" column="stat_json"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="attachmentInfo" column="attachment_info"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<result property="emergencyContact" column="emergency_contact"/>
|
||||
<result property="relationship" column="relationship"/>
|
||||
<result property="emergencyContactPhone" column="emergency_contact_phone"/>
|
||||
<result property="socialInsuranceType" column="social_insurance_type"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
|
||||
@@ -22,6 +22,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="grossWeight" column="gross_weight"/>
|
||||
<result property="netWeight" column="net_weight"/>
|
||||
<result property="length" column="length"/>
|
||||
<result property="actualLength" column="actual_length"/>
|
||||
<result property="actualWidth" column="actual_width"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
@@ -100,6 +102,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
mc.packing_status,
|
||||
mc.sale_id AS saleId,
|
||||
mc.length,
|
||||
mc.actual_length,
|
||||
mc.actual_width,
|
||||
mc.coating_type,
|
||||
mc.temper_grade,
|
||||
mc.business_purpose,
|
||||
@@ -152,6 +156,105 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
) ca ON mc.coil_id = ca.coil_id
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
|
||||
<!-- orderBy=true 专用:包含库位排序辅助字段(aw_sort_key/aw_layer_key/aw_id_key)以及父库位 join -->
|
||||
<select id="selectVoPagePlusOrderBy" resultType="com.klp.domain.vo.WmsMaterialCoilVo">
|
||||
SELECT
|
||||
mc.coil_id,
|
||||
mc.parent_coil_id,
|
||||
mc.export_time,
|
||||
mc.export_by,
|
||||
mc.enter_coil_no,
|
||||
mc.current_coil_no,
|
||||
mc.supplier_coil_no,
|
||||
mc.data_type,
|
||||
mc.material_type,
|
||||
mc.next_warehouse_id,
|
||||
mc.qrcode_record_id,
|
||||
mc.team,
|
||||
mc.has_merge_split,
|
||||
mc.parent_coil_nos,
|
||||
mc.item_type,
|
||||
mc.item_id,
|
||||
mc.gross_weight,
|
||||
mc.net_weight,
|
||||
mc.status,
|
||||
mc.remark,
|
||||
mc.warehouse_id,
|
||||
mc.actual_warehouse_id,
|
||||
mc.del_flag,
|
||||
mc.create_time,
|
||||
mc.update_time,
|
||||
mc.create_by,
|
||||
mc.update_by,
|
||||
mc.quality_status,
|
||||
mc.trimming_requirement,
|
||||
mc.packaging_requirement,
|
||||
mc.packing_status,
|
||||
mc.sale_id AS saleId,
|
||||
mc.length,
|
||||
mc.actual_length,
|
||||
mc.actual_width,
|
||||
mc.coating_type,
|
||||
mc.temper_grade,
|
||||
mc.business_purpose,
|
||||
mc.is_related_to_order,
|
||||
mc.exclusive_status,
|
||||
su.nick_name AS saleName,
|
||||
w.warehouse_name AS warehouseName,
|
||||
nw.warehouse_name AS nextWarehouseName,
|
||||
aw.actual_warehouse_name AS actualWarehouseName,
|
||||
CASE WHEN mc.item_type = 'raw_material' THEN rm.specification
|
||||
WHEN mc.item_type = 'product' THEN p.specification
|
||||
ELSE NULL END AS specification,
|
||||
CASE WHEN mc.item_type = 'raw_material' THEN rm.material
|
||||
WHEN mc.item_type = 'product' THEN p.material
|
||||
ELSE NULL END AS material,
|
||||
CASE WHEN mc.item_type = 'raw_material' THEN rm.manufacturer
|
||||
WHEN mc.item_type = 'product' THEN p.manufacturer
|
||||
ELSE NULL END AS manufacturer,
|
||||
CASE WHEN mc.item_type = 'raw_material' THEN rm.surface_treatment_desc
|
||||
WHEN mc.item_type = 'product' THEN p.surface_treatment_desc
|
||||
ELSE NULL END AS surfaceTreatmentDesc,
|
||||
CASE WHEN mc.item_type = 'raw_material' THEN rm.zinc_layer
|
||||
WHEN mc.item_type = 'product' THEN p.zinc_layer
|
||||
ELSE NULL END AS zincLayer,
|
||||
-- 物品名称和编号(用于兼容)
|
||||
CASE
|
||||
WHEN mc.item_type = 'raw_material' THEN rm.raw_material_name
|
||||
WHEN mc.item_type = 'product' THEN p.product_name
|
||||
ELSE NULL
|
||||
END as itemName,
|
||||
CASE
|
||||
WHEN mc.item_type = 'raw_material' THEN rm.raw_material_code
|
||||
WHEN mc.item_type = 'product' THEN p.product_code
|
||||
ELSE NULL
|
||||
END as itemCode,
|
||||
-- 库位排序辅助字段(用于全局交错排序,避免在 ORDER BY 中写复杂表达式触发 MP 注入拦截)
|
||||
COALESCE(CASE WHEN aw.actual_warehouse_type = 4 THEN awp.sort_no ELSE aw.sort_no END, 0) AS aw_sort_key,
|
||||
CASE WHEN aw.actual_warehouse_type = 4 THEN CAST(SUBSTRING_INDEX(aw.actual_warehouse_code, '-', -1) AS UNSIGNED) ELSE 0 END AS aw_layer_key,
|
||||
COALESCE(aw.actual_warehouse_id, 0) AS aw_id_key,
|
||||
-- 异常数量统计
|
||||
COALESCE(ca.abnormal_count, 0) AS abnormalCount
|
||||
FROM wms_material_coil mc
|
||||
LEFT JOIN wms_warehouse w ON mc.warehouse_id = w.warehouse_id
|
||||
LEFT JOIN wms_warehouse nw ON mc.next_warehouse_id = nw.warehouse_id
|
||||
LEFT JOIN wms_actual_warehouse aw ON mc.actual_warehouse_id = aw.actual_warehouse_id
|
||||
LEFT JOIN wms_actual_warehouse awp ON aw.parent_id = awp.actual_warehouse_id
|
||||
LEFT JOIN sys_user su ON mc.sale_id = su.user_id
|
||||
LEFT JOIN wms_raw_material rm ON mc.item_type = 'raw_material' AND mc.item_id = rm.raw_material_id
|
||||
LEFT JOIN wms_product p ON mc.item_type = 'product' AND mc.item_id = p.product_id
|
||||
LEFT JOIN (
|
||||
SELECT coil_id, COUNT(*) AS abnormal_count
|
||||
FROM wms_coil_abnormal
|
||||
WHERE del_flag = 0
|
||||
GROUP BY coil_id
|
||||
) ca ON mc.coil_id = ca.coil_id
|
||||
${ew.customSqlSegment}
|
||||
</select>
|
||||
|
||||
|
||||
<!-- 查询不同类型的钢卷在不同库区的分布情况 -->
|
||||
<select id="getDistributionByItemType" resultType="java.util.Map">
|
||||
SELECT
|
||||
@@ -373,10 +476,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
mc.current_coil_no AS currentCoilNo,
|
||||
-- 日期
|
||||
mc.create_time AS createTime,
|
||||
-- 班组
|
||||
mc.team AS team,
|
||||
-- 发货时间
|
||||
mc.export_time AS exportTime,
|
||||
-- 新增:更新时间(用于发货时间为空时兜底)
|
||||
mc.update_time AS updateTime,
|
||||
-- 发货人
|
||||
mc.export_by AS exportBy,
|
||||
-- 重量
|
||||
mc.net_weight AS netWeight,
|
||||
-- 长度
|
||||
|
||||
Reference in New Issue
Block a user