Smart_Canteen_Handheld_Devi.../pages/enterAndExit/exit/add.vue

706 lines
21 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>
<page-meta :page-font-size="fontValue+'px'" :root-font-size="fontValue+'px'"></page-meta>
<view class="health-form">
<Navbar title="新增出库" :showRightText="false" :isBack="true" />
<scroll-view style="width: 100%;height: calc(100vh - 80px);" scroll-y="true">
<u--form labelPosition="left" :model="form" :rules="rules" ref="uForm" style="margin-left: 20rpx;">
<u-form-item label="出库单号:" labelWidth="180rpx" style="height: 6vh">
<u--input
v-model.number="form.outCode"
placeholder="自动生成"
:disabled="true"
type="number"
></u--input>
</u-form-item>
<u-form-item label="所属区域" prop="areaId" required labelWidth="180rpx" style="height: 6vh">
<uni-data-select
v-model="form.areaId"
:localdata="selectors.areaId.options"
placeholder="请选择所属区域"
style="text-align: left;"
@change="changeWarehouse"
></uni-data-select>
</u-form-item>
<u-form-item label="货品仓库" prop="warehouseId" required labelWidth="180rpx" style="height: 6vh">
<uni-data-select
v-model="form.warehouseId"
:localdata="selectors.warehouseId.options"
placeholder="请选择货品仓库"
style="text-align: left;"
></uni-data-select>
</u-form-item>
<u-form-item label="出库类型" prop="outType" required labelWidth="180rpx" style="height: 6vh">
<uni-data-select
v-model="form.outType"
:localdata="selectors.outType.options"
placeholder="请选择入库类型"
style="text-align: left;"
></uni-data-select>
</u-form-item>
<u-form-item label="领料人" prop="fetchUserId" required labelWidth="180rpx" style="height: 6vh">
<uni-data-select
v-model="form.fetchUserId"
:localdata="selectors.fetchUserId.options"
placeholder="请选择入库人"
style="text-align: left;"
></uni-data-select>
</u-form-item>
<u-form-item label="备注说明" prop="remark" labelWidth="180rpx" style="height: 200rpx">
<uni-easyinput type="textarea" v-model="form.remark" placeholder="请输入备注" maxlength="100" />
</u-form-item>
<u-form-item style="width: 100%; padding: 20rpx 0;">
<view class="button-group">
<view @click="selectGoods" class="action-button" style="background: linear-gradient( 270deg, #7D97FF 0%, #4367F5 100%);width: 200rpx;">
<image src="/static/images/handheld/ic_select_goods.png" class="button-icon"></image>
<text class="button-text">选择货品</text>
</view>
<view @click="selectDocument" class="action-button" style="margin-left: 20rpx;background: linear-gradient( 270deg, #FFB679 0%, #EF882E 100%);width: 200rpx;">
<image src="/static/images/handheld/ic_select_document.png" class="button-icon"></image>
<text class="button-text">选择领料单</text>
</view>
</view>
</u-form-item>
<scroll-view class="chronic-science" scroll-y="true">
<view class="scroll-view-item" v-for="(item,index) in imsOutInventoryDetailAddList" :key="index">
<view class="scroll-view-item_content">
<view
style="width: 100%;height: 90%;display: flex;flex-direction: column;justify-content: space-between;padding: 15px;">
<view
style="width: 100%;font-size:26rpx;color: black;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;height: 35px;display: flex">
<checkbox-group style="width: 30px;height: 30px" @change="checkClick(item)">
<checkbox :checked="item.checked" />
</checkbox-group>
<view
style="width: 100%;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;height: 25px;display: flex;font-size:32rpx;font-weight: 600;color: #FF6816">
<view style="width:90%;">
<text style="margin-left: 10px;">{{ item.materialName }}</text>
</view>
<view style="width:10%;display: flex;align-items: center;justify-content: center">{{ index + 1 }}
</view>
</view>
</view>
<view style="width: 100%;display:flex;height: 30px">
<view style="width: 50%;display: flex;align-items: center">
<view class="scroll_title">计量单位</view>
<view class="scroll_content">{{ item.unitName }}</view>
</view>
<view style="width: 50%;display: flex;align-items: center">
<view class="scroll_title">库存数量</view>
<view class="scroll_content">{{ item.materialNum }}</view>
</view>
</view>
<view style="width: 100%;display:flex;height: 50px">
<view style="width: 100%;display: flex;align-items: center">
<view class="scroll_title_input"><i style="color:red;">*</i>领取数量</view>
<view class="scroll_content_input">
<uni-easyinput placeholder="输入数量" type="number" v-model="item.fetchNum"
@blur="calculateTotal(item)"></uni-easyinput>
</view>
</view>
</view>
</view>
</view>
</view>
</scroll-view>
</u--form>
</scroll-view>
<view class="submit-btn">
<view class="checked">
<checkbox-group @tap="checkAll">
<checkbox :checked="allChecked" />
</checkbox-group>
<text class="check-all-text">全选</text>
</view>
<view class="total-info">
<view class="total-item">
<text class="total-label">总数量:</text>
<text class="total-value">{{ totalNum }}</text>
</view>
</view>
<u-button class="action-btn delete-btn" text="删除" @click="del"></u-button>
<u-button class="action-btn save-btn" text="保存" @click="handleSubmit"></u-button>
</view>
<u-action-sheet
v-if="currentSelector"
:show="selectorVisible"
:actions="getSelectorOptions(currentSelector)"
:title="getSelectorTitle(currentSelector)"
@close="hideSelector"
style="max-height: 400px"
@select="handleSelectorSelect"></u-action-sheet>
</view>
</template>
<script>
import {
addEnterRecord,
addOutRecord,
getAreaApi,
getPersonApi,
getSupplierApi,
getWarehouseApi
} from '@/api/enterExit'
import UButton from '@/uni_modules/uview-ui/components/u-button/u-button.vue'
import URow from '@/uni_modules/uview-ui/components/u-row/u-row.vue'
export default {
components: { URow, UButton },
data() {
return {
fontValue: uni.getStorageSync('fontSize') || 8,
selectorVisible: false,
currentSelector: null,
allChecked: false,
totalMoney: 0.00,
totalNum: 0.00,
selectors: {
areaId: { options: [], title: '请选择所属区域' },
warehouseId: { options: [], title: '请选择所属仓库' },
fetchUserId: { options: [], title: '请选择领料人' },
supplierId: { options: [], title: '请选择供应商' },
outType: {
options: [
{ name: '领取出库', text: '领取出库', value: '1' },
{ name: '报损出库', text: '报损出库', value: '2' },
{ name: '退货出库', text: '退货出库', value: '3' },
{ name: '调拨出库', text: '调拨出库', value: '4' }
], title: '请选择出库类型'
}
},
imsOutInventoryDetailAddList: [],
form: {
areaName: null,
areaId: null,
warehouseId: null,
warehouseName: null,
outType: null,
remark: null,
fetchUserId: null,
supplierId: null,
status: 2,
totalAmount: 0,
totalNum: 0,
outDate: null
},//详情
showProductCalendar: false,
showExpireCalendar: false,
dateValue: new Date(),
dateValue1: new Date(),
selectedItem: {
supplierId: null,
supplierName: null
},
currentDateOption: -1,
isUploading: false,
}
},
onLoad(options) {
if (options.selectList) {
this.imsOutInventoryDetailAddList = JSON.parse(decodeURIComponent(options.selectList))
console.log('选中的货品列表:', this.imsOutInventoryDetailAddList)
this.imsOutInventoryDetailAddList.forEach(item => {
item.checked = false // 初始化为未选中状态
})
this.form = options.form ? JSON.parse(decodeURIComponent(options.form)) : this.form
console.log('form------',this.form)
this.areaControlName = this.getDisplayName('areaId', this.form.areaId)
this.calculateTotal()
}
this.getAreaControlList()
this.getWarehouseControlList()
this.getFetchUserIdControlList()
this.getSupplierControlList()
},
methods: {
async getAreaControlList() {
const res = await getAreaApi()
this.selectors.areaId.options = res.data[0].children.map(item => ({
name: item.label,
text: item.label,
value: item.id
}))
console.log(res, '区域列表')
},
async getWarehouseControlList() {
const res = await getWarehouseApi(this.form.areaId)
this.selectors.warehouseId.options = res.rows.map(item => ({
name: item.warehouseName,
text: item.warehouseName,
value: item.warehouseId
}))
console.log(res, '仓库列表')
},
async getFetchUserIdControlList() {
// 假设有一个获取入库人列表的API
const res = await getPersonApi(124) // 这里可以替换为实际的API
this.selectors.fetchUserId.options = res.rows.map(item => ({
name: item.userName,
text: item.userName,
value: item.userId
}))
console.log(res, '入库人列表')
},
async getSupplierControlList() {
// 假设有一个获取供应商列表的API
const res = await getSupplierApi() // 这里可以替换为实际的API
this.selectors.supplierId.options = res.rows.map(item => ({
name: item.supplierName,
text: item.supplierName,
value: item.supplierId
}))
console.log(res, '供应商列表')
},
showSelector(selector) {
this.currentSelector = selector
this.selectorVisible = true
},
hideSelector() {
this.currentSelector = null
this.selectorVisible = false
},
getSelectorOptions(selector) {
return this.selectors[selector]?.options || []
},
getSelectorTitle(selector) {
return this.selectors[selector]?.title || ''
},
handleSelectorSelect(e) {
this.form[this.currentSelector] = e.value
this.hideSelector()
},
changeWarehouse() {
this.form.warehouseId = null
this.getWarehouseControlList()
},
getDisplayName(selector, value) {
const options = this.selectors[selector]?.options || []
const selectedOption = options.find(option => option.value == value)
return selectedOption ? selectedOption.name : ''
},
// 单个商品的选择
checkClick(item) {
item.checked = !item.checked
if (!item.checked) {
this.allChecked = false
} else {
// 判断每一个商品是否是被选择的状态
const goods = this.imsOutInventoryDetailAddList.every(item => {
return item.checked === true
})
if (goods) {
this.allChecked = true
} else {
this.allChecked = false
}
}
},
checkAll() {
this.allChecked = !this.allChecked
if (this.allChecked) {
this.imsOutInventoryDetailAddList.map(item => {
item.checked = true
})
} else {
this.imsOutInventoryDetailAddList.map(item => {
item.checked = false
})
}
},
hideKeyboard() {
uni.hideKeyboard()
},
selectGoods() {
if (!this.form.areaId) {
uni.showToast({
title: '请先选择所属区域',
icon: 'none'
})
return
}
if (!this.form.warehouseId) {
uni.showToast({
title: '请先选择所属仓库',
icon: 'none'
})
return
}
uni.navigateTo({
url: '/pages/enterAndExit/exit/selectGoods?form=' + JSON.stringify(this.form)
})
},
selectDocument() {
if (!this.form.areaId) {
uni.showToast({
title: '请先选择所属区域',
icon: 'none'
})
return
}
if (!this.form.warehouseId) {
uni.showToast({
title: '请先选择所属仓库',
icon: 'none'
})
return
}
uni.navigateTo({
url: '/pages/enterAndExit/exit/selectDocument?form=' + JSON.stringify(this.form)
})
},
del() {
this.imsOutInventoryDetailAddList = this.imsOutInventoryDetailAddList.filter(item => !item.checked)
this.allChecked = false
this.calculateTotal()
},
handleSubmit() {
if (this.isUploading) return
this.isUploading = true
if (this.checkIsExist(this.form.areaId)) {
this.isUploading = false
uni.showToast({
title: '请选择所属区域',
icon: 'none'
})
return
} else if (this.checkIsExist(this.form.warehouseId)) {
this.isUploading = false
uni.showToast({
title: '请选择货品仓库',
icon: 'none'
})
return
} else if (this.checkIsExist(this.form.outType)) {
this.isUploading = false
uni.showToast({
title: '请选择出库类型',
icon: 'none'
})
return
} else if (this.checkIsExist(this.form.fetchUserId)) {
this.isUploading = false
uni.showToast({
title: '请选择领料人',
icon: 'none'
})
return
} else if (this.imsOutInventoryDetailAddList.length === 0) {
this.isUploading = false
uni.showToast({
title: '请选择出库货品',
icon: 'none'
})
return
}
var tf = false
this.imsOutInventoryDetailAddList.forEach(item => {
if (tf) {
this.isUploading = false
return
}
if (this.checkIsExist(item.fetchNum)) {
this.isUploading = false
uni.showToast({
title: '请输入货品:【' + item.materialName + '】的数量',
icon: 'none'
})
tf = true
return
}
if (item.materialNum && item.materialNum > 0 && item.fetchNum > item.materialNum) {
this.isUploading = false
uni.showToast({
title: '货品:【' + item.materialName + '】的出库数量不能大于库存数量【' + item.materialNum + '】',
icon: 'none'
})
tf = true
}
})
if (!tf) {
this.uploadDate()
}
},
async uploadDate() {
var list = this.imsOutInventoryDetailAddList
const now = new Date()
const dateTime = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
let param = {
...this.form,
imsOutInventoryDetailAddList: list,
totalNum: this.totalNum,
outDate: dateTime
}
const res = await addOutRecord(param)
console.log(res)
if (res.code == 200) {
uni.$u.toast('出库成功')
setTimeout(() => {
this.$tab.reLaunch('/pages/enterAndExit/exit/index')
}, 1000)
} else {
this.isUploading = false
uni.$u.toast('出库失败,请稍后再试')
}
},
checkIsExist(param) {
return param == null || param === '' || param === undefined
},
calculateTotal(e) {
if (!e || typeof e.fetchNum === 'undefined') {
this.totalNum = 0
}else if(e.fetchNum && e.fetchNum < 0) {
uni.showToast({
title: '领取数量不能小于0',
icon: 'none'
})
e.fetchNum = undefined
}
this.totalNum = this.imsOutInventoryDetailAddList.reduce((sum, item) => {
return sum + (item.fetchNum ? parseFloat(item.fetchNum) : 0)
}, 0)
}
}
}
</script>
<style scoped lang="scss">
page {
//从上到下渐变
min-height: 100vh;
background-size: 100% 100%;
}
.u-form-item {
min-height: 80rpx !important;
padding: 20rpx 0 !important;
}
.button-group {
display: flex;
justify-content: space-around;
width: 100%;
}
.action-button {
width: 48%;
height: 110rpx;
border-radius: 8rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.button-icon {
width: 40rpx;
height: 40rpx;
margin-bottom: 10rpx;
}
.button-text {
color: #FFFFFF;
font-size: 28rpx;
}
.health-form {
padding: 20rpx;
height: 100vh;
background-color: #F7F7F7;
overflow-y: hidden;
.chronic-diseases {
margin-top: 20rpx;
&__label {
font-size: 28rpx;
color: $u-main-color;
margin-bottom: 20rpx;
display: block;
}
}
}
.submit-btn {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx;
background: #fff;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.checked {
display: flex;
align-items: center;
width: 20%;
}
.check-all-text {
margin-left: 10rpx;
font-size: 26rpx;
}
.total-info {
width: 30%;
}
.total-item {
display: flex;
align-items: center;
}
.total-label {
font-size: 20rpx;
color: #A69F9A;
}
.total-value {
font-size: 28rpx;
color: #FF6816;
font-weight: bold;
margin-left: 10rpx;
}
.action-btn {
width: 150rpx !important;
height: 70rpx !important;
border-radius: 8rpx !important;
margin-left: 20rpx !important;
}
.delete-btn {
background: linear-gradient(270deg, #F87665 0%, #E43D26 100%) !important;
color: white !important;
}
.save-btn {
background: linear-gradient(270deg, #FFB679 0%, #EF882E 100%) !important;
color: white !important;
}
.searchInput {
width: 80%;
height: 40px;
margin-left: 10px;
font-size: 16px;
}
.chronic-science {
width: 100%;
height: 35vh;
.scroll-view-item {
width: 96%;
background: #fff;
margin-top: 10px;
border-radius: 23rpx;
.scroll-view-item_content {
width: 100%;
display: flex;
align-items: center;
height: fit-content;
justify-content: space-between;
border: 0.1rpx solid #ececec;
border-radius: 20rpx;
box-shadow: 0rpx 6rpx 10rpx 0rpx rgba(87, 87, 87, 0.14);
.scroll_title {
width: 50%;
font-size: 28rpx;
color: #0F274B;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-family: PingFang SC-Medium;
}
.scroll_title_input {
width: 30%;
font-size: 28rpx;
color: #0F274B;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-family: PingFang SC-Medium;
}
.scroll_content {
width: 50%;
font-size: 28rpx;
color: #86817B;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-family: PingFang SC-Regular;
}
.scroll_content_input {
width: 70%;
font-size: 28rpx;
color: #86817B;
white-space: nowrap;
text-overflow: ellipsis;
font-family: PingFang SC-Regular;
}
}
}
}
::v-deep .uni-scroll-view-content {
max-height: 16vh !important;
}
::v-deep .u-form-item {
min-height: 100rpx;
&__body__right__content__slot {
text-align: right;
}
}
::v-deep .u-checkbox {
margin-bottom: 16rpx;
}
/deep/ uni-checkbox .uni-checkbox-input {
width: 25px;
height: 25px;
border-radius: 15px;
}
/deep/ uni-checkbox .uni-checkbox-input.uni-checkbox-input-checked {
border-color: #ddd;
color: #fff !important;
background-color: #3E34FF !important;
}
/deep/ uni-checkbox .uni-checkbox-input {
border-color: #ddd;
}
/deep/ uni-checkbox .uni-checkbox-input:hover {
border-color: #ddd;
}
.date-input {
flex: 1;
width: 75%;
.date-placeholder {
color: #999999;
}
.selected-date {
color: #333333;
}
}
</style>