Browse Source

init

master
han\hanst 6 months ago
parent
commit
df3da69280
  1. 8
      src/api/inbound.js
  2. 57
      src/views/main.vue
  3. 426
      src/views/modules/recv/inboundStorage.vue
  4. 1
      src/views/modules/recv/po-recv.vue
  5. 14
      src/views/modules/recv/qualifiedStorage.vue

8
src/api/inbound.js

@ -28,4 +28,10 @@ export const confirmInboundStorage = data => createAPI(`inbound/confirmInboundSt
* 删除标签
* @param {Object} data - 删除参数
*/
export const deleteLabel = data => createAPI(`inbound/deleteLabel`, 'post', data)
export const deleteLabel = data => createAPI(`inbound/deleteLabel`, 'post', data)
/**
* 获取物料清单
* @param {Object} data - 查询参数 {site, buNo, inboundNo}
*/
export const getMaterialList = data => createAPI(`inbound/getMaterialList`, 'post', data)

57
src/views/main.vue

@ -400,6 +400,8 @@ export default {
font-size: 14px;
font-weight: 500;
transition: all 0.2s ease;
min-width: 60px;
justify-content: center;
}
.logout-button:hover {
@ -407,8 +409,13 @@ export default {
}
.logout-button i {
margin-right: 4px;
margin-right: 6px;
font-size: 14px;
flex-shrink: 0;
}
.logout-button span {
white-space: nowrap;
}
/* 内容区域 */
@ -455,11 +462,16 @@ export default {
.menu-item {
background: white;
border-radius: 12px;
padding: 12px 6px;
padding: 12px 6px 10px;
text-align: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.2s;
cursor: pointer;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 80px;
}
.menu-item:active {
@ -473,8 +485,9 @@ export default {
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 6px;
margin: 0 auto 8px;
color: white;
flex-shrink: 0;
}
.menu-icon.purchase {
@ -537,6 +550,12 @@ export default {
font-size: 11px;
color: #333;
font-weight: bold;
line-height: 1.2;
margin-top: 2px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
/* 响应式设计 */
@ -552,6 +571,12 @@ export default {
.logout-button {
padding: 6px 12px;
font-size: 13px;
min-width: 55px;
}
.logout-button i {
margin-right: 5px;
font-size: 13px;
}
.warehouse-dropdown {
@ -576,11 +601,20 @@ export default {
}
.menu-item {
padding: 10px 4px;
padding: 8px 4px 6px;
min-height: 70px;
}
.menu-icon {
width: 35px;
height: 35px;
margin-bottom: 6px;
}
.menu-text {
font-size: 10px;
line-height: 1.1;
margin-top: 2px;
}
}
@ -588,6 +622,21 @@ export default {
.button-grid {
grid-template-columns: repeat(3, 1fr);
}
.menu-item {
padding: 10px 5px 8px;
min-height: 75px;
}
.menu-icon {
width: 38px;
height: 38px;
margin-bottom: 7px;
}
.menu-text {
font-size: 10.5px;
}
}
@media screen and (min-width: 768px) {

426
src/views/modules/recv/inboundStorage.vue

@ -31,11 +31,11 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">标签张数</div>
<div class="detail-value qualified">{{ materialInfo.labelCount }}/{{ materialInfo.totalLabels }}</div>
<div class="detail-value qualified">{{ materialInfo.labelinCount }}/{{ materialInfo.totalLabels }}</div>
</div>
<div class="detail-item">
<div class="detail-label">物料总数</div>
<div class="detail-value qualified">{{ materialInfo.qualifiedQty }}/{{ materialInfo.totalQty }}</div>
<div class="detail-value qualified">{{ materialInfo.totalinLabels }}/{{ materialInfo.labelCount }}</div>
</div>
<div class="detail-item">
<div class="detail-label">批次号</div>
@ -50,8 +50,13 @@
<!-- 入库信息确认标题 -->
<div class="section-title">
<i class="el-icon-circle-check"></i>
<span>入库信息确认</span>
<div class="title-left">
<i class="el-icon-circle-check"></i>
<span>入库信息确认</span>
</div>
<div class="title-right">
<span class="material-list-link" @click="showMaterialListDialog">物料清单</span>
</div>
</div>
<!-- 标签列表 -->
@ -129,11 +134,64 @@
</div>
</div>
</div>
<!-- 物料清单弹窗 -->
<div v-if="showMaterialDialog" class="material-overlay">
<div class="material-modal">
<div class="modal-header">
<span class="modal-title">物料清单</span>
<i class="el-icon-close close-btn" @click="closeMaterialDialog"></i>
</div>
<div class="modal-body">
<!-- 加载状态 -->
<div v-if="materialListLoading" class="loading-container">
<i class="el-icon-loading"></i>
<span>加载中...</span>
</div>
<!-- 物料表格 -->
<div v-else-if="materialList.length > 0" class="material-table">
<div class="table-header">
<div class="col-no">NO.</div>
<!-- <div class="col-label-code">标签条码</div>-->
<div class="col-material-code">物料编码</div>
<div class="col-required-qty">需求数量</div>
<div class="col-inbound-qty">已入库数</div>
</div>
<div class="table-body">
<div
v-for="(item, index) in materialList"
:key="index"
class="table-row"
>
<div class="col-no">{{ index + 1 }}</div>
<!-- <div class="col-label-code">{{ item.labelCode || item.rollNo }}</div>-->
<div class="col-material-code">{{ item.materialCode || item.partNo }}</div>
<div class="col-required-qty">{{ item.labelCount || 0 }}</div>
<div class="col-inbound-qty">{{ item.totalinLabels || 0 }}</div>
</div>
</div>
</div>
<!-- 空数据状态 -->
<div v-else class="empty-material">
<i class="el-icon-document"></i>
<p>暂无物料数据</p>
</div>
</div>
<div class="modal-footer">
<button class="btn-close" @click="closeMaterialDialog">关闭</button>
</div>
</div>
</div>
</div>
</template>
<script>
import { getInboundDetails, validateLabelWithInbound, confirmInboundStorage, deleteLabel } from "@/api/inbound.js";
import { getInboundDetails, validateLabelWithInbound, confirmInboundStorage, deleteLabel, getMaterialList } from "@/api/inbound.js";
import { getCurrentWarehouse } from '@/utils'
import moment from 'moment';
export default {
@ -145,7 +203,10 @@ export default {
inboundNo: '',
partNo: '',
showLocationDialog: false,
locationCode: ''
locationCode: '',
showMaterialDialog: false,
materialList: [],
materialListLoading: false
};
},
methods: {
@ -309,11 +370,53 @@ export default {
}
},
//
showMaterialListDialog() {
this.showMaterialDialog = true;
this.loadMaterialList();
},
//
loadMaterialList() {
if (!this.materialInfo.site || !this.materialInfo.buNo || !this.inboundNo) {
this.$message.error('缺少必要参数,无法获取物料清单');
return;
}
this.materialListLoading = true;
const params = {
site: this.materialInfo.site,
buNo: this.materialInfo.buNo,
inboundNo: this.inboundNo
};
getMaterialList(params).then(({ data }) => {
this.materialListLoading = false;
if (data && data.code === 0) {
this.materialList = data.data || [];
} else {
this.$message.error(data.msg || '获取物料清单失败');
this.materialList = [];
}
}).catch(error => {
this.materialListLoading = false;
console.error('获取物料清单失败:', error);
this.$message.error('获取物料清单失败');
this.materialList = [];
});
},
//
closeMaterialDialog() {
this.showMaterialDialog = false;
},
//
loadInboundDetails() {
const params = {
inboundNo: this.inboundNo,
partNo: this.partNo,
buNo: this.buNo,
warehouseId: getCurrentWarehouse(),
site:localStorage.getItem('site'),
};
@ -335,7 +438,7 @@ export default {
//
this.inboundNo = this.$route.params.inboundNo;
this.partNo = this.$route.params.partNo;
this.buNo = this.$route.params.buNo;
if (!this.inboundNo || !this.partNo) {
this.$message.error('参数错误');
this.$router.back();
@ -372,8 +475,8 @@ export default {
padding: 8px 16px;
background: #17B3A3;
color: white;
height: 50px;
min-height: 50px;
height: 40px;
min-height: 40px;
}
.header-left {
@ -494,14 +597,15 @@ export default {
}
.detail-value.qualified {
color: #00C853;
font-weight: 600;
color: #17B3A3;
font-weight: 500;
}
/* 区域标题 */
.section-title {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
background: white;
margin: 0 16px;
@ -510,16 +614,39 @@ export default {
border-bottom: 2px solid #17B3A3;
}
.section-title i {
.title-left {
display: flex;
align-items: center;
}
.title-left i {
color: #17B3A3;
font-size: 16px;
margin-right: 8px;
}
.section-title span {
.title-left span {
color: #17B3A3;
font-size: 14px;
font-weight: 500;
}
.title-right {
display: flex;
align-items: center;
}
.material-list-link {
color: #17B3A3;
font-size: 14px;
font-weight: 500;
cursor: pointer;
text-decoration: underline;
transition: color 0.2s ease;
}
.material-list-link:hover {
color: #0d8f7f;
}
/* 标签列表 */
@ -553,7 +680,7 @@ export default {
}
.col-no {
width: 40px;
width: 20px;
text-align: center;
}
@ -825,4 +952,275 @@ export default {
background: #c0c4cc;
cursor: not-allowed;
}
/* 物料清单弹窗样式 */
.material-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
}
.material-modal {
background: white;
border-radius: 12px;
width: 100%;
max-width: 800px;
max-height: 80vh;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
overflow: hidden;
display: flex;
flex-direction: column;
}
.material-modal .modal-header {
background: #17B3A3;
color: white;
padding: 5px 16px;
display: flex;
justify-content: space-between;
align-items: center;
min-height: 28px;
}
.close-btn {
font-size: 16px;
cursor: pointer;
color: white;
transition: color 0.2s ease;
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
}
.close-btn:hover {
color: #e0e0e0;
}
.material-modal .modal-title {
font-size: 16px;
font-weight: 500;
margin: 0;
line-height: 1.2;
}
.material-modal .modal-body {
flex: 1;
overflow: auto;
padding: 0;
}
.material-table {
width: 100%;
}
.table-header {
display: flex;
background: #f8f9fa;
padding: 10px 6px;
border-bottom: 2px solid #17B3A3;
font-size: 12px;
color: #333;
font-weight: 600;
position: sticky;
top: 0;
z-index: 1;
}
.table-body {
max-height: 400px;
overflow-y: auto;
}
.table-row {
display: flex;
padding: 10px 6px;
border-bottom: 1px solid #f0f0f0;
font-size: 12px;
color: #333;
transition: background-color 0.2s ease;
}
.table-row:hover {
background-color: #f8f9fa;
}
.table-row:last-child {
border-bottom: none;
}
.material-table .col-no {
width: 25px;
text-align: center;
flex-shrink: 0;
font-size: 12px;
}
.material-table .col-label-code {
flex: 1.8;
text-align: center;
min-width: 100px;
font-size: 12px;
word-break: break-all;
}
.material-table .col-material-code {
flex: 1.8;
text-align: center;
min-width: 100px;
font-size: 12px;
word-break: break-all;
}
.material-table .col-required-qty {
flex: 0.8;
text-align: center;
min-width: 65px;
font-size: 12px;
}
.material-table .col-inbound-qty {
flex: 0.8;
text-align: center;
min-width: 65px;
font-size: 12px;
}
.material-modal .modal-footer {
padding: 15px 20px;
display: flex;
justify-content: center;
border-top: 1px solid #f0f0f0;
}
.btn-close {
padding: 10px 20px;
border-radius: 6px;
font-size: 14px;
cursor: pointer;
transition: all 0.2s;
border: 1px solid #17B3A3;
background: white;
color: #17B3A3;
}
.btn-close:hover {
background: #17B3A3;
color: white;
}
/* 加载状态样式 */
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #666;
}
.loading-container i {
font-size: 24px;
margin-bottom: 12px;
color: #17B3A3;
}
.loading-container span {
font-size: 14px;
}
/* 空数据状态样式 */
.empty-material {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: #999;
}
.empty-material i {
font-size: 48px;
margin-bottom: 16px;
color: #ddd;
}
.empty-material p {
margin: 0;
font-size: 14px;
}
/* 响应式设计 - 物料清单弹窗 */
@media (max-width: 768px) {
.material-modal {
max-width: 98vw;
max-height: 85vh;
}
.material-table .col-no {
width: 25px;
font-size: 11px;
}
.material-table .col-label-code,
.material-table .col-material-code {
flex: 1.5;
min-width: 85px;
font-size: 11px;
}
.material-table .col-required-qty,
.material-table .col-inbound-qty {
flex: 0.7;
min-width: 50px;
font-size: 11px;
}
.table-header,
.table-row {
font-size: 11px;
padding: 8px 4px;
}
}
@media (max-width: 480px) {
.material-modal {
max-width: 100vw;
max-height: 90vh;
border-radius: 0;
}
.material-table .col-no {
width: 25px;
font-size: 10px;
}
.material-table .col-label-code,
.material-table .col-material-code {
flex: 1.3;
min-width: 65px;
font-size: 10px;
}
.material-table .col-required-qty,
.material-table .col-inbound-qty {
flex: 0.6;
min-width: 55px;
font-size: 10px;
}
.table-header,
.table-row {
font-size: 10px;
padding: 6px 2px;
}
}
</style>

1
src/views/modules/recv/po-recv.vue

@ -138,5 +138,6 @@ export default {
white-space: nowrap; /* 防止文字换行 */
overflow: hidden;
text-overflow: ellipsis;
margin-top: 2px;
}
</style>

14
src/views/modules/recv/qualifiedStorage.vue

@ -37,11 +37,11 @@
<div class="card-details">
<div class="detail-item">
<div class="detail-label">标签张数</div>
<div class="detail-value qualified">{{ item.labelCount }}/{{ item.totalLabels }}</div>
<div class="detail-value qualified">{{ item.labelinCount }}/{{ item.totalLabels }}</div>
</div>
<div class="detail-item">
<div class="detail-label">物料总数</div>
<div class="detail-value qualified">{{ item.qualifiedQty }}/{{ item.totalQty }}</div>
<div class="detail-value qualified">{{ item.totalinLabels }}/{{ item.labelCount }}</div>
</div>
<div class="detail-item">
<div class="detail-label">批次号</div>
@ -91,12 +91,12 @@ export default {
if (this.searchCode.trim()) {
this.searchQualifiedList(this.searchCode.trim());
} else {
this.loadQualifiedList();
this.loadQualifiedList('N');
}
},
//
loadQualifiedList() {
loadQualifiedList(isToday) {
const currentWarehouse = getCurrentWarehouse();
if (!currentWarehouse) {
this.$message.error('请先选择仓库');
@ -107,7 +107,8 @@ export default {
const params = {
warehouseId: currentWarehouse,
site:localStorage.getItem('site'),
status: 'PENDING_INBOUND' //
status: '待入库',//
inboundDate:isToday
};
getQualifiedInboundList(params).then(({ data }) => {
@ -162,6 +163,7 @@ export default {
this.$router.push({
name: 'inboundStorage',
params: {
buNo: item.buNo,
inboundNo: item.inboundNo,
partNo: item.partNo
}
@ -178,7 +180,7 @@ export default {
});
//
this.loadQualifiedList();
this.loadQualifiedList('Y');
}
};
</script>

Loading…
Cancel
Save