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> |