bonus-ui/src/views/EquipmentEntryApply/equipmentInput/add.vue

761 lines
27 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>
<!-- 弹窗内容区域 -->
<div class="app-container" style="height: calc(100vh - 84px); overflow-y: unset">
<div class="page-header">
<div>
<i
class="el-icon-arrow-left goBack-btn"
@click="goBack"
style="border-color: transparent; color: #00a288; background: transparent; padding-left: 0; padding-right: 0"
>返回</i
>
<span class="page-title">{{ pageTitle }}</span>
</div>
<div class="dialog-footer" style="float: right">
<el-button size="medium" @click="goBack">取消</el-button>
<el-button type="primary" size="medium" @click="handleSubmit">确认</el-button>
</div>
</div>
<el-form
label-width="120px"
ref="formRef"
style="padding: 12px; overflow-y: auto; height: calc(100vh - 180px); width: 100%"
label-position="right"
:model="form"
:rules="equipRules"
>
<div style="display: flex; padding-bottom: 5px">
<div style="width: 5px; background-color: #00a288; margin-right: 10px"></div>
基础信息
</div>
<el-row :gutter="24" style="padding-top: 10px">
<el-col :span="6">
<el-form-item label="专业" prop="major">
<el-select v-model="form.major" placeholder="请选择专业" @change="majorChange" style="width: 100%">
<el-option v-for="item in majorList" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工序" prop="process">
<el-cascader
style="width: 100%"
v-model="form.process"
placeholder="请选择工序"
:options="processList"
@change="processChange"
></el-cascader>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="装备类目" prop="category">
<el-cascader
style="width: 100%"
v-model="form.category"
:options="categoryList"
placeholder="请选择装备类目"
@change="categoryChange"
></el-cascader>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="装备名称" prop="name">
<el-input autocomplete="off" maxlength="30" placeholder="请输入装备名称" v-model="form.name" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="规格型号" prop="specificationModel">
<el-input
autocomplete="off"
maxlength="30"
v-model="form.specificationModel"
placeholder="请输入规格型号"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="资产原值(万元)" prop="originalValue">
<el-input
@input="handlePriceInput"
autocomplete="off"
maxlength="20"
v-model="form.originalValue"
placeholder="请输入资产原值"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="生产厂家" prop="manufacturerId">
<el-select v-model="form.manufacturerId" placeholder="请选择生产厂家" clearable style="width: 100%">
<el-option v-for="item in manufacturerList" :key="item.id" :label="item.label" :value="item.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="生产日期" prop="productionDate">
<el-date-picker
v-model="form.productionDate"
type="date"
placeholder="请选择生产日期"
value-format="yyyy-MM-dd"
style="width: 100%"
:picker-options="{
disabledDate(time) {
return time.getTime() > Date.now()
},
}"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="6">
<el-form-item label="下次维保日期" prop="nextMaintenanceDate">
<el-date-picker
v-model="form.nextMaintenanceDate"
placeholder="请选择下次维保日期"
value-format="yyyy-MM-dd"
type="date"
style="width: 100%"
>
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="装备原始编码" prop="originalCode">
<el-input clearable maxlength="20" placeholder="请输入装备原始编码" v-model="form.originalCode" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="最大使用年限" prop="maxServiceLifeYears">
<el-input-number
clearable
maxlength="20"
placeholder="请输入最大使用年限"
v-model="form.maxServiceLifeYears"
:min="1"
:max="100"
:precision="0"
:controls="false"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="计数单位" prop="unit">
<!-- <el-input v-model="form.unit" placeholder="请输入计数单位" clearable maxlength="11" /> -->
<el-select v-model="form.unit" placeholder="请选择计数单位" clearable style="width: 100%">
<el-option
v-for="dict in dict.type.dev_unit_type"
:key="dict.label"
:label="dict.label"
:value="dict.label"
/>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="6">
<el-form-item label="管理模式" prop="manageType">
<el-select
v-model="form.manageType"
placeholder="请选择管理方式"
clearable
@change="deviceTypeChange"
style="width: 100%"
>
<el-option label="编码" value="0" />
<el-option label="数量" value="1" />
</el-select>
</el-form-item>
</el-col> -->
</el-row>
<el-row :gutter="24">
<!-- <el-col :span="6">
<el-form-item label="装备数量" prop="count">
<el-input-number
v-model="form.count"
placeholder="请输入装备数量"
:min="1"
:max="100"
:precision="0"
:controls="false"
style="width: 100%"
:disabled="form.manageType == 0"
/>
</el-form-item>
</el-col> -->
<el-col :span="6">
<el-form-item label="采购日期" prop="purchaseDate">
<el-date-picker
v-model="form.purchaseDate"
placeholder="请选择采购日期"
value-format="yyyy-MM-dd"
type="date"
style="width: 100%"
:picker-options="{
disabledDate(time) {
return time.getTime() > Date.now()
},
}"
>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<div style="display: flex; padding-bottom: 10px">
<div style="width: 5px; background-color: #00a288; margin-right: 10px"></div>
特征属性
</div>
<el-row :gutter="24" style="padding-top: 10px">
<!-- propertyVoList -->
<el-col :span="6" v-for="(item, index) in propertyVoList" :key="index">
<el-form-item v-if="item.inputType == 1" :label="item.propertyName">
<el-input autocomplete="off" maxlength="30" v-model="item.propertyValue" clearable />
</el-form-item>
<!-- 单选 -->
<el-form-item v-if="item.inputType == 2" :label="item.propertyName">
<el-select v-model="item.propertyValue" placeholder="请选择" clearable style="width: 100%">
<el-option
v-for="(item, index) in handleData(item.value)"
:key="index"
:label="item.value"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<!-- 多选 -->
<el-form-item v-if="item.inputType == 3" :label="item.propertyName">
<el-select v-model="item.propertyValue" multiple placeholder="请选择" clearable style="width: 100%">
<el-option
v-for="(item, index) in handleData(item.value)"
:key="index"
:label="item.value"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- <el-col :span="6">
<el-form-item label="专业特征" prop="specialtyFeature">
<el-input autocomplete="off" maxlength="30" v-model="form.specialtyFeature" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="工序特征" prop="processFeature">
<el-input autocomplete="off" maxlength="30" v-model="form.processFeature" clearable />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="类目特征" prop="categoryFeature">
<el-input autocomplete="off" maxlength="30" v-model="form.categoryFeature" clearable />
</el-form-item>
</el-col> -->
</el-row>
<div style="display: flex; padding-bottom: 10px">
<div style="width: 5px; background-color: #00a288; margin-right: 10px"></div>
装备图片
</div>
<el-row :gutter="24" style="padding-top: 10px">
<el-col>
<el-form-item label="展示图" prop="mainFileList">
<ImageUpload
v-model="form.mainFileList"
:value="form.mainFileList"
:limit="6"
@change="handleImageChange"
/>
</el-form-item>
</el-col>
</el-row>
<div style="display: flex; padding-bottom: 10px">
<div style="width: 5px; background-color: #00a288; margin-right: 10px"></div>
相关证书
</div>
<el-row :gutter="24" style="padding-top: 10px">
<el-col>
<el-form-item label="合格证" prop="certificateList">
<FileUpload
v-model="form.certificateList"
:value="form.certificateList"
:limit="3"
:fileSize="10"
:fileType="['jpg', 'png', 'pdf']"
@change="handleCertificateChange"
/>
</el-form-item>
<el-form-item label="检测证书" prop="inspectionList">
<FileUpload
v-model="form.inspectionList"
:value="form.inspectionList"
:limit="3"
:fileSize="10"
:fileType="['doc', 'docx', 'ppt', 'pdf']"
@change="handleInspectionChange"
/>
</el-form-item>
<el-form-item label="采购发票" prop="purchaseInvoices">
<FileUpload
v-model="form.purchaseInvoices"
:value="form.purchaseInvoices"
:limit="3"
:fileSize="10"
:fileType="['pdf', 'jpg', 'png', 'jpeg']"
@change="handlePurchaseInvoicesChange"
/>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script>
import {
addInterDevice,
getEquipmentAddIdApi,
firstLevel,
secondAndThirdLevel,
fourthToSixthLevel,
getDeviceApi,
equipmentEditApiNew,
getEquipmentPropertyTypeApi,
} from '@/api/EquipmentEntryApply'
import { getManufacturerSelectApi } from '@/api/EquipmentLedger/index.js'
import ImageUpload from '@/components/ImageUpload'
import FileUpload from '@/components/FileImageUpload'
export default {
name: 'EquipmentEntryEditDialog', // 明确组件名称
emits: ['update:isVisible', 'submit', 'getOrderId'], // 声明事件
dicts: ['dev_unit_type'],
components: { ImageUpload, FileUpload },
data() {
return {
isSubmit: false,
query: {},
pageTitle: '新增装备',
// 下拉列表数据
majorList: [],
processList: [],
categoryList: [],
manufacturerList: [],
form: {
major: '', // 专业
process: [], // 工序
category: [], // 类目
name: '', // 装备名称
specificationModel: '', // 规格型号
originalValue: '', // 资产原值
productionDate: '', // 出厂日期
manufacturerId: '', // 生产厂家
originalCode: '', // 装备原始编码
nextMaintenanceDate: '', // 下次维保日期
maxServiceLifeYears: '', // 装备寿命
manageType: '0', // 管理模式
count: 1, // 装备数量
unit: '', // 计数单位
purchaseDate: '',
specialtyFeature: '', // 专业特征
processFeature: '', // 工序特征
categoryFeature: '', // 类目特征
// deviceTypeList: [], // 装备类型列表
mainFileList: [], // 展示图
certificateList: [], // 合格证
inspectionList: [], // 检测证书
},
// 表单校验规则(所有字段均为必填)
equipRules: {
major: [{ required: true, message: '请选择专业', trigger: 'change' }],
process: [{ required: true, message: '请选择工序', trigger: 'change' }],
category: [{ required: true, message: '请选择装备类目', trigger: 'change' }],
name: [{ required: true, message: '请输入装备名称', trigger: 'blur' }],
specificationModel: [{ required: true, message: '请输入规格型号', trigger: 'blur' }],
originalValue: [{ required: true, message: '请输入资产原值', trigger: 'blur' }],
productionDate: [{ required: true, message: '请选择出厂日期', trigger: 'change' }],
manufacturerId: [{ required: true, message: '请输入生产厂家', trigger: 'blur' }],
originalCode: [{ required: true, message: '请输入装备原始编码', trigger: 'blur' }],
nextMaintenanceDate: [{ required: true, message: '请选择下次维保日期', trigger: 'change' }],
maxServiceLifeYears: [{ required: true, message: '请输入装备寿命', trigger: 'blur' }],
// manageType: [{ required: true, message: '请选择管理方式', trigger: 'change' }],
count: [{ required: true, message: '请输入装备数量', trigger: 'blur' }],
unit: [{ required: true, message: '请输入计数单位', trigger: 'blur' }],
purchaseDate: [{ required: true, message: '请选择采购日期', trigger: 'change' }],
certificateList: [{ required: true, message: '请上传合格证', trigger: 'change' }],
inspectionList: [{ required: true, message: '请上传检测证书', trigger: 'change' }],
mainFileList: [{ required: true, message: '请上传图片', trigger: 'change' }]
},
propertyVoList: [], // 特征属性集合
}
},
created() {
this.firstLevel()
this.getManufacturerSelectList()
this.query = this.$route.query
console.log('🚀 ~ this.query:', this.query)
this.form.orderId = this.orderId = this.query.orderId || ''
if (this.query && this.query.maId) {
this.pageTitle = '编辑装备'
this.getInfo()
}
},
methods: {
// 获取详情
async getInfo() {
try {
const res = await getDeviceApi(this.query.maId)
console.log('🚀 ~ getInfo ~ res:', res)
this.form = res.data
this.form.mainFileList = res.data.appearanceImages
? res.data.appearanceImages.map((item) => item.fileUrl).join(',')
: []
this.form.certificateList = res.data.certificates
? res.data.certificates.map((item) => item.fileUrl).join(',')
: []
this.form.inspectionList = res.data.inspectionReports
? res.data.inspectionReports.map((item) => item.fileUrl).join(',')
: []
this.form.purchaseInvoices = res.data.purchaseInvoices
? res.data.purchaseInvoices.map((item) => item.fileUrl).join(',')
: []
this.form.process = [String(res.data.mainProcessId), String(res.data.subProcessId)].filter(Boolean)
console.log('🚀 ~ getInfo ~ this.form.process:', this.form.process)
this.form.category = [
String(res.data.mainCategoryId),
String(res.data.subCategoryId),
String(res.data.branchId),
].filter(Boolean)
this.propertyVoList = res.data.propertyVoList || []
console.log('🚀 ~ getInfo ~ this.propertyVoList:', this.propertyVoList)
if (this.propertyVoList.length > 0) {
this.propertyVoList.forEach((item) => {
if (item.inputType == 3) {
item.propertyValue = item.propertyValue.split(',')
}
})
}
const res2 = await secondAndThirdLevel({ firstLevelId: this.form.majorId })
this.processList = this.convertToSubTree(res2.data)
const res3 = await fourthToSixthLevel({ thirdLevelId: this.form.subProcessId })
this.categoryList = this.convertToSubTree(res3.data)
} catch (error) {
console.log('🚀 ~ getInfo ~ error:', error)
}
},
// 获取厂家
getManufacturerSelectList() {
getManufacturerSelectApi().then((res) => {
console.log('🚀 ~ getManufacturerSelectList ~ res:', res)
if (res.code === 200) {
this.manufacturerList = res.data
}
})
},
/**
* 获取一级类型
*/
firstLevel() {
firstLevel().then((res) => {
if (res.code === 200) {
this.majorList = res.data
}
})
},
majorChange(item) {
if (!item) {
this.processList = []
this.form.process = []
} else {
secondAndThirdLevel({ firstLevelId: item }).then((res) => {
if (res.code === 200) {
this.processList = this.convertToSubTree(res.data)
}
})
}
},
processChange(item) {
console.log('🚀 ~ processChange ~ item:', item)
if (item.length === 0) {
this.categoryList = []
this.form.category = []
} else {
fourthToSixthLevel({ thirdLevelId: item[item.length - 1] }).then((res) => {
if (res.code === 200) {
this.categoryList = this.convertToSubTree(res.data)
}
})
}
},
categoryChange(item) {
console.log('🚀 ~ processChange ~ item:', item)
this.propertyVoList = []
this.getPropertyVoList(item[item.length - 1])
},
// 返回上一页
goBack() {
this.$tab.closePage()
},
deviceTypeChange(val) {
if (val === 0) {
this.form.count = 1
}
},
// 价格输入处理
handlePriceInput(v) {
this.form.originalValue = v.replace(/[^\d.]/g, '')
},
// 处理图片上传变化
handleImageChange(files) {
this.form.mainFileList = files
this.$refs.formRef.validateField('mainFileList')
},
// 处理合格证上传变化
handleCertificateChange(files) {
this.form.certificateList = files
this.$refs.formRef.validateField('certificateList')
},
// 处理检测证书上传变化
handleInspectionChange(files) {
this.form.inspectionList = files
this.$refs.formRef.validateField('inspectionList')
},
// 处理采购发票上传变化
handlePurchaseInvoicesChange(files) {
this.form.purchaseInvoices = files
this.$refs.formRef.validateField('purchaseInvoices')
},
/**
* 处理表单提交
*/
async handleSubmit() {
console.log('🚀 ~ handleSubmit ~ this.form:', this.form, this.propertyVoList)
this.$refs['formRef'].validate(async (valid) => {
if (valid) {
if (this.isSubmit) return
this.isSubmit = true
const loading = this.$loading()
try {
if (!this.query.orderId) {
const result = await getEquipmentAddIdApi()
this.orderId = result.data.id
this.form.orderId = this.orderId
}
// 获取数组最后一个元素最末级分类ID
// this.form.typeId = this.form.deviceTypeList[this.form.deviceTypeList.length - 1]
// 获取类目的最后一个值
this.form.typeId = this.form.category[this.form.category.length - 1]
let appearanceImages = [] // 装备图片
let certificates = [] // 合格证
let inspectionReports = [] // 验收报告
let purchaseInvoices = [] // 采购发票
if (this.form.mainFileList) {
const arr = this.form.mainFileList.split(',')
console.log('🚀 ~ 提交 ~ arr:', arr)
appearanceImages = arr.map((item) => {
const parts = item.split('/')
return {
fileName: parts[parts.length - 1],
fileUrl: item,
}
})
console.log('🚀 ~ handleSubmit ~ appearanceImages:', appearanceImages)
}
if (this.form.certificateList) {
const arr = this.form.certificateList.split(',')
certificates = arr.map((item) => {
const parts = item.split('/')
return {
fileName: parts[parts.length - 1],
fileUrl: item,
}
})
console.log('🚀 ~ handleSubmit ~ certificates:', certificates)
} else {
// 提示
this.$message.error('请上传合格证')
return
}
if (this.form.inspectionList) {
const arr = this.form.inspectionList.split(',')
inspectionReports = arr.map((item) => {
const parts = item.split('/')
return {
fileName: parts[parts.length - 1],
fileUrl: item,
}
})
console.log('🚀 ~ handleSubmit ~ inspectionReports:', inspectionReports)
} else {
// 提示
this.$message.error('请上传检测证书')
return
}
if (this.form.purchaseInvoices) {
const arr = this.form.purchaseInvoices.split(',')
purchaseInvoices = arr.map((item) => {
const parts = item.split('/')
return {
fileName: parts[parts.length - 1],
fileUrl: item,
}
})
console.log('🚀 ~ handleSubmit ~ purchaseInvoices:', purchaseInvoices)
}
// 判断特征项是否填写 propertyVoList 每个propertyValue 都要有值
if (this.propertyVoList && this.propertyVoList.length > 0) {
const unfilledIndex = this.propertyVoList.findIndex(
(item) => !item.propertyValue || item.propertyValue === '',
)
if (unfilledIndex !== -1) {
this.$message.warning(`请填写第 ${unfilledIndex + 1} 个特征项`)
return
}
}
this.propertyVoList.forEach((item) => {
console.log('item.item.propertyValue', item.propertyValue)
if (item.inputType == 3 && Array.isArray(item.propertyValue)) {
item.propertyValue = item.propertyValue.join(',')
}
})
let res = null
const params = {
...this.form,
appearanceImages,
certificates,
inspectionReports,
purchaseInvoices,
propertyVoList: this.propertyVoList,
}
if (this.query && this.query.maId) {
params.maId = this.query.maId
res = await equipmentEditApiNew(params)
} else {
res = await addInterDevice(params)
}
if (res.code === 200) {
// this.goBack()
this.$router.push({
name: 'equipmentInput',
query: {
orderId: this.orderId,
isAddVisible: false,
isApprovalVisible: false,
},
}).then(() => {
this.$tab.closePage({ path: '/equipment/equipment-input/add' })
})
}
} catch (error) {
console.log('🚀 ~ handleSubmit ~ error:', error)
} finally {
this.isSubmit = false
loading.close()
}
}
})
},
/**
* 转换类型数据为树形结构(适用于级联选择器)
*/
convertToSubTree(list) {
const map = {}
const tree = []
// 构建节点映射
list.forEach((item) => {
map[item.value] = {
value: item.value.toString(),
label: item.label,
}
})
// 构建树形关系
list.forEach((item) => {
const current = map[item.value]
const parent = map[item.parentId]
if (parent) {
if (!parent.children) {
parent.children = []
}
parent.children.push(current)
} else {
tree.push(current)
}
})
return tree
},
// 获取特征值
async getPropertyVoList(typeId) {
try {
const res = await getEquipmentPropertyTypeApi(typeId)
console.log('特征值-->:', res)
this.propertyVoList = res.data || []
} catch (error) {
console.log('获取特征值失败:', error)
}
},
// 处理数据
handleData(data) {
console.log('处理数据:', data)
if (!data) return []
return data.split(',').map((item) => {
return {
label: item,
value: item,
}
})
},
},
}
</script>
<style lang="scss" scoped>
.page-header {
display: flex;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
font-size: 18px;
border-bottom: 1px solid #e6e6e6;
justify-content: space-between;
.page-title {
font-size: 18px;
font-weight: 600;
margin-left: 15px;
color: #303133;
}
}
.dialog-content {
padding: 10px 0;
min-height: 200px; // 确保有足够高度
}
.goBack-btn:hover {
cursor: pointer;
color: #33b5a0;
}
.dialog-footer {
display: flex;
justify-content: flex-end;
gap: 10px; // 按钮间距
}
</style>