bonus-material-app/src/pages/back/backNum.vue

585 lines
20 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>
<uni-nav-bar
status-bar
leftIcon="left"
title="退料数量"
backgroundColor="#dcf4ff"
:border="false"
fixed
@clickLeft="leftClick"
>
<!-- 使用右侧插槽自定义提交按钮 -->
<!-- <template #right>
<button
class="submit-btn"
@click="submitNum"
>
确定
</button>
</template> -->
</uni-nav-bar>
<view class="accept page-common">
<div class="card top-content" :class="{'is-expanded': isExpanded}">
<div class="card-header" @click="isExpanded = !isExpanded">
<span class="title">任务信息</span>
<uni-icons class="icon" type="down" size="19" :class="{'is-expanded': isExpanded}"></uni-icons>
</div>
<uni-forms :model="taskInfo" label-width="170rpx" :border="true">
<uni-forms-item label="单位:" name="unitName">
<span style="height: 100%;display: flex;align-items: center;">{{ taskInfo.unitName }}</span>
</uni-forms-item>
<uni-forms-item label="工程:" name="proName">
<span style="height: 100%;display: flex;align-items: center;">{{ taskInfo.proName }}</span>
</uni-forms-item>
<uni-forms-item label="单号:" name="code">
<span style="height: 100%;display: flex;align-items: center;">{{ taskInfo.code }}</span>
</uni-forms-item>
<uni-forms-item label="人员:" name="backPerson">
<span style="height: 100%;display: flex;align-items: center;">{{ taskInfo.backPerson }}</span>
</uni-forms-item>
<uni-forms-item label="电话:" name="phone">
<span style="height: 100%;display: flex;align-items: center;">{{ taskInfo.phone }}</span>
</uni-forms-item>
</uni-forms>
</div>
<div class="card">
<div class="card-header">
<span class="title">退料物资</span>
<div class="header-right">
<span class="tip">已选 {{ typeList.length }} </span>
</div>
</div>
<div class="select-area">
<uni-row :gutter="24" style="display: flex; align-items: center">
<uni-col :span="12">
<view>
<!-- <uni-data-select v-model="typeId"
placeholder="请选择物资类型"
:localdata="maTypeSelectList" @change="getMaCode" filterable >
</uni-data-select> -->
<eselect
style="width: 100%; height: 90rpx"
v-model="typeId"
:options="maTypeSelectList"
@change="getMaCode"
@clear="clearTypeId"
></eselect>
</view>
</uni-col>
<uni-col :span="12">
<view>
<!-- <uni-data-select v-model="typeCode"
placeholder="请选择规格型号"
:localdata="maCodeSelectList" @change="selectMaCode">
</uni-data-select> -->
<eselect
style="width: 100%; height: 90rpx"
v-model="typeCode"
ref="treeSelect"
:options="maCodeSelectList"
@change="selectMaCode"
@clear=""
></eselect>
</view>
</uni-col>
</uni-row>
</div>
</div>
<uni-table border stripe emptyText="暂无更多数据">
<!-- 表头行 -->
<uni-tr>
<uni-th width="100px" style="font-size: 24rpx;" align="center">类型名称</uni-th>
<uni-th width="100px" style="font-size: 24rpx;" align="center">规格型号</uni-th>
<uni-th width="60px" style="font-size: 24rpx;" align="center">在用数</uni-th>
<uni-th width="90px" style="font-size: 24rpx;" align="center">退料数</uni-th>
<!-- <uni-th width="90px" style="font-size: 24rpx;" align="center">外观</uni-th> -->
<uni-th width="90px" style="font-size: 24rpx;" align="center">完好数量</uni-th>
<uni-th width="90px" style="font-size: 24rpx;" align="center">不合格数量</uni-th>
<uni-th width="70px" style="font-size: 24rpx;" align="center">操作</uni-th>
</uni-tr>
<!-- 表格数据行 -->
<uni-tr v-for="(item,index) in typeList" :key="item.id">
<uni-td style="font-size: 24rpx;text-align: center;">{{item.materialName}}</uni-td>
<uni-td style="font-size: 24rpx;text-align: center;">{{item.typeName}}</uni-td>
<uni-td style="font-size: 24rpx;text-align: center;">{{item.num}}</uni-td>
<uni-td style="font-size: 24rpx;text-align: center;">
<uni-easyinput
placeholder="退料数"
v-model="item.preNum"
type="number"
:clearable="false"
@input="onChangeNumber(item)"
:styles="{width: '100rpx'}"
/>
</uni-td>
<uni-td style="font-size: 24rpx;text-align: center;">
<uni-easyinput
placeholder="完好数量"
v-model="item.goodNum"
type="number"
:clearable="false"
@change="changeNum(item)"
:styles="{width: '100rpx'}"
:disabled="!item.preNum"
/>
</uni-td>
<uni-td style="font-size: 24rpx;text-align: center;">
<uni-easyinput
placeholder="不合格数量"
v-model="item.badNum"
type="number"
:clearable="false"
@change="changeNum(item)"
:styles="{width: '100rpx'}"
:disabled="!item.preNum"
/>
</uni-td>
<!-- <uni-td style="font-size: 24rpx;text-align: center;">
<uni-easyinput
placeholder="外观"
v-model="item.apDetection"
:styles="{width: '100rpx'}"
/>
</uni-td> -->
<uni-td style="font-size: 24rpx;text-align: center;">
<view class="uni-group">
<view class="action-btn" @click="uploadImg(item)">
<uni-icons type="camera" size="20" style="color: #3784fb;"/>
</view>
<view class="action-btn delete" @click="delRow(index)">
<uni-icons type="trash-filled" size="20" style="color: red;margin-left:10px;"/>
</view>
</view>
</uni-td>
</uni-tr>
</uni-table>
<div class="footer-btn">
<button class="btn-cont" @click="submitNum">确认</button>
</div>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getUseType,insertApp } from '../../services/back.js';
import eselect from '@/components/tree-select/eselect.vue'
const taskInfo = ref({})
const maTypeSelectList = ref([])
const typeId = ref()//类型
const maCodeSelectList = ref([])
const typeCode = ref("")//规格型号
const typeList = ref([])
const isExpanded = ref(false)
const treeSelect = ref()
const leftClick = () => {
// 返回
uni.navigateBack({
delta: 1, // 返回到已存在的页面
})
}
//类下拉选
const getMaType = () => {
let obj = {
"agreementId":taskInfo.value.agreementId,
}
getUseType(obj).then(res => {
console.log(res)
maTypeSelectList.value = res.data.map(option => {
return {
// value:option.typeId,
// text:option.typeName,
id:option.typeId,
name:option.typeName,
parentId: 0
}
});
}).catch(error => {
console.log(error)
})
}
//规格
const getMaCode = (e) => {
console.log('🚀 ~ getMaCode ~ e:', e.id)
typeId.value = e.id
console.log('🚀 ~ getMaCode ~ typeId.value:', typeId.value)
let obj = {
"agreementId":taskInfo.value.agreementId,
"typeId":typeId.value
}
console.log('🚀 ~ getMaCode ~ obj:', obj)
getUseType(obj).then(res => {
console.log(res)
maCodeSelectList.value = res.data.map(option => {
let obj = {
...option,
bmFileInfos:[],
// value:option.typeId,
// text:option.typeName,
id:option.typeId,
name:option.typeName,
parentId: 0
}
return obj
});
}).catch(error => {
console.log(error)
})
}
const clearTypeId = () => {
typeId.value = ''
typeCode.value = ''
maCodeSelectList.value = []
treeSelect.value.showLabel = ''
console.log('🚀 ~ clearTypeId ~ treeSelect.value:', treeSelect.value)
}
//选择规格型号
const selectMaCode = (e) => {
console.log('🚀 ~ selectMaCode ~ e:', e)
// 不可重复添加
if(typeList.value.some(item => item.typeId == e.id)){
typeCode.value = '' // 清空绑定的值
treeSelect.value.showLabel = '' // 清空下拉框的显示文本
// 提示
uni.showToast({
title: '请勿重复添加',
icon: 'none'
});
return
}
maCodeSelectList.value.forEach(item=>{
console.log(item)
if(item.typeId==e.id){
typeList.value.unshift(item)
}
})
console.log(typeList.value)
// 选完型号后,清空型号选择框的值
typeCode.value = '' // 清空绑定的值
treeSelect.value.showLabel = '' // 清空下拉框的显示文本
}
//提交
const submitNum = () => {
console.log(taskInfo.value)
console.log(typeList.value)
// 校验 preNum 必须大于 0
if (typeList.value.length === 0) {
console.log('🚀 ~ submitNum ~ typeList.value:', typeList.value)
uni.showToast({
title: '请添加退料物资',
icon: 'none',
})
return
}
for (let i = 0; i < typeList.value.length; i++) {
if (typeList.value[i].preNum <= 0 || !typeList.value[i].preNum) {
uni.showToast({
title: '退料数不能为空或等于0',
icon: 'none',
})
return
}
}
let obj = {
"backApplyInfo":taskInfo.value,
"backApplyDetailsList":typeList.value
}
insertApp(obj).then(res => {
console.log(res)
if(res.code==200){
uni.showToast({ title: '编辑成功', icon: 'none' })
uni.navigateBack({
delta: 2 // 返回到已存在的页面
});
}else{
uni.showToast({ title: res.msg, icon: 'none' })
}
}).catch(error => {
console.log(error)
})
}
//上传
const uploadImg = (item) => {
uni.chooseImage({
count: 1, //图片可选择数量
sizeType: ['original', 'compressed'], //original 原图compressed 压缩图,默认二者都有
sourceType: ['album', 'camera',], //album 从相册选图camera 使用相机,默认二者都有。
success: res => {
console.log(res)
let imgFiles = res.tempFilePaths //图片的本地文件路径列表
// imgBeseUrl.value = imgFiles[0]
// console.log('本地地址', imgFiles)
// console.log('请求地址', baseURL+"/file/upload")
uni.uploadFile({
// url: baseURL+"/file/upload",//app
url: "/file/upload",//h5
filePath: imgFiles[0],
name: 'file',
success: (res) => {
res = JSON.parse(res.data)
console.log('上传成功', res.code);
console.log('上传成功', res.data);
if(res.code&&res.code==200){
let obj = {
"name":res.data.name,
"url":res.data.url
}
item.bmFileInfos.value = [obj]
uni.showToast({ title: '上传成功', icon: 'none' })
}else{
item.bmFileInfos.value = []
uni.showToast({ title: '上传失败', icon: 'none' })
}
},
fail: (err) => {
console.error('上传失败', err);
}
});
// this.$refs.vForm.clearValidate()
}
})
}
//删除
const delRow = (index) => {
console.log(index)
console.log(typeList.value)
typeList.value.splice(index,1)
}
// 数量框change事件
const onChangeNumber = (item) => {
console.log(item)
console.log(item.preNum)
console.log(item.preNum)
let maxNum = Number(item.num)
// outboundNum.value
setTimeout(()=>{
if(item.unitValue==1){
item.preNum = Number(String(item.preNum).replace(/[^\d.]/g,''))
}else{
item.preNum = Number(String(item.preNum).replace(/[^\d]/g,''))
}
if (Number(item.preNum)<= 0) {
item.preNum = 0;
}
if (Number(item.preNum) > maxNum) {
uni.showToast({
title: '已达到当前资最大在用数量!',
icon: 'none',
})
item.preNum = maxNum;
}
},500)
}
const changeNum = (row) => {
console.log('🚀 ~ changeNum ~ row:', row)
// 将badNum 和 goodNum 向上取整
// 只能输入正整数 过滤掉除正整数外的东西
if (row.badNum) {
row.badNum = Math.ceil(String(row.badNum).replace(/[^\d]/g, ''))
console.log('🚀 ~ changeNum ~ row.badNum:', row.badNum)
}
if (row.goodNum) {
console.log('🚀 ~ changeNum ~ row.goodNum:', row.goodNum)
row.goodNum = Math.ceil(String(row.goodNum).replace(/[^\d]/g, ''))
}
// 不能大于preNum
if (Number(row.badNum) + Number(row.goodNum) > row.preNum) {
console.log('🚀 ~ changeNum ~ row.badNum + row.goodNum > row.preNum:', row.badNum , row.goodNum)
// this.$message.error('完好数量和不合格数量之和不能大于退料数量')
uni.showToast({
title: '完好数量和不合格数量之和不能大于退料数量',
icon: 'none',
})
row.badNum = 0
row.goodNum = 0
}
}
onLoad((options)=>{
console.log(options)
taskInfo.value = JSON.parse(options.taskInfo)
console.log(taskInfo.value)
getMaType()
})
</script>
<style lang="scss" scoped>
.submit-btn {
background-color: #007aff; /* 蓝色背景 */
color: white; /* 白色文字 */
border: none; /* 去掉边框 */
border-radius: 5px; /* 圆角 */
padding: 0 14px; /* 左右内边距 */
height: 30px; /* 高度 */
line-height: 30px; /* 垂直居中 */
font-size: 15px; /* 字体放大 */
margin-right: 2px; /* 与边缘间距 */
}
::v-deep .tree-item .head {
justify-content: center !important;
}
.accept {
padding: 24rpx;
height: 95vh;
word-break: break-all;
background-color: #f7f8fa;
display: flex;
flex-direction: column;
// 卡片样式
.card {
padding: 32rpx;
background-color: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
margin-bottom: 24rpx;
// 卡片头部
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 24rpx;
.title {
font-size: 32rpx;
font-weight: 600;
color: #262626;
position: relative;
padding-left: 24rpx;
&::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 6rpx;
height: 28rpx;
background: #3784fb;
border-radius: 6rpx;
}
}
.header-right {
.tip {
font-size: 26rpx;
color: #8c8c8c;
}
}
.icon {
transition: transform 0.5s ease; /* 添加动画过渡 */
transform: rotate(0deg);
&.is-expanded {
transform: rotate(180deg);
}
}
}
// 操作按钮样式
.uni-group {
display: flex;
justify-content: center;
align-items: center;
.uni-icons {
padding: 8rpx;
border-radius: 8rpx;
transition: all 0.3s ease;
&:active {
transform: scale(0.9);
opacity: 0.8;
}
}
}
// 选择区域
.select-area {
padding: 24rpx 0;
border-bottom: 2rpx solid #f5f5f5;
}
// // 表格区域
// .table-area {
// margin-top: 24rpx;
// margin: 24rpx -32rpx 0;
// overflow-x: auto;
// :deep(.uni-table) {
// width: 1080rpx;
// padding: 0 10rpx;
// .uni-table-tr {
// .uni-table-th {
// min-width: 140rpx;
// &:last-child {
// min-width: 120rpx;
// }
// }
// .uni-table-td {
// .action-btn {
// display: inline-flex;
// padding: 12rpx;
// border-radius: 8rpx;
// transition: all 0.3s ease;
// margin: 0 8rpx;
// &:active {
// background-color: rgba(0, 0, 0, 0.05);
// }
// &.delete:active {
// background-color: rgba(255, 77, 79, 0.05);
// }
// }
// }
// }
// }
// }
}
// 底部按钮
.footer-btn {
margin-top: auto;
padding: 32rpx;
background: #fff;
box-shadow: 0 -4rpx 16rpx rgba(0, 0, 0, 0.05);
.btn-cont {
width: 100%;
height: 88rpx;
line-height: 88rpx;
text-align: center;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
color: #fff;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease;
&:active {
transform: scale(0.98);
opacity: 0.9;
box-shadow: 0 2rpx 8rpx rgba(55, 132, 251, 0.2);
}
}
}
}
.top-content {
height: 30px;
overflow: hidden;
transition: max-height 0.5s ease-out;
&.is-expanded {
height: auto;
}
}
</style>