Files
entityControl_mobile/pagesStorage/addOutStorage.vue
2026-03-06 16:50:46 +08:00

491 lines
14 KiB
Vue
Raw Permalink 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="container">
<!-- 项目描述,物料号,物料描述,供应商编码,供应商名称,SAP订单编号,入库单据号,出库单据号入库类型库位码 -->
<uv-search v-model="searchValue" placeholder="请输入" searchIcon="scan" :showAction="true" actionText="搜索"
@search="searchList" @custom="searchList" @clickIcon="getScanCode()" style="margin-bottom: 20rpx;"></uv-search>
<view class="section" v-if="list.length">
<view class="section-title">货物信息{{ list.length }}</view>
<view class="info-box" v-for="(item, index) in list" :key="index">
<view
style="display: flex;align-items: center;justify-content: space-between;width: 100%;margin-bottom: 16rpx;">
<!-- <view style="font-weight: bold;">总数量: {{ item.htQty }}</view> -->
<view></view>
<uv-button type="error" v-show="item.outboundStatus" text="已预出库" plain size="mini"></uv-button>
</view>
<view class="info-row">
<text class="info-label">物料号</text>
<text class="info-value">{{ item.wlNo }}</text>
</view>
<view class="info-row">
<text class="info-label">物料描述</text>
<text class="info-value">{{ item.wlMs }}</text>
</view>
<view class="info-row">
<text class="info-label">存放位置</text>
<text class="info-value">{{ item.pcode }}</text>
</view>
<view class="info-row">
<text class="info-label">订单号</text>
<text class="info-value">{{ item.sapNo }}</text>
</view>
<view class="info-row">
<text class="info-label">项目编号</text>
<text class="info-value">{{ item.xmNo }}</text>
</view>
<view class="info-row">
<text class="info-label">项目名称</text>
<text class="info-value">{{ item.xmMs }}</text>
</view>
<view class="info-row">
<text class="info-label">供应商</text>
<text class="info-value">{{ item.gysMc }}</text>
</view>
<view class="info-row">
<text class="info-label">身份码</text>
<text class="info-value">{{ item.entityId || "-" }}</text>
</view>
<view class="info-row">
<text class="info-label">库存数量</text>
<text class="info-value">{{ item.realQty }}({{ item.dw }})</text>
</view>
<!-- <view>
<text class="info-label">出库数量({{ item.dw }})</text>
<view class="info-row" style="margin-top: 10rpx;">
<uv-input placeholder="出库数量" class="form-control" border="surround" clearable v-model="item.htDj"></uv-input>
</view>
</view> -->
<view>
<text class="info-label">现场照片</text>
<!-- name="3" multiple -->
<uv-upload style="margin-top: 10rpx;" :fileList="item.fileList" :maxCount="1" @afterRead="afterRead($event, item)" :previewFullImage="true" @delete="deletePic($event, item)"></uv-upload>
</view>
<view>
<text class="info-label">备注</text>
<uv-textarea v-model="item.remark" placeholder="备注" style="margin-top: 10rpx;"></uv-textarea>
</view>
<view style="display: flex;width: 100%;align-items: center;justify-content: flex-end;margin-top: 20rpx;">
<uv-button type="primary" style="height: 50rpx" text="预出库" @tap="item.outboundStatus = true"
:disabled="item.outboundStatus"></uv-button>
</view>
</view>
</view>
<uv-modal ref="stockModalRef" :rules="stockRules" title="出库信息" class="stockModalForm" :showCancelButton="true"
:closeOnClickOverlay="false" @confirm="stockSubmit" asyncClose>
<view class="slot-content" style="width: 100%;">
<uv-form labelPosition="left" labelWidth="80" :model="formModel" :rules="stockRules" ref="stockFormRef">
<uv-form-item label="出库类型" prop="operationType" borderBottom>
<uni-data-select v-model="formModel.operationType" :localdata="storageTypeData"
placeholder="请选择出类型"></uni-data-select>
</uv-form-item>
<uv-form-item label="领料人" prop="teamCode" borderBottom>
<uni-data-select v-model="formModel.teamCode" :localdata="constructionData"
placeholder="请选择领料人"></uni-data-select>
</uv-form-item>
<uv-form-item label="理货员" prop="operator" borderBottom>
<uni-data-select v-model="formModel.operator" :localdata="userData" placeholder="请选择理货员"></uni-data-select>
</uv-form-item>
<uv-form-item label="预出库" prop="execStatus" borderBottom>
<uni-data-select v-model="formModel.execStatus" :localdata="execStatusList" placeholder="请选择是否预出库"></uni-data-select>
</uv-form-item>
<uv-form-item label="是否配送" prop="isDelivery" borderBottom>
<uni-data-select v-model="formModel.isDelivery" :localdata="deliveryData" placeholder="请选择配送"></uni-data-select>
</uv-form-item>
<!-- <uv-form-item label="出库时间" prop="lyTime" borderBottom>
<uv-input placeholder="请选择出库时间" border="surround" v-model="formModel.lyTime" class="disabledInput"
@tap="openCalendar" disabled>
<template v-slot:suffix>
<uv-icon name="arrow-right" color="#999" size="14"></uv-icon>
</template>
</uv-input>
</uv-form-item> -->
</uv-form>
</view>
</uv-modal>
<!-- <uv-calendar ref="calendarRef" mode="single" class="calendar" @confirm="confirmCalendar"></uv-calendar> -->
<view class="btn">
<uv-button type="primary" text="确定" size="large" style="width: 48%;" v-if="list.length" @tap="openScan">
</uv-button>
<uv-button type="primary" text="确定" size="large" style="width: 48%;" class="mainBtn" v-if="list.length"
@tap="openInfo"> </uv-button>
</view>
</view>
</template>
<script setup>
import { ref, reactive, computed } from 'vue';
import { outStockList, constructionList, outStorageTypeList, userList, addOutStock } from "@/api/storage"
import { onLoad } from "@dcloudio/uni-app";
import { uploadImg } from "@/api/upload"
const searchValue = ref("")
const getScanCode = () => {
uni.scanCode({
success: function (res) {
// console.log('条码内容:' + res.result);
searchValue.value = res.result
searchList()
}
});
}
const list = ref([])
// 搜索列表
const searchList = () => {
let obj = {
keyword: searchValue.value,
pageNum: 1,
pageSize: 200,
isChuku: 0,
}
outStockList(obj).then(res => {
// console.log("搜索", res)
res.rows.forEach(e => {
e.fileList = []
e.outboundStatus = false
});
list.value = res.rows
})
}
// 出库类型
const storageTypeData = ref([])
const getStoragTypeList = () => {
outStorageTypeList({ pageNum: 1, pageSize: 100 }).then(res => {
// console.log("入库类型", res)
res.rows.forEach(item => {
item.value = item.typeCode
item.text = item.typeName
});
storageTypeData.value = res.rows
})
}
// 施工队
const constructionData = ref([])
const getConstructionList = () => {
constructionList({ pageNum: 1, pageSize: 100 }).then(res => {
console.log("施工队", res)
res.rows.forEach(item => {
item.value = item.teamCode
item.text = item.teamName
});
constructionData.value = res.rows
})
}
// 用户
const userData = ref([])
const deliveryData = ref([
{ value: 1, text: '是' },
{ value: 0, text: '否' },
])
const approverData = ref([])
const getUserList = () => {
userList().then(res => {
// console.log("入库类型", res)
res.data.forEach(item => {
item.value = item.userId
item.text = item.userName
});
userData.value = res.data
})
}
// 上传
const afterRead = (event, item) => {
uploadImg(event.file.url, {}).then(res=>{
item.fileList.push({ url: res.url })
})
}
const deletePic = (event, item) => {
item.fileList.splice(event.index, 1)
}
onLoad(() => {
getConstructionList()
getStoragTypeList()
getUserList()
})
const openScan = () => {
uni.scanCode({
scanType: ['qrCode'],
success: function (res) {
console.log('条码内容:' + res.result);
let scanIndex = list.value.findIndex(e => e.pcode == res.result)
if (scanIndex == -1) {
uni.showToast({
title: '未找到该货物',
icon: 'none',
mask: true
})
return
} else {
if (list.value[scanIndex].outboundStatus) {
uni.showToast({
title: '该货物已预出库',
icon: 'none',
mask: true
})
return
}
list.value[scanIndex].outboundStatus = true
}
}
});
}
let ids = ref([])
const openInfo = () => {
formModel.value.operationType = ""
formModel.value.teamCode = ""
formModel.value.operator = ""
formModel.value.isDelivery = null
// formModel.value.lyTime = ""
ids.value = list.value.filter(item => item.outboundStatus)
console.log("ids", ids.value)
if (ids.value.length > 0) {
// const allFileLists = list.value.filter(item => {
// return item.outboundStatus && item.fileList.length > 0
// })
// if (!allFileLists.length) {
// uni.showToast({
// title: "请上传所有出库的货物图片",
// icon: "none"
// })
// return
// }
stockModalRef.value.open()
} else {
uni.showToast({
title: '请选择出库信息',
icon: 'none',
mask: true
})
}
}
// 弹窗
const execStatusList = ref([
{ value: "0", text: "预出库" },
{ value: "1", text: "已出库" },
]);
const stockModalRef = ref(null)
const stockFormRef = ref()
const formModel = ref({
operationType: '',
teamCode: '',
operator: '',
approverId: '',
execStatus: null,
isDelivery: null,
bizType: 1,
// lyTime: '',
})
const stockRules = ref({
'operationType': {
type: 'string',
required: true,
message: '请选择出库类型',
trigger: ['blur', 'change']
},
'teamCode': {
type: 'string',
required: true,
message: '请选择领料人',
trigger: ['blur', 'change']
},
'operator': {
type: 'number',
required: true,
message: '请选择理货员',
trigger: ['blur', 'change']
},
'execStatus': {
type: 'string',
required: true,
message: '请选择是否预出库',
trigger: ['blur', 'change']
},
'isDelivery': {
type: 'number',
required: true,
message: '请选择是否配送',
trigger: ['blur', 'change']
},
'approverId': {
type: 'number',
required: true,
message: '请选择审核员',
trigger: ['blur', 'change']
},
// 'lyTime': {
// type: 'string',
// required: true,
// message: '请选择出库时间',
// trigger: ['blur', 'change']
// },
})
// const calendarRef = ref(null)
// const openCalendar = () => {
// calendarRef.value.open()
// }
// const confirmCalendar = (res) => {
// formModel.value.lyTime = res[0]
// }
const stockSubmit = () => {
stockFormRef.value.validate().then(res => {
let form = JSON.parse(JSON.stringify(formModel.value))
let obj = {
rkBill: {
...form,
},
}
const arr = JSON.parse(JSON.stringify(list.value))
obj.rkInfoList = arr.filter(item => item.outboundStatus)
obj.rkInfoList.forEach(item => {
item.photoUrl = item.fileList.length ? item.fileList[0].url : ''
});
console.log("obj", obj)
addOutStock(obj).then(res => {
stockModalRef.value.close()
uni.showToast({
title: '出库成功',
icon: 'success',
mask: true
})
uni.navigateBack({})
})
}).catch(errors => {
stockModalRef.value.closeLoading()
})
}
</script>
<style scoped lang="scss">
.container {
padding: 30rpx;
padding-bottom: 120rpx;
background-color: #f7f7f7;
min-height: calc(100vh - 60rpx);
position: relative;
}
.section {
background: #fff;
padding: 40rpx;
margin-bottom: 30rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.1);
.form-control {
flex: 1;
border: 2rpx solid #ddd;
border-radius: 8rpx;
font-size: 28rpx;
}
.section-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 40rpx;
color: #333;
border-left: 8rpx solid #2196F3;
padding-left: 20rpx;
}
.info-box {
background: #f8f9fa;
padding: 30rpx;
border-radius: 8rpx;
margin-bottom: 20rpx;
}
.info-row {
display: flex;
justify-content: space-between;
margin-bottom: 16rpx;
}
.info-label {
color: #666;
width: 200rpx;
flex-shrink: 0;
}
.info-value {
font-weight: 500;
}
}
.btn {
position: fixed;
width: calc(100vw - 60rpx);
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
background: #FFFFFF;
}
.stockModalForm {
::v-deep .uni-select {
border-color: #FFFFFF;
border-bottom: unset;
padding: 0;
}
:deep(.uv-popup__content) {
overflow: unset !important;
}
::v-deep .uv-modal {
overflow: unset !important;
}
// ::v-deep .uv-input__content {
// flex-direction: column;
// }
::v-deep .uv-input__content__prefix-icon {
margin: 0 !important;
}
::v-deep .uv-input {
padding: 0 !important;
border: unset;
border-color: unset;
height: 70rpx;
}
::v-deep .uni-select__input-placeholder {
font-size: unset;
color: #c0c4cc;
}
::v-deep .uni-select__selector-item {
text-align: left;
}
}
::v-deep uni-toast {
z-index: 30000 !important;
}
::v-deep .calendar {
z-index: 30000 !important;
}
</style>