1853 lines
62 KiB
Vue
1853 lines
62 KiB
Vue
<template>
|
||
<div>
|
||
<!-- 查询条件 -->
|
||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" inline label-width="auto" size="small">
|
||
<el-card class="search-box" shadow="never">
|
||
<el-row>
|
||
<!-- <el-form-item label="审批状态" prop="status">-->
|
||
<!-- <el-select clearable style="width: 200px" placeholder="请选择审批状态" v-model="queryParams.status">-->
|
||
<!-- <el-option label="待审批" value="0"/>-->
|
||
<!-- <el-option label="已审批" value="1"/>-->
|
||
<!-- <el-option label="草稿" value="3"/>-->
|
||
<!-- </el-select>-->
|
||
<!-- </el-form-item>-->
|
||
|
||
<el-form-item prop="name" label="装备名称">
|
||
<el-input clearable style="width: 200px" placeholder="请输入内容" v-model.trim="queryParams.name"/>
|
||
</el-form-item>
|
||
|
||
<el-form-item prop="specificationModel" label="规格型号">
|
||
<el-input
|
||
clearable
|
||
style="width: 200px"
|
||
placeholder="请输入内容"
|
||
v-model.trim="queryParams.specificationModel"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item prop="originalCode" label="装备原始编码">
|
||
<el-input clearable style="width: 200px" placeholder="请输入内容" v-model.trim="queryParams.originalCode"/>
|
||
</el-form-item>
|
||
|
||
<el-form-item prop="manufacturerId" label="生产厂家">
|
||
<el-select v-model="queryParams.manufacturerId" placeholder="请选择生产厂家" clearable filterable style="width: 200px">
|
||
<el-option v-for="item in manufacturerList" :key="item.id" :label="item.label" :value="item.id"/>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item prop="productionDate" label="出厂日期">
|
||
<el-date-picker
|
||
type="daterange"
|
||
style="width: 200px"
|
||
unlink-panels
|
||
range-separator="至"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
value-format="yyyy-MM-dd"
|
||
v-model="queryParams.productionDate"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item prop="minOriginalValue" label="资产原值(万元)">
|
||
<el-input
|
||
clearable
|
||
style="width: 95px"
|
||
placeholder="请输入"
|
||
@input="handleNumberInput('minOriginalValue')"
|
||
v-model.trim="queryParams.minOriginalValue"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item prop="maxOriginalValue" label="-" style="margin-left: -6%">
|
||
<el-input
|
||
clearable
|
||
style="width: 95px"
|
||
placeholder="请输入"
|
||
@input="handleNumberInput('maxOriginalValue')"
|
||
v-model.trim="queryParams.maxOriginalValue"
|
||
/>
|
||
</el-form-item>
|
||
|
||
<el-form-item style="float: right">
|
||
<el-button icon="el-icon-search" type="primary" @click="queryTableList" size="mini" style="background: #2CBAB2;"> 查询</el-button>
|
||
<el-button icon="el-icon-refresh" @click="resetTableList" size="mini"> 重置</el-button>
|
||
</el-form-item>
|
||
</el-row>
|
||
<el-row>
|
||
<el-col :span="24" style="text-align: right"></el-col>
|
||
</el-row>
|
||
</el-card>
|
||
</el-form>
|
||
|
||
<el-card class="content-box" shadow="never">
|
||
<el-row>
|
||
<el-col :span="24" style="text-align: right" v-if="!routerParams.isView">
|
||
<el-button type="primary" size="mini" @click="equipmentDeployment" v-show="!isAddVisible" style="background: #2CBAB2;">
|
||
新增装备
|
||
</el-button>
|
||
<el-button type="primary" size="mini" @click="handleImport" v-show="!isAddVisible" style="background: #2CBAB2;"> 批量导入</el-button>
|
||
<el-button
|
||
type="primary"
|
||
size="mini"
|
||
@click="handleImportImg"
|
||
v-show="!isAddVisible"
|
||
:disabled="tableData.length == 0"
|
||
>
|
||
批量导入文件
|
||
</el-button>
|
||
<el-button
|
||
size="small"
|
||
type="primary"
|
||
@click="handleSubmit"
|
||
v-if="!isAddVisible"
|
||
:disabled="tableData.length === 0"
|
||
>
|
||
暂存
|
||
</el-button>
|
||
</el-col>
|
||
</el-row>
|
||
<!-- 表格 -->
|
||
<el-table
|
||
:data="tableData"
|
||
style="width: auto"
|
||
show-overflow-tooltip
|
||
:span-method="handleSpanMethod"
|
||
border
|
||
stripe
|
||
class="my-table"
|
||
@row-dblclick="handleDblClick"
|
||
ref="tableRef"
|
||
>
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="55"
|
||
type="index"
|
||
:index="(index) => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1"
|
||
>
|
||
<template slot="header" slot-scope="scope">
|
||
<div>序号</div>
|
||
<div v-if="!routerParams.isView">
|
||
<i
|
||
class="el-icon-circle-plus-outline"
|
||
style="color: #48a089; font-size: 20px; cursor: pointer"
|
||
@click="addList"
|
||
/>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="orderNumber"
|
||
label="录入单号"
|
||
align="center"
|
||
show-overflow-tooltip
|
||
column-key="orderNumber"
|
||
min-width="200"
|
||
/>
|
||
<el-table-column prop="major" label="专业" align="center" show-overflow-tooltip min-width="200px">
|
||
<template slot-scope="{ row }">
|
||
<span v-if="!row.isNew">{{ row.major }}</span>
|
||
<el-select
|
||
v-else
|
||
v-model="row.major"
|
||
placeholder="请选择专业"
|
||
clearable
|
||
filterable
|
||
@change="(val) => majorChange(val, row)"
|
||
style="width: 100%"
|
||
>
|
||
<el-option v-for="item in row.majorList" :key="item.value" :label="item.label" :value="item.value"/>
|
||
</el-select>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="工序" align="center" show-overflow-tooltip min-width="200px">
|
||
<template slot-scope="{ row }">
|
||
<span v-if="!row.isNew">{{ row.mainProcess }}{{ row.subProcess ? '>' + row.subProcess : '' }}</span>
|
||
<el-cascader
|
||
v-else
|
||
v-model="row.process"
|
||
placeholder="请选择工序"
|
||
clearable
|
||
filterable
|
||
:options="row.processList"
|
||
@change="(val) => processChange(val, row)"
|
||
style="width: 100%"
|
||
></el-cascader>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="装备类目" show-overflow-tooltip align="center" min-width="200px">
|
||
<template slot-scope="{ row }">
|
||
<span v-if="!row.isNew">
|
||
{{ row.mainCategory ? row.mainCategory + '>' : '' }}
|
||
{{ row.branch ? row.subCategory + '>' : row.subCategory }}{{ row.branch }}
|
||
</span>
|
||
<el-cascader
|
||
v-else
|
||
v-model="row.category"
|
||
:options="row.categoryList"
|
||
clearable
|
||
filterable
|
||
placeholder="请选择装备类目"
|
||
@change="(val) => categoryChange(val, row)"
|
||
style="width: 100%"
|
||
></el-cascader>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column prop="name" label="装备名称" show-overflow-tooltip align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.name }}</span>
|
||
<el-input v-else maxlength="50" v-model="row.name" placeholder="请输入装备名称" clearable/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="specificationModel"
|
||
label="规格型号"
|
||
show-overflow-tooltip
|
||
align="center"
|
||
min-width="200px"
|
||
>
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.specificationModel }}</span>
|
||
<el-input v-else maxlength="50" v-model="row.specificationModel" placeholder="请输入规格型号" clearable/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="originalCode"
|
||
label="装备原始编码"
|
||
show-overflow-tooltip
|
||
align="center"
|
||
min-width="200px"
|
||
>
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.originalCode }}</span>
|
||
<el-input v-else maxlength="50" v-model="row.originalCode" placeholder="请输入装备原始编码" clearable/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="unit" label="计量单位" show-overflow-tooltip align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.unit }}</span>
|
||
<el-select v-else v-model="row.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>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="manufacturer" label="生产厂家" show-overflow-tooltip align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.manufacturer }}</span>
|
||
<el-select v-else v-model="row.manufacturerId" placeholder="请选择生产厂家" clearable filterable style="width: 100%">
|
||
<el-option v-for="item in manufacturerList" :key="item.id" :label="item.label" :value="item.id"/>
|
||
</el-select>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="productionDate" label="出厂日期" show-overflow-tooltip align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.productionDate }}</span>
|
||
<el-date-picker
|
||
v-else
|
||
v-model="row.productionDate"
|
||
type="date"
|
||
placeholder="请选择出厂日期"
|
||
value-format="yyyy-MM-dd"
|
||
style="width: 100%"
|
||
:picker-options="{
|
||
disabledDate(time) {
|
||
return time.getTime() > Date.now()
|
||
},
|
||
}"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="purchaseDate" label="采购日期" align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.purchaseDate }}</span>
|
||
<el-date-picker
|
||
v-else
|
||
v-model="row.purchaseDate"
|
||
type="date"
|
||
placeholder="请选择采购日期"
|
||
value-format="yyyy-MM-dd"
|
||
style="width: 100%"
|
||
:picker-options="{
|
||
disabledDate(time) {
|
||
return time.getTime() > Date.now()
|
||
},
|
||
}"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="originalValue"
|
||
label="资产原值(万元)"
|
||
show-overflow-tooltip
|
||
align="center"
|
||
min-width="200px"
|
||
>
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.originalValue }}</span>
|
||
<el-input
|
||
v-else
|
||
maxlength="20"
|
||
v-model="row.originalValue"
|
||
placeholder="请输入资产原值(万元)"
|
||
clearable
|
||
@input="(val) => handlePriceInput(val, row)"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="maxServiceLifeYears" label="最大使用年限(年)" align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.maxServiceLifeYears }}</span>
|
||
<el-input-number
|
||
v-else
|
||
clearable
|
||
maxlength="20"
|
||
placeholder="请输入最大使用年限"
|
||
v-model="row.maxServiceLifeYears"
|
||
:min="1"
|
||
:max="100"
|
||
:precision="0"
|
||
:controls="false"
|
||
style="width: 100%"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column prop="nextMaintenanceDate" label="下次维保日期" align="center" min-width="200px">
|
||
<template v-slot="{ row }">
|
||
<span v-if="!row.isNew">{{ row.nextMaintenanceDate }}</span>
|
||
<el-date-picker
|
||
v-else
|
||
v-model="row.nextMaintenanceDate"
|
||
type="date"
|
||
placeholder="请选择下次维保日期"
|
||
value-format="yyyy-MM-dd"
|
||
style="width: 100%"
|
||
:picker-options="{
|
||
disabledDate(time) {
|
||
return time.getTime() < Date.now()
|
||
},
|
||
}"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
prop="reportManagement"
|
||
label="相关配套资料"
|
||
show-overflow-tooltip
|
||
align="center"
|
||
min-width="200px"
|
||
>
|
||
<template v-slot="{ row }">
|
||
<span style="color: #00a288; cursor: pointer" @click="handleFileListUpload(row)">报告管理</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
|
||
<!-- 动态生成 fieldVoList 列 -->
|
||
<el-table-column
|
||
v-for="(item, index) in fieldVoList"
|
||
:key="'field-col-' + index"
|
||
align="center"
|
||
show-overflow-tooltip
|
||
:label="item.propertyName"
|
||
:prop="item.propertyCode"
|
||
min-width="200px"
|
||
>
|
||
<template v-slot="{ row }">
|
||
<div v-if="row.isNew && row.fieldVoList && row.fieldVoList.length > index">
|
||
<el-input v-if="row.fieldVoList[index].inputType == 'INPUT'"
|
||
autocomplete="off"
|
||
maxlength="30" v-model="row.fieldVoList[index].propertyValue"
|
||
clearable
|
||
/>
|
||
|
||
<!-- 日期选择器 -->
|
||
<el-date-picker
|
||
v-else-if="row.fieldVoList[index].inputType == 'DATE'"
|
||
v-model="row.fieldVoList[index].propertyValue"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
format="yyyy-MM-dd"
|
||
value-format="yyyy-MM-dd"
|
||
clearable
|
||
style="width: 100%"
|
||
/>
|
||
|
||
<el-select
|
||
v-else-if="row.fieldVoList[index].inputType == 'SELECT' "
|
||
v-model="row.fieldVoList[index].propertyValue"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="option in getSelectOptions(row.fieldVoList[index].value)"
|
||
:key="option.value"
|
||
:label="option.label"
|
||
:value="option.value"
|
||
/>
|
||
</el-select>
|
||
</div>
|
||
|
||
<span v-else>{{ getLedgerValue(row, item.propertyCode) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
|
||
<el-table-column
|
||
v-for="(item, index) in columns"
|
||
v-if="item.visible"
|
||
:key="index"
|
||
align="center"
|
||
show-overflow-tooltip
|
||
:label="item.label"
|
||
:prop="item.prop"
|
||
min-width="200px"
|
||
>
|
||
<template v-slot="{ row }" v-if="/^feature(Item|Value)\d+$/.test(item.prop)">
|
||
<div
|
||
v-if="
|
||
(index + 1) % 2 === 0 &&
|
||
row.isNew &&
|
||
row.propertyVoList.length > 0 &&
|
||
row.propertyVoList[(index + 1) / 2 - 1]
|
||
"
|
||
>
|
||
<el-input
|
||
v-if="row.propertyVoList[(index + 1) / 2 - 1].inputType == 1"
|
||
autocomplete="off"
|
||
maxlength="30"
|
||
v-model="row.propertyVoList[(index + 1) / 2 - 1].propertyValue"
|
||
clearable
|
||
/>
|
||
<el-select
|
||
v-if="row.propertyVoList[(index + 1) / 2 - 1].inputType == 2"
|
||
v-model="row.propertyVoList[(index + 1) / 2 - 1].propertyValue"
|
||
placeholder="请选择"
|
||
clearable
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="(item, index) in row.propertyVoList[(index + 1) / 2 - 1].valueList"
|
||
:key="index"
|
||
:label="item.value"
|
||
:value="item.value"
|
||
/>
|
||
</el-select>
|
||
<el-select
|
||
v-if="row.propertyVoList[(index + 1) / 2 - 1].inputType == 3"
|
||
v-model="row.propertyVoList[(index + 1) / 2 - 1].propertyValues"
|
||
placeholder="请选择"
|
||
multiple
|
||
clearable
|
||
style="width: 100%"
|
||
>
|
||
<el-option
|
||
v-for="(item2, index) in row.propertyVoList[(index + 1) / 2 - 1].valueList2"
|
||
:key="index"
|
||
:label="item2.value"
|
||
:value="item2.value"
|
||
/>
|
||
</el-select>
|
||
</div>
|
||
<span
|
||
v-else-if="
|
||
row.isNew &&
|
||
row.propertyVoList.length > 0 &&
|
||
row.propertyVoList[Math.ceil(index / 2)] &&
|
||
row.propertyVoList[Math.ceil(index / 2)].mustHave != 0
|
||
"
|
||
style="color: red"
|
||
>{{ getFeatureValue(row, item.prop) }}</span
|
||
>
|
||
<span v-else>{{ getFeatureValue(row, item.prop) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<!-- <el-table-column
|
||
prop="orderCreateUser"
|
||
label="申请人"
|
||
show-overflow-tooltip
|
||
align="center"
|
||
fixed="right"
|
||
min-width="200px"
|
||
/>
|
||
<el-table-column
|
||
prop="orderCreateTime"
|
||
label="申请时间"
|
||
show-overflow-tooltip
|
||
align="center"
|
||
fixed="right"
|
||
min-width="200px"
|
||
/> -->
|
||
<!-- <el-table-column
|
||
prop="entryStatus"
|
||
align="center"
|
||
show-overflow-tooltip
|
||
label="审批状态"
|
||
fixed="right"
|
||
min-width="100px"
|
||
>
|
||
<template slot-scope="{ row }">
|
||
<el-tag v-if="row.entryStatus == 0" size="small" type="warning">待审批</el-tag>
|
||
<el-tag v-if="row.entryStatus == 1" size="small" type="success">已通过</el-tag>
|
||
<el-tag v-if="row.entryStatus == 2" size="small" type="success">已驳回</el-tag>
|
||
<el-tag v-if="row.entryStatus == 3" size="small" type="info">草稿</el-tag>
|
||
</template>
|
||
</el-table-column> -->
|
||
<el-table-column label="操作" align="center" min-width="220" fixed="right">
|
||
<template slot-scope="{ row, $index }">
|
||
<el-button v-if="!row.isNew" type="text" style="color: #2CBAB2;" @click="handleViewDetail(row)">
|
||
查看
|
||
</el-button>
|
||
<el-button
|
||
type="text"
|
||
style="color: #2CBAB2;"
|
||
@click="handleDblClick(row)"
|
||
v-if="row.orderStatus == '3' && !isAddVisible && !row.isNew && !routerParams.isView"
|
||
>
|
||
编辑
|
||
</el-button>
|
||
<el-button type="text" style="color: #2CBAB2;" @click="submitRow(row)" v-if="row.isNew && !routerParams.isView">
|
||
保存
|
||
</el-button>
|
||
<el-button
|
||
v-if="((row.orderStatus == '3' && !isAddVisible) || row.isNew) && !routerParams.isView"
|
||
type="text"
|
||
@click="deleteRowInfo(row, $index)"
|
||
style="color: #FF5129"
|
||
>
|
||
删除
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<div class="pagination-wrapper">
|
||
<pagination
|
||
:total="total"
|
||
@pagination="getList"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
/>
|
||
</div>
|
||
</el-card>
|
||
<EquipmentEntryEditDialog
|
||
:is-visible.sync="isEditVisible"
|
||
:order-id="orderId"
|
||
:is-view="isViewMode"
|
||
@getOrderId="getOrderId"
|
||
/>
|
||
<!-- 图片上传 -->
|
||
<el-dialog :title="uploadTitle" :visible.sync="uploadVisible" width="40%">
|
||
<FileUpload
|
||
v-model="fileList"
|
||
:value="fileList"
|
||
:limit="uploadLimit"
|
||
:fileSize="fileSize"
|
||
:fileType="uploadFileType"
|
||
@input="handleFileList"
|
||
/>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="uploadVisible = false">关 闭</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
<!-- 弹框 -->
|
||
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="40%">
|
||
<el-table :data="dialogList" fit highlight-current-row style="width: 100%" height="546">
|
||
<el-table-column type="index" width="55" label="序号" align="center"/>
|
||
<el-table-column label="附件名称" prop="fileName" align="center">
|
||
<!-- 插槽 -->
|
||
<template v-slot="{ row }">
|
||
<span style="color: #00a288; cursor: pointer" @click="handleFile(row)">{{ row.fileName }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<span slot="footer" class="dialog-footer">
|
||
<el-button @click="dialogVisible = false">关 闭</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
<el-dialog title="批量导入图片" :visible.sync="upload.open2" width="400px" append-to-body>
|
||
<el-upload
|
||
ref="upload2"
|
||
:limit="1"
|
||
accept=".zip"
|
||
:headers="upload.headers"
|
||
:action="upload.url2 + '?orderId=' + orderId"
|
||
:disabled="upload.isUploading"
|
||
:on-progress="handleFileUploadProgress"
|
||
:on-success="handleFileSuccess2"
|
||
:auto-upload="false"
|
||
drag
|
||
>
|
||
<i class="el-icon-upload"></i>
|
||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||
<div class="el-upload__tip text-center" slot="tip">
|
||
<span>仅允许导入zip格式文件。</span>
|
||
<el-link
|
||
type="primary"
|
||
:underline="false"
|
||
style="font-size: 12px; vertical-align: baseline"
|
||
@click="importTemplate2"
|
||
>下载模板
|
||
</el-link>
|
||
</div>
|
||
</el-upload>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitFileForm2" style="background: #2CBAB2;">确 定</el-button>
|
||
<el-button @click="upload.open2 = false">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
|
||
<el-upload
|
||
ref="upload"
|
||
:limit="1"
|
||
accept=".xlsx, .xls"
|
||
:headers="upload.headers"
|
||
:action="upload.url + '?orderId=' + queryParams.orderId"
|
||
:disabled="upload.isUploading"
|
||
:on-progress="handleFileUploadProgress"
|
||
:on-success="handleFileSuccess"
|
||
:auto-upload="false"
|
||
drag
|
||
>
|
||
<i class="el-icon-upload"></i>
|
||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||
<div class="el-upload__tip text-center" slot="tip">
|
||
<span>仅允许导入xls、xlsx格式文件。</span>
|
||
<el-link
|
||
type="primary"
|
||
:underline="false"
|
||
style="font-size: 12px; vertical-align: baseline"
|
||
@click="importTemplate"
|
||
>下载模板
|
||
</el-link>
|
||
</div>
|
||
</el-upload>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button type="primary" @click="submitFileForm" style="background: #2CBAB2;">确 定</el-button>
|
||
<el-button @click="upload.open = false">取 消</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- 报告管理 -->
|
||
<el-dialog title="报告管理" :visible.sync="openReport" width="900px" append-to-body>
|
||
<el-table :data="fileDataList" width="100%" height="350px">
|
||
<el-table-column label="序号" type="index" width="55" align="center"/>
|
||
<el-table-column label="报告类型" align="center" prop="dictLabel" :show-overflow-tooltip="true">
|
||
<template v-slot="{ row }">
|
||
<span v-if="row.type == 1 || row.type == 2 || row.type == 3">
|
||
<span style="color: red">*</span>
|
||
{{ row.dictLabel }}
|
||
</span>
|
||
<span v-else>{{ row.dictLabel }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" align="center" width="100">
|
||
<template slot-scope="{ row }">
|
||
<div style="display: flex; align-items: center; justify-content: center">
|
||
<el-button v-if="currentRow.isNew" size="mini" type="text" style="color: #2CBAB2;"
|
||
@click="handleFileUpload(currentRow, row.type)"
|
||
>上传
|
||
</el-button
|
||
>
|
||
<el-button
|
||
v-if="
|
||
(row.type == 1 && currentRow.appearanceImages.length > 0) ||
|
||
(row.type == 2 && currentRow.certificates.length > 0) ||
|
||
(row.type == 3 && currentRow.inspectionReports.length > 0) ||
|
||
(row.type == 4 && currentRow.purchaseInvoices.length > 0)
|
||
"
|
||
size="mini"
|
||
type="text" style="color: #2CBAB2;"
|
||
@click="handleView(currentRow, row.type)"
|
||
>
|
||
查看
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-dialog>
|
||
<AddEquip ref="addEquipRef" @handleSubmit="handleSubmit" @getList="getList" @replaceRoute="replaceRoute"/>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import EquipmentEntryEditDialog from '@/views/EquipmentEntryApply/equipmentInput/edit.vue'
|
||
import AddEquip from './AddEquip'
|
||
import {
|
||
getConfigApi
|
||
} from '@/api/EquipmentEntryApply'
|
||
|
||
// 使用defineComponent规范组件定义
|
||
import {
|
||
getDeviceByOrderIdApi,
|
||
equipmentPassAndRejectApiNew,
|
||
addWarehousingApi,
|
||
updateWarehousingApi,
|
||
removeDeviceApi,
|
||
getEquipmentAddIdApi,
|
||
addInterDevice,
|
||
equipmentEditApiNew,
|
||
firstLevel,
|
||
secondAndThirdLevel,
|
||
fourthToSixthLevel,
|
||
getEquipmentPropertyTypeApi, removeDeviceApiByMaIds
|
||
} from '@/api/EquipmentEntryApply'
|
||
import { getManufacturerSelectApi } from '@/api/EquipmentLedger/index.js'
|
||
import { getToken } from '@/utils/auth'
|
||
import FileUpload from '@/components/FileImageUpload'
|
||
|
||
export default {
|
||
name: 'EquipmentInput',
|
||
components: { EquipmentEntryEditDialog, FileUpload, AddEquip },
|
||
emits: ['update:isVisible', 'submit'], // 声明事件
|
||
dicts: ['dev_unit_type'],
|
||
created() {
|
||
console.log('🚀 ~ this.$route:', this.$route)
|
||
this.orderId = this.$route.query && this.$route.query.orderId
|
||
console.log('🚀 ~ this.orderId:', this.orderId)
|
||
this.routerParams = this.$route.query
|
||
console.log('🚀 ~ this.routerParams:', this.routerParams)
|
||
this.isAddVisible = this.$route.query.isAddVisible && JSON.parse(this.$route.query.isAddVisible)
|
||
this.isApprovalVisible = this.$route.query.isApprovalVisible && JSON.parse(this.$route.query.isApprovalVisible)
|
||
if (!this.orderId) {
|
||
this.orderId = ''
|
||
this.pageTitle = '新增设备录入'
|
||
this.submitButtonText = '提交申请'
|
||
} else if (this.isAddVisible) {
|
||
this.pageTitle = '查看装备'
|
||
this.submitButtonText = ''
|
||
this.getList()
|
||
} else {
|
||
this.pageTitle = '编辑装备'
|
||
this.submitButtonText = '提交申请'
|
||
this.getList()
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
isSubmit: false,
|
||
isAddVisible: false,
|
||
isApprovalVisible: false,
|
||
isEditVisible: false,
|
||
orderId: '',
|
||
// 表格数据
|
||
tableData: [],
|
||
total: 0,
|
||
upload: {
|
||
// 是否显示弹出层(用户导入)
|
||
open: false,
|
||
open2: false,
|
||
// 弹出层标题(用户导入)
|
||
title: '',
|
||
// 是否禁用上传
|
||
isUploading: false,
|
||
// 是否更新已经存在的用户数据
|
||
|
||
// 设置上传的请求头部
|
||
headers: { Authorization: 'Bearer ' + getToken() },
|
||
// 上传的地址
|
||
url: process.env.VUE_APP_BASE_API + '/material-mall/order/importData',
|
||
url2: process.env.VUE_APP_BASE_API + '/material-mall/order/upload-multi'
|
||
},
|
||
queryParams: {
|
||
orderCreateUser: '',
|
||
orderCreateTime: '',
|
||
status: '',
|
||
name: '',
|
||
specificationModel: '',
|
||
originalCode: '',
|
||
manufacturerId: '',
|
||
productionDate: '',
|
||
minOriginalValue: '',
|
||
maxOriginalValue: '',
|
||
orderId: '',
|
||
pageNum: 1,
|
||
pageSize: 10
|
||
},
|
||
// 用于存储上一次的有效值,避免循环验证
|
||
lastValidValues: {
|
||
minOriginalValue: '',
|
||
maxOriginalValue: ''
|
||
},
|
||
currentRow: null,
|
||
uploadType: 1, // 1:装备外观,2:合格证,3:定期检验报告,4:采购发票
|
||
uploadVisible: false,
|
||
uploadTitle: '',
|
||
uploadLimit: 3,
|
||
fileSize: 10,
|
||
uploadFileType: ['jpg', 'png', 'pdf'],
|
||
fileList: null,
|
||
orderNumber: '',
|
||
manufacturerList: [], // 生产厂家列表
|
||
// 可添加表单数据
|
||
formData: {
|
||
// 示例字段,可根据实际需求修改
|
||
equipmentName: '',
|
||
model: '',
|
||
quantity: 1
|
||
},
|
||
isViewMode: false, // 添加查看模式标识
|
||
pageTitle: '',
|
||
submitButtonText: '',
|
||
columns: [
|
||
{ key: 26, label: `特征项1`, prop: 'featureItem1', visible: true },
|
||
{ key: 27, label: `特征值1`, prop: 'featureValue1', visible: true },
|
||
{ key: 28, label: `特征项2`, prop: 'featureItem2', visible: true },
|
||
{ key: 29, label: `特征值2`, prop: 'featureValue2', visible: true },
|
||
{ key: 30, label: `特征项3`, prop: 'featureItem3', visible: true },
|
||
{ key: 31, label: `特征值3`, prop: 'featureValue3', visible: true },
|
||
{ key: 32, label: `特征项4`, prop: 'featureItem4', visible: true },
|
||
{ key: 33, label: `特征值4`, prop: 'featureValue4', visible: true },
|
||
{ key: 34, label: `特征项5`, prop: 'featureItem5', visible: true },
|
||
{ key: 35, label: `特征值5`, prop: 'featureValue5', visible: true },
|
||
{ key: 36, label: `特征项6`, prop: 'featureItem6', visible: true },
|
||
{ key: 37, label: `特征值6`, prop: 'featureValue6', visible: true },
|
||
{ key: 38, label: `特征项7`, prop: 'featureItem7', visible: true },
|
||
{ key: 39, label: `特征值7`, prop: 'featureValue7', visible: true },
|
||
{ key: 40, label: `特征项8`, prop: 'featureItem8', visible: true },
|
||
{ key: 41, label: `特征值8`, prop: 'featureValue8', visible: true },
|
||
{ key: 42, label: `特征项9`, prop: 'featureItem9', visible: true },
|
||
{ key: 43, label: `特征值9`, prop: 'featureValue9', visible: true }
|
||
],
|
||
fieldVoList:[],
|
||
|
||
dialogVisible: false,
|
||
dialogTitle: '',
|
||
dialogList: [],
|
||
openReport: false,
|
||
fileDataList: [
|
||
{ dictLabel: '装备外观', type: '1' },
|
||
{ dictLabel: '合格证', type: '2' },
|
||
{ dictLabel: '定期检测报告', type: '3' },
|
||
{ dictLabel: '采购发票', type: '4' }
|
||
],
|
||
routerParams: null
|
||
}
|
||
},
|
||
watch: {
|
||
isVisible(val) {
|
||
if (val) {
|
||
this.getConfig()
|
||
this.getList()
|
||
}
|
||
}
|
||
},
|
||
|
||
mounted() {
|
||
this.getManufacturerSelectList()
|
||
this.getConfig()
|
||
},
|
||
methods: {
|
||
handleNumberInput(key) {
|
||
let value = this.queryParams[key] || ''
|
||
// 1. 清理输入
|
||
const cleanedValue = this.cleanNumberInput(value)
|
||
|
||
// 2. 存储为上次有效值(清理后)
|
||
this.lastValidValues[key] = cleanedValue
|
||
|
||
// 3. 根据输入类型进行验证
|
||
if (key === 'minOriginalValue') {
|
||
this.queryParams[key] = this.validateMinValue(cleanedValue)
|
||
} else if (key === 'maxOriginalValue') {
|
||
this.queryParams[key] = this.validateMaxValue(cleanedValue)
|
||
} else {
|
||
this.queryParams[key] = cleanedValue
|
||
}
|
||
|
||
// 4. 确保响应式更新
|
||
this.$forceUpdate()
|
||
},
|
||
|
||
// 清理数字输入
|
||
cleanNumberInput(input) {
|
||
if (!input) return ''
|
||
|
||
// 过滤非数字和小数点
|
||
let cleaned = input.replace(/[^\d.]/g, '')
|
||
|
||
// 处理多个小数点
|
||
const dotIndex = cleaned.indexOf('.')
|
||
if (dotIndex !== -1) {
|
||
const before = cleaned.substring(0, dotIndex + 1)
|
||
const after = cleaned.substring(dotIndex + 1).replace(/\./g, '')
|
||
cleaned = before + after
|
||
}
|
||
|
||
// 限制小数位数
|
||
const parts = cleaned.split('.')
|
||
if (parts.length > 1) {
|
||
cleaned = parts[0] + '.' + parts[1].slice(0, 2)
|
||
}
|
||
|
||
return cleaned
|
||
},
|
||
|
||
// 验证最小值(不能大于最大值)
|
||
validateMinValue(value) {
|
||
// 如果是空值或纯小数点,直接返回
|
||
if (!value || value === '.') return value
|
||
|
||
const maxValue = this.queryParams.maxOriginalValue
|
||
const minNum = this.safeParseNumber(value)
|
||
const maxNum = this.safeParseNumber(maxValue)
|
||
|
||
// 如果最大值无效,直接返回清理后的值
|
||
if (maxNum === null) return value
|
||
|
||
// 如果最小值大于最大值,则使用最大值
|
||
if (minNum !== null && minNum > maxNum) {
|
||
return maxValue
|
||
}
|
||
|
||
return value
|
||
},
|
||
|
||
// 验证最大值(不能小于最小值)
|
||
validateMaxValue(value) {
|
||
// 如果是空值或纯小数点,直接返回
|
||
if (!value || value === '.') return value
|
||
|
||
const minValue = this.queryParams.minOriginalValue
|
||
const maxNum = this.safeParseNumber(value)
|
||
const minNum = this.safeParseNumber(minValue)
|
||
|
||
// 如果最小值无效,直接返回清理后的值
|
||
if (minNum === null) return value
|
||
|
||
// 如果最大值小于最小值,则使用最小值
|
||
if (maxNum !== null && maxNum < minNum) {
|
||
return minValue
|
||
}
|
||
|
||
return value
|
||
},
|
||
|
||
// 安全解析数字
|
||
safeParseNumber(str) {
|
||
if (!str || str === '.' || isNaN(Number(str))) {
|
||
return null
|
||
}
|
||
return Number(str)
|
||
},
|
||
|
||
// 同时验证两个值(在表单提交前调用)
|
||
validateNumberRange() {
|
||
const minNum = this.safeParseNumber(this.queryParams.minOriginalValue)
|
||
const maxNum = this.safeParseNumber(this.queryParams.maxOriginalValue)
|
||
|
||
if (minNum !== null && maxNum !== null && minNum > maxNum) {
|
||
// 交换值,使最小值 <= 最大值
|
||
const temp = this.queryParams.minOriginalValue
|
||
this.queryParams.minOriginalValue = this.queryParams.maxOriginalValue
|
||
this.queryParams.maxOriginalValue = temp
|
||
|
||
// 提示用户
|
||
this.$message.warning('已自动调整数值范围,确保最小值 ≤ 最大值')
|
||
return false
|
||
}
|
||
|
||
return true
|
||
},
|
||
// 文件上传中处理
|
||
handleFileUploadProgress(event, file, fileList) {
|
||
this.upload.isUploading = true
|
||
},
|
||
// 文件上传成功处理
|
||
// 文件上传成功处理
|
||
handleFileSuccess(response, file, fileList) {
|
||
this.upload.open = false
|
||
this.upload.isUploading = false
|
||
this.$refs.upload.clearFiles()
|
||
this.$alert(
|
||
'<div style=\'overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;\'>' +
|
||
response.msg +
|
||
'</div>',
|
||
'导入结果',
|
||
{ dangerouslyUseHTMLString: true }
|
||
)
|
||
// 【修复1】仅在接口返回有效orderId时才更新,否则保留原来的orderId
|
||
if (response.data) {
|
||
this.orderId = response.data
|
||
const routerParams = this.$route.query || {}
|
||
this.$router
|
||
.replace({
|
||
query: {
|
||
id: routerParams.id || '',
|
||
applyId: routerParams.applyId || '',
|
||
orderId: response.data || routerParams.orderId || '',
|
||
isAddVisible: routerParams.isAddVisible || '',
|
||
isApprovalVisible: routerParams.isApprovalVisible || ''
|
||
}
|
||
})
|
||
.then(() => {
|
||
console.log('🚀 ~ 导入成功跳转完成')
|
||
this.getList()
|
||
this.handleSubmit()
|
||
})
|
||
} else {
|
||
// 【修复2】如果没有返回orderId,直接刷新当前列表,使用已有的orderId
|
||
this.getList()
|
||
}
|
||
},
|
||
handleFileSuccess2(response, file, fileList) {
|
||
this.upload.open2 = false
|
||
this.upload.isUploading = false
|
||
this.$refs.upload2.clearFiles()
|
||
this.$alert(
|
||
'<div style=\'overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;\'>' +
|
||
response.msg +
|
||
'</div>',
|
||
'导入结果',
|
||
{ dangerouslyUseHTMLString: true }
|
||
)
|
||
// 【修复3】不管是否成功,都直接刷新列表,使用当前已有的orderId
|
||
setTimeout(() => {
|
||
this.getList()
|
||
}, 200)
|
||
},
|
||
// 提交上传文件
|
||
submitFileForm() {
|
||
this.$refs.upload.submit()
|
||
},
|
||
submitFileForm2() {
|
||
this.$refs.upload2.submit()
|
||
},
|
||
// 获取厂家
|
||
getManufacturerSelectList() {
|
||
getManufacturerSelectApi().then((res) => {
|
||
console.log('🚀 ~ getManufacturerSelectList ~ res:', res)
|
||
if (res.code === 200) {
|
||
this.manufacturerList = res.data
|
||
}
|
||
})
|
||
},
|
||
// 返回上一页
|
||
goBack() {
|
||
// this.$router.go(-1)
|
||
this.$router.push({ path: '/stockManagement/entryApply' })
|
||
},
|
||
async approval(row, status) {
|
||
equipmentPassAndRejectApiNew({ devIds: row.maId, status: status, id: this.orderId }).then((res) => {
|
||
if (res.code === 200) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: '操作成功'
|
||
})
|
||
this.getList()
|
||
}
|
||
})
|
||
},
|
||
|
||
|
||
getConfig() {
|
||
getConfigApi().then(res => {
|
||
this.fieldVoList = res.data.config || []
|
||
})
|
||
},
|
||
|
||
// 获取列表数据
|
||
async getList() {
|
||
try {
|
||
this.queryParams.startOrderCreateTime = this.queryParams.orderCreateTime
|
||
? this.queryParams.orderCreateTime[0]
|
||
: ''
|
||
this.queryParams.endOrderCreateTime = this.queryParams.orderCreateTime
|
||
? this.queryParams.orderCreateTime[1]
|
||
: ''
|
||
this.queryParams.startProductionDate = this.queryParams.productionDate ? this.queryParams.productionDate[0] : ''
|
||
this.queryParams.endProductionDate = this.queryParams.productionDate ? this.queryParams.productionDate[1] : ''
|
||
this.queryParams.orderId = this.orderId || ''
|
||
const params = { ...this.queryParams, orderId: this.$route.query.orderId || '' }
|
||
delete params.orderCreateTime
|
||
delete params.productionDate
|
||
const res = await getDeviceByOrderIdApi(params)
|
||
this.tableData = res.data.rows
|
||
|
||
|
||
// console.log("查询列表数据",res.data.rows.fieldVoList)
|
||
// this.fieldVoList = res.data.rows.fieldVoList || []
|
||
// console.log("查询列表数据",this.fieldVoList)
|
||
|
||
this.total = res.data.total
|
||
|
||
setTimeout(() => {
|
||
this.$refs.tableRef.doLayout()
|
||
}, 200)
|
||
} catch (error) {
|
||
console.error('获取列表失败:', error)
|
||
}
|
||
},
|
||
|
||
getOrderId(data) {
|
||
this.orderId = data.orderId
|
||
this.queryTableList()
|
||
},
|
||
|
||
// 查询表格数据
|
||
queryTableList() {
|
||
this.validateNumberRange()
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
equipmentDeployment() {
|
||
const orderId = this.$route.query.orderId || ''
|
||
this.$refs.addEquipRef.openDialog(orderId)
|
||
},
|
||
|
||
// 删除按钮
|
||
async deleteRowInfo(row, index) {
|
||
this.$confirm('是否确定删除?', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
.then(() => {
|
||
if (row.maId) {
|
||
return removeDeviceApiByMaIds([row.maId])
|
||
} else {
|
||
this.tableData.splice(index, 1)
|
||
this.$message({
|
||
type: 'success',
|
||
message: '删除成功'
|
||
})
|
||
}
|
||
})
|
||
.then((res) => {
|
||
if (res.code === 200) {
|
||
this.$message({
|
||
type: 'success',
|
||
message: '删除成功'
|
||
})
|
||
this.getList()
|
||
}
|
||
})
|
||
.catch(() => {
|
||
})
|
||
},
|
||
// 重置表格查询
|
||
resetTableList() {
|
||
this.$refs.queryFormRef.resetFields()
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
|
||
/**
|
||
* 处理表单提交
|
||
*/
|
||
async handleSubmit() {
|
||
console.log('提交表单')
|
||
// 判断图片是否上传
|
||
let hasMissing = false
|
||
for (const item of this.tableData) {
|
||
if (!item.appearanceImages?.length) {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: '请上传装备外观附件'
|
||
})
|
||
hasMissing = true
|
||
break
|
||
}
|
||
|
||
if (!item.certificates?.length) {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: '请上传装备合格证附件'
|
||
})
|
||
hasMissing = true
|
||
break
|
||
}
|
||
|
||
if (!item.inspectionReports?.length) {
|
||
this.$message({
|
||
type: 'warning',
|
||
message: '请上传装备检验报告附件'
|
||
})
|
||
hasMissing = true
|
||
break
|
||
}
|
||
}
|
||
if (hasMissing) return
|
||
|
||
console.log('🚀 ~ this.isSubmit:', this.isSubmit)
|
||
if (this.isSubmit) return
|
||
this.isSubmit = true
|
||
const loading = this.$loading()
|
||
const id = this.$route.query.id || ''
|
||
const orderId = this.$route.query.orderId || ''
|
||
const applyId = this.$route.query.applyId || ''
|
||
|
||
try {
|
||
if (id) {
|
||
await updateWarehousingApi({ id, orderId, applyId })
|
||
} else {
|
||
const routerParams = this.$route.query || {}
|
||
const res = await addWarehousingApi({ orderId, applyId })
|
||
this.$router.replace({
|
||
query: {
|
||
id: res.data.id || '',
|
||
applyId: routerParams.applyId || '',
|
||
orderId: routerParams.orderId || '',
|
||
isAddVisible: routerParams.isAddVisible || '',
|
||
isApprovalVisible: routerParams.isApprovalVisible || ''
|
||
}
|
||
})
|
||
}
|
||
this.$message({
|
||
type: 'success',
|
||
message: '操作成功'
|
||
})
|
||
} catch (error) {
|
||
console.log('🚀 ~ error:', error)
|
||
} finally {
|
||
loading.close()
|
||
this.isSubmit = false
|
||
}
|
||
},
|
||
|
||
handleSpanMethod({ row, column, rowIndex, columnIndex }) {
|
||
// 如果不是“录入单号”列,则不处理
|
||
if (columnIndex !== 1) {
|
||
// 假设“录入单号”是第1列(index=1)
|
||
return {
|
||
rowspan: 1,
|
||
colspan: 1
|
||
}
|
||
}
|
||
|
||
const orderNumber = row.orderNumber
|
||
this.orderNumber = orderNumber
|
||
let count = 1
|
||
|
||
// 计算从当前行开始,连续有多少个相同的 orderNumber
|
||
for (let i = rowIndex + 1; i < this.tableData.length; i++) {
|
||
if (this.tableData[i].orderNumber === orderNumber) {
|
||
count++
|
||
} else {
|
||
break
|
||
}
|
||
}
|
||
|
||
// 判断当前行是否是该 orderNumber 的第一条记录
|
||
const isFirst = !this.tableData.some((item, idx) => idx < rowIndex && item.orderNumber === orderNumber)
|
||
|
||
if (isFirst) {
|
||
// 第一次出现,合并 count 行
|
||
return {
|
||
rowspan: count,
|
||
colspan: 1
|
||
}
|
||
} else {
|
||
// 不是第一次,隐藏该单元格
|
||
return {
|
||
rowspan: 0,
|
||
colspan: 0
|
||
}
|
||
}
|
||
},
|
||
handleImport() {
|
||
this.upload.title = '导入'
|
||
this.upload.open = true
|
||
},
|
||
handleImportImg() {
|
||
this.upload.open2 = true
|
||
},
|
||
handleViewDetail(row) {
|
||
this.$router.push({ path: '/equipment/details', query: { id: row.maId } })
|
||
},
|
||
getFeatureValue(row, prop) {
|
||
const match = prop.match(/feature(Item|Value)(\d+)/)
|
||
if (!match) return '-'
|
||
|
||
const type = match[1] // 'Item' or 'Value'
|
||
const index = Number(match[2]) - 1
|
||
const list = row.propertyVoList || []
|
||
|
||
if (!list[index]) return '-'
|
||
|
||
return type === 'Item' ? list[index].propertyName : list[index].propertyValue
|
||
},
|
||
handleFile(row) {
|
||
// 打开文件预览
|
||
window.open(row.fileUrl, '_blank')
|
||
},
|
||
// 查看
|
||
handleView(row, type) {
|
||
if (type == 1) {
|
||
this.dialogTitle = '装备外观'
|
||
this.dialogList = row.appearanceImages || []
|
||
} else if (type == 2) {
|
||
this.dialogTitle = '合格证'
|
||
this.dialogList = row.certificates || []
|
||
} else if (type == 3) {
|
||
this.dialogTitle = '定期检验报告'
|
||
this.dialogList = row.inspectionReports || []
|
||
} else if (type == 4) {
|
||
this.dialogTitle = '采购发票'
|
||
this.dialogList = row.purchaseInvoices || []
|
||
}
|
||
this.dialogVisible = true
|
||
},
|
||
handleFileListUpload(row) {
|
||
this.currentRow = row
|
||
console.log('🚀 ~ this.currentRow:', this.currentRow)
|
||
this.openReport = true
|
||
},
|
||
// 上传
|
||
handleFileUpload(row, type) {
|
||
this.uploadType = type
|
||
// this.currentRow = row
|
||
if (type == 1) {
|
||
this.uploadTitle = '装备外观'
|
||
this.fileList = this.joinFileUrls(this.currentRow.appearanceImages)
|
||
this.uploadLimit = 6
|
||
this.fileSize = 5
|
||
this.uploadFileType = ['jpg', 'png', 'jpeg']
|
||
} else if (type == 2) {
|
||
this.uploadTitle = '合格证'
|
||
this.fileList = this.joinFileUrls(this.currentRow.certificates)
|
||
this.uploadLimit = 3
|
||
this.fileSize = 10
|
||
this.uploadFileType = ['jpg', 'png', 'pdf']
|
||
} else if (type == 3) {
|
||
this.uploadTitle = '定期检验报告'
|
||
this.fileList = this.joinFileUrls(this.currentRow.inspectionReports)
|
||
this.uploadLimit = 3
|
||
this.fileSize = 10
|
||
this.uploadFileType = ['jpg', 'png', 'pdf']
|
||
} else if (type == 4) {
|
||
this.uploadTitle = '采购发票'
|
||
this.fileList = this.joinFileUrls(this.currentRow.purchaseInvoices)
|
||
this.uploadLimit = 3
|
||
this.fileSize = 10
|
||
this.uploadFileType = ['jpg', 'png', 'pdf']
|
||
}
|
||
this.uploadVisible = true
|
||
},
|
||
handleFileList(file) {
|
||
console.log('🚀 ~ file:', file)
|
||
if (this.uploadType == 1) {
|
||
this.currentRow.fileList1 = file
|
||
if (!file) {
|
||
this.currentRow.appearanceImages = []
|
||
return
|
||
}
|
||
this.currentRow.appearanceImages = this.formatFileList(file)
|
||
} else if (this.uploadType == 2) {
|
||
this.currentRow.fileList2 = file
|
||
if (!file) {
|
||
this.currentRow.certificates = []
|
||
return
|
||
}
|
||
this.currentRow.certificates = this.formatFileList(file)
|
||
} else if (this.uploadType == 3) {
|
||
this.currentRow.fileList3 = file
|
||
if (!file) {
|
||
this.currentRow.inspectionReports = []
|
||
return
|
||
}
|
||
this.currentRow.inspectionReports = this.formatFileList(file)
|
||
} else if (this.uploadType == 4) {
|
||
this.currentRow.fileList4 = file
|
||
if (!file) {
|
||
this.currentRow.purchaseInvoices = []
|
||
return
|
||
}
|
||
this.currentRow.purchaseInvoices = this.formatFileList(file)
|
||
}
|
||
},
|
||
formatFileList(file) {
|
||
const arr = file.split(',')
|
||
return arr.map((item) => {
|
||
const parts = item.split('/')
|
||
return {
|
||
fileName: parts[parts.length - 1],
|
||
fileUrl: item
|
||
}
|
||
})
|
||
},
|
||
joinFileUrls(list) {
|
||
if (!Array.isArray(list) || list.length === 0) return ''
|
||
|
||
return list
|
||
.filter((item) => item && item.fileUrl)
|
||
.map((item) => item.fileUrl)
|
||
.join(',')
|
||
},
|
||
importTemplate() {
|
||
this.download('/material-mall/order/template', {}, `装备信息导入模板_${new Date().getTime()}.xlsx`)
|
||
},
|
||
importTemplate2() {
|
||
this.download(
|
||
`/material-mall/order/zip?orderId=${this.queryParams.orderId}`,
|
||
{},
|
||
`批量导入图片模板_${new Date().getTime()}.zip`
|
||
)
|
||
},
|
||
async addList() {
|
||
try {
|
||
if (!this.$route.query.orderId) {
|
||
const routerParams = this.$route.query || {}
|
||
const result = await getEquipmentAddIdApi()
|
||
this.orderId = result.data.id
|
||
this.$router.replace({
|
||
query: {
|
||
id: routerParams.id || '',
|
||
applyId: routerParams.applyId || '',
|
||
orderId: result.data.id,
|
||
isAddVisible: this.isAddVisible,
|
||
isApprovalVisible: this.isApprovalVisible
|
||
}
|
||
})
|
||
}
|
||
const newRow = {
|
||
isNew: true, // 标记为新行
|
||
orderNumber: this.orderNumber,
|
||
major: '', // 专业
|
||
process: [], // 工序
|
||
category: [], // 类目
|
||
name: '', // 装备名称
|
||
specificationModel: '', // 规格型号
|
||
originalValue: '', // 资产原值
|
||
productionDate: '', // 出厂日期
|
||
manufacturerId: '', // 生产厂家
|
||
originalCode: '', // 装备原始编码
|
||
nextMaintenanceDate: '', // 下次维保日期
|
||
maxServiceLifeYears: '', // 装备寿命
|
||
manageType: '0', // 管理模式
|
||
count: 1, // 装备数量
|
||
unit: '', // 计数单位
|
||
purchaseDate: '', // 采购日期
|
||
appearanceImages: [], // 装备图片
|
||
certificates: [], // 合格证
|
||
inspectionReports: [], // 检测证书
|
||
purchaseInvoices: [], // 采购发票
|
||
propertyVoList: [], // 特征属性
|
||
|
||
fieldVoList: this.fieldVoList, // 台账属性
|
||
|
||
majorList: [], // 专业列表
|
||
processList: [], // 工序列表
|
||
categoryList: [], // 类目列表
|
||
manufacturerList: [], // 生产厂家列表
|
||
fileList1: null, // 装备图片
|
||
fileList2: null, // 合格证
|
||
fileList3: null, // 检测证书
|
||
fileList4: null // 采购发票
|
||
}
|
||
await this.getFirstLevel(newRow)
|
||
this.tableData.unshift(newRow)
|
||
console.log('🚀 ~ this.tableData:', this.tableData)
|
||
console.log('----》》》', this.fieldVoList)
|
||
} catch (error) {
|
||
console.log('🚀 ~ error:', error)
|
||
}
|
||
},
|
||
// 转换为树形结构
|
||
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
|
||
},
|
||
getFirstLevel(row) {
|
||
console.log('🚀 ~ row:', row)
|
||
firstLevel().then((res) => {
|
||
if (res.code === 200) {
|
||
row.majorList = res.data
|
||
}
|
||
})
|
||
},
|
||
majorChange(item, row) {
|
||
console.log('🚀 ~ item, row:', item, row)
|
||
if (!item) {
|
||
row.processList = []
|
||
row.process = []
|
||
} else {
|
||
secondAndThirdLevel({ firstLevelId: item }).then((res) => {
|
||
if (res.code === 200) {
|
||
row.processList = this.convertToSubTree(res.data)
|
||
}
|
||
})
|
||
}
|
||
},
|
||
processChange(item, row) {
|
||
console.log('🚀 ~ processChange ~ item:', item)
|
||
if (item.length === 0) {
|
||
row.categoryList = []
|
||
row.category = []
|
||
} else {
|
||
fourthToSixthLevel({ thirdLevelId: item[item.length - 1] }).then((res) => {
|
||
if (res.code === 200) {
|
||
row.categoryList = this.convertToSubTree(res.data)
|
||
}
|
||
})
|
||
}
|
||
},
|
||
categoryChange(item, row) {
|
||
console.log('🚀 ~ processChange ~ item:', item)
|
||
row.propertyVoList = []
|
||
this.getPropertyVoList(item[item.length - 1], row)
|
||
},
|
||
// 获取特征值
|
||
async getPropertyVoList(typeId, row) {
|
||
try {
|
||
const res = await getEquipmentPropertyTypeApi(typeId)
|
||
console.log('特征值-->:', res)
|
||
row.propertyVoList = res.data || []
|
||
row.propertyVoList.forEach((item) => {
|
||
if (item.inputType == 2) {
|
||
item.valueList = this.handleData(item.value)
|
||
}
|
||
if (item.inputType == 3) {
|
||
item.valueList2 = this.handleData(item.value)
|
||
// item.propertyValues = null
|
||
this.$set(item, 'propertyValues', null)
|
||
}
|
||
})
|
||
console.log('🚀 ~ row.propertyVoList:', row.propertyVoList)
|
||
} catch (error) {
|
||
console.log('获取特征值失败:', error)
|
||
}
|
||
},
|
||
// 价格输入处理
|
||
handlePriceInput(v, row) {
|
||
row.originalValue = row.originalValue
|
||
.replace(/[^\d.]/g, '') // 删除所有非数字和点
|
||
.replace(/\.{2,}/g, '.') // 多个点 -> 单点
|
||
.replace(/^(\d+)\.(.*)\./, '$1.$2') // 只允许一个点
|
||
},
|
||
async handleDblClick(row, column, event) {
|
||
if (this.routerParams.isView || row.isNew) return
|
||
this.$set(row, 'majorList', [])
|
||
this.$set(row, 'processList', [])
|
||
this.$set(row, 'categoryList', [])
|
||
this.$set(row, 'process', [String(row.mainProcessId), String(row.subProcessId)])
|
||
row.branchId
|
||
? this.$set(row, 'category', [String(row.mainCategoryId), String(row.subCategoryId), String(row.branchId)])
|
||
: this.$set(row, 'category', [String(row.mainCategoryId), String(row.subCategoryId)])
|
||
await this.getFirstLevel(row)
|
||
await this.majorChange(row.majorId, row)
|
||
await this.processChange(row.process, row)
|
||
|
||
if (!row.propertyVoList) row.propertyVoList = []
|
||
row.propertyVoList.forEach((item) => {
|
||
if (item.inputType == 2) {
|
||
item.valueList = this.handleData(item.value)
|
||
}
|
||
if (item.inputType == 3) {
|
||
item.valueList2 = this.handleData(item.value)
|
||
this.$set(item, 'propertyValues', item.propertyValue ? item.propertyValue.split(',') : [])
|
||
}
|
||
})
|
||
|
||
// 双击行进入编辑
|
||
console.log('双击的行数据:', row)
|
||
this.$set(row, 'isNew', true)
|
||
},
|
||
submitRow(row) {
|
||
console.log('🚀 ~ row:', row)
|
||
try {
|
||
row.orderId = this.orderId || this.$route.query.orderId
|
||
row.typeId = row.category.length > 0 ? row.category[row.category.length - 1] : null
|
||
// 校验必填项
|
||
if (!row.major) return this.$message.warning(`请选择专业`)
|
||
if (row.process.length == 0) return this.$message.warning(`请选择工序`)
|
||
if (row.category.length == 0) return this.$message.warning(`请选择类目`)
|
||
if (!row.name) return this.$message.warning(`请填写装备名称`)
|
||
if (!row.specificationModel) return this.$message.warning(`请填写规格型号`)
|
||
if (!row.originalCode) return this.$message.warning(`请填写装备原始编码`)
|
||
if (!row.unit) return this.$message.warning(`请选择计量单位`)
|
||
if (!row.manufacturerId) return this.$message.warning(`请选择生产厂家`)
|
||
if (!row.productionDate) return this.$message.warning(`请选择出厂日期`)
|
||
if (!row.purchaseDate) return this.$message.warning(`请选择采购日期`)
|
||
if (!row.originalValue) return this.$message.warning(`请填写资产原值`)
|
||
if (!row.maxServiceLifeYears) return this.$message.warning(`请填写最大使用年限`)
|
||
if (!row.nextMaintenanceDate) return this.$message.warning(`请选择下次维保日期`)
|
||
if (row.appearanceImages.length == 0) return this.$message.warning(`请上传装备外观`)
|
||
if (row.certificates.length == 0) return this.$message.warning(`请上传合格证`)
|
||
if (row.inspectionReports.length == 0) return this.$message.warning(`请上传定期检验报告`)
|
||
|
||
row.propertyVoList.forEach((item) => {
|
||
if (item.inputType == 3 && Array.isArray(item.propertyValues)) {
|
||
item.propertyValue = item.propertyValues.join(',')
|
||
}
|
||
})
|
||
// 判断特征项是否填写
|
||
if (row.propertyVoList && row.propertyVoList.length > 0) {
|
||
const unfilledIndex = row.propertyVoList.findIndex(
|
||
(item) => (!item.propertyValue || item.propertyValue === '') && item.mustHave != '0'
|
||
)
|
||
|
||
if (unfilledIndex !== -1) {
|
||
this.$message.warning(`第 ${unfilledIndex + 1} 个特征项为必填项,请填写完整`)
|
||
return
|
||
}
|
||
}
|
||
|
||
// 添加 fieldVoList 必填项验证
|
||
if (row.isNew && row.fieldVoList && row.fieldVoList.length > 0) {
|
||
// 收集必填但未填写的字段
|
||
const missingRequiredFields = []
|
||
|
||
row.fieldVoList.forEach((field, index) => {
|
||
// 检查是否是必填项
|
||
if (field.mustHave != 0) {
|
||
// 检查值是否为空
|
||
const value = field.propertyValue
|
||
if (value === undefined || value === null || value === '') {
|
||
missingRequiredFields.push(field.propertyName || `字段${index + 1}`)
|
||
}
|
||
}
|
||
})
|
||
|
||
// 如果有必填项未填写,提示用户
|
||
if (missingRequiredFields.length > 0) {
|
||
this.$message.error(`请填写以下必填项:${missingRequiredFields.join('、')}`)
|
||
return
|
||
}
|
||
}
|
||
|
||
console.log('🚀 ~ row.propertyVoList:', row.propertyVoList)
|
||
|
||
// 二次确认
|
||
this.$confirm('是否确定保存?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(async() => {
|
||
if (this.isSubmit) return
|
||
this.isSubmit = true
|
||
const loading = this.$loading()
|
||
try {
|
||
if (row.maId) {
|
||
await equipmentEditApiNew(row)
|
||
} else {
|
||
await addInterDevice(row)
|
||
}
|
||
this.isSubmit = false
|
||
this.handleSubmit()
|
||
this.getList()
|
||
} catch (error) {
|
||
console.log('🚀 ~ error:', error)
|
||
} finally {
|
||
this.isSubmit = false
|
||
loading.close()
|
||
}
|
||
})
|
||
} catch (error) {
|
||
console.log('🚀 ~ error:', error)
|
||
}
|
||
},
|
||
// 处理数据
|
||
handleData(data) {
|
||
console.log('处理数据:', data)
|
||
if (!data) return []
|
||
return data.split(',').map((item) => {
|
||
return {
|
||
label: item,
|
||
value: item
|
||
}
|
||
})
|
||
},
|
||
replaceRoute(orderId) {
|
||
const routerParams = this.$route.query || {}
|
||
console.log('routerParams--->>', routerParams)
|
||
this.$router.replace({
|
||
query: {
|
||
id: routerParams.id || '',
|
||
applyId: routerParams.applyId || '',
|
||
orderId,
|
||
isAddVisible: routerParams.isAddVisible,
|
||
isApprovalVisible: routerParams.isApprovalVisible
|
||
}
|
||
})
|
||
},
|
||
|
||
|
||
// 台账属性分割值字符串为数组
|
||
getSelectOptions(value) {
|
||
if (!value) return []
|
||
return value.split(/[,,]/).map(v => ({
|
||
value: v.trim(),
|
||
label: v.trim()
|
||
}))
|
||
},
|
||
|
||
//台账属性回显属性
|
||
getLedgerValue(row, propertyCode) {
|
||
// 如果 row.fieldVoList 顺序和 fieldVoList 一致,可以使用索引
|
||
const configIndex = this.fieldVoList.findIndex(item => item.propertyCode === propertyCode)
|
||
|
||
if (configIndex !== -1 && row.fieldVoList && row.fieldVoList[configIndex]) {
|
||
const value = row.fieldVoList[configIndex].propertyValue
|
||
if (value !== null && value !== undefined) {
|
||
return value
|
||
}
|
||
}
|
||
|
||
// 如果索引查找失败,使用 find 方法
|
||
if (row.fieldVoList && Array.isArray(row.fieldVoList)) {
|
||
const field = row.fieldVoList.find(item => item.propertyCode === propertyCode)
|
||
if (field && field.propertyValue !== null && field.propertyValue !== undefined) {
|
||
return field.propertyValue
|
||
}
|
||
}
|
||
|
||
// 最后尝试从 row 对象本身获取
|
||
return row[propertyCode] || ''
|
||
}
|
||
}
|
||
}
|
||
</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; // 确保有足够高度
|
||
}
|
||
|
||
.dialog-footer {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
gap: 10px; // 按钮间距
|
||
}
|
||
|
||
.search-box {
|
||
margin-bottom: 20px;
|
||
border-radius: 8px;
|
||
}
|
||
|
||
.content-box {
|
||
border-radius: 8px;
|
||
// height: calc(100vh - 350px);
|
||
display: flex;
|
||
flex-direction: column;
|
||
overflow: hidden;
|
||
|
||
::v-deep .el-card__body {
|
||
display: flex !important;
|
||
flex-direction: column !important;
|
||
height: 100% !important;
|
||
padding: 20px;
|
||
}
|
||
|
||
.el-row:first-child {
|
||
margin-bottom: 16px;
|
||
flex-shrink: 0;
|
||
|
||
.el-col {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
gap: 12px;
|
||
}
|
||
}
|
||
|
||
.table-container {
|
||
flex: 1;
|
||
overflow: hidden;
|
||
margin-bottom: 0;
|
||
min-height: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.pagination-wrapper {
|
||
flex-shrink: 0;
|
||
padding-top: 6px;
|
||
margin-top: auto;
|
||
|
||
::v-deep .pagination-container {
|
||
padding: 0px 20px !important;
|
||
/* margin-bottom: 30px; */
|
||
}
|
||
}
|
||
|
||
::v-deep .el-table {
|
||
// 启用斑马纹
|
||
&.el-table--striped .el-table__body {
|
||
tr.el-table__row--striped td {
|
||
background-color: #f6fbfa !important; // 浅紫色
|
||
}
|
||
}
|
||
|
||
.el-table__header {
|
||
background: #e9f0ee;
|
||
|
||
th {
|
||
background: #e9f0ee !important;
|
||
color: #606266;
|
||
font-weight: 600;
|
||
height: 50px;
|
||
}
|
||
}
|
||
|
||
&.el-table--striped .el-table__body tr.el-table__row:hover > td.el-table__cell {
|
||
background-color: #ccf1e9 !important;
|
||
}
|
||
|
||
.el-table__body tr.hover-row > td.el-table__cell {
|
||
background-color: #ccf1e9 !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
::v-deep .el-input-number.is-without-controls .el-input__inner {
|
||
text-align: left;
|
||
}
|
||
|
||
|
||
::v-deep.el-button--primary{
|
||
background-color: #2CBAB2;
|
||
border-color: #2CBAB2;
|
||
}
|
||
</style>
|