Merge branch '0.8.X' of http://49.232.154.205:10100/DeXun/klp-oa into 0.8.X
This commit is contained in:
@@ -0,0 +1,10 @@
|
|||||||
|
-- ------------------------------------------------------------
|
||||||
|
-- 质量评审 — 钢卷明细增加逻辑库区字段
|
||||||
|
-- V16__qc_quality_review_warehouse.sql
|
||||||
|
-- ------------------------------------------------------------
|
||||||
|
|
||||||
|
ALTER TABLE `qc_quality_review_coil`
|
||||||
|
ADD COLUMN `before_warehouse_id` bigint DEFAULT NULL COMMENT '改判前逻辑库区ID' AFTER `before_quality`,
|
||||||
|
ADD COLUMN `before_warehouse_name` varchar(100) DEFAULT NULL COMMENT '改判前逻辑库区名称' AFTER `before_warehouse_id`,
|
||||||
|
ADD COLUMN `target_warehouse_id` bigint DEFAULT NULL COMMENT '改判后目标库区ID' AFTER `regrade_quality`,
|
||||||
|
ADD COLUMN `target_warehouse_name` varchar(100) DEFAULT NULL COMMENT '改判后目标库区名称' AFTER `target_warehouse_id`;
|
||||||
@@ -55,9 +55,21 @@ public class QcQualityReviewCoil extends BaseEntity {
|
|||||||
/** 改判前质量等级 */
|
/** 改判前质量等级 */
|
||||||
private String beforeQuality;
|
private String beforeQuality;
|
||||||
|
|
||||||
|
/** 改判前逻辑库区ID */
|
||||||
|
private Long beforeWarehouseId;
|
||||||
|
|
||||||
|
/** 改判前逻辑库区名称 */
|
||||||
|
private String beforeWarehouseName;
|
||||||
|
|
||||||
/** 改判后质量状态(字典:regrade_quality_type) */
|
/** 改判后质量状态(字典:regrade_quality_type) */
|
||||||
private String regradeQuality;
|
private String regradeQuality;
|
||||||
|
|
||||||
|
/** 改判后目标库区ID */
|
||||||
|
private Long targetWarehouseId;
|
||||||
|
|
||||||
|
/** 改判后目标库区名称 */
|
||||||
|
private String targetWarehouseName;
|
||||||
|
|
||||||
/** 执行状态:0=待执行 1=已执行 */
|
/** 执行状态:0=待执行 1=已执行 */
|
||||||
private Long executeStatus;
|
private Long executeStatus;
|
||||||
|
|
||||||
|
|||||||
@@ -55,9 +55,21 @@ public class QcQualityReviewCoilBo extends BaseEntity {
|
|||||||
/** 改判前质量等级 */
|
/** 改判前质量等级 */
|
||||||
private String beforeQuality;
|
private String beforeQuality;
|
||||||
|
|
||||||
|
/** 改判前逻辑库区ID */
|
||||||
|
private Long beforeWarehouseId;
|
||||||
|
|
||||||
|
/** 改判前逻辑库区名称 */
|
||||||
|
private String beforeWarehouseName;
|
||||||
|
|
||||||
/** 改判后质量状态 */
|
/** 改判后质量状态 */
|
||||||
private String regradeQuality;
|
private String regradeQuality;
|
||||||
|
|
||||||
|
/** 改判后目标库区ID */
|
||||||
|
private Long targetWarehouseId;
|
||||||
|
|
||||||
|
/** 改判后目标库区名称 */
|
||||||
|
private String targetWarehouseName;
|
||||||
|
|
||||||
/** 执行状态 */
|
/** 执行状态 */
|
||||||
private Long executeStatus;
|
private Long executeStatus;
|
||||||
|
|
||||||
|
|||||||
@@ -53,9 +53,21 @@ public class QcQualityReviewCoilVo extends BaseEntity {
|
|||||||
/** 改判前质量等级 */
|
/** 改判前质量等级 */
|
||||||
private String beforeQuality;
|
private String beforeQuality;
|
||||||
|
|
||||||
|
/** 改判前逻辑库区ID */
|
||||||
|
private Long beforeWarehouseId;
|
||||||
|
|
||||||
|
/** 改判前逻辑库区名称 */
|
||||||
|
private String beforeWarehouseName;
|
||||||
|
|
||||||
/** 改判后质量状态 */
|
/** 改判后质量状态 */
|
||||||
private String regradeQuality;
|
private String regradeQuality;
|
||||||
|
|
||||||
|
/** 改判后目标库区ID */
|
||||||
|
private Long targetWarehouseId;
|
||||||
|
|
||||||
|
/** 改判后目标库区名称 */
|
||||||
|
private String targetWarehouseName;
|
||||||
|
|
||||||
/** 执行状态 */
|
/** 执行状态 */
|
||||||
private Long executeStatus;
|
private Long executeStatus;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import com.klp.common.core.page.TableDataInfo;
|
|||||||
import com.klp.common.utils.StringUtils;
|
import com.klp.common.utils.StringUtils;
|
||||||
import com.klp.common.helper.LoginHelper;
|
import com.klp.common.helper.LoginHelper;
|
||||||
import com.klp.domain.WmsMaterialCoil;
|
import com.klp.domain.WmsMaterialCoil;
|
||||||
|
import com.klp.domain.WmsWarehouse;
|
||||||
import com.klp.mapper.WmsMaterialCoilMapper;
|
import com.klp.mapper.WmsMaterialCoilMapper;
|
||||||
|
import com.klp.mapper.WmsWarehouseMapper;
|
||||||
import com.klp.service.IWmsMaterialCoilService;
|
import com.klp.service.IWmsMaterialCoilService;
|
||||||
import com.klp.mes.qc.domain.QcQualityReview;
|
import com.klp.mes.qc.domain.QcQualityReview;
|
||||||
import com.klp.mes.qc.domain.QcQualityReviewCoil;
|
import com.klp.mes.qc.domain.QcQualityReviewCoil;
|
||||||
@@ -43,13 +45,11 @@ import java.util.*;
|
|||||||
@Service
|
@Service
|
||||||
public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
|
public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
|
||||||
|
|
||||||
/** 技术部逻辑库ID(C/D级改判后移入此库区) */
|
|
||||||
private static final Long TECH_WAREHOUSE_ID = 2019583656787259393L;
|
|
||||||
|
|
||||||
private final QcQualityReviewMapper baseMapper;
|
private final QcQualityReviewMapper baseMapper;
|
||||||
private final QcQualityReviewCoilMapper coilMapper;
|
private final QcQualityReviewCoilMapper coilMapper;
|
||||||
private final QcQualityReviewLogMapper logMapper;
|
private final QcQualityReviewLogMapper logMapper;
|
||||||
private final WmsMaterialCoilMapper wmsMaterialCoilMapper;
|
private final WmsMaterialCoilMapper wmsMaterialCoilMapper;
|
||||||
|
private final WmsWarehouseMapper wmsWarehouseMapper;
|
||||||
private final IWmsMaterialCoilService wmsMaterialCoilService;
|
private final IWmsMaterialCoilService wmsMaterialCoilService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -313,12 +313,11 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
|
|||||||
coil.getCoilId(), coil.getRegradeQuality(), reason);
|
coil.getCoilId(), coil.getRegradeQuality(), reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 根据改判后质量等级自动更新钢卷所在逻辑库区
|
// 2. 使用手动指定的目标逻辑库区更新钢卷所在库区
|
||||||
Long targetWarehouseId = determineTargetWarehouse(coil.getRegradeQuality());
|
if (coil.getTargetWarehouseId() != null && coil.getCoilId() != null) {
|
||||||
if (targetWarehouseId != null && coil.getCoilId() != null) {
|
|
||||||
wmsMaterialCoilMapper.update(null, Wrappers.<WmsMaterialCoil>lambdaUpdate()
|
wmsMaterialCoilMapper.update(null, Wrappers.<WmsMaterialCoil>lambdaUpdate()
|
||||||
.eq(WmsMaterialCoil::getCoilId, coil.getCoilId())
|
.eq(WmsMaterialCoil::getCoilId, coil.getCoilId())
|
||||||
.set(WmsMaterialCoil::getWarehouseId, targetWarehouseId));
|
.set(WmsMaterialCoil::getWarehouseId, coil.getTargetWarehouseId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 更新明细执行状态
|
// 3. 更新明细执行状态
|
||||||
@@ -359,10 +358,12 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
|
|||||||
coil.setGroupSeq(seq);
|
coil.setGroupSeq(seq);
|
||||||
}
|
}
|
||||||
// 若未传改判前质量等级,从钢卷表获取
|
// 若未传改判前质量等级,从钢卷表获取
|
||||||
if (StringUtils.isBlank(coil.getBeforeQuality()) && coil.getCoilId() != null) {
|
if (coil.getCoilId() != null) {
|
||||||
WmsMaterialCoil wmsCoil = wmsMaterialCoilMapper.selectById(coil.getCoilId());
|
WmsMaterialCoil wmsCoil = wmsMaterialCoilMapper.selectById(coil.getCoilId());
|
||||||
if (wmsCoil != null) {
|
if (wmsCoil != null) {
|
||||||
|
if (StringUtils.isBlank(coil.getBeforeQuality())) {
|
||||||
coil.setBeforeQuality(wmsCoil.getQualityStatus());
|
coil.setBeforeQuality(wmsCoil.getQualityStatus());
|
||||||
|
}
|
||||||
if (StringUtils.isBlank(coil.getCurrentCoilNo())) {
|
if (StringUtils.isBlank(coil.getCurrentCoilNo())) {
|
||||||
coil.setCurrentCoilNo(wmsCoil.getCurrentCoilNo());
|
coil.setCurrentCoilNo(wmsCoil.getCurrentCoilNo());
|
||||||
}
|
}
|
||||||
@@ -372,6 +373,14 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
|
|||||||
if (coil.getNetWeight() == null) {
|
if (coil.getNetWeight() == null) {
|
||||||
coil.setNetWeight(wmsCoil.getNetWeight());
|
coil.setNetWeight(wmsCoil.getNetWeight());
|
||||||
}
|
}
|
||||||
|
// 自动带出当前逻辑库区
|
||||||
|
if (coil.getBeforeWarehouseId() == null && wmsCoil.getWarehouseId() != null) {
|
||||||
|
coil.setBeforeWarehouseId(wmsCoil.getWarehouseId());
|
||||||
|
WmsWarehouse wh = wmsWarehouseMapper.selectById(wmsCoil.getWarehouseId());
|
||||||
|
if (wh != null) {
|
||||||
|
coil.setBeforeWarehouseName(wh.getWarehouseName());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coilMapper.insert(coil);
|
coilMapper.insert(coil);
|
||||||
@@ -402,23 +411,6 @@ public class QcQualityReviewServiceImpl implements IQcQualityReviewService {
|
|||||||
return "QR-" + dateStr + "-" + String.format("%04d", count + 1);
|
return "QR-" + dateStr + "-" + String.format("%04d", count + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 根据改判后质量等级确定目标逻辑库区
|
|
||||||
* O/A/B → 不移动,C+/C/C- → 技术部逻辑库,D+/D/D- → 技术部逻辑库
|
|
||||||
*/
|
|
||||||
private Long determineTargetWarehouse(String regradeQuality) {
|
|
||||||
if (regradeQuality == null) return null;
|
|
||||||
// O/A/B 级不移动
|
|
||||||
if ("O".equals(regradeQuality) || "A".equals(regradeQuality) || "B".equals(regradeQuality)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// C/D 级 → 技术部逻辑库
|
|
||||||
if (regradeQuality.startsWith("C") || regradeQuality.startsWith("D")) {
|
|
||||||
return TECH_WAREHOUSE_ID;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void validEntityBeforeSave(QcQualityReview entity) {
|
private void validEntityBeforeSave(QcQualityReview entity) {
|
||||||
if (StringUtils.isBlank(entity.getProductName())) {
|
if (StringUtils.isBlank(entity.getProductName())) {
|
||||||
throw new RuntimeException("产品名称不能为空");
|
throw new RuntimeException("产品名称不能为空");
|
||||||
|
|||||||
@@ -16,7 +16,11 @@
|
|||||||
<result property="netWeight" column="net_weight"/>
|
<result property="netWeight" column="net_weight"/>
|
||||||
<result property="defectDesc" column="defect_desc"/>
|
<result property="defectDesc" column="defect_desc"/>
|
||||||
<result property="beforeQuality" column="before_quality"/>
|
<result property="beforeQuality" column="before_quality"/>
|
||||||
|
<result property="beforeWarehouseId" column="before_warehouse_id"/>
|
||||||
|
<result property="beforeWarehouseName" column="before_warehouse_name"/>
|
||||||
<result property="regradeQuality" column="regrade_quality"/>
|
<result property="regradeQuality" column="regrade_quality"/>
|
||||||
|
<result property="targetWarehouseId" column="target_warehouse_id"/>
|
||||||
|
<result property="targetWarehouseName" column="target_warehouse_name"/>
|
||||||
<result property="executeStatus" column="execute_status"/>
|
<result property="executeStatus" column="execute_status"/>
|
||||||
<result property="executeTime" column="execute_time"/>
|
<result property="executeTime" column="execute_time"/>
|
||||||
<result property="remark" column="remark"/>
|
<result property="remark" column="remark"/>
|
||||||
|
|||||||
@@ -63,6 +63,19 @@ export function exportAttendanceReport(params) {
|
|||||||
url: '/wms/attendanceRecords/exportReport',
|
url: '/wms/attendanceRecords/exportReport',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
params: params,
|
params: params,
|
||||||
responseType: 'blob'
|
responseType: 'blob',
|
||||||
|
// enames 是数组,需要特殊序列化避免逗号被二次编码
|
||||||
|
paramsSerializer: params => {
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
Object.keys(params).forEach(key => {
|
||||||
|
const val = params[key];
|
||||||
|
if (Array.isArray(val)) {
|
||||||
|
searchParams.append(key, val.join(','));
|
||||||
|
} else if (val !== undefined && val !== null && val !== '') {
|
||||||
|
searchParams.append(key, val);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return searchParams.toString();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,3 +42,20 @@ export function delEmployeeInfo(infoId) {
|
|||||||
method: 'delete'
|
method: 'delete'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取所有不重复的部门名称
|
||||||
|
export function getDepts() {
|
||||||
|
return request({
|
||||||
|
url: '/wms/employeeInfo/depts',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据部门查询在职员工
|
||||||
|
export function getEmployeesByDept(dept) {
|
||||||
|
return request({
|
||||||
|
url: '/wms/employeeInfo/employeesByDept',
|
||||||
|
method: 'get',
|
||||||
|
params: { dept }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||||
|
|
||||||
<el-table-column label="发货状态" align="center" prop="status" width="150">
|
<el-table-column label="发货状态" align="center" prop="status" width="80">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag v-if="scope.row.status === 1" type="success" size="mini">已发货</el-tag>
|
<el-tag v-if="scope.row.status === 1" type="success" size="mini">已发货</el-tag>
|
||||||
<el-tag v-else type="info" size="mini">未发货</el-tag>
|
<el-tag v-else type="info" size="mini">未发货</el-tag>
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-search"
|
<el-button size="mini" type="text" icon="el-icon-search"
|
||||||
@click="handleDigitalCoilNo(scope.row)">数字钢卷</el-button>
|
@click="handleDigitalCoilNo(scope.row)">数字钢卷</el-button>
|
||||||
<el-button size="mini" type="text" icon="el-icon-search" @click="handleTrace(scope.row)">追溯</el-button>
|
<el-button size="mini" type="text" icon="el-icon-search" @click="handleTrace(scope.row)">钢卷追溯</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</KLPTable>
|
</KLPTable>
|
||||||
@@ -283,3 +283,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.el-table .el-button + .el-button {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -39,49 +39,49 @@
|
|||||||
|
|
||||||
<!-- 产品行 -->
|
<!-- 产品行 -->
|
||||||
<div v-for="(item, index) in products" :key="index" class="table-row" :class="{ 'table-row-hover': !readonly }">
|
<div v-for="(item, index) in products" :key="index" class="table-row" :class="{ 'table-row-hover': !readonly }">
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<div class="serial-number">
|
<div class="serial-number">
|
||||||
<span>{{ index + 1 }}</span>
|
<span>{{ index + 1 }}</span>
|
||||||
<el-button v-if="!readonly && products.length > 1" type="text" size="mini" icon="el-icon-delete"
|
<el-button v-if="!readonly && products.length > 1" type="text" size="mini" icon="el-icon-delete"
|
||||||
class="delete-btn" @click="removeProduct(index)" />
|
class="delete-btn" @click="removeProduct(index)" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.spec" placeholder="请输入规格" :readonly="readonly" size="small" />
|
<el-input v-model="item.spec" placeholder="请输入规格" :readonly="readonly" size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-select v-model="item.material" placeholder="请选择材质" :disabled="readonly" size="small" filterable allow-create clearable style="width:100%;">
|
<el-select v-model="item.material" placeholder="请选择材质" :disabled="readonly" size="small" filterable allow-create clearable style="width:100%;">
|
||||||
<el-option v-for="opt in materialOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
<el-option v-for="opt in materialOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.quantity" placeholder="请输入数量" :readonly="readonly" size="small"
|
<el-input v-model="item.quantity" placeholder="请输入数量" :readonly="readonly" size="small"
|
||||||
@change="onQuantityChange(item)" />
|
@change="onQuantityChange(item)" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.taxPrice" placeholder="请输入含税单价" :readonly="readonly" size="small"
|
<el-input v-model="item.taxPrice" placeholder="请输入含税单价" :readonly="readonly" size="small"
|
||||||
@change="onTaxPriceChange(item)" />
|
@change="onTaxPriceChange(item)" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.taxDivisor" placeholder="税率除数" :readonly="readonly"
|
<el-input v-model="item.taxDivisor" placeholder="税率除数" :readonly="readonly"
|
||||||
size="small" />
|
size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.noTaxPrice" placeholder="无税单价" :readonly="readonly"
|
<el-input v-model="item.noTaxPrice" placeholder="无税单价" :readonly="readonly"
|
||||||
size="small" />
|
size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.taxTotal" placeholder="含税总额" :readonly="readonly" size="small" />
|
<el-input v-model="item.taxTotal" placeholder="含税总额" :readonly="readonly" size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.noTaxTotal" placeholder="无税总额" :readonly="readonly"
|
<el-input v-model="item.noTaxTotal" placeholder="无税总额" :readonly="readonly"
|
||||||
size="small" />
|
size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.taxAmount" placeholder="税额" :readonly="readonly" size="small" />
|
<el-input v-model="item.taxAmount" placeholder="税额" :readonly="readonly" size="small" />
|
||||||
</div>
|
</div>
|
||||||
<div class="table-cell">
|
<div class="table-cell edit-cell">
|
||||||
<el-input v-model="item.remark" placeholder="请输入备注" :readonly="readonly" size="small" />
|
<el-input v-model="item.remark" placeholder="请输入备注" :readonly="readonly" size="small" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -397,6 +397,10 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.edit-cell {
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
.table-cell:last-child {
|
.table-cell:last-child {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
<p>从左侧选择一条采购合同进行审核</p>
|
<p>从左侧选择一条采购合同进行审核</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else class="pa-view">
|
<div v-else class="pa-view" v-loading="detailLoading">
|
||||||
<div class="pa-d-head">
|
<div class="pa-d-head">
|
||||||
<div>
|
<div>
|
||||||
<span class="pa-d-title">{{ current.planNo }}</span>
|
<span class="pa-d-title">{{ current.planNo }}</span>
|
||||||
@@ -91,8 +91,9 @@
|
|||||||
<div class="pa-section">采购要求<span class="pa-section-hint" v-if="current.items && current.items.length">共 {{ current.items.length }} 项</span></div>
|
<div class="pa-section">采购要求<span class="pa-section-hint" v-if="current.items && current.items.length">共 {{ current.items.length }} 项</span></div>
|
||||||
<el-table :data="current.items || []" border size="mini" max-height="320" class="pa-table">
|
<el-table :data="current.items || []" border size="mini" max-height="320" class="pa-table">
|
||||||
<el-table-column label="#" type="index" width="44" align="center" />
|
<el-table-column label="#" type="index" width="44" align="center" />
|
||||||
<el-table-column label="规格" prop="spec" min-width="200" show-overflow-tooltip />
|
<el-table-column label="规格" prop="spec" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column label="总重量(T)" prop="weight" min-width="110" align="right" />
|
<el-table-column label="材质" prop="material" min-width="100" show-overflow-tooltip />
|
||||||
|
<el-table-column label="总重量(T)" prop="weight" min-width="100" align="right" />
|
||||||
<el-table-column label="厂商" prop="manufacturer" min-width="180" show-overflow-tooltip />
|
<el-table-column label="厂商" prop="manufacturer" min-width="180" show-overflow-tooltip />
|
||||||
<template slot="empty"><span>无采购要求</span></template>
|
<template slot="empty"><span>无采购要求</span></template>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -131,6 +132,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
loading: true,
|
loading: true,
|
||||||
buttonLoading: false,
|
buttonLoading: false,
|
||||||
|
detailLoading: false,
|
||||||
total: 0,
|
total: 0,
|
||||||
pendingCount: 0,
|
pendingCount: 0,
|
||||||
planList: [],
|
planList: [],
|
||||||
@@ -175,10 +177,11 @@ export default {
|
|||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
selectPlan(row) {
|
selectPlan(row) {
|
||||||
|
this.detailLoading = true
|
||||||
getPurchasePlan(row.planId).then(res => {
|
getPurchasePlan(row.planId).then(res => {
|
||||||
this.current = res.data || {}
|
this.current = res.data || {}
|
||||||
this.auditOpinion = this.current.auditOpinion || ''
|
this.auditOpinion = this.current.auditOpinion || ''
|
||||||
})
|
}).finally(() => { this.detailLoading = false })
|
||||||
},
|
},
|
||||||
doAudit(status) {
|
doAudit(status) {
|
||||||
this.buttonLoading = true
|
this.buttonLoading = true
|
||||||
@@ -192,10 +195,11 @@ export default {
|
|||||||
this.getList(true) // 刷新列表但保留右侧当前计划
|
this.getList(true) // 刷新列表但保留右侧当前计划
|
||||||
this.loadPendingCount()
|
this.loadPendingCount()
|
||||||
// 右侧停留在刚审核的计划:状态/历史即时更新,驳回后可直接重新审核
|
// 右侧停留在刚审核的计划:状态/历史即时更新,驳回后可直接重新审核
|
||||||
|
this.detailLoading = true
|
||||||
getPurchasePlan(pid).then(res => {
|
getPurchasePlan(pid).then(res => {
|
||||||
this.current = res.data || {}
|
this.current = res.data || {}
|
||||||
this.auditOpinion = ''
|
this.auditOpinion = ''
|
||||||
})
|
}).finally(() => { this.detailLoading = false })
|
||||||
}).finally(() => { this.buttonLoading = false })
|
}).finally(() => { this.buttonLoading = false })
|
||||||
},
|
},
|
||||||
auditText(s) {
|
auditText(s) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
<p>从左侧选择一条采购合同</p>
|
<p>从左侧选择一条采购合同</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else v-loading="detailLoading">
|
||||||
<div class="pd-d-head">
|
<div class="pd-d-head">
|
||||||
<div>
|
<div>
|
||||||
<span class="pd-d-title">{{ current.planNo }}</span>
|
<span class="pd-d-title">{{ current.planNo }}</span>
|
||||||
@@ -61,6 +61,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="pd-head-act">
|
<div class="pd-head-act">
|
||||||
<el-button size="small" icon="el-icon-refresh" :loading="refreshing" @click="doRefreshArrival">刷新到货</el-button>
|
<el-button size="small" icon="el-icon-refresh" :loading="refreshing" @click="doRefreshArrival">刷新到货</el-button>
|
||||||
|
<el-button size="small" icon="el-icon-download" @click="downloadTemplate">下载模板</el-button>
|
||||||
<el-upload
|
<el-upload
|
||||||
:headers="upload.headers"
|
:headers="upload.headers"
|
||||||
:action="uploadUrl"
|
:action="uploadUrl"
|
||||||
@@ -94,9 +95,10 @@
|
|||||||
<div class="pd-sec-title">采购要求</div>
|
<div class="pd-sec-title">采购要求</div>
|
||||||
<el-table :data="current.items" border size="mini" max-height="300">
|
<el-table :data="current.items" border size="mini" max-height="300">
|
||||||
<el-table-column label="#" type="index" width="44" align="center" />
|
<el-table-column label="#" type="index" width="44" align="center" />
|
||||||
<el-table-column label="规格" prop="spec" min-width="200" show-overflow-tooltip />
|
<el-table-column label="规格" prop="spec" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column label="总重量(T)" prop="weight" min-width="110" align="right" />
|
<el-table-column label="材质" prop="material" min-width="100" show-overflow-tooltip />
|
||||||
<el-table-column label="厂商" prop="manufacturer" min-width="180" show-overflow-tooltip />
|
<el-table-column label="总重量(T)" prop="weight" min-width="100" align="right" />
|
||||||
|
<el-table-column label="厂商" prop="manufacturer" min-width="150" show-overflow-tooltip />
|
||||||
<template slot="empty"><span>无采购要求</span></template>
|
<template slot="empty"><span>无采购要求</span></template>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
@@ -162,6 +164,7 @@ import {
|
|||||||
refreshArrival
|
refreshArrival
|
||||||
} from '@/api/erp/purchasePlan'
|
} from '@/api/erp/purchasePlan'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ErpPurchaseDelivery',
|
name: 'ErpPurchaseDelivery',
|
||||||
@@ -176,6 +179,7 @@ export default {
|
|||||||
deliveryList: [],
|
deliveryList: [],
|
||||||
deliveryLoading: false,
|
deliveryLoading: false,
|
||||||
refreshing: false,
|
refreshing: false,
|
||||||
|
detailLoading: false,
|
||||||
upload: { headers: { Authorization: 'Bearer ' + getToken() } },
|
upload: { headers: { Authorization: 'Bearer ' + getToken() } },
|
||||||
progressColor: '#5b8db8'
|
progressColor: '#5b8db8'
|
||||||
}
|
}
|
||||||
@@ -220,7 +224,8 @@ export default {
|
|||||||
refreshDetail() {
|
refreshDetail() {
|
||||||
const planId = this.current.planId
|
const planId = this.current.planId
|
||||||
if (!planId) return
|
if (!planId) return
|
||||||
getPurchasePlan(planId).then(res => { this.current = { ...this.current, ...(res.data || {}) } })
|
this.detailLoading = true
|
||||||
|
getPurchasePlan(planId).then(res => { this.current = { ...this.current, ...(res.data || {}) } }).finally(() => { this.detailLoading = false })
|
||||||
this.deliveryLoading = true
|
this.deliveryLoading = true
|
||||||
listDelivery(planId).then(res => { this.deliveryList = res.data || [] }).finally(() => { this.deliveryLoading = false })
|
listDelivery(planId).then(res => { this.deliveryList = res.data || [] }).finally(() => { this.deliveryLoading = false })
|
||||||
},
|
},
|
||||||
@@ -269,6 +274,15 @@ export default {
|
|||||||
},
|
},
|
||||||
contractStatusText(v) {
|
contractStatusText(v) {
|
||||||
return { 0: '草稿', 1: '生效', 2: '作废', 3: '已完成' }[v] || '—'
|
return { 0: '草稿', 1: '生效', 2: '作废', 3: '已完成' }[v] || '—'
|
||||||
|
},
|
||||||
|
downloadTemplate() {
|
||||||
|
const headers = ['日期', '牌号', '规格', '卷号', '单卷重量', '车号', '数量', '件数', '销售', '钢厂到站']
|
||||||
|
const sampleRow = ['2026-01-01', 'Q235B', '1.0*1250*C', 'COIL0001', '20.50', '辽A12345', '60.8', '3', 'XS001', '沈阳站']
|
||||||
|
const wb = XLSX.utils.book_new()
|
||||||
|
const ws = XLSX.utils.aoa_to_sheet([headers, sampleRow])
|
||||||
|
ws['!cols'] = headers.map(h => ({ wch: h.length > 4 ? 14 : 10 }))
|
||||||
|
XLSX.utils.book_append_sheet(wb, ws, '到货模板')
|
||||||
|
XLSX.writeFile(wb, '到货导入模板.xlsx')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,10 +124,13 @@
|
|||||||
</div>
|
</div>
|
||||||
<el-table :data="form.items" border size="mini" max-height="340">
|
<el-table :data="form.items" border size="mini" max-height="340">
|
||||||
<el-table-column label="#" type="index" width="44" align="center" />
|
<el-table-column label="#" type="index" width="44" align="center" />
|
||||||
<el-table-column label="规格" min-width="220">
|
<el-table-column label="规格" min-width="160">
|
||||||
<template slot-scope="s"><el-input v-model="s.row.spec" size="mini" placeholder="如 3.00×1230" /></template>
|
<template slot-scope="s"><el-input v-model="s.row.spec" size="mini" placeholder="如 3.00×1230" /></template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="总重量(T)" min-width="120">
|
<el-table-column label="材质" min-width="120">
|
||||||
|
<template slot-scope="s"><el-input v-model="s.row.material" size="mini" placeholder="如 Q235B" /></template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="总重量(T)" min-width="110">
|
||||||
<template slot-scope="s"><el-input v-model="s.row.weight" size="mini" /></template>
|
<template slot-scope="s"><el-input v-model="s.row.weight" size="mini" /></template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="厂商" min-width="200">
|
<el-table-column label="厂商" min-width="200">
|
||||||
@@ -157,7 +160,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 查看 -->
|
<!-- 查看 -->
|
||||||
<div v-else class="pp-view">
|
<div v-else class="pp-view" v-loading="detailLoading">
|
||||||
<div class="pp-d-head">
|
<div class="pp-d-head">
|
||||||
<div>
|
<div>
|
||||||
<span class="pp-d-title">{{ current.planNo }}</span>
|
<span class="pp-d-title">{{ current.planNo }}</span>
|
||||||
@@ -212,9 +215,10 @@
|
|||||||
<el-tab-pane label="采购要求" name="items">
|
<el-tab-pane label="采购要求" name="items">
|
||||||
<el-table :data="current.items" border size="mini" max-height="340">
|
<el-table :data="current.items" border size="mini" max-height="340">
|
||||||
<el-table-column label="#" type="index" width="44" align="center" />
|
<el-table-column label="#" type="index" width="44" align="center" />
|
||||||
<el-table-column label="规格" prop="spec" min-width="200" show-overflow-tooltip />
|
<el-table-column label="规格" prop="spec" min-width="160" show-overflow-tooltip />
|
||||||
<el-table-column label="总重量(T)" prop="weight" min-width="110" align="right" />
|
<el-table-column label="材质" prop="material" min-width="100" show-overflow-tooltip />
|
||||||
<el-table-column label="厂商" prop="manufacturer" min-width="180" show-overflow-tooltip />
|
<el-table-column label="总重量(T)" prop="weight" min-width="100" align="right" />
|
||||||
|
<el-table-column label="厂商" prop="manufacturer" min-width="150" show-overflow-tooltip />
|
||||||
<template slot="empty"><span>无采购要求</span></template>
|
<template slot="empty"><span>无采购要求</span></template>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -367,6 +371,7 @@ export default {
|
|||||||
},
|
},
|
||||||
buttonLoading: false,
|
buttonLoading: false,
|
||||||
submitLoading: false,
|
submitLoading: false,
|
||||||
|
detailLoading: false,
|
||||||
selectedContracts: [],
|
selectedContracts: [],
|
||||||
// 合同选择器
|
// 合同选择器
|
||||||
pickerOpen: false,
|
pickerOpen: false,
|
||||||
@@ -419,7 +424,8 @@ export default {
|
|||||||
refreshDetail() {
|
refreshDetail() {
|
||||||
const planId = this.current.planId
|
const planId = this.current.planId
|
||||||
if (!planId) return
|
if (!planId) return
|
||||||
getPurchasePlan(planId).then(res => { this.current = { ...this.current, ...(res.data || {}) } })
|
this.detailLoading = true
|
||||||
|
getPurchasePlan(planId).then(res => { this.current = { ...this.current, ...(res.data || {}) } }).finally(() => { this.detailLoading = false })
|
||||||
},
|
},
|
||||||
// ---- 新增 / 编辑 ----
|
// ---- 新增 / 编辑 ----
|
||||||
resetForm() {
|
resetForm() {
|
||||||
@@ -431,6 +437,7 @@ export default {
|
|||||||
this.mode = 'edit'
|
this.mode = 'edit'
|
||||||
},
|
},
|
||||||
handleEdit() {
|
handleEdit() {
|
||||||
|
this.detailLoading = true
|
||||||
getPurchasePlan(this.current.planId).then(res => {
|
getPurchasePlan(this.current.planId).then(res => {
|
||||||
const d = res.data || {}
|
const d = res.data || {}
|
||||||
this.form = {
|
this.form = {
|
||||||
@@ -440,7 +447,7 @@ export default {
|
|||||||
}
|
}
|
||||||
this.selectedContracts = []
|
this.selectedContracts = []
|
||||||
this.mode = 'edit'
|
this.mode = 'edit'
|
||||||
})
|
}).finally(() => { this.detailLoading = false })
|
||||||
},
|
},
|
||||||
cancelEdit() {
|
cancelEdit() {
|
||||||
this.mode = this.planList.length ? 'view' : 'empty'
|
this.mode = this.planList.length ? 'view' : 'empty'
|
||||||
@@ -520,7 +527,7 @@ export default {
|
|||||||
}).catch(() => cb([]))
|
}).catch(() => cb([]))
|
||||||
},
|
},
|
||||||
blankItem() {
|
blankItem() {
|
||||||
return { spec: '', weight: '', manufacturer: '' }
|
return { spec: '', material: '', weight: '', manufacturer: '' }
|
||||||
},
|
},
|
||||||
addItem() {
|
addItem() {
|
||||||
// 新行继承上一行的厂商(同批多为同厂),规格/重量留空
|
// 新行继承上一行的厂商(同批多为同厂),规格/重量留空
|
||||||
|
|||||||
@@ -124,12 +124,22 @@
|
|||||||
<el-tag size="mini" type="danger">{{ scope.row.beforeQuality }}</el-tag>
|
<el-tag size="mini" type="danger">{{ scope.row.beforeQuality }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="regradeQuality" label="改判后" width="110" align="center">
|
<el-table-column prop="regradeQuality" label="改判后" width="100" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-tag v-if="scope.row.regradeQuality" size="mini" type="warning">{{ scope.row.regradeQuality }}</el-tag>
|
<el-tag v-if="scope.row.regradeQuality" size="mini" type="warning">{{ scope.row.regradeQuality }}</el-tag>
|
||||||
<span v-else class="text-muted">待指定</span>
|
<span v-else class="text-muted">待指定</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="beforeWarehouseName" label="当前库区" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.beforeWarehouseName || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="targetWarehouseName" label="改判后库区" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.targetWarehouseName || '不移动' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
@@ -170,9 +180,15 @@
|
|||||||
<el-table-column prop="beforeQuality" label="当前等级" width="80" align="center">
|
<el-table-column prop="beforeQuality" label="当前等级" width="80" align="center">
|
||||||
<template slot-scope="s"><el-tag size="mini" type="danger">{{ s.row.beforeQuality }}</el-tag></template>
|
<template slot-scope="s"><el-tag size="mini" type="danger">{{ s.row.beforeQuality }}</el-tag></template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="regradeQuality" label="改判后等级" width="110" align="center">
|
<el-table-column prop="regradeQuality" label="改判后等级" width="100" align="center">
|
||||||
<template slot-scope="s"><el-tag size="mini" type="warning">{{ s.row.regradeQuality }}</el-tag></template>
|
<template slot-scope="s"><el-tag size="mini" type="warning">{{ s.row.regradeQuality }}</el-tag></template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="beforeWarehouseName" label="当前库区" width="100" />
|
||||||
|
<el-table-column prop="targetWarehouseName" label="改判后库区" width="120">
|
||||||
|
<template slot-scope="s">
|
||||||
|
<span>{{ s.row.targetWarehouseName || '不移动' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -228,7 +244,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 编辑弹窗 -->
|
<!-- 编辑弹窗 -->
|
||||||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="960px" :close-on-click-modal="false" append-to-body class="review-dialog">
|
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="1200px" :close-on-click-modal="false" append-to-body class="review-dialog">
|
||||||
<el-form ref="form" :model="editForm" :rules="rules" label-width="100px" size="small">
|
<el-form ref="form" :model="editForm" :rules="rules" label-width="100px" size="small">
|
||||||
<!-- ===== 基本信息 ===== -->
|
<!-- ===== 基本信息 ===== -->
|
||||||
<div class="dialog-section">
|
<div class="dialog-section">
|
||||||
@@ -274,19 +290,37 @@
|
|||||||
<el-table-column prop="supplierCoilNo" label="原料卷号" min-width="130" />
|
<el-table-column prop="supplierCoilNo" label="原料卷号" min-width="130" />
|
||||||
<el-table-column prop="spec" label="规格(mm)" width="100" />
|
<el-table-column prop="spec" label="规格(mm)" width="100" />
|
||||||
<el-table-column prop="netWeight" label="卷重(t)" width="80" align="right" />
|
<el-table-column prop="netWeight" label="卷重(t)" width="80" align="right" />
|
||||||
<el-table-column prop="defectDesc" label="缺陷描述" min-width="160">
|
<el-table-column prop="defectDesc" label="缺陷描述" min-width="150">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-input v-model="scope.row.defectDesc" size="mini" placeholder="输入缺陷描述" />
|
<el-input v-model="scope.row.defectDesc" size="mini" placeholder="输入缺陷" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="regradeQuality" label="改判后等级" min-width="130">
|
<el-table-column prop="beforeQuality" label="当前等级" width="80" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-select v-model="scope.row.regradeQuality" placeholder="请选择" size="mini">
|
<el-tag size="mini" type="danger">{{ scope.row.beforeQuality }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="regradeQuality" label="改判后等级" width="120">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-select v-model="scope.row.regradeQuality" placeholder="请选择" size="mini" style="width:100%;">
|
||||||
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label" :value="item.value" />
|
<el-option v-for="item in dict.type.coil_quality_status" :key="item.value" :label="item.label" :value="item.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="60" align="center">
|
<el-table-column prop="beforeWarehouseName" label="当前库区" width="100">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ scope.row.beforeWarehouseName || '-' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="targetWarehouseId" label="改判后库区" width="140">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-select v-model="scope.row.targetWarehouseId" placeholder="请选择" size="mini" style="width:100%;" @change="onTargetWarehouseChange(scope.row)">
|
||||||
|
<el-option label="不移动" :value="null" />
|
||||||
|
<el-option v-for="w in warehouseOptions" v-if="w.warehouseType === 1" :key="w.warehouseId" :label="w.warehouseName" :value="w.warehouseId" />
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" width="55" align="center">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<el-button size="mini" type="text" icon="el-icon-delete" @click="editForm.coilList.splice(scope.$index, 1)"></el-button>
|
<el-button size="mini" type="text" icon="el-icon-delete" @click="editForm.coilList.splice(scope.$index, 1)"></el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -372,6 +406,7 @@ import { listQualityReview, getQualityReview, addQualityReview, updateQualityRev
|
|||||||
submitQualityReview, approveQualityReview, rejectQualityReview, executeQualityReview,
|
submitQualityReview, approveQualityReview, rejectQualityReview, executeQualityReview,
|
||||||
listQualityReviewCoil, listQualityReviewLog } from '@/api/mes/qc/qualityReview'
|
listQualityReviewCoil, listQualityReviewLog } from '@/api/mes/qc/qualityReview'
|
||||||
import CoilSelector from '@/components/CoilSelector'
|
import CoilSelector from '@/components/CoilSelector'
|
||||||
|
import { listWarehouse } from '@/api/wms/warehouse'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'QualityReview',
|
name: 'QualityReview',
|
||||||
@@ -398,6 +433,7 @@ export default {
|
|||||||
|
|
||||||
// 钢卷选择
|
// 钢卷选择
|
||||||
showCoilSelector: false,
|
showCoilSelector: false,
|
||||||
|
warehouseOptions: [], // 库区下拉选项
|
||||||
|
|
||||||
// 编辑弹窗
|
// 编辑弹窗
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
@@ -436,6 +472,11 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
dialogVisible(val) {
|
||||||
|
if (val) this.loadWarehouseOptions()
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// ===== 列表 =====
|
// ===== 列表 =====
|
||||||
handleQuery() {
|
handleQuery() {
|
||||||
@@ -546,24 +587,51 @@ export default {
|
|||||||
// ===== 钢卷选择(弹窗内) =====
|
// ===== 钢卷选择(弹窗内) =====
|
||||||
onDialogCoilConfirm(selected) {
|
onDialogCoilConfirm(selected) {
|
||||||
if (!selected || selected.length === 0) return
|
if (!selected || selected.length === 0) return
|
||||||
|
const existingIds = new Set(this.editForm.coilList.map(c => c.coilId))
|
||||||
|
const newSelected = selected.filter(coil => !existingIds.has(coil.coilId))
|
||||||
|
const dupCount = selected.length - newSelected.length
|
||||||
|
if (dupCount > 0) {
|
||||||
|
this.$message.warning(`已跳过 ${dupCount} 个重复钢卷`)
|
||||||
|
}
|
||||||
|
if (newSelected.length === 0) return
|
||||||
const startIdx = this.editForm.coilList.length || 0
|
const startIdx = this.editForm.coilList.length || 0
|
||||||
const newCoils = selected.map((coil, idx) => ({
|
const newCoils = newSelected.map((coil, idx) => ({
|
||||||
coilId: coil.coilId,
|
coilId: coil.coilId,
|
||||||
currentCoilNo: coil.currentCoilNo,
|
currentCoilNo: coil.currentCoilNo,
|
||||||
supplierCoilNo: coil.supplierCoilNo || coil.enterCoilNo,
|
supplierCoilNo: coil.supplierCoilNo || coil.enterCoilNo,
|
||||||
spec: coil.specification, // CoilSelector返回的字段名为specification
|
spec: coil.specification,
|
||||||
netWeight: coil.netWeight,
|
netWeight: coil.netWeight,
|
||||||
defectDesc: '',
|
defectDesc: '',
|
||||||
regradeQuality: '', // 改判后等级,由创建者填写
|
regradeQuality: '',
|
||||||
|
beforeWarehouseId: coil.warehouseId || null,
|
||||||
|
beforeWarehouseName: this.getWarehouseName(coil.warehouseId),
|
||||||
|
targetWarehouseId: null,
|
||||||
|
targetWarehouseName: '',
|
||||||
groupSeq: startIdx + idx + 1,
|
groupSeq: startIdx + idx + 1,
|
||||||
beforeQuality: coil.qualityStatus || 'O'
|
beforeQuality: coil.qualityStatus || 'O'
|
||||||
}))
|
}))
|
||||||
this.editForm.coilList = [...(this.editForm.coilList || []), ...newCoils]
|
this.editForm.coilList = [...(this.editForm.coilList || []), ...newCoils]
|
||||||
},
|
},
|
||||||
|
getWarehouseName(warehouseId) {
|
||||||
|
if (!warehouseId) return ''
|
||||||
|
const wh = this.warehouseOptions.find(w => w.warehouseId === warehouseId)
|
||||||
|
return wh ? wh.warehouseName : ''
|
||||||
|
},
|
||||||
handleRemoveCoil(index) {
|
handleRemoveCoil(index) {
|
||||||
this.coilList.splice(index, 1)
|
this.coilList.splice(index, 1)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ===== 库区选择 =====
|
||||||
|
loadWarehouseOptions() {
|
||||||
|
listWarehouse().then(res => {
|
||||||
|
this.warehouseOptions = res.data || []
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onTargetWarehouseChange(row) {
|
||||||
|
const selected = this.warehouseOptions.find(w => w.warehouseId === row.targetWarehouseId)
|
||||||
|
row.targetWarehouseName = selected ? selected.warehouseName : ''
|
||||||
|
},
|
||||||
|
|
||||||
// ===== 提交送审 =====
|
// ===== 提交送审 =====
|
||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
this.$confirm('确认提交送审?', '提示', { type: 'warning' }).then(() => {
|
this.$confirm('确认提交送审?', '提示', { type: 'warning' }).then(() => {
|
||||||
|
|||||||
@@ -64,9 +64,15 @@
|
|||||||
<el-table-column prop="beforeQuality" label="当前等级" width="80" align="center">
|
<el-table-column prop="beforeQuality" label="当前等级" width="80" align="center">
|
||||||
<template slot-scope="s"><el-tag size="mini" type="danger">{{ s.row.beforeQuality }}</el-tag></template>
|
<template slot-scope="s"><el-tag size="mini" type="danger">{{ s.row.beforeQuality }}</el-tag></template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="regradeQuality" label="改判后等级" width="110" align="center">
|
<el-table-column prop="regradeQuality" label="改判后等级" width="100" align="center">
|
||||||
<template slot-scope="s"><el-tag size="mini" type="warning">{{ s.row.regradeQuality }}</el-tag></template>
|
<template slot-scope="s"><el-tag size="mini" type="warning">{{ s.row.regradeQuality }}</el-tag></template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column prop="beforeWarehouseName" label="当前库区" width="100" />
|
||||||
|
<el-table-column prop="targetWarehouseName" label="改判后库区" width="120">
|
||||||
|
<template slot-scope="s">
|
||||||
|
<span>{{ s.row.targetWarehouseName || '不移动' }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top:12px;">
|
<div style="margin-top:12px;">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-container acid-do-container">
|
<div class="app-container acid-do-container">
|
||||||
<div class="search-section">
|
<div class="search-section">
|
||||||
<h3 class="page-title">综合钢卷修正</h3>
|
<h3 class="page-title">钢卷追踪</h3>
|
||||||
<el-form :model="materialQueryParams" ref="materialQueryForm" size="small" :inline="true" class="search-form">
|
<el-form :model="materialQueryParams" ref="materialQueryForm" size="small" :inline="true" class="search-form">
|
||||||
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
<el-form-item label="入场钢卷号" prop="enterCoilNo">
|
||||||
<el-input v-model="materialQueryParams.enterCoilNo" placeholder="请输入入场钢卷号" clearable
|
<el-input v-model="materialQueryParams.enterCoilNo" placeholder="请输入入场钢卷号" clearable
|
||||||
|
|||||||
@@ -211,7 +211,14 @@
|
|||||||
<el-input v-model="exportFormData.ename" placeholder="请输入姓名(可选)" clearable />
|
<el-input v-model="exportFormData.ename" placeholder="请输入姓名(可选)" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="部门" prop="deptname">
|
<el-form-item label="部门" prop="deptname">
|
||||||
<el-input v-model="exportFormData.deptname" placeholder="请输入部门(可选)" clearable />
|
<el-select v-model="exportFormData.deptname" placeholder="请选择部门(可选)" clearable filterable @change="handleDeptChange" style="width: 100%">
|
||||||
|
<el-option v-for="dept in deptList" :key="dept" :label="dept" :value="dept" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="员工" prop="enames" v-if="exportFormData.deptname">
|
||||||
|
<el-select v-model="exportFormData.enames" placeholder="请选择员工(可选,不选则导出整个部门)" multiple clearable filterable style="width: 100%">
|
||||||
|
<el-option v-for="emp in employeeList" :key="emp.name" :label="emp.name + ' (' + emp.jobType + ')'" :value="emp.name" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
@@ -224,6 +231,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { listRecords, getRecords, delRecords, addRecords, updateRecords, syncRecords, exportAttendanceReport } from "@/api/wms/attendance";
|
import { listRecords, getRecords, delRecords, addRecords, updateRecords, syncRecords, exportAttendanceReport } from "@/api/wms/attendance";
|
||||||
|
import { getDepts, getEmployeesByDept } from "@/api/wms/employeeInfo";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Records",
|
name: "Records",
|
||||||
@@ -247,12 +255,17 @@ export default {
|
|||||||
exportDialogVisible: false,
|
exportDialogVisible: false,
|
||||||
// 导出loading
|
// 导出loading
|
||||||
exportLoading: false,
|
exportLoading: false,
|
||||||
|
// 部门列表
|
||||||
|
deptList: [],
|
||||||
|
// 员工列表(根据部门动态加载)
|
||||||
|
employeeList: [],
|
||||||
// 导出表单
|
// 导出表单
|
||||||
exportFormData: {
|
exportFormData: {
|
||||||
dateRange: [],
|
dateRange: [],
|
||||||
pin: "",
|
pin: "",
|
||||||
ename: "",
|
ename: "",
|
||||||
deptname: ""
|
deptname: "",
|
||||||
|
enames: []
|
||||||
},
|
},
|
||||||
// 导出表单校验
|
// 导出表单校验
|
||||||
exportRules: {
|
exportRules: {
|
||||||
@@ -474,6 +487,12 @@ export default {
|
|||||||
this.exportFormData.pin = "";
|
this.exportFormData.pin = "";
|
||||||
this.exportFormData.ename = "";
|
this.exportFormData.ename = "";
|
||||||
this.exportFormData.deptname = "";
|
this.exportFormData.deptname = "";
|
||||||
|
this.exportFormData.enames = [];
|
||||||
|
this.employeeList = [];
|
||||||
|
// 加载部门列表
|
||||||
|
getDepts().then(res => {
|
||||||
|
this.deptList = res.data || [];
|
||||||
|
});
|
||||||
this.exportDialogVisible = true;
|
this.exportDialogVisible = true;
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.exportForm && this.$refs.exportForm.clearValidate();
|
this.$refs.exportForm && this.$refs.exportForm.clearValidate();
|
||||||
@@ -484,19 +503,51 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
/** 部门变更时加载对应员工 */
|
||||||
|
handleDeptChange(dept) {
|
||||||
|
this.exportFormData.enames = [];
|
||||||
|
if (dept) {
|
||||||
|
getEmployeesByDept(dept).then(res => {
|
||||||
|
this.employeeList = res.data || [];
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.employeeList = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
/** 执行导出考勤记录表 */
|
/** 执行导出考勤记录表 */
|
||||||
doExportReport() {
|
async doExportReport() {
|
||||||
this.$refs.exportForm.validate(valid => {
|
const valid = await this.$refs.exportForm.validate().catch(() => false);
|
||||||
if (!valid) return;
|
if (!valid) return;
|
||||||
|
|
||||||
const [startDate, endDate] = this.exportFormData.dateRange;
|
const [startDate, endDate] = this.exportFormData.dateRange;
|
||||||
this.exportLoading = true;
|
this.exportLoading = true;
|
||||||
exportAttendanceReport({
|
|
||||||
|
try {
|
||||||
|
let enames = undefined;
|
||||||
|
|
||||||
|
if (this.exportFormData.deptname) {
|
||||||
|
// 选了部门:通过 wms_employee_info 查员工姓名来过滤
|
||||||
|
if (this.exportFormData.enames && this.exportFormData.enames.length > 0) {
|
||||||
|
enames = this.exportFormData.enames;
|
||||||
|
} else {
|
||||||
|
const res = await getEmployeesByDept(this.exportFormData.deptname);
|
||||||
|
const allEmps = res.data || [];
|
||||||
|
enames = allEmps.map(e => e.name);
|
||||||
|
if (enames.length === 0) {
|
||||||
|
this.$modal.msgWarning('该部门下没有在职员工');
|
||||||
|
this.exportLoading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await exportAttendanceReport({
|
||||||
startTime: startDate,
|
startTime: startDate,
|
||||||
endTime: endDate,
|
endTime: endDate,
|
||||||
pin: this.exportFormData.pin || undefined,
|
pin: !enames ? (this.exportFormData.pin || undefined) : undefined,
|
||||||
ename: this.exportFormData.ename || undefined,
|
ename: !enames ? (this.exportFormData.ename || undefined) : undefined,
|
||||||
deptname: this.exportFormData.deptname || undefined
|
enames: enames
|
||||||
}).then(res => {
|
});
|
||||||
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
@@ -509,10 +560,9 @@ export default {
|
|||||||
this.$modal.msgSuccess("导出成功");
|
this.$modal.msgSuccess("导出成功");
|
||||||
this.exportLoading = false;
|
this.exportLoading = false;
|
||||||
this.exportDialogVisible = false;
|
this.exportDialogVisible = false;
|
||||||
}).catch(() => {
|
} catch (e) {
|
||||||
this.exportLoading = false;
|
this.exportLoading = false;
|
||||||
});
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ public class AttendanceRecordsController extends BaseController {
|
|||||||
@RequestParam String endTime,
|
@RequestParam String endTime,
|
||||||
@RequestParam(required = false) String pin,
|
@RequestParam(required = false) String pin,
|
||||||
@RequestParam(required = false) String ename,
|
@RequestParam(required = false) String ename,
|
||||||
@RequestParam(required = false) String deptname,
|
@RequestParam(required = false) String enames,
|
||||||
HttpServletResponse response) {
|
HttpServletResponse response) {
|
||||||
iAttendanceRecordsService.exportReport(startTime, endTime, pin, ename, deptname, response);
|
iAttendanceRecordsService.exportReport(startTime, endTime, pin, ename, enames, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
|
|||||||
@@ -96,4 +96,20 @@ public class WmsEmployeeInfoController extends BaseController {
|
|||||||
@PathVariable Long[] infoIds) {
|
@PathVariable Long[] infoIds) {
|
||||||
return toAjax(iWmsEmployeeInfoService.deleteWithValidByIds(Arrays.asList(infoIds), true));
|
return toAjax(iWmsEmployeeInfoService.deleteWithValidByIds(Arrays.asList(infoIds), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有不重复的部门名称
|
||||||
|
*/
|
||||||
|
@GetMapping("/depts")
|
||||||
|
public R<List<String>> getDepts() {
|
||||||
|
return R.ok(iWmsEmployeeInfoService.getDistinctDepts());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据部门查询在职员工
|
||||||
|
*/
|
||||||
|
@GetMapping("/employeesByDept")
|
||||||
|
public R<List<WmsEmployeeInfoVo>> getEmployeesByDept(@RequestParam String dept) {
|
||||||
|
return R.ok(iWmsEmployeeInfoService.getEmployeesByDept(dept));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,5 +33,5 @@ public interface IAttendanceRecordsService {
|
|||||||
/**
|
/**
|
||||||
* 导出考勤记录表(复杂格式)
|
* 导出考勤记录表(复杂格式)
|
||||||
*/
|
*/
|
||||||
void exportReport(String startTime, String endTime, String pin, String ename, String deptname, HttpServletResponse response);
|
void exportReport(String startTime, String endTime, String pin, String ename, String enames, HttpServletResponse response);
|
||||||
}
|
}
|
||||||
@@ -46,4 +46,14 @@ public interface IWmsEmployeeInfoService {
|
|||||||
* 校验并批量删除员工信息信息
|
* 校验并批量删除员工信息信息
|
||||||
*/
|
*/
|
||||||
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有不重复的部门名称
|
||||||
|
*/
|
||||||
|
List<String> getDistinctDepts();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据部门查询在职员工信息
|
||||||
|
*/
|
||||||
|
List<WmsEmployeeInfoVo> getEmployeesByDept(String dept);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class AttendanceRecordsServiceImpl implements IAttendanceRecordsService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exportReport(String startTime, String endTime, String pin, String ename, String deptname, HttpServletResponse response) {
|
public void exportReport(String startTime, String endTime, String pin, String ename, String enames, HttpServletResponse response) {
|
||||||
try {
|
try {
|
||||||
// 1. 解析时间范围
|
// 1. 解析时间范围
|
||||||
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
@@ -119,14 +119,17 @@ public class AttendanceRecordsServiceImpl implements IAttendanceRecordsService {
|
|||||||
LambdaQueryWrapper<AttendanceRecords> lqw = Wrappers.lambdaQuery();
|
LambdaQueryWrapper<AttendanceRecords> lqw = Wrappers.lambdaQuery();
|
||||||
lqw.ge(AttendanceRecords::getChecktime, startDatetime);
|
lqw.ge(AttendanceRecords::getChecktime, startDatetime);
|
||||||
lqw.le(AttendanceRecords::getChecktime, endDatetime);
|
lqw.le(AttendanceRecords::getChecktime, endDatetime);
|
||||||
|
// 如果传入了员工姓名列表,优先按姓名列表过滤
|
||||||
|
if (StringUtils.isNotBlank(enames)) {
|
||||||
|
List<String> enameList = Arrays.asList(enames.split(","));
|
||||||
|
lqw.in(AttendanceRecords::getEname, enameList);
|
||||||
|
} else {
|
||||||
if (StringUtils.isNotBlank(pin)) {
|
if (StringUtils.isNotBlank(pin)) {
|
||||||
lqw.eq(AttendanceRecords::getPin, pin);
|
lqw.eq(AttendanceRecords::getPin, pin);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(ename)) {
|
if (StringUtils.isNotBlank(ename)) {
|
||||||
lqw.like(AttendanceRecords::getEname, ename);
|
lqw.like(AttendanceRecords::getEname, ename);
|
||||||
}
|
}
|
||||||
if (StringUtils.isNotBlank(deptname)) {
|
|
||||||
lqw.eq(AttendanceRecords::getDeptname, deptname);
|
|
||||||
}
|
}
|
||||||
lqw.orderByAsc(AttendanceRecords::getPin).orderByAsc(AttendanceRecords::getChecktime);
|
lqw.orderByAsc(AttendanceRecords::getPin).orderByAsc(AttendanceRecords::getChecktime);
|
||||||
List<AttendanceRecords> records = baseMapper.selectList(lqw);
|
List<AttendanceRecords> records = baseMapper.selectList(lqw);
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ import com.klp.service.IWmsEmployeeInfoService;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 员工信息Service业务层处理
|
* 员工信息Service业务层处理
|
||||||
@@ -145,4 +147,33 @@ public class WmsEmployeeInfoServiceImpl implements IWmsEmployeeInfoService {
|
|||||||
}
|
}
|
||||||
return baseMapper.deleteBatchIds(ids) > 0;
|
return baseMapper.deleteBatchIds(ids) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有不重复的部门名称(仅在职员工)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<String> getDistinctDepts() {
|
||||||
|
LambdaQueryWrapper<WmsEmployeeInfo> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(WmsEmployeeInfo::getIsLeave, 0);
|
||||||
|
List<WmsEmployeeInfoVo> list = baseMapper.selectVoList(lqw);
|
||||||
|
return list.stream()
|
||||||
|
.map(WmsEmployeeInfoVo::getDept)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(org.apache.commons.lang3.StringUtils::isNotBlank)
|
||||||
|
.distinct()
|
||||||
|
.sorted()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据部门查询在职员工信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<WmsEmployeeInfoVo> getEmployeesByDept(String dept) {
|
||||||
|
LambdaQueryWrapper<WmsEmployeeInfo> lqw = Wrappers.lambdaQuery();
|
||||||
|
lqw.eq(WmsEmployeeInfo::getDept, dept)
|
||||||
|
.eq(WmsEmployeeInfo::getIsLeave, 0)
|
||||||
|
.orderByAsc(WmsEmployeeInfo::getName);
|
||||||
|
return baseMapper.selectVoList(lqw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user