bonus-material-app/src/pages/materialsStation/toolsLease/toolsLeaseAdd.vue

811 lines
24 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 dark :fixed="true" shadow background-color="#4AA4EA" status-bar title="工器具领料"
><template v-slot:left>
<view style="font-size: 18px; display: flex; align-items: center" @click="back">
<!-- 图标 -->
<uni-icons type="left" size="20" color="#fff"></uni-icons>
<!-- 文本 -->
<text>返回</text>
</view>
</template>
<template v-slot:right v-if="opts.isOut">
<view
v-if="formData.pickType == 0 || !formData.pickType"
@click="submit(0)"
style="font-size: 18px; display: flex; align-items: center"
>
<!-- 文本 -->
<text>暂存</text>
</view>
</template>
</uni-nav-bar>
<div class="content">
<uni-section title="任务信息" type="line"></uni-section>
<uni-forms ref="form" :rules="rules" :model="formData" label-width="90px">
<uni-forms-item label="领用类型" required name="pickType" v-if="opts.isOut && !opts.isEdit">
<uni-data-select
v-model="formData.pickType"
:localdata="pickTypeList"
:clear="false"
filterable
@change="changePickType"
></uni-data-select>
</uni-forms-item>
<uni-forms-item label="领用工程" required name="proId">
<uni-data-select
v-model="formData.proId"
:localdata="prodRange"
:clear="false"
filterable
@change="changeProd"
></uni-data-select>
</uni-forms-item>
<uni-forms-item label="领用项目部" required name="departId" v-if="formData.pickType == 1">
<uni-data-select
v-model="formData.departId"
:localdata="proDeptList"
:clear="false"
filterable
@change="changeDept"
></uni-data-select>
</uni-forms-item>
<uni-forms-item
label="领料班组"
required
name="teamId"
v-if="formData.pickType == 0 || !formData.pickType"
>
<uni-data-select
v-model="formData.teamId"
:localdata="teamRange"
filterable
:clear="false"
@change="changeTeamd"
></uni-data-select>
</uni-forms-item>
<uni-forms-item
label="领料人"
required
name="leasePerson"
>
<uni-easyinput
v-model="formData.leasePerson"
placeholder="请输入内容"
:disabled="formData.pickType == 0"
></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="联系电话" name="relPhone">
<uni-easyinput
v-model="formData.relPhone"
placeholder="请输入内容"
maxlength="11"
:disabled="isEdit"
@blur="checkPhone"
></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="备注" name="remark">
<uni-easyinput
v-model="formData.remark"
placeholder="请输入内容"
maxlength="200"
></uni-easyinput>
</uni-forms-item>
<uni-forms-item label="所属分包" name="subUnitName">
<uni-easyinput
v-model="formData.subUnitName"
:placeholder="formData.subUnitName ? '请输入所属分包' : '暂无分包'"
maxlength="200"
disabled
></uni-easyinput>
</uni-forms-item>
<!-- <uni-forms-item label="适用班组数" name="fitNum" v-if="!opts.isOut">
<uni-easyinput
v-model="formData.fitNum"
type="number"
placeholder="请输入内容"
maxlength="10"
:clearable="false"
@blur="fitNumChange"
></uni-easyinput>
</uni-forms-item> -->
<uni-section title="领用工具器" type="line" />
<eselect
v-model="equipmentId"
style="width: 100%; height: 90rpx; margin: 10px 0"
ref="treeSelect"
:options="equipmentList"
:disabled="!formData.teamId || !formData.proId"
@change="changeEquipment"
></eselect>
</uni-forms>
<uni-table ref="table" border stripe emptyText="暂无更多数据">
<uni-tr>
<uni-th width="50" align="center">序号</uni-th>
<uni-th width="160" align="center">类型名称</uni-th>
<uni-th width="180" align="center">规格型号</uni-th>
<uni-th width="100" align="center">{{ opts.isOut ? '出库数' : '领用数' }}</uni-th>
<uni-th width="80" align="center">在库数</uni-th>
<uni-th width="80" align="center">在用数</uni-th>
<uni-th width="80" align="center" v-if="opts.isOut">预领数</uni-th>
<uni-th width="100" align="center">备注</uni-th>
<uni-th width="100" align="center">操作</uni-th>
</uni-tr>
<uni-tr v-for="(item, index) in tableData" :key="index">
<uni-td align="center">{{ index + 1 }}</uni-td>
<uni-td align="center">{{ item.maTypeName }}</uni-td>
<uni-td align="center">
<view class="name">{{ item.typeName }}</view>
</uni-td>
<uni-td align="center"
><uni-easyinput
v-if="item.manageType == 1 || !opts.isOut"
v-model="item.preNum"
placeholder="请输入数量"
:clearable="false"
@change="checkPerNum(item)"
></uni-easyinput>
<!-- 编码 -->
<span v-else style="color: #409eff" @click="getCode(item)">{{
!item.maCodeList || item.maCodeList.length == 0 ? '选择编码' : item.maCodeList.length
}}</span>
</uni-td>
<uni-td align="center">{{ item.storageNum }}</uni-td>
<uni-td align="center">{{ item.useNum }}</uni-td>
<uni-td align="center" v-if="opts.isOut">{{ item.preNum }}</uni-td>
<uni-td align="center">
<uni-easyinput
v-if="opts.isOut"
v-model="item.remark"
placeholder="请输入备注"
></uni-easyinput>
</uni-td>
<uni-td align="center">
<view
style="
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
"
>
<button
class="uni-button"
size="mini"
type="warn"
@click="
() => {
tableData.splice(index, 1)
}
"
>
删除
</button>
<button
v-if="item.manageType == 0 && item.maCodeList"
class="uni-button"
size="mini"
@click="handleDetail(item)"
style="margin-top: 5px"
>
详情
</button>
</view>
</uni-td>
</uni-tr>
</uni-table>
<button v-if="opts.isOut" style="width: 100%; margin: 50px 0" type="primary" @click="submit(1)">
提 交
</button>
<button v-else style="width: 100%; margin: 50px 0" type="primary" @click="submit(0)">
提 交
</button>
</div>
<uni-popup ref="popup" type="center" border-radius="6px 6px 6px 6px" background-color="#fff">
<div style="padding: 20px">
<div>编码详情</div>
<div class="code-list">
<div v-for="(item, index) in popupRow" :key="index">
<span>{{ item.maCode }}</span>
</div>
</div>
</div>
</uni-popup>
</template>
<script setup>
import { onLoad, onShow, onBackPress } from '@dcloudio/uni-app'
import { ref, reactive } from 'vue'
import eselect from '@/pages/materialsStation/toolsLease/components/eselect.vue'
import {
getBmTeamList,
getProjectList,
getTypeTreeList,
addLeaseTask,
editLeaseTask,
detailsLeaseTask,
getAgreementInfoByIdApi,
getPickDepartListApi,
} from '@/services/materialsStation'
import { useMemberStore } from '@/stores'
const memberStore = useMemberStore()
const userInfo = ref(memberStore.userInfo || {})
const loading = ref(false)
const title = ref('工器具领料申请')
const opts = ref({})
const form = ref()
const formData = reactive({
teamId: undefined,
projectId: undefined,
leasePerson: '',
relPhone: '',
isOut: 1,
remark: '',
fitNum: 1,
proId: undefined,
pickType: 0,
departId: undefined,
departName: '',
})
const lastFitNum = ref(formData.fitNum)
const equipmentId = ref()
const teamRange = ref([]) // 班组
const prodRange = ref([]) // 工程
const equipmentList = ref([]) // 工器具
const rules = ref({
teamId: {
rules: [{ required: true, errorMessage: '请选择班组' }],
},
proId: {
rules: [{ required: true, errorMessage: '请选择工程' }],
},
leasePerson: {
rules: [{ required: true, errorMessage: '请填写领用人' }],
},
// relPhone: {
// rules: [{ required: true, errorMessage: '请填写联系电话' }],
// },
})
const tableData = ref([])
const popup = ref()
const popupRow = ref({})
const proDeptList = ref([])
const pickTypeList = ref([
{ text: '班组', value: 0 },
{ text: '项目部', value: 1 },
])
// 适用班组数
const fitNumChange = () => {
const newVal = Math.min(5, Math.max(1, parseInt(formData.fitNum) || 1))
// 计算变化比例
const ratio = newVal / lastFitNum.value
// 更新每条数据的预领数量
tableData.value.forEach((item) => {
// 仅当是数字才执行,避免 null 或空
if (typeof item.preNum === 'number') {
item.preNum = Math.max(1, Math.floor(item.preNum * ratio)) // 向下取整且至少为1
}
})
// 更新 formData.fitNum 和记录的 lastFitNum
formData.fitNum = newVal
lastFitNum.value = newVal
}
// 编辑获取详情
const getDetailsById = async () => {
try {
uni.showLoading({
title: '加载中...',
mask: true, // 遮罩层
})
const res = await detailsLeaseTask(opts.value.id)
console.log('🚀 ~ getDetailsById ~ res:', res)
tableData.value = res.data.leaseApplyDetailsList
tableData.value.forEach((item) => {
item.maCodeList = item.maCodeVoList || item.maCodeList || []
})
Object.assign(formData, res.data.leaseApplyInfo)
formData.proId = res.data.leaseApplyInfo.proId
formData.projectId = prodRange.value.find(
(item) => item.proId == res.data.leaseApplyInfo.proId,
)?.projectId
formData.relPhone = res.data.leaseApplyInfo.phone || res.data.leaseApplyInfo.relPhone || ''
await getTeamList()
await getAgreementInfoById()
if (res.msg.includes('您所选择的')) {
// 弹框提示
uni.showModal({
content: res.msg,
showCancel: false,
confirmText: '关闭',
confirmColor: '#ccc',
})
}
} catch (error) {
console.log('🚀 ~ getDetailsById ~ error:', error)
} finally {
uni.hideLoading()
}
}
// 获取项目部列表
const getProDeptList = async () => {
try {
const res = await getPickDepartListApi({ proId: formData.projectId })
if (!res.data || res.data.length == 0) return
proDeptList.value = res.data.map((item) => {
return {
...item,
value: item.departId,
text: item.departName,
}
})
} catch (error) {
console.log('🚀 ~ getProDeptList ~ error:', error)
}
}
// 获取班组
const getTeamList = async () => {
try {
const params = {
isAll: 0,
projectId: formData.projectId,
idCard: uni.getStorageSync('idCard'),
}
// if (!opts.value.isOut) {
// params.idCard = uni.getStorageSync('idCard')
// }
console.log('🚀 ~ getTeamList ~ params:', params)
const res = await getBmTeamList(params)
// teamRange.value = res.data
if (res.data.length > 0) {
teamRange.value = res.data.map((item) => {
return {
...item,
value: item.id,
text: item.teamName,
}
})
// console.log('🚀 ~ teamRange.value=res.data.map ~ teamRange.value:', teamRange.value)
// 如果 teamRange.value 列表中的 idCard 有与userInfo.userName 一致的,则设置 teamId
if (opts.value.isEdit) {
const team = res.data.find((item) => item.teamName == formData.teamName)
console.log('xxxxxxxxx', team)
formData.teamId = team.id
formData.teamName = team.teamName
formData.leasePerson = team.relName
formData.relPhone = team.relPhone || ''
formData.relName = team.relName
formData.teamLeaderIdCard = team.teamLeaderIdCard
formData.subUnitName = team.subUnitName || ''
} else {
formData.teamId = res.data[0].id
formData.teamName = res.data[0].teamName
formData.leasePerson = res.data[0].relName
formData.relPhone = res.data[0].relPhone || ''
formData.relName = res.data[0].relName
formData.teamLeaderIdCard = res.data[0].teamLeaderIdCard
formData.subUnitName = res.data[0].subUnitName || ''
}
// getProjectListApi()
// getAgreementInfoById()
} else {
uni.showToast({
icon: 'none',
title: '暂无班组入场信息',
})
}
} catch (error) {
console.log('🚀 ~ getTeamList ~ error:', error)
}
}
// 获取工程
const getProjectListApi = async () => {
try {
const res = await getProjectList({ unitId: null, isApp: true, teamName: formData.teamName })
if (!res.data || !res.data.length) return
console.log('🚀 ~ getProjectListApi ~ res:', res)
prodRange.value = res.data.map((item) => {
return {
...item,
value: item.proId,
text: item.proName,
}
})
} catch (error) {
console.log('🚀 ~ getProjectListApi ~ error:', error)
}
}
// 获取协议信息
const getAgreementInfoById = async () => {
try {
const params = {
teamId: formData.teamId,
proId: formData.proId,
// projectId: formData.projectId,
}
const res = await getAgreementInfoByIdApi(params)
console.log('🚀 ~ getAgreementInfoById ~ res:', res)
if (!res.data) {
equipmentList.value = []
return
}
const agreementId = res.data
if (agreementId.length > 0) {
getEquipmentList(agreementId)
} else {
console.log('工程和班组没有协议')
}
} catch (error) {
console.log('🚀 ~ getAgreementInfoById ~ error:', error)
}
}
// 获取工具器
const getEquipmentList = async (params) => {
console.log('🚀 ~ getEquipmentList ~ params:', params)
uni.showLoading({
title: '加载中...',
mask: true, // 遮罩层
})
try {
const res = await getTypeTreeList({
agreementIdList: params,
proId: formData.proId,
teamName: formData.teamName,
})
if (res.data) {
equipmentList.value = formatEquipmentTree(res.data)
console.log('🚀 ~ getEquipmentList ~ machineList.value:', equipmentList.value)
}
} catch (error) {
console.log('🚀 ~ getMachineListApi ~ error:', error)
} finally {
uni.hideLoading()
}
}
function formatEquipmentTree(list) {
return list.map((item) => {
const newItem = {
...item,
id: item.typeId,
name: item.typeName,
}
if (item.children && item.children.length > 0) {
newItem.children = formatEquipmentTree(item.children)
}
return newItem
})
}
// 校验电话
const checkPhone = (rule, value, callback) => {
if (!/^1[3-9][0-9]{9}$/.test(formData.relPhone)) {
uni.showToast({
icon: 'none',
title: '请输入正确的电话号码',
})
// 清空
formData.relPhone = ''
return false
}
return true
}
// 检查数量
const checkPerNum = (item) => {
// 大于1的正整数 正则校验
if (item.unitValue == 1) {
item.preNum = Number(String(item.preNum).replace(/[^\d.]/g, ''))
} else {
item.preNum = Number(String(item.preNum).replace(/[^\d]/g, ''))
}
// if (!/^[1-9]\d*$/.test(item.preNum)) {
// uni.showToast({
// icon: 'none',
// title: '请输入正确的数量',
// })
// // 重置为1
// item.preNum = 1
// return false
// }
if (opts.value.isOut) {
if (item.preNum > item.storageNum) {
uni.showToast({
icon: 'none',
title: '出库数量不能大于库存数量',
})
// 重置为库存数量
item.preNum = item.storageNum
return false
}
}
}
const changeDept = (e) => {
console.log('🚀 ~ changeDept ~ e:', e)
const dept = proDeptList.value.find((item) => item.departId === e)
console.log('🚀 ~ changeDept ~ dept:', dept)
formData.teamId = dept.departId
formData.teamName = dept.departName
getAgreementInfoById()
}
// 选择班组
const changeTeamd = (e) => {
console.log('🚀 ~ changeTeamd ~ e:', e)
const team = teamRange.value.find((item) => item.id === e)
console.log('🚀 ~ changeTeamd ~ team:', team)
// formData.projectId = null
formData.teamName = team ? team.teamName : ''
formData.leasePerson = team ? team.relName : ''
formData.relPhone = team ? team.relPhone : ''
formData.relName = team ? team.relName : ''
formData.phone = team ? team.relPhone : ''
formData.teamLeaderIdCard = team ? team.teamLeaderIdCard : ''
formData.subUnitName = team ? team.subUnitName : ''
equipmentList.value = []
// getProjectListApi()
getAgreementInfoById()
}
const changePickType = (e) => {
tableData.value = []
formData.teamId = null
if (e == 0) {
getTeamList()
} else {
getProDeptList()
}
}
// 选择工程
const changeProd = async (e) => {
console.log('🚀 ~ changeProd ~ e:', e)
formData.proId = e
formData.projectId = prodRange.value.find((item) => item.proId == e)?.projectId
formData.teamId = null
formData.leasePerson = ''
console.log('xxxxxxxxxxxxxxxxxxxxxx', formData.projectId)
tableData.value = []
if (formData.pickType == 0) {
await getTeamList()
} else {
await getProDeptList()
}
await getAgreementInfoById()
}
// 选择工器具
const changeEquipment = (e) => {
console.log('🚀 ~ changeEquipment ~ e:', e)
// 判断是否已添加同型号
if (tableData.value.some((item) => item.typeId === e.typeId)) {
uni.showToast({
icon: 'none',
title: '该型号已添加',
})
return
}
// 从 equipmentList.value 中获取点击id的上一级的 typeName
const equipment = findEquipmentById(equipmentList.value, e.parentId)
tableData.value.unshift({
...JSON.parse(JSON.stringify(e)),
storageNum: e.num,
maTypeName: equipment.typeName,
preNum: 1, // 数量默认为1
maCodeList: [],
})
setTimeout(() => {
equipmentId.value = ''
}, 300)
}
// 递归查找指定 id 的节点
function findEquipmentById(list, id) {
for (const item of list) {
if (item.id === id) {
return item
}
if (item.children && item.children.length > 0) {
const found = findEquipmentById(item.children, id)
if (found) return found
}
}
return null
}
// 处理详情
const handleDetail = (item) => {
console.log('🚀 ~ handleDetail ~ item:', item)
// 弹框展示编码详情 uni-popup 展示详情
popup.value.open()
popupRow.value = item.maCodeList
}
// 获取编码
const getCode = (item) => {
console.log('🚀 ~ getCode ~ item:', item)
if (item.maCodeList && item.maCodeList.length > 0) {
item.maCodeList.forEach((code) => {
code.checked = true
})
}
item.isEdit = opts.value.isEdit
uni.navigateTo({
url:
'/pages/materialsStation/toolsLease/codeOut?params=' +
JSON.stringify({ ...item, proId: formData.proId, teamId: formData.teamId}),
})
}
const submit = (isOut) => {
console.log('🚀 ~ submit ~ submit:', formData)
// 校验表单
form.value
.validate()
.then(async (valid) => {
formData.isOut = isOut
formData.phone = formData.relPhone
formData.createBy = uni.getStorageSync('username') || ''
console.log('🚀 ~ form.value.validate.then ~ valid:', valid)
if (tableData.value.length === 0) {
await uni.showToast({
title: '请添加领用数据',
icon: 'none',
duration: 1000,
})
return
}
tableData.value.forEach((item) => {
if (item.manageType == 0 && opts.value.isOut) {
item.preNum = item.maCodeList ? item.maCodeList.length : 0
}
item.outNum = item.preNum
})
// tableData.value 循环 preNum 不能小于 0, 小于0的提示到具体行
for (let i = 0; i < tableData.value.length; i++) {
console.log('🚀 ~ .then ~ tableData.value[i].preNum:', tableData.value[i].preNum)
if (tableData.value[i].preNum < 0) {
await uni.showToast({
title: `${i + 1}行出库数量不能为0`,
icon: 'none',
duration: 1000,
})
return
}
}
const params = {
leaseApplyDetailsList: tableData.value,
leaseApplyInfo: formData,
}
console.log('🚀 ~ .then ~ params:', params)
if (isOut != 0) {
// 弹框确定
const resp = await uni.showModal({
title: '提示',
content: '是否确认提交?',
confirmText: '提交',
cancelText: '取消',
})
console.log('🚀 ~ .confirm ~ resp:', resp)
if (!resp.confirm) return
}
uni.showLoading({
title: '提交中...',
mask: true, // 遮罩层
})
try {
if (!opts.value.isEdit) {
console.log('新增')
const res = await addLeaseTask(params)
tableData.value = []
uni.hideLoading()
console.log('🚀 ~ .then ~ res:', res)
uni.showToast({
icon: 'none',
title: '操作成功',
})
back()
} else if (opts.value.isEdit) {
const res = await editLeaseTask(params)
tableData.value = []
uni.hideLoading()
uni.showToast({
icon: 'none',
title: '操作成功',
})
back()
}
} catch (error) {
console.log('🚀 ~ .then ~ error:', error)
uni.hideLoading()
}
})
.catch((err) => {
console.log('🚀 ~ form.value.validate.catch ~ err:', err)
})
}
const back = () => {
if (tableData.value.length > 0 && formData.pickType != 1) {
uni
.showModal({
title: '提示',
content: '当前有未提交的数据,是否暂存?',
confirmText: '暂存',
cancelText: '不暂存',
})
.then((res) => {
if (res.confirm) {
submit(0)
} else {
uni.navigateBack({
delta: 1,
})
}
})
} else {
uni.navigateBack({
delta: 1,
})
}
}
onLoad((opt) => {
console.log('onLoad', opt)
opts.value = opt.params ? JSON.parse(opt.params) : {}
title.value = opts.value.title
if (opts.value.isEdit) {
getProjectListApi().then(() => {
getDetailsById()
})
} else {
// getTeamList()
getProjectListApi()
}
})
onShow(() => {
console.log('onShow')
// 监听添加编码
uni.$on('maCodeList', (data) => {
console.log('🚀 ~ onShow ~ data:', data)
const item = tableData.value.find((item) => item.typeId == data[0].typeId)
console.log('🚀 ~ onShow ~ item:', item)
if (item) {
item.maCodeList = data
item.preNum = data.length
}
})
console.log('🚀 ~ onShow ~ tableData.value:', tableData.value)
})
onBackPress((opt) => {
console.log('🚀 ~ onBackPress ~ opt:', opt)
if (opt.from == 'backbutton') {
if (tableData.value.length > 0) {
// 仅提示数据未提交
uni.showToast({
title: `当前有未提交数据, 请先${formData.pickType != 1 ? '提交' : '暂存或提交'}`,
icon: 'none',
duration: 1000,
})
return true
}
} else {
return false
}
})
</script>
<style lang="scss" scoped>
.content {
padding: 10px;
background-color: #fafafa;
}
.col {
display: flex;
align-items: center;
margin-bottom: 15px;
}
</style>