Files
klp-mono/apps/hand-factory/pages/easycode/editby.vue
砂糖 9fab0ade4d feat(发货): 新增发货功能模块及相关页面
- 添加发货功能页面及API接口
- 更新tabbar图标和路由配置
- 修改物料信息展示逻辑
- 优化页面跳转和权限控制
- 更新应用版本至1.3.29
2026-03-28 18:02:04 +08:00

587 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="typing-container">
<view class="info-grid">
<view class="info-item">
<text class="item-label">品名</text>
<text class="item-value">{{ coilDetail.itemName }}</text>
</view>
<view class="info-item">
<text class="item-label">规格</text>
<text class="item-value">{{ coilDetail.itemSpecification }}</text>
</view>
<view class="info-item">
<text class="item-label">材质</text>
<text class="item-value">{{ coilDetail.itemMaterial }}</text>
</view>
<view class="info-item">
<text class="item-label">厂家</text>
<text class="item-value">{{ coilDetail.itemManufacturer }}</text>
</view>
<view class="info-item">
<text class="item-label">入场钢卷号</text>
<text class="item-value">{{ coilDetail.enterCoilNo || '-' }}</text>
</view>
</view>
<!-- 表单区域 -->
<view class="form-card" v-if="form.coilId">
<view class="card-title">
<text class="title-dot"></text>
<text class="title-text">钢卷信息</text>
</view>
<!-- 当前钢卷号 -->
<view class="form-item">
<text class="form-label">当前钢卷号</text>
<input v-model="form.currentCoilNo" placeholder="请输入当前钢卷号" class="form-input"
:disabled="coilDetail.dataType === 0" :class="{ 'form-input-disabled': coilDetail.dataType === 0 }" />
</view>
<!-- 班组 -->
<view class="form-item">
<text class="form-label">班组</text>
<input v-model="form.team" placeholder="请输入班组名称" class="form-input" :disabled="coilDetail.dataType === 0"
:class="{ 'form-input-disabled': coilDetail.dataType === 0 }" />
</view>
<!-- 库区选择 -->
<view class="form-item form-item-optional">
<text class="form-label-optional">目标库位</text>
<klp-warehouse-picker v-model="form.warehouseId" :disabled="coilDetail.dataType === 0" placeholder="请选择目标库区" />
</view>
<!-- <view class="form-item form-item-optional">
<text class="form-label-optional">真实库区</text>
<klp-warehouse-picker v-model="form.actualWarehouseId" :disabled="coilDetail.dataType === 0"
placeholder="请选择目标库区" ware-type="actual" />
</view> -->
<!-- 物品类型产品原材料选择使用封装组件 -->
<klp-material-picker
:item-type.sync="form.itemType"
:item-id.sync="form.itemId"
:material-type.sync="form.materialType"
:disabled="coilDetail.dataType === 0"
:page-size="2000"
/>
<!-- 毛重 -->
<view class="form-item form-item-optional">
<text class="form-label-optional">毛重 ()</text>
<input v-model="form.grossWeight" type="digit" placeholder="请输入毛重(选填)" class="form-input"
:disabled="coilDetail.dataType === 0" :class="{ 'form-input-disabled': coilDetail.dataType === 0 }" />
</view>
<!-- 净重 -->
<view class="form-item form-item-optional">
<text class="form-label-optional">净重 ()</text>
<input v-model="form.netWeight" type="digit" placeholder="请输入净重(选填)" class="form-input"
:disabled="coilDetail.dataType === 0" :class="{ 'form-input-disabled': coilDetail.dataType === 0 }" />
</view>
<!-- 长度 -->
<view class="form-item form-item-optional">
<text class="form-label-optional">长度 ()</text>
<input v-model="form.length" type="digit" placeholder="请输入长度(选填)" class="form-input"
:disabled="coilDetail.dataType === 0" :class="{ 'form-input-disabled': coilDetail.dataType === 0 }" />
</view>
<!-- 操作者信息 -->
<view class="operator-info">
<text class="operator-label">操作人</text>
<text class="operator-name">{{ operatorName }}</text>
</view>
<!-- 操作按钮 -->
<view class="action-buttons">
<button v-if="coilDetail.dataType === 1" class="btn btn-primary" @click="handleConfirm" :disabled="loading">
{{ loading ? '提交中...' : '更新钢卷信息' }}
</button>
</view>
</view>
</view>
</template>
<script>
import { getMaterialCoil, updateMaterialCoil } from '@/api/wms/coil';
import { addPendingAction } from '@/api/wms/pendingAction';
export default {
data() {
return {
form: {},
coilDetail: {
},
loading: false,
}
},
computed: {
// 获取当前操作者昵称
operatorName() {
return this.$store.state.user.nickName || this.$store.state.user.name || '未知'
}
},
methods: {
fetchCoil(coilId) {
getMaterialCoil(coilId).then(res => {
this.form = res.data;
this.coilDetail = {
...res.data,
itemName: res.data.itemName,
itemSpecification: res.data.specification,
itemManufacturer: res.data.manufacturer,
itemMaterial: res.data.material
};
console.log('钢卷信息', this.form, )
})
},
// 获取设备信息(原有方法不变)
getDeviceInfo() {
try {
const systemInfo = uni.getSystemInfoSync();
return `${systemInfo.platform} ${systemInfo.model}`;
} catch (e) {
return 'Unknown Device';
}
},
async handleConfirm() {
uni.showLoading({
title: '正在更新钢卷信息'
})
try {
this.loading = true;
// 1. 更新钢卷
console.log('待提交数据', this.form)
await updateMaterialCoil(this.form)
// 2. 创建操作记录
await addPendingAction({
actionType: 404,
coilId: this.form.coilId,
currentCoilNo: this.form.currentCoilNo,
actionStatus: 2 ,// 直接完成的操作记录
sourceType: 'scan', // 扫码来源
scanTime: new Date().toISOString(),
scanDevice: this.getDeviceInfo(),
warehouseId: this.form.warehouseId,
processTime: new Date(),
completeTime: new Date()
})
// 3. 提示操作成功
uni.showToast({
title: '更新成功',
icon: 'success'
})
// 4. 延时0.5s后返回上一级页面
setTimeout(() => {
uni.navigateBack()
}, 500)
} finally {
uni.hideLoading()
}
}
},
onLoad(options) {
// 根据传递来的信息展示在表单上
const coilId = options.coilId;
if (!coilId) {
uni.reLaunch({
url: '/pages/easycode/easycode'
})
}
this.fetchCoil(coilId);
}
}
</script>
<style scoped lang="scss">
.typing-container {
padding-bottom: 30rpx;
}
/* 扫码区域 */
.scan-section {
padding: 80rpx 40rpx;
background: #fff;
border-radius: 16rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
.scan-btn-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 30rpx;
.scan-icon {
width: 160rpx;
height: 160rpx;
border-radius: 50%;
background: linear-gradient(135deg, #007aff 0%, #0051d5 100%);
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 8rpx 24rpx rgba(0, 122, 255, 0.3);
&:active {
transform: scale(0.95);
}
}
.icon-camera {
font-size: 70rpx;
}
.scan-tip {
font-size: 28rpx;
color: #666;
}
}
}
/* 卡片样式 */
.info-card,
.material-card,
.form-card {
background: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
/* 警告卡片 */
.warning-card {
background: #fff2f0;
border: 2rpx solid #ffccc7;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
display: flex;
align-items: center;
gap: 20rpx;
.warning-icon {
font-size: 48rpx;
flex-shrink: 0;
}
.warning-content {
flex: 1;
.warning-title {
display: block;
font-size: 28rpx;
font-weight: 600;
color: #cf1322;
margin-bottom: 8rpx;
}
.warning-desc {
display: block;
font-size: 24rpx;
color: #a8071a;
line-height: 1.4;
}
}
}
.card-title {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 25rpx;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f0f0f0;
.title-dot {
width: 8rpx;
height: 28rpx;
background: #007aff;
border-radius: 4rpx;
margin-right: 12rpx;
}
.title-text {
flex: 1;
font-size: 32rpx;
font-weight: 600;
color: #333;
}
.status-badge {
font-size: 22rpx;
padding: 4rpx 12rpx;
border-radius: 12rpx;
margin-right: 10rpx;
&.status-1 {
background: #d1f2eb;
color: #0c6957;
}
&.status-0 {
background: #f8d7da;
color: #721c24;
}
}
.more-btn {
display: flex;
align-items: center;
gap: 8rpx;
padding: 8rpx 16rpx;
background: #f0f7ff;
border-radius: 20rpx;
border: 1rpx solid #007aff;
.icon-more {
font-size: 24rpx;
color: #007aff;
}
.more-text {
font-size: 24rpx;
color: #007aff;
}
}
}
/* 信息网格 */
.info-grid {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
.info-item {
flex: 1;
min-width: 45%;
background: #f8f9fa;
padding: 20rpx;
border-radius: 12rpx;
&.full-width {
flex: 0 0 100%;
}
.item-label {
display: block;
font-size: 24rpx;
color: #999;
margin-bottom: 10rpx;
}
.item-value {
display: block;
font-size: 28rpx;
color: #333;
font-weight: 500;
}
}
}
/* 表单项 */
.form-item {
margin-bottom: 30rpx;
&:last-of-type {
margin-bottom: 0;
}
.form-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 15rpx;
font-weight: 500;
&::before {
content: '*';
color: #ff4d4f;
margin-right: 6rpx;
}
}
.form-label-optional {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 15rpx;
font-weight: 500;
}
.form-input {
width: 100%;
height: 88rpx;
padding: 0 24rpx;
background: #f8f9fa;
border: 2rpx solid #e8e8e8;
border-radius: 12rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
transition: all 0.3s;
&:focus {
background: #fff;
border-color: #007aff;
}
&.form-input-disabled {
background: #f5f5f5;
color: #999;
cursor: not-allowed;
}
}
}
/* 操作者信息 */
.operator-info {
display: flex;
align-items: center;
justify-content: center;
padding: 20rpx 0;
margin-top: 20rpx;
.operator-label {
font-size: 26rpx;
color: #999;
}
.operator-name {
font-size: 26rpx;
color: #007aff;
font-weight: 500;
}
}
/* 操作按钮 */
.action-buttons {
display: flex;
gap: 20rpx;
margin-top: 30rpx;
.btn {
flex: 1;
height: 88rpx;
border-radius: 12rpx;
font-size: 30rpx;
font-weight: 500;
border: none;
transition: all 0.2s;
&:active {
transform: scale(0.98);
}
&[disabled] {
opacity: 0.6;
}
}
.btn-secondary {
background: #f5f5f5;
color: #666;
}
.btn-primary {
background: linear-gradient(135deg, #007aff 0%, #0051d5 100%);
color: #fff;
box-shadow: 0 4rpx 16rpx rgba(0, 122, 255, 0.3);
}
}
/* BOM弹窗 */
.bom-popup {
background: #fff;
border-radius: 24rpx 24rpx 0 0;
max-height: 70vh;
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
.popup-title {
font-size: 32rpx;
color: #333;
font-weight: 600;
}
.popup-close {
font-size: 40rpx;
color: #999;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.popup-body {
padding: 30rpx;
max-height: 500rpx;
.bom-item {
display: flex;
gap: 20rpx;
padding: 24rpx;
background: #f8f9fa;
border-radius: 12rpx;
margin-bottom: 20rpx;
&:last-child {
margin-bottom: 0;
}
.bom-index {
width: 60rpx;
height: 60rpx;
background: #007aff;
color: #fff;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
font-weight: bold;
flex-shrink: 0;
}
.bom-content {
flex: 1;
.bom-row {
display: flex;
margin-bottom: 10rpx;
&:last-child {
margin-bottom: 0;
}
.bom-label {
font-size: 26rpx;
color: #666;
min-width: 120rpx;
}
.bom-value {
font-size: 26rpx;
color: #333;
font-weight: 500;
}
}
}
}
.empty-tip {
text-align: center;
padding: 60rpx 0;
color: #999;
font-size: 28rpx;
}
}
}
</style>