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

693 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>
<view class="accept page-common">
<div class="card">
<div>任务信息</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" style="margin-top: 10px">
<uni-row :gutter="24">
<uni-col :span="6">接收方式</uni-col>
<uni-col :span="6">
<view class="coding-btn" @click="onCodeIdentify">编码识别</view>
</uni-col>
<uni-col :span="6">
<view class="coding-btn" @click="scanStart">二维码识别</view>
</uni-col>
</uni-row>
</div>
<ScanQrCode
ref="scanQrCodeRef"
@scanSuccess="handleScanSuccess"
@scanError="handleScanError"
/>
<div class="card" style="margin-top: 10px">
<uni-row :gutter="24" style="display: flex; align-items: center; margin-bottom: 10px">
<uni-col :span="6">设备编码</uni-col>
<uni-col :span="12">
<uni-easyinput placeholder="请输入内容" maxlength="30" v-model="maCode" />
</uni-col>
<uni-col :span="6">
<view class="coding-btn search-btn" @click="getMaInfo">编码检索</view>
</uni-col>
</uni-row>
<uni-row :gutter="24" style="display: flex; align-items: center; margin-bottom: 10px">
<uni-col :span="6">物资类型:</uni-col>
<uni-col :span="16">
{{ typeName }}
</uni-col>
</uni-row>
<uni-row :gutter="24" style="display: flex; align-items: center; margin-bottom: 10px">
<uni-col :span="6">规格型号:</uni-col>
<uni-col :span="16">
{{ materialName }}
</uni-col>
</uni-row>
<uni-row :gutter="24" style="display: flex; align-items: center; margin-bottom: 10px">
<uni-col :span="6">设备状态:</uni-col>
<uni-col :span="16">
{{ maStatusName }}
</uni-col>
</uni-row>
<uni-row :gutter="24" style="display: flex; align-items: center; margin-bottom: 10px">
<uni-col :span="6">外观判定:</uni-col>
<uni-col :span="16">
<!-- <uni-easyinput placeholder="请输入内容" v-model="apDetection"/> -->
<radio-group @change="changeRadio">
<radio value="完好" checked style="margin-right: 5px">完好</radio>
<radio value="不合格">不合格</radio>
</radio-group>
</uni-col>
</uni-row>
<uni-row :gutter="24" style="display: flex; align-items: center; margin-bottom: 10px">
<uni-col :span="4">附件:</uni-col>
<uni-col :span="20">
<div class="upload-container">
<div class="upload" @click="uploadImg" v-if="imgList.length < 3">+</div>
<div class="image-preview" v-for="(img, index) in imgList" :key="index">
<image :src="img.url" mode="aspectFill"></image>
<view class="delete-btn" @click.stop="deleteImage(index)">×</view>
</div>
</div>
</uni-col>
</uni-row>
</div>
<div class="btn">
<!-- <button class="btn-cont" @click="reject">取消</button> -->
<button class="btn-cont" @click="submitCode">确认</button>
</div>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { getMachine, insertApp } from '../../services/back.js'
import ScanQrCode from '@/pages/devicesSearch/ScanQrCode.vue'
import { baseURL } from '@/utils/http'
const taskInfo = ref({})
const maId = ref('') //编码
const maCode = ref('') //编码
const typeName = ref('') //物资类型
const materialName = ref('') //规格型号
const typeId = ref('') //类型id
const maStatusName = ref('') //状态
const apDetection = ref('完好') //外观判定
const imgBeseUrl = ref('') //图片展示
const imgList = ref([]) // 图片列表,用于回显
const bmFileInfos = ref([]) // 上传后的图片信息
const scanQrCodeRef = ref(null)
const changeRadio = (e) => {
console.log(e.detail.value)
apDetection.value = e.detail.value
}
//根据编码获取设备类型
const getMaInfo = () => {
console.log(maCode.value)
let param = {
maCode: maCode.value,
unitId: taskInfo.value.unitId,
proId: taskInfo.value.proId,
id: taskInfo.value.id,
}
getMachine(param)
.then((res) => {
console.log(res)
if (res.code == 200) {
if (res.data && res.data.length > 0) {
typeName.value = res.data[0].typeName
materialName.value = res.data[0].materialName
maStatusName.value = res.data[0].maStatusName
maId.value = res.data[0].maId
typeId.value = res.data[0].typeId
} else {
uni.showToast({ title: '该编码非该单位工程领用,不可退料!', icon: 'none' })
}
}
})
.catch((error) => {
console.log(error)
})
}
const qrCode = ref('') //图片展示
// 二维码扫码
const scanStart = async () => {
qrCode.value = ''
if (scanQrCodeRef.value) {
scanQrCodeRef.value.scanQrCode()
}
// var mpaasScanModule = uni.requireNativePlugin('Mpaas-Scan-Module')
// mpaasScanModule.mpaasScan(
// {
// // 扫码识别类型参数可多选qrCode、barCode不设置默认识别所有
// scanType: ['qrCode', 'barCode'],
// // 是否隐藏相册默认false不隐藏
// hideAlbum: false,
// //ios需要设置这个参数只支持中英文 zh-Hans、en默认中文
// language: 'en',
// //相册选择照片识别错误提示(ios)
// failedMsg: '未识别到二维码,请重试',
// //Android支持全屏需要设置此参数
// screenType: 'full',
// },
// (ret) => {
// console.log(ret)
// if (ret.resp_code == 10) {
// uni.showToast({ title: '用户取消', icon: 'none' })
// }
// if (ret.resp_code == 11) {
// uni.showToast({ title: '扫码失败', icon: 'none' })
// }
// if (ret.resp_code == 1000) {
// qrCode.value = ret.resp_result
// console.log(qrCode.value)
// let param = {
// qrCode: qrCode.value,
// unitId: taskInfo.value.unitId,
// proId: taskInfo.value.proId,
// }
// getMachine(param)
// .then((res) => {
// console.log(res)
// console.log(res.data[0])
// maCode.value = res.data[0].maCode
// typeName.value = res.data[0].typeName
// materialName.value = res.data[0].typeModelName
// maStatusName.value = res.data[0].maStatusName
// maId.value = res.data[0].maId
// typeId.value = res.data[0].typeId
// })
// .catch((error) => {
// console.log(error)
// })
// }
// },
// )
}
// 处理扫描成功事件
const handleScanSuccess = (result) => {
qrCode.value = result?.text?.split('?qrcode=')[1] || result?.text
if (qrCode.value === '') {
uni.showToast({ title: '扫码识别失败', icon: 'none' })
} else {
getMaInfoScan()
}
}
// 处理扫描失败事件
const handleScanError = (error) => {
console.error('扫描出错:', error.message)
uni.showToast({ title: error.message, icon: 'none' })
}
const getMaInfoScan = () => {
let param = {
qrCode: qrCode.value,
unitId: taskInfo.value.unitId,
proId: taskInfo.value.proId,
id: taskInfo.value.id,
}
getMachine(param)
.then((res) => {
console.log(res)
console.log(res.data[0])
maCode.value = res.data[0].maCode
typeName.value = res.data[0].typeName
materialName.value = res.data[0].typeModelName
maStatusName.value = res.data[0].maStatusName
maId.value = res.data[0].maId
typeId.value = res.data[0].typeId
})
.catch((error) => {
console.log(error)
})
}
// // 扫码识别按钮
// const scanStart = () => {
// console.log('编码识别--')
// // 只允许通过相机扫码
// uni.scanCode({
// onlyFromCamera: true,
// scanType: ['qrCode', 'pdf417'],
// success: (res) => {
// console.log('扫码结果:' + res.result);
// maCode.value = res.result;
// },
// fail: (err) => {
// // uni.showToast({
// // title: '取消',
// // icon: 'none'
// // });
// }
// });
// }
// function getCamera() {
// console.log(1)
// navigator.camera.getPicture(this.onCameraSuccess, this.onCameraError, {
// quality: 50,
// destinationType: window.Camera.DestinationType.DATA_URL,
// sourceType: window.Camera.PictureSourceType.CAMERA,
// })
// }
// function getPhoto() {
// console.log(2)
// navigator.camera.getPicture(this.onCameraSuccess, this.onCameraError, {
// quality: 50,
// destinationType: window.Camera.DestinationType.DATA_URL,
// sourceType: window.Camera.PictureSourceType.SAVEDPHOTOALBUM,
// })
// }
// 编码识别按钮
const onCodeIdentify = () => {
console.log('编码识别--')
uni.navigateTo({
url: `/pages/back/backCodeScan?queryParams=${JSON.stringify(taskInfo.value)}`,
})
}
//提交
const submitCode = () => {
console.log(taskInfo.value)
if (maId.value == '') {
uni.showToast({ title: '请先添加退料设备编码!', icon: 'none' })
} else if(apDetection.value == '不合格') {
uni.showToast({ title: '请上传附件!', icon: 'none' })
} else {
// console.log(typeList.value)
let obj = {
maId: maId.value,
maCode: maCode.value,
typeId: typeId.value,
apDetection: apDetection.value,
goodNum: apDetection.value == '完好' ? 1 : 0,
badNum: apDetection.value == '不合格' ? 1 : 0,
bmFileInfos: bmFileInfos.value,
}
let param = {
backApplyInfo: taskInfo.value,
backApplyDetails: obj,
}
insertApp(param)
.then((res) => {
console.log(res)
if (res.code == 200) {
uni.showToast({ title: '添加成功!', icon: 'none' })
typeName.value = ''
materialName.value = ''
maStatusName.value = ''
typeId.value = ''
maId.value = ''
maCode.value = ''
typeId.value = ''
apDetection.value = '完好'
bmFileInfos.value = []
imgBeseUrl.value = ''
// uni.navigateBack({
// delta: 1 // 返回到已存在的页面
// });
} else {
uni.showToast({ title: res.msg, icon: 'none' })
}
})
.catch((error) => {
console.log(error)
})
}
}
//上传
const uploadImg = () => {
uni.chooseImage({
count: 3 - imgList.value.length, // 最多选择3张减去已选数量
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
const tempFiles = res.tempFiles
if (imgList.value.length + tempFiles.length > 3) {
uni.showToast({ title: '最多只能上传3张图片', icon: 'none' })
return
}
// 显示选择的图片
for (let i = 0; i < tempFiles.length; i++) {
imgList.value.push({
url: tempFiles[i].path,
uploading: true
})
}
// 上传所有图片
const uploadPromises = tempFiles.map(file => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: '/file/upload',
filePath: file.path,
name: 'file',
success: (uploadRes) => {
const resData = JSON.parse(uploadRes.data)
if (resData.code === 200) {
resolve({
name: resData.data.name,
url: resData.data.url,
taskType: '10'
})
} else {
reject(new Error('上传失败'))
}
},
fail: (err) => {
reject(err)
}
})
})
})
try {
const results = await Promise.all(uploadPromises)
bmFileInfos.value = [...bmFileInfos.value, ...results]
uni.showToast({ title: '上传成功', icon: 'none' })
// 更新图片状态
imgList.value = imgList.value.map(img => {
return {
...img,
uploading: false
}
})
} catch (error) {
uni.showToast({ title: '部分图片上传失败', icon: 'none' })
// 移除上传失败的图片
imgList.value = imgList.value.filter(img => !img.uploading)
}
}
})
}
// 删除图片
const deleteImage = (index) => {
imgList.value.splice(index, 1)
bmFileInfos.value.splice(index, 1)
}
onLoad((options) => {
console.log(options)
taskInfo.value = JSON.parse(options.taskInfo)
console.log(taskInfo.value)
})
</script>
<style lang="scss" scoped>
::v-deep .uni-easyinput__content {
padding: 0 !important;
}
/* 在style部分添加 */
.upload-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.upload {
width: 160rpx;
height: 160rpx;
background-color: #f7f8fa;
border: 2rpx dashed #d9d9d9;
border-radius: 12rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 48rpx;
color: #bfbfbf;
transition: all 0.3s ease;
}
.image-preview {
width: 160rpx;
height: 160rpx;
position: relative;
border-radius: 12rpx;
overflow: hidden;
}
.image-preview image {
width: 100%;
height: 100%;
}
.delete-btn {
position: absolute;
top: 0;
right: 0;
width: 40rpx;
height: 40rpx;
background-color: rgba(0, 0, 0, 0.5);
color: white;
display: flex;
justify-content: center;
align-items: center;
border-bottom-left-radius: 12rpx;
font-size: 32rpx;
line-height: 32rpx;
}
.uploading-mask {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 24rpx;
}
::v-deep .uni-radio-input {
width: 16px;
height: 16px;
}
.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;
// 卡片标题
> div:first-child {
font-size: 32rpx;
font-weight: 600;
color: #262626;
margin-bottom: 24rpx;
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;
}
}
// 表单样式
:deep(.uni-forms) {
.uni-forms-item {
padding: 24rpx 0;
margin-bottom: 0;
border-bottom: 2rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
.uni-forms-item__label {
color: #8c8c8c;
}
span {
color: #262626;
font-size: 28rpx;
}
}
}
// 扫码按钮样式
.coding-btn {
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
border-radius: 12rpx;
text-align: center;
color: #fff;
font-size: 28rpx;
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);
}
// 检索按钮样式
&.search-btn {
background: #fff7eb;
color: #fa8c16;
border: 2rpx solid #fa8c16;
box-shadow: none;
&:active {
background: #fff3e0;
}
}
}
// 信息展示行
:deep(.uni-row) {
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
.uni-col-6 {
color: #8c8c8c;
font-size: 28rpx;
}
.uni-col-16 {
color: #262626;
font-size: 28rpx;
}
// 输入框样式
.uni-easyinput__content {
background-color: #f7f8fa;
border: 2rpx solid #e8e8e8;
border-radius: 12rpx;
height: 88rpx;
padding: 0 24rpx;
transition: all 0.3s ease;
&:focus-within {
border-color: #3784fb;
box-shadow: 0 0 0 2rpx rgba(55, 132, 251, 0.1);
}
.uni-easyinput__content-input {
font-size: 28rpx;
height: 88rpx;
line-height: 88rpx;
}
}
}
// 上传区域样式
.upload {
width: 160rpx;
height: 160rpx;
background-color: #f7f8fa;
border: 2rpx dashed #d9d9d9;
border-radius: 12rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 48rpx;
color: #bfbfbf;
transition: all 0.3s ease;
&:active {
background-color: #f0f0f0;
border-color: #3784fb;
}
image {
width: 100%;
height: 100%;
border-radius: 12rpx;
object-fit: cover;
}
}
}
// 底部按钮
.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);
}
}
}
}
</style>