491 lines
14 KiB
Vue
491 lines
14 KiB
Vue
|
|
<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>
|