1131 lines
38 KiB
Vue
1131 lines
38 KiB
Vue
<template>
|
||
<!-- 数量出库 -->
|
||
<view class="page-container">
|
||
<view class="table-list-item top-content" :class="{ 'is-expanded': isExpanded }">
|
||
<uni-row :gutter="24" style="display: flex;align-items: center;">
|
||
<uni-col :span="6">物资名称:</uni-col>
|
||
<uni-col :span="15"
|
||
><view class="cont">{{ queryParams.typeName }}</view>
|
||
</uni-col>
|
||
<uni-col :span="3">
|
||
<uni-icons
|
||
class="down-icon"
|
||
:class="{ 'icon-is-expanded': isExpanded }"
|
||
type="down"
|
||
size="19"
|
||
@click="isExpanded = !isExpanded"
|
||
></uni-icons>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row :gutter="24">
|
||
<uni-col :span="6">物资类型:</uni-col>
|
||
<uni-col :span="18"
|
||
><view class="cont">{{ queryParams.type }}</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row :gutter="24">
|
||
<uni-col :span="6">设备编码:</uni-col>
|
||
<uni-col :span="18"
|
||
><view class="cont">{{ queryParams.repairDeviceList[rowIndex].code }}</view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<uni-row :gutter="24" style="display: flex;align-items: center">
|
||
<uni-col :span="6">维修人员:</uni-col>
|
||
<uni-col :span="18">
|
||
<uni-data-select :localdata="repairPersonData" v-model="repairPerson" placeholder="请选择维修人员" />
|
||
</uni-col>
|
||
</uni-row>
|
||
</view>
|
||
<uni-row
|
||
:gutter="24"
|
||
class="search-form"
|
||
style="background: #fff; padding: 10px; margin: 5px; border-radius: 5px"
|
||
>
|
||
<uni-col :span="6">
|
||
<view class="btnBox internal" @click="changeTab(1)"> 内部维修 </view>
|
||
</uni-col>
|
||
<uni-col :span="6">
|
||
<view class="btnBox return" @click="changeTab(2)"> 返厂维修 </view>
|
||
</uni-col>
|
||
<uni-col :span="6">
|
||
<view class="btnBox scrap" @click="changeTab(3)"> 待报废 </view>
|
||
</uni-col>
|
||
<uni-col :span="6">
|
||
<view class="btnBox complete" @click="saveCode"> 提交 </view>
|
||
</uni-col>
|
||
</uni-row>
|
||
<scroll-view scroll-y style="padding-bottom: 20rpx">
|
||
<!-- <view class="table-list-item">
|
||
<h2 style="padding: 4rpx 0; font-weight: bold">维修信息</h2>
|
||
<uni-forms ref="baseForm" label-align="right">
|
||
<uni-forms-item label="维修人员">
|
||
<uni-data-select
|
||
:localdata="repairPersonData"
|
||
v-model="repairPerson"
|
||
placeholder="请选择维修人员"
|
||
/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="备注">
|
||
<uni-easyinput placeholder="请填写备注" maxlength="50" v-model="remark" />
|
||
</uni-forms-item>
|
||
<uni-forms-item label="附件">
|
||
<div class="upload" @click="uploadImg" v-if="imgBeseUrl == ''">+</div>
|
||
<div class="upload" @click="uploadImg" v-else>
|
||
<image
|
||
:src="imgBeseUrl"
|
||
style="width: 160rpx; height: 160rpx"
|
||
mode=""
|
||
></image>
|
||
</div>
|
||
</uni-forms-item>
|
||
</uni-forms>
|
||
</view> -->
|
||
|
||
<!-- 内部维修 -->
|
||
<view class="table-list-item" v-if="repairType == 1">
|
||
<h2 style="padding: 4rpx 0; font-weight: bold">内部维修</h2>
|
||
<uni-forms ref="baseForm" label-align="right">
|
||
<!-- <uni-forms-item label="维修数量">
|
||
<uni-easyinput placeholder="请填写维修数量" v-model="formLeft.repairNum"/>
|
||
</uni-forms-item> -->
|
||
<div v-for="(item, index) in partItems" :key="index">
|
||
<uni-forms-item label="配件类型">
|
||
<treeSelect
|
||
style="width: 100%;height: 90rpx;"
|
||
:ref="el => { if (el) treeSelectRef[index] = el }"
|
||
:options="partTreeData"
|
||
v-model="item.partId"
|
||
@change="partTreeChange"
|
||
:index="index"
|
||
@clear="clearPart"
|
||
:defaultProps="defaultProps"
|
||
></treeSelect>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="配件数量">
|
||
<uni-easyinput
|
||
placeholder="配件数量"
|
||
v-model="item.partNum"
|
||
type="number"
|
||
:clearable="false"
|
||
@input="partCheckNum(item)"
|
||
/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="是否收费">
|
||
<div style="width: 100%; display: flex">
|
||
<uni-data-select
|
||
:localdata="isChargeList"
|
||
v-model="item.partType"
|
||
placeholder="请选择是否收费"
|
||
:clear="false"
|
||
/>
|
||
<div class="operation-btns">
|
||
<span class="add" @click="addPart">加</span>
|
||
<span class="remove" @click="delPart(index)">减</span>
|
||
</div>
|
||
</div>
|
||
</uni-forms-item>
|
||
<div style="border-bottom: 1 solid #333;"></div>
|
||
</div>
|
||
<uni-forms-item label="备注">
|
||
<uni-easyinput placeholder="备注" v-model="partRemark" />
|
||
</uni-forms-item>
|
||
<uni-forms-item label="附件">
|
||
<div class="upload" @click="uploadImg('part')" v-if="partImgUrl == ''">+</div>
|
||
<div class="upload" @click="uploadImg('part')" v-else>
|
||
<image
|
||
:src="partImgUrl"
|
||
style="width: 160rpx; height: 160rpx"
|
||
mode=""
|
||
></image>
|
||
</div>
|
||
<PreviewImg :imgUrl="partImgUrl" />
|
||
</uni-forms-item>
|
||
</uni-forms>
|
||
</view>
|
||
|
||
<!-- 返厂维修 -->
|
||
<view class="table-list-item" v-if="repairType == 2">
|
||
<h2 style="padding: 4rpx 0; font-weight: bold">返厂维修</h2>
|
||
<uni-forms ref="baseForm" label-align="right">
|
||
<!-- <uni-forms-item label="维修数量">
|
||
<uni-easyinput placeholder="请输入维修数量" v-model="formMiddle.repairNum"/>
|
||
</uni-forms-item> -->
|
||
|
||
<div v-for="(item, index) in partItemsMiddle" :key="index">
|
||
<uni-forms-item label="配件名称">
|
||
<uni-easyinput placeholder="请输入配件名称" v-model="item.partName" />
|
||
</uni-forms-item>
|
||
<uni-forms-item label="物资厂家">
|
||
<uni-data-select
|
||
:localdata="partsMillList"
|
||
v-model="item.supplierId"
|
||
placeholder="请选择物资厂家"
|
||
/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="是否收费">
|
||
<uni-data-select
|
||
:localdata="isChargeList"
|
||
v-model="item.partType"
|
||
:clearable="false"
|
||
placeholder="请选择是否收费"
|
||
/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="配件数量">
|
||
<uni-easyinput
|
||
v-model="item.partNum"
|
||
placeholder="请输入配件数量"
|
||
type="number"
|
||
:clearable="false"
|
||
@input="partCheckNum(item)"
|
||
/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="金额">
|
||
<div style="width: 100%; display: flex">
|
||
<uni-easyinput
|
||
v-model="item.partPrice"
|
||
placeholder="请输入金额"
|
||
type="number"
|
||
:clearable="false"
|
||
@input="costCheckNum(item)"
|
||
/>
|
||
<div class="operation-btns">
|
||
<span class="add" @click="addMidPart">加</span>
|
||
<span class="remove" @click="delMidPart(index)">减</span>
|
||
</div>
|
||
</div>
|
||
</uni-forms-item>
|
||
<div style="border-bottom: 1 solid #333;"></div>
|
||
</div>
|
||
<uni-forms-item label="备注">
|
||
<uni-easyinput placeholder="备注" v-model="returnRemark" />
|
||
</uni-forms-item>
|
||
<uni-forms-item label="附件">
|
||
<div class="upload" @click="uploadImg('ret')" v-if="returnImgUrl == ''">+</div>
|
||
<div class="upload" @click="uploadImg('ret')" v-else>
|
||
<image
|
||
:src="returnImgUrl"
|
||
style="width: 160rpx; height: 160rpx"
|
||
mode=""
|
||
></image>
|
||
</div>
|
||
<PreviewImg :imgUrl="returnImgUrl" />
|
||
</uni-forms-item>
|
||
</uni-forms>
|
||
</view>
|
||
|
||
<!-- 维修报废 -->
|
||
<view class="table-list-item" v-if="repairType == 3">
|
||
<h2 style="padding: 4rpx 0; font-weight: bold">维修报废</h2>
|
||
<uni-forms ref="baseForm" label-align="right">
|
||
<!-- <uni-forms-item label="报废数量">
|
||
<uni-easyinput placeholder="请填写报废数量" v-model="formRight.scrapNum"/>
|
||
</uni-forms-item> -->
|
||
<uni-forms-item label="报废原因">
|
||
<uni-easyinput
|
||
placeholder="请填写报废原因"
|
||
v-model="formRight.scrapReason"
|
||
style="margin-bottom: 10px"
|
||
/>
|
||
<uni-data-select
|
||
:localdata="scrapReasonList"
|
||
v-model="formRight.scrapId"
|
||
placeholder="请选择报废原因"
|
||
@change="changeScrap"
|
||
/>
|
||
</uni-forms-item>
|
||
<uni-forms-item label="损坏原因">
|
||
<uni-data-select
|
||
:clearable="false"
|
||
:localdata="damageReasonList"
|
||
v-model="formRight.scrapType"
|
||
placeholder="请选择损坏原因"
|
||
/>
|
||
</uni-forms-item>
|
||
<!-- <uni-forms-item label="其他原因">
|
||
<uni-easyinput placeholder="请填写其他原因" />
|
||
</uni-forms-item> -->
|
||
<uni-forms-item label="附件">
|
||
<!-- <div class="upload" @click="uploadScrapImg" v-if="imgBeseUrl2 == ''">+</div>-->
|
||
<!-- <div class="upload" @click="uploadScrapImg" v-else>-->
|
||
<!-- <image-->
|
||
<!-- :src="imgBeseUrl2"-->
|
||
<!-- style="width: 160rpx; height: 160rpx"-->
|
||
<!-- mode=""-->
|
||
<!-- ></image>-->
|
||
<!-- </div>-->
|
||
<div class="upload-container">
|
||
<div class="upload" @click="uploadImg2" v-if="imgList2.length < 3">+</div>
|
||
<div class="image-preview" v-for="(img, index) in imgList2" :key="index">
|
||
<image :src="img.url" mode="aspectFill"></image>
|
||
<view class="delete-btn" @click.stop="deleteImage2(index)">×</view>
|
||
<PreviewImg :imgUrl="img.url" />
|
||
</div>
|
||
</div>
|
||
</uni-forms-item>
|
||
<div style="border-bottom: 1 solid #333;"></div>
|
||
</uni-forms>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, ref, reactive,nextTick } from 'vue'
|
||
import {
|
||
partTypeTreeList,
|
||
getSupplierList,
|
||
getRepairerListApi,
|
||
saveRepairRow,
|
||
getScrapReasonList,
|
||
getPartItemApi,
|
||
} from '@/services/repair/repair.js'
|
||
import { baseURL } from '@/utils/http'
|
||
import treeSelect from '../tree-select/tselectTwo.vue'
|
||
import { onLoad,onShow } from '@dcloudio/uni-app'
|
||
import { decryptWithSM4, encryptWithSM4, hashWithSM3AndSalt } from '@/utils/sm'
|
||
import PreviewImg from '@/components/PreviewImg/index.vue'
|
||
const queryParams = ref({})
|
||
const rowIndex = ref(-1)
|
||
const partRemark = ref('') // 内部-备注
|
||
const partImgUrl = ref('')
|
||
const partFileList = ref([])
|
||
const returnRemark = ref('') // 返厂
|
||
const returnImgUrl = ref('')
|
||
const returnFileList = ref([])
|
||
const isExpanded = ref(false)
|
||
|
||
onLoad((options) => {
|
||
console.log(options)
|
||
queryParams.value = JSON.parse(options.queryParams)
|
||
rowIndex.value = options.rowIndex
|
||
console.log(queryParams.value)
|
||
getScrapReasonListData()
|
||
})
|
||
onShow(() => {
|
||
getPartTreeData()
|
||
//获取定损的配件信息
|
||
getPartItemData()
|
||
})
|
||
|
||
|
||
const repairType = ref(1)
|
||
const changeTab = async (e) => {
|
||
repairType.value = e
|
||
}
|
||
const damageReasonList = ref([
|
||
{ value: 0, text: '自然损坏' },
|
||
{ value: 1, text: '人为损坏' },
|
||
])
|
||
const isChargeList = ref([
|
||
{ value: 1, text: '是' },
|
||
{ value: 0, text: '否' },
|
||
])
|
||
|
||
const { userInfo } = JSON.parse(uni.getStorageSync('member'))
|
||
// console.log('🚀 ~ userInfo:', userInfo)
|
||
|
||
// 报废原因
|
||
const scrapReasonList = ref([])
|
||
const getScrapReasonListData = async () => {
|
||
const params = {
|
||
typeId: queryParams.value.typeId,
|
||
}
|
||
const res = await getScrapReasonList(params)
|
||
scrapReasonList.value = res.data.map((item) => {
|
||
let obj = {
|
||
value: item.id,
|
||
text: item.reason,
|
||
}
|
||
return obj
|
||
})
|
||
console.log('🚀 ~ 报废原因下拉 ~ res:', res)
|
||
}
|
||
|
||
// 报废原因change事件
|
||
const changeScrap = (val) => {
|
||
console.log('🚀 ~ changeScrap ~ val:', val)
|
||
const scrapReason = scrapReasonList.value.find((v) => v.value === val)
|
||
console.log('🚀 ~ changeScrap ~ scrapReason:', scrapReason)
|
||
// formRight.value.scrapReason = scrapReason.text
|
||
console.log('🚀 ~ changeScrap ~ formRight.value:', formRight.value)
|
||
}
|
||
|
||
//获取维修人员
|
||
const repairPersonData = ref([])
|
||
const repairPerson = ref('')
|
||
const getRepairerListData = async () => {
|
||
const res = await getRepairerListApi({})
|
||
console.log(res)
|
||
repairPersonData.value = res.data.map((item) => {
|
||
let obj = {
|
||
value: item.userId,
|
||
text: item.repairer,
|
||
}
|
||
return obj
|
||
})
|
||
// 如果 userInfo.userId 在repairPersonData.value 数组中说明是维修人员,则默认选中, 否则默认选中第一个
|
||
if (
|
||
repairPersonData.value &&
|
||
repairPersonData.value.findIndex((v) => v.value === userInfo.userId) > -1
|
||
) {
|
||
repairPerson.value = userInfo.userId
|
||
} else {
|
||
repairPerson.value = repairPersonData.value[0].value
|
||
}
|
||
}
|
||
getRepairerListData()
|
||
|
||
const remark = ref('') //备注
|
||
|
||
const imgBeseUrl = ref('') //图片展示
|
||
const bmFileInfos = ref([]) //图片数组
|
||
//上传
|
||
const uploadImg = (item) => {
|
||
// if(item.imgBeseUrl){
|
||
// uni.showToast({ title: '图片已上传', icon: 'none' })
|
||
// return
|
||
// }
|
||
// const count = 1 - imgList.value.length
|
||
// if (count <= 0) {
|
||
// uni.showToast({ title: '最多上传1张图片', icon: 'none' })
|
||
// return
|
||
// }else{
|
||
uni.showActionSheet({
|
||
itemList: ['拍照', '从相册选择'],
|
||
success: (res) => {
|
||
if (res.tapIndex === 0) {
|
||
getCameraFj(item)
|
||
} else if (res.tapIndex === 1) {
|
||
// 从相册选择
|
||
getPhotoFj(item)
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('操作菜单选择失败:', err)
|
||
},
|
||
})
|
||
// }
|
||
|
||
}
|
||
|
||
|
||
// 附件拍照
|
||
const getCameraFj = (item) => {
|
||
navigator.camera.getPicture((file) => onCameraSuccessFj(file, item), onCameraErrorFj, {
|
||
quality: 50,
|
||
destinationType: window.Camera.DestinationType.DATA_URL,
|
||
sourceType: window.Camera.PictureSourceType.CAMERA,
|
||
})
|
||
}
|
||
// 附件从相册选择
|
||
const getPhotoFj = (item) => {
|
||
navigator.camera.getPicture((file) => onCameraSuccessFj(file, item), onCameraErrorFj, {
|
||
quality: 50,
|
||
destinationType: window.Camera.DestinationType.DATA_URL,
|
||
sourceType: window.Camera.PictureSourceType.SAVEDPHOTOALBUM,
|
||
})
|
||
}
|
||
|
||
const onCameraErrorFj = (message) => {
|
||
console.log(message)
|
||
}
|
||
|
||
const onCameraSuccessFj = (file, item) => {
|
||
uploadSignUrlFj(file, item)
|
||
}
|
||
|
||
const generateRandomString = (length) => {
|
||
let result = '';
|
||
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||
const charactersLength = characters.length;
|
||
for (let i = 0; i < length; i++) {
|
||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||
}
|
||
return result;
|
||
}
|
||
|
||
const uploadSignUrlFj = (file, item) => {
|
||
const base64Data = file
|
||
|
||
uni.request({
|
||
url: '/file/uploadBase64',
|
||
method: 'POST',
|
||
data: {
|
||
base64File:base64Data,
|
||
fileName: `${generateRandomString(10)}_${Date.now()}.png`,
|
||
fileType: 'image/png'
|
||
},
|
||
success: (uploadRes) => {
|
||
console.log("xxxxxxxxxx",uploadRes)
|
||
let urlObj = null
|
||
if(!uploadRes.data.code){
|
||
urlObj = JSON.parse(decryptWithSM4(uploadRes.data))
|
||
}else{
|
||
uploadRes =JSON.parse(uploadRes.data)
|
||
}
|
||
console.log('🚀 ~ uploadSignUrlFj ~ uploadRes:', urlObj)
|
||
|
||
if (urlObj.code && urlObj.code == 200) {
|
||
let obj = {
|
||
name: urlObj.data.name,
|
||
url: urlObj.data.url,
|
||
}
|
||
if (item == 'part') {
|
||
partFileList.value = [obj]
|
||
partImgUrl.value = urlObj.data.url
|
||
} else if (item == 'ret') {
|
||
returnFileList.value = [obj]
|
||
returnImgUrl.value = urlObj.data.url
|
||
}
|
||
|
||
uni.showToast({ title: '上传成功', icon: 'none' })
|
||
} else {
|
||
uni.showToast({ title: '上传失败', icon: 'none' })
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('上传失败', err)
|
||
uni.showToast({ title: '上传失败', icon: 'none' })
|
||
}
|
||
})
|
||
}
|
||
|
||
|
||
//配件树
|
||
const partTreeData = ref([])
|
||
const defaultProps = ref({
|
||
id: 'id',
|
||
children: 'children',
|
||
label: 'label',
|
||
})
|
||
const getPartTreeData = async () => {
|
||
const res = await partTypeTreeList({})
|
||
partTreeData.value = res.data
|
||
}
|
||
const treeSelectRef = ref([])
|
||
const clearPart = (index) => {
|
||
partItems.value[index].partId = ''
|
||
}
|
||
const partTreeChange = (val, index) => {
|
||
const isHas = partItems.value.findIndex((v) => v.partId === val.id)
|
||
if (isHas > -1) {
|
||
//不可选择相同的配件
|
||
console.log(isHas)
|
||
uni.showToast({ title: '已存在该配件类型', icon: 'none' })
|
||
treeSelectRef.value[index].clearInput()
|
||
partItems.value[index].partId = ''
|
||
partItems.value[index].storageNum = ''
|
||
partItems.value[index].partNum = 0
|
||
} else {
|
||
partItems.value[index].partId = val.id
|
||
partItems.value[index].storageNum = val.storageNum
|
||
partItems.value[index].partNum = 1
|
||
}
|
||
}
|
||
|
||
//内部维修
|
||
const partItems = ref([{ partNum: '', partType: 1, partId: '', storageNum: '', remark: '', fileList: [] }])
|
||
|
||
const getPartItemData = async () => {
|
||
console.log("bbbbbbbbbbbbbbbbb",queryParams.value.ids)
|
||
const res = await getPartItemApi({
|
||
ids: queryParams.value.ids,
|
||
})
|
||
if(res.data && res.data.length > 0) {
|
||
// 1. 先设置数据
|
||
partItems.value = res.data.map(item => ({
|
||
...item,
|
||
partType: item.partId ? 1 : 0 // 假设 partType 表示是否有 partId
|
||
}));
|
||
|
||
// 使用 nextTick 确保组件渲染完成
|
||
nextTick(() => {
|
||
setTimeout(() => {
|
||
partItems.value.forEach((item, index) => {
|
||
if (item.partId) {
|
||
const treeSelect = treeSelectRef.value[index];
|
||
if (treeSelect?.setSelectedValue) {
|
||
treeSelect.setSelectedValue(item.partId);
|
||
}
|
||
}
|
||
});
|
||
}, 500); // 延迟 500ms 确保 treeSelect 内部数据加载完成
|
||
});
|
||
}
|
||
}
|
||
const addPart = () => {
|
||
partItems.value.push({ partNum: '', partType: 1, partId: '', storageNum: '', remark: '', fileList: [] })
|
||
}
|
||
const delPart = (index) => {
|
||
if (partItems.value.length > 1) {
|
||
partItems.value.splice(index, 1)
|
||
}
|
||
}
|
||
const partIds = ref([])
|
||
const formLeft = ref({
|
||
// repairNum:0
|
||
})
|
||
|
||
//返厂维修
|
||
const partsMillList = ref([])
|
||
const getSupplierListData = async () => {
|
||
const res = await getSupplierList({})
|
||
partsMillList.value = res.rows.map((item) => {
|
||
let obj = {
|
||
value: item.supplierId,
|
||
text: item.supplier,
|
||
}
|
||
return obj
|
||
})
|
||
}
|
||
getSupplierListData()
|
||
const partItemsMiddle = ref([
|
||
{ partName: '', supplierId: '', partNum: 1, partPrice: 0, partType: 1, remark: '', fileList: [] },
|
||
])
|
||
const addMidPart = () => {
|
||
partItemsMiddle.value.push({
|
||
partName: '',
|
||
supplierId: '',
|
||
partNum: 1,
|
||
partPrice: 0,
|
||
partType: 1,
|
||
remark: '',
|
||
fileList: [],
|
||
})
|
||
}
|
||
const delMidPart = (index) => {
|
||
if (partItemsMiddle.value.length > 1) {
|
||
partItemsMiddle.value.splice(index, 1)
|
||
}
|
||
}
|
||
const formMiddle = ref({
|
||
// supplierId:undefined,
|
||
// repairNum:0
|
||
})
|
||
|
||
//待报废
|
||
const formRight = ref({
|
||
// scrapNum:0,
|
||
scrapType: 1,
|
||
scrapId: null, // 报废原因id
|
||
scrapReason: '', // 报废原因
|
||
fileList: [],
|
||
})
|
||
const imgBeseUrl2 = ref('') //图片展示
|
||
const imgList2 = ref([]) // 图片列表,用于回显
|
||
//上传
|
||
const uploadImg2 = () => {
|
||
uni.showActionSheet({
|
||
itemList: ['拍照', '从相册选择'],
|
||
success: (res) => {
|
||
if (res.tapIndex === 0) {
|
||
getCameraFjBF()
|
||
} else if (res.tapIndex === 1) {
|
||
// 从相册选择
|
||
getPhotoFjBF()
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('操作菜单选择失败:', err)
|
||
},
|
||
})
|
||
}
|
||
|
||
// 附件拍照
|
||
const getCameraFjBF = () => {
|
||
navigator.camera.getPicture(onCameraSuccessFjBF, onCameraErrorFjBF, {
|
||
quality: 50,
|
||
destinationType: window.Camera.DestinationType.DATA_URL,
|
||
sourceType: window.Camera.PictureSourceType.CAMERA,
|
||
})
|
||
}
|
||
// 附件从相册选择
|
||
const getPhotoFjBF = () => {
|
||
navigator.camera.getPicture(onCameraSuccessFjBF, onCameraErrorFjBF, {
|
||
quality: 50,
|
||
destinationType: window.Camera.DestinationType.DATA_URL,
|
||
sourceType: window.Camera.PictureSourceType.SAVEDPHOTOALBUM,
|
||
})
|
||
}
|
||
|
||
const onCameraErrorFjBF = (message) => {
|
||
console.log(message)
|
||
}
|
||
|
||
const onCameraSuccessFjBF = (file) => {
|
||
uploadSignUrlFjBF(file)
|
||
}
|
||
|
||
const uploadSignUrlFjBF = (file) => {
|
||
const base64Data = file
|
||
|
||
uni.request({
|
||
url: '/file/uploadBase64',
|
||
method: 'POST',
|
||
data: {
|
||
base64File:base64Data,
|
||
fileName: `${generateRandomString(10)}_${Date.now()}.png`,
|
||
fileType: 'image/png'
|
||
},
|
||
success: (uploadRes) => {
|
||
if(!uploadRes.data.code){
|
||
uploadRes = JSON.parse(decryptWithSM4(uploadRes.data))
|
||
}else{
|
||
uploadRes = JSON.parse(uploadRes.data)
|
||
}
|
||
if (uploadRes.code && uploadRes.code == 200) {
|
||
imgList2.value.push({
|
||
url: uploadRes.data.url, // Show local path first
|
||
serverUrl: uploadRes.data.url // Store server URL
|
||
})
|
||
// bmFileInfos.value.push({
|
||
// name: uploadRes.data.name,
|
||
// url: uploadRes.data.url,
|
||
// taskType: '10'
|
||
// })
|
||
uni.showToast({ title: '上传成功', icon: 'none' })
|
||
} else {
|
||
uni.showToast({ title: '上传失败', icon: 'none' })
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('上传失败', err)
|
||
uni.showToast({ title: '上传失败', icon: 'none' })
|
||
}
|
||
})
|
||
}
|
||
|
||
|
||
|
||
// 删除图片
|
||
const deleteImage2 = (index) => {
|
||
imgList2.value.splice(index, 1)
|
||
formRight.value.fileList.splice(index, 1)
|
||
}
|
||
|
||
const rowData = ref({})
|
||
// 配件框change事件
|
||
const partCheckNum = (item) => {
|
||
// console.log(item)
|
||
// console.log(item.partNum)
|
||
setTimeout(() => {
|
||
item.partNum = Number(String(item.partNum).replace(/[^\d.]/g, ''))
|
||
if (item.storageNum) {
|
||
// console.log(item.partNum)
|
||
// console.log(item.storageNum)
|
||
if (Number(item.partNum) >= Number(item.storageNum)) {
|
||
item.partNum = Number(item.storageNum)
|
||
}
|
||
}
|
||
}, 500)
|
||
}
|
||
// 金额框change事件
|
||
const costCheckNum = (item) => {
|
||
// console.log(item)
|
||
// console.log(item.partPrice)
|
||
setTimeout(() => {
|
||
item.partPrice = Number(String(item.partPrice).replace(/[^\d.]/g, ''))
|
||
}, 500)
|
||
}
|
||
//维修完成校验
|
||
const saveCode = () => {
|
||
if (repairType.value == 1) {
|
||
let index1 = partItems.value.findIndex((v) => v.partId == '')
|
||
let index2 = partItems.value.findIndex((v) => v.partNum == 0)
|
||
if (repairPerson.value == '') {
|
||
uni.showToast({ title: '请先选择维修人员!', icon: 'none' })
|
||
} else {
|
||
saveCodeApi()
|
||
}
|
||
} else if (repairType.value == 2) {
|
||
let index1 = partItemsMiddle.value.findIndex((v) => v.partName == '')
|
||
let index2 = partItemsMiddle.value.findIndex((v) => v.supplierId == '')
|
||
let index3 = partItemsMiddle.value.findIndex((v) => v.partNum == 0)
|
||
if (repairPerson.value == '') {
|
||
uni.showToast({ title: '请先选择维修人员!', icon: 'none' })
|
||
} else if (index1 > -1) {
|
||
uni.showToast({ title: '请先填写配件名称!', icon: 'none' })
|
||
} else if (index2 > -1) {
|
||
uni.showToast({ title: '请选择物资厂家!', icon: 'none' })
|
||
} else if (index3 > -1) {
|
||
uni.showToast({ title: '请填写配件数量!', icon: 'none' })
|
||
} else {
|
||
saveCodeApi()
|
||
}
|
||
} else if (repairType.value == 3) {
|
||
console.log(formRight.value)
|
||
if (repairPerson.value == '') {
|
||
uni.showToast({ title: '请先选择维修人员!', icon: 'none' })
|
||
} else if (!formRight.value.scrapReason && !formRight.value.scrapId) {
|
||
uni.showToast({ title: '请填写报废原因', icon: 'none' })
|
||
} else {
|
||
saveCodeApi()
|
||
}
|
||
}
|
||
}
|
||
//维修完成请求
|
||
const saveCodeApi = async () => {
|
||
//请求接口
|
||
rowData.value = queryParams.value
|
||
//维修人员
|
||
rowData.value.repairDeviceList[rowIndex.value].repairList = [
|
||
{
|
||
repairer: repairPerson.value,
|
||
// remark: remark.value,
|
||
// fileList: bmFileInfos.value,
|
||
},
|
||
]
|
||
rowData.value.repairDeviceList[rowIndex.value].codeInRepairPartList = []
|
||
rowData.value.repairDeviceList[rowIndex.value].codeOutRepairPartList = []
|
||
rowData.value.repairDeviceList[rowIndex.value].codeScrapRepairPartList = []
|
||
if (repairType.value == 1) {
|
||
for (let i = 0; i < partItems.value.length; i++) {
|
||
rowData.value.repairDeviceList[rowIndex.value].codeInRepairPartList.push({
|
||
partType: partItems.value[i].partType,
|
||
partId: partItems.value[i].partId,
|
||
partNum: partItems.value[i].partNum,
|
||
storageNum: partItems.value[i].storageNum,
|
||
remark: partItems.value[i].remark,
|
||
fileList: partItems.value[i].bmFileInfos,
|
||
// repairNum: formLeft.value.repairNum,
|
||
})
|
||
}
|
||
} else if (repairType.value == 2) {
|
||
for (let i = 0; i < partItemsMiddle.value.length; i++) {
|
||
rowData.value.repairDeviceList[rowIndex.value].codeOutRepairPartList.push({
|
||
partType: partItemsMiddle.value[i].partType,
|
||
partPrice: partItemsMiddle.value[i].partPrice,
|
||
partNum: partItemsMiddle.value[i].partNum,
|
||
partName: partItemsMiddle.value[i].partName,
|
||
supplierId: partItemsMiddle.value[i].supplierId,
|
||
remark: partItemsMiddle.value[i].remark,
|
||
fileList: partItemsMiddle.value[i].bmFileInfos,
|
||
// repairNum: formMiddle.value.repairNum,
|
||
})
|
||
}
|
||
} else if (repairType.value == 3) {
|
||
rowData.value.repairDeviceList[rowIndex.value].codeScrapRepairPartList.push(formRight.value)
|
||
}
|
||
rowData.value.repairDeviceList[rowIndex.value].repairType = repairType.value
|
||
rowData.value.repairDeviceList[rowIndex.value].inRepairList = [{ remark: partRemark.value, fileList: partFileList.value }]
|
||
rowData.value.repairDeviceList[rowIndex.value].outRepairList = [{ remark: returnRemark.value, fileList: returnFileList.value }]
|
||
console.log(rowData.value.repairDeviceList)
|
||
uni.showLoading({ title: '提交中...' })
|
||
saveRepairRow(rowData.value.repairDeviceList).then(async (response) => {
|
||
if (response.code == 200) {
|
||
uni.showToast({ title: '保存成功', icon: 'none' })
|
||
uni.navigateBack({
|
||
delta: 1, // 返回到已存在的页面
|
||
})
|
||
}
|
||
}).catch((error) => {
|
||
console.log(error)
|
||
}).finally(() => {
|
||
uni.hideLoading()
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.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;
|
||
}
|
||
// 上传区域样式
|
||
.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;
|
||
}
|
||
}
|
||
.page-container {
|
||
display: flex;
|
||
height: 100vh;
|
||
padding: 24rpx;
|
||
flex-direction: column;
|
||
background-color: #f7f8fa;
|
||
|
||
// 基本信息卡片
|
||
.table-list-item {
|
||
background-color: #fff;
|
||
border-radius: 20rpx;
|
||
padding: 24rpx;
|
||
margin-bottom: 24rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
|
||
// 标题样式
|
||
h2 {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #262626;
|
||
margin-bottom: 24rpx;
|
||
position: relative;
|
||
padding-left: 24rpx;
|
||
margin-left: 10px;
|
||
|
||
&::before {
|
||
content: '';
|
||
position: absolute;
|
||
left: -10px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 6rpx;
|
||
height: 28rpx;
|
||
background: #3784fb;
|
||
border-radius: 6rpx;
|
||
}
|
||
}
|
||
|
||
// 信息行
|
||
.uni-row {
|
||
padding: 16rpx 0;
|
||
font-size: 28rpx;
|
||
border-bottom: 2rpx solid #f5f5f5;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.uni-col-6 {
|
||
color: #8c8c8c;
|
||
}
|
||
|
||
.cont {
|
||
color: #262626;
|
||
}
|
||
}
|
||
|
||
// 表单样式
|
||
:deep(.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;
|
||
}
|
||
|
||
.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-data-select {
|
||
.uni-select {
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 操作按钮组
|
||
.search-form {
|
||
// margin-bottom: 24rpx;
|
||
// background: #fff !important;
|
||
// border-radius: 20rpx !important;
|
||
// padding: 24rpx !important;
|
||
// box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
|
||
.btnBox {
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
text-align: center;
|
||
color: #fff;
|
||
font-size: 28rpx;
|
||
font-weight: 600;
|
||
border-radius: 12rpx;
|
||
transition: all 0.3s ease;
|
||
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
|
||
|
||
&:active {
|
||
transform: scale(0.98);
|
||
opacity: 0.9;
|
||
}
|
||
|
||
// 内部维修按钮
|
||
&.internal {
|
||
background: linear-gradient(135deg, #2ecc71 0%, #27ae60 100%);
|
||
box-shadow: 0 6rpx 20rpx rgba(46, 204, 113, 0.2);
|
||
}
|
||
|
||
// 返厂维修按钮
|
||
&.return {
|
||
background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
|
||
box-shadow: 0 6rpx 20rpx rgba(243, 156, 18, 0.2);
|
||
}
|
||
|
||
// 待报废按钮
|
||
&.scrap {
|
||
background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
|
||
box-shadow: 0 6rpx 20rpx rgba(231, 76, 60, 0.2);
|
||
}
|
||
|
||
// 维修完成按钮
|
||
&.complete {
|
||
background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
|
||
box-shadow: 0 6rpx 20rpx rgba(52, 152, 219, 0.2);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 加减按钮
|
||
.operation-btns {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16rpx;
|
||
margin-left: 24rpx;
|
||
|
||
span {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 8rpx;
|
||
font-size: 32rpx;
|
||
transition: all 0.3s ease;
|
||
|
||
&:active {
|
||
transform: scale(0.95);
|
||
opacity: 0.8;
|
||
}
|
||
|
||
// 添加按钮
|
||
&.add {
|
||
color: #2ecc71;
|
||
background-color: rgba(46, 204, 113, 0.1);
|
||
}
|
||
|
||
// 删除按钮
|
||
&.remove {
|
||
color: #e74c3c;
|
||
background-color: rgba(231, 76, 60, 0.1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// 加载提示文字
|
||
.loading-text {
|
||
text-align: center;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
padding: 20rpx 0;
|
||
}
|
||
|
||
.outbound-btn {
|
||
width: 70%;
|
||
margin: 25rpx auto;
|
||
height: 65rpx;
|
||
line-height: 65rpx;
|
||
text-align: center;
|
||
background-color: #19be6b;
|
||
border-radius: 12rpx;
|
||
color: #fff;
|
||
}
|
||
.top-content {
|
||
height: 60px;
|
||
overflow: hidden;
|
||
transition: max-height 0.5s ease-out;
|
||
|
||
&.is-expanded {
|
||
height: 200px !important;
|
||
overflow: visible !important;
|
||
}
|
||
.down-icon {
|
||
display: inline-block;
|
||
transition: transform 0.5s ease; /* 添加动画过渡 */
|
||
transform: rotate(0deg);
|
||
|
||
&.icon-is-expanded {
|
||
transform: rotate(180deg) !important;
|
||
}
|
||
}
|
||
}
|
||
</style>
|