feat(mes/qc): add quality certificate management function
- 新增质量证明书主、明细的CRUD接口 - 新增质量证明书列表页、明细编辑页 - 新增打印预览组件和PDF导出打印功能 - 添加配套的静态资源和路由依赖 - 优化路由菜单处理逻辑
This commit is contained in:
888
klp-ui/src/views/mes/qc/certificate/item.vue
Normal file
888
klp-ui/src/views/mes/qc/certificate/item.vue
Normal file
@@ -0,0 +1,888 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="tab-container">
|
||||
<div class="select-button" @click="openCertificateDialog">
|
||||
<i class="el-icon-setting"></i>
|
||||
</div>
|
||||
<div class="custom-tabs">
|
||||
<div class="tab-nav">
|
||||
<button v-if="certificateList.length > 0 && queryParams.pageNum > 1" class="nav-btn prev" @click="prevPage">
|
||||
<i class="el-icon-arrow-left"></i>
|
||||
</button>
|
||||
<div class="tab-header">
|
||||
<div v-for="cert in certificateList" :key="cert.certificateId" class="tab-item"
|
||||
:class="{ active: activeTab === cert.certificateId.toString() }" @click="handleTabClick(cert)">
|
||||
<div class="tab-title">{{ cert.certificateNo }}</div>
|
||||
<div class="tab-info">
|
||||
<span>{{ cert.productName }}</span>
|
||||
<span class="date">{{ parseTime(cert.issueDate, '{y}-{m}-{d}') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="certificateList.length === 0" class="tab-item disabled">
|
||||
<div class="tab-title">暂无质保书</div>
|
||||
<div class="tab-info">请点击齿轮图标选择质保书</div>
|
||||
</div>
|
||||
</div>
|
||||
<button v-if="certificateList.length > 0 && queryParams.pageNum < totalPage" class="nav-btn next" @click="nextPage">
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="currentCertificateId" class="certificate-detail-container">
|
||||
<div class="card-header">
|
||||
<h3>{{ currentCertificateInfo.certificateNo || '质保书明细' }}</h3>
|
||||
<div>
|
||||
<el-button type="primary" plain @click="handleAdd">新增明细</el-button>
|
||||
<el-button type="success" plain @click="openBatchAddDialog">批量新增</el-button>
|
||||
<el-button type="danger" plain @click="handleBatchDelete"
|
||||
:disabled="selectedRows.length === 0">批量删除</el-button>
|
||||
<el-button type="warning" plain icon="el-icon-printer" @click="handlePrint">打印</el-button>
|
||||
<el-button type="info" plain @click="getList">刷新</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-form class="certificate-info" :model="currentCertificateInfo" label-width="80px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="证明书号">
|
||||
<el-input v-model="currentCertificateInfo.certificateNo" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="合同号">
|
||||
<el-input v-model="currentCertificateInfo.contractNo" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="产品名称">
|
||||
<el-input v-model="currentCertificateInfo.productName" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="签发日期">
|
||||
<el-date-picker v-model="currentCertificateInfo.issueDate" type="date" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="执行标准">
|
||||
<el-input v-model="currentCertificateInfo.standard" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="收货单位">
|
||||
<el-input v-model="currentCertificateInfo.consignee" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="生产厂家">
|
||||
<el-input v-model="currentCertificateInfo.manufacturer" @change="handleCertificateInfoChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="certificateItemList" style="width: 100%" border
|
||||
@selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" fixed="left" />
|
||||
<el-table-column label="操作" align="center" width="140" fixed="left">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="primary" size="mini" @click="handleSave(scope.row)">保存</el-button>
|
||||
<el-button type="danger" size="mini" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="钢卷号" align="center" prop="coilNo" width="180">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.coilNo" style="background-color: #fff3e6;" placeholder="点击选择钢卷">
|
||||
<template slot="append">
|
||||
<el-button size="mini" icon="el-icon-search" @click="openCoilSelectDialog(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="炉号" align="center" prop="heatNo" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.heatNo" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="材质" align="center" prop="materialType" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.materialType" style="background-color: #fff3e6;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="规格(mm)" align="center" prop="size" width="120">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.size" style="background-color: #fff3e6;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="件数" align="center" prop="pieces" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model.number="scope.row.pieces" style="background-color: #fff3e6;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="重量(t)" align="center" prop="weight" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model.number="scope.row.weight" style="background-color: #fff3e6;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="C(%)" align="center" prop="c" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.c" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Si(%)" align="center" prop="si" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.si" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Mn(%)" align="center" prop="mn" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.mn" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="P(%)" align="center" prop="p" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.p" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="S(%)" align="center" prop="s" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.s" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="Als(%)" align="center" prop="als" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.als" style="background-color: #e6f7ff;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="屈服强度(MPa)" align="center" prop="yieldStrength" width="130">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model.number="scope.row.yieldStrength" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="抗拉强度(MPa)" align="center" prop="tensileStrength" width="130">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model.number="scope.row.tensileStrength" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="伸长率(%)" align="center" prop="elongation" width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.elongation" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="硬度(HRB)" align="center" prop="hardness" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model.number="scope.row.hardness" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="弯曲试验" align="center" prop="bendingTest" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.bendingTest" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="表面质量" align="center" prop="surfaceQuality" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.surfaceQuality" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="表面结构" align="center" prop="surfaceStructure" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.surfaceStructure" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="边缘状态" align="center" prop="edgeStatus" width="100">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.edgeStatus" style="background-color: #f6ffed;" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="备注" align="center" prop="remark">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.remark" style="background-color: #fff0f6;" />
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
|
||||
@pagination="getList" />
|
||||
</div>
|
||||
<el-empty v-else class="appempty" description="选择质保书查看明细" />
|
||||
|
||||
<el-dialog :title="'选择钢卷'" :visible.sync="coilDialogVisible" width="900px" append-to-body>
|
||||
<div class="dialog-toolbar">
|
||||
<el-form :model="coilQueryParams" ref="coilQueryForm" size="small" :inline="true" label-width="68px">
|
||||
<el-form-item label="钢卷号" prop="coilNo">
|
||||
<el-input v-model="coilQueryParams.coilNo" placeholder="请输入钢卷号" clearable
|
||||
@keyup.enter.native="handleCoilQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="材质" prop="material">
|
||||
<el-input v-model="coilQueryParams.material" placeholder="请输入材质" clearable
|
||||
@keyup.enter.native="handleCoilQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="规格" prop="specification">
|
||||
<el-input v-model="coilQueryParams.specification" placeholder="请输入规格" clearable
|
||||
@keyup.enter.native="handleCoilQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleCoilQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetCoilQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table v-loading="coilLoading" :data="coilList" height="350px" @row-click="handleCoilSelect">
|
||||
<el-table-column label="钢卷号" align="center" prop="currentCoilNo" />
|
||||
<el-table-column label="材质" align="center" prop="material" />
|
||||
<el-table-column label="规格" align="center" prop="specification" />
|
||||
<el-table-column label="重量(t)" align="center" prop="netWeight" />
|
||||
</el-table>
|
||||
<pagination v-show="coilTotal > 0" :total="coilTotal" :page.sync="coilQueryParams.pageNum"
|
||||
:limit.sync="coilQueryParams.pageSize" @pagination="getCoilList" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="'选择质保书'" :visible.sync="certificateDialogVisible" width="900px" append-to-body>
|
||||
<div class="dialog-toolbar">
|
||||
<el-form :model="certificateQueryParams" ref="certificateQueryForm" size="small" :inline="true" label-width="68px">
|
||||
<el-form-item label="证明书号" prop="certificateNo">
|
||||
<el-input v-model="certificateQueryParams.certificateNo" placeholder="请输入证明书号" clearable
|
||||
@keyup.enter.native="handleCertificateQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同号" prop="contractNo">
|
||||
<el-input v-model="certificateQueryParams.contractNo" placeholder="请输入合同号" clearable
|
||||
@keyup.enter.native="handleCertificateQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="certificateQueryParams.productName" placeholder="请输入产品名称" clearable
|
||||
@keyup.enter.native="handleCertificateQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleCertificateQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetCertificateQuery">重置</el-button>
|
||||
<el-button type="success" icon="el-icon-plus" size="mini" @click="handleAddCertificate">新增质保书</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-table v-loading="certificateLoading" :data="allCertificateList" height="350px" @row-click="handleTabClick">
|
||||
<el-table-column label="证明书号" align="center" prop="certificateNo" />
|
||||
<el-table-column label="合同号" align="center" prop="contractNo" />
|
||||
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||
<el-table-column label="执行标准" align="center" prop="standard" />
|
||||
<el-table-column label="收货单位" align="center" prop="consignee" />
|
||||
<el-table-column label="签发日期" align="center" prop="issueDate" width="140">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ parseTime(scope.row.issueDate, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
</el-table>
|
||||
<pagination v-show="certificateTotal > 0" :total="certificateTotal" :page.sync="certificateQueryParams.pageNum"
|
||||
:limit.sync="certificateQueryParams.pageSize" @pagination="getCertificateList" />
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :title="'新增质保书'" :visible.sync="addCertificateDialogVisible" width="800px" append-to-body>
|
||||
<el-form :model="certificateForm" ref="certificateForm" label-width="100px">
|
||||
<el-form-item label="证明书号" prop="certificateNo">
|
||||
<el-input v-model="certificateForm.certificateNo" placeholder="请输入证明书号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="合同号" prop="contractNo">
|
||||
<el-input v-model="certificateForm.contractNo" placeholder="请输入合同号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input v-model="certificateForm.productName" placeholder="请输入产品名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="执行标准" prop="standard">
|
||||
<el-input v-model="certificateForm.standard" placeholder="请输入执行标准" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收货单位" prop="consignee">
|
||||
<el-input v-model="certificateForm.consignee" placeholder="请输入收货单位" />
|
||||
</el-form-item>
|
||||
<el-form-item label="生产厂家" prop="manufacturer">
|
||||
<el-input v-model="certificateForm.manufacturer" placeholder="请输入生产厂家" />
|
||||
</el-form-item>
|
||||
<el-form-item label="签发日期" prop="issueDate">
|
||||
<el-date-picker v-model="certificateForm.issueDate" value-format="yyyy-MM-dd HH:mm:ss" type="date" placeholder="请选择签发日期" />
|
||||
</el-form-item>
|
||||
<el-form-item label="质保证明说明" prop="note">
|
||||
<el-input v-model="certificateForm.note" type="textarea" placeholder="请输入内容" auto-height />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input v-model="certificateForm.remark" type="textarea" placeholder="请输入内容" auto-height />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="addCertificateDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitCertificateForm">确定</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<CoilSelector
|
||||
:visible.sync="batchAddDialogVisible"
|
||||
:use-trigger="false"
|
||||
:multiple="true"
|
||||
@confirm="handleBatchAddConfirm"
|
||||
/>
|
||||
|
||||
<!-- 隐藏的打印组件 -->
|
||||
<CertificatePrintPreview
|
||||
ref="certificatePrint"
|
||||
v-show="false"
|
||||
:certificate="printCertificateData"
|
||||
:items="printItemsData"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listCertificateItem, getCertificateItem, delCertificateItem, addCertificateItem, updateCertificateItem } from "@/api/mes/qc/certificateItem";
|
||||
import { listCertificate, getCertificate, updateCertificate, addCertificate } from "@/api/mes/qc/certificate";
|
||||
import { listMaterialCoil } from "@/api/wms/coil";
|
||||
import CoilSelector from "@/components/CoilSelector/index.vue";
|
||||
import CertificatePrintPreview from "./components/CertificatePrintPreview.vue";
|
||||
import { print as printPdf } from "./lib/printUtils";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoilSelector,
|
||||
CertificatePrintPreview
|
||||
},
|
||||
name: "CertificateItem",
|
||||
computed: {
|
||||
totalPage() {
|
||||
return Math.ceil(this.certificateTotal / this.certificateQueryParams.pageSize)
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
buttonLoading: false,
|
||||
loading: false,
|
||||
certificateLoading: false,
|
||||
total: 0,
|
||||
certificateTotal: 0,
|
||||
certificateList: [],
|
||||
allCertificateList: [],
|
||||
certificateItemList: [],
|
||||
currentCertificateId: undefined,
|
||||
currentCertificateInfo: {},
|
||||
activeTab: '',
|
||||
certificateDialogVisible: false,
|
||||
coilDialogVisible: false,
|
||||
batchAddDialogVisible: false,
|
||||
addCertificateDialogVisible: false,
|
||||
printComponentVisible: false,
|
||||
printCertificateData: {},
|
||||
printItemsData: [],
|
||||
certificateForm: {
|
||||
certificateNo: '',
|
||||
contractNo: '',
|
||||
productName: '',
|
||||
standard: '',
|
||||
consignee: '',
|
||||
manufacturer: '',
|
||||
issueDate: '',
|
||||
remark: ''
|
||||
},
|
||||
coilLoading: false,
|
||||
coilTotal: 0,
|
||||
coilList: [],
|
||||
currentEditRow: null,
|
||||
selectedRows: [],
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 50,
|
||||
certificateId: undefined
|
||||
},
|
||||
certificateQueryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
certificateNo: undefined,
|
||||
contractNo: undefined,
|
||||
productName: undefined
|
||||
},
|
||||
coilQueryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
coilNo: undefined,
|
||||
material: undefined,
|
||||
specification: undefined
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getCertificateList();
|
||||
},
|
||||
methods: {
|
||||
parseTime(time, pattern) {
|
||||
if (!time) return '';
|
||||
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}';
|
||||
const date = new Date(time);
|
||||
const year = date.getFullYear();
|
||||
const month = date.getMonth() + 1;
|
||||
const day = date.getDate();
|
||||
const hour = date.getHours();
|
||||
const minute = date.getMinutes();
|
||||
const second = date.getSeconds();
|
||||
return format.replace('{y}', year)
|
||||
.replace('{m}', month.toString().padStart(2, '0'))
|
||||
.replace('{d}', day.toString().padStart(2, '0'))
|
||||
.replace('{h}', hour.toString().padStart(2, '0'))
|
||||
.replace('{i}', minute.toString().padStart(2, '0'))
|
||||
.replace('{s}', second.toString().padStart(2, '0'));
|
||||
},
|
||||
getCertificateList() {
|
||||
this.certificateLoading = true;
|
||||
listCertificate(this.certificateQueryParams).then(response => {
|
||||
this.allCertificateList = response.rows;
|
||||
this.certificateTotal = response.total;
|
||||
this.certificateList = response.rows;
|
||||
this.certificateLoading = false;
|
||||
});
|
||||
},
|
||||
handleCertificateQuery() {
|
||||
this.certificateQueryParams.pageNum = 1;
|
||||
this.getCertificateList();
|
||||
},
|
||||
resetCertificateQuery() {
|
||||
this.certificateQueryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
certificateNo: undefined,
|
||||
contractNo: undefined,
|
||||
productName: undefined
|
||||
};
|
||||
this.getCertificateList();
|
||||
},
|
||||
handleTabClick(certificate) {
|
||||
this.activeTab = certificate.certificateId.toString();
|
||||
this.certificateDialogVisible = false;
|
||||
this.handleRowClick(certificate);
|
||||
},
|
||||
handleRowClick(row) {
|
||||
this.currentCertificateId = row.certificateId;
|
||||
this.currentCertificateInfo = row;
|
||||
this.queryParams.certificateId = row.certificateId;
|
||||
this.getList();
|
||||
},
|
||||
getCertificateDetail(certificateId) {
|
||||
getCertificate(certificateId).then(response => {
|
||||
this.currentCertificateInfo = response.data;
|
||||
});
|
||||
},
|
||||
prevPage() {
|
||||
if (this.certificateQueryParams.pageNum > 1) {
|
||||
this.certificateQueryParams.pageNum--;
|
||||
this.getCertificateList();
|
||||
}
|
||||
},
|
||||
nextPage() {
|
||||
if (this.certificateQueryParams.pageNum < this.totalPage) {
|
||||
this.certificateQueryParams.pageNum++;
|
||||
this.getCertificateList();
|
||||
}
|
||||
},
|
||||
openCertificateDialog() {
|
||||
this.getCertificateList();
|
||||
this.certificateDialogVisible = true;
|
||||
},
|
||||
openCoilSelectDialog(row) {
|
||||
this.currentEditRow = row;
|
||||
this.coilDialogVisible = true;
|
||||
this.getCoilList();
|
||||
},
|
||||
getCoilList() {
|
||||
this.coilLoading = true;
|
||||
listMaterialCoil(this.coilQueryParams).then(response => {
|
||||
this.coilList = response.rows;
|
||||
this.coilTotal = response.total;
|
||||
this.coilLoading = false;
|
||||
});
|
||||
},
|
||||
handleCoilQuery() {
|
||||
this.coilQueryParams.pageNum = 1;
|
||||
this.getCoilList();
|
||||
},
|
||||
resetCoilQuery() {
|
||||
this.coilQueryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
coilNo: undefined,
|
||||
material: undefined,
|
||||
specification: undefined
|
||||
};
|
||||
this.getCoilList();
|
||||
},
|
||||
handleCoilSelect(row) {
|
||||
if (this.currentEditRow) {
|
||||
this.currentEditRow.coilNo = row.currentCoilNo;
|
||||
this.currentEditRow.materialType = row.material;
|
||||
this.currentEditRow.size = row.specification;
|
||||
this.currentEditRow.weight = row.netWeight;
|
||||
this.currentEditRow.pieces = 1;
|
||||
}
|
||||
this.coilDialogVisible = false;
|
||||
this.currentEditRow = null;
|
||||
},
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listCertificateItem({
|
||||
...this.queryParams,
|
||||
certificateId: this.currentCertificateId,
|
||||
}).then(response => {
|
||||
this.certificateItemList = response.rows.sort((a, b) => {
|
||||
return parseInt(a.itemSeqNo) - parseInt(b.itemSeqNo);
|
||||
});
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleAdd() {
|
||||
const newRow = {
|
||||
certificateId: this.currentCertificateId,
|
||||
itemSeqNo: this.certificateItemList.length + 1
|
||||
};
|
||||
|
||||
addCertificateItem(newRow).then(response => {
|
||||
this.$message({
|
||||
message: "新增成功",
|
||||
type: "success"
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
openBatchAddDialog() {
|
||||
this.batchAddDialogVisible = true;
|
||||
},
|
||||
handleBatchAddConfirm(coils) {
|
||||
if (!coils || coils.length === 0) {
|
||||
this.$message.warning('请选择钢卷');
|
||||
return;
|
||||
}
|
||||
|
||||
const totalCount = coils.length;
|
||||
let successCount = 0;
|
||||
let failCount = 0;
|
||||
|
||||
coils.forEach((coil, index) => {
|
||||
const newRow = {
|
||||
certificateId: this.currentCertificateId,
|
||||
itemSeqNo: this.certificateItemList.length + index + 1,
|
||||
coilNo: coil.currentCoilNo,
|
||||
materialType: coil.material,
|
||||
size: coil.specification,
|
||||
weight: coil.netWeight,
|
||||
pieces: 1
|
||||
};
|
||||
|
||||
addCertificateItem(newRow).then(() => {
|
||||
successCount++;
|
||||
if (successCount + failCount === totalCount) {
|
||||
this.batchAddDialogVisible = false;
|
||||
if (successCount === totalCount) {
|
||||
this.$message.success(`批量新增成功,共新增 ${successCount} 条明细`);
|
||||
} else {
|
||||
this.$message.warning(`批量新增完成,成功 ${successCount} 条,失败 ${failCount} 条`);
|
||||
}
|
||||
this.getList();
|
||||
}
|
||||
}).catch(() => {
|
||||
failCount++;
|
||||
if (successCount + failCount === totalCount) {
|
||||
this.batchAddDialogVisible = false;
|
||||
if (failCount === totalCount) {
|
||||
this.$message.error('批量新增失败');
|
||||
} else {
|
||||
this.$message.warning(`批量新增完成,成功 ${successCount} 条,失败 ${failCount} 条`);
|
||||
}
|
||||
this.getList();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
handleAddCertificate() {
|
||||
this.certificateForm = {
|
||||
certificateNo: '',
|
||||
contractNo: '',
|
||||
productName: '',
|
||||
standard: '',
|
||||
consignee: '',
|
||||
manufacturer: '',
|
||||
issueDate: '',
|
||||
note: 'D.T=Denu_Test \t T.S=Tensile Strength \t D=弯心直径MandrelDiameter \n Strength \t G.L=拉伸标距GaugeLength \t EL=Percentage Elongation After Fracture',
|
||||
remark: '1.本产品经检验满足订货标准要求。The material has been tested with satisfactory resultsin accordance with the speciicatication \n 2.本质量证明书中空白项目均不作为交货条件。The blank items shouldn’tbe regarded as delivery conditions. \n 3.盖章后生效。The quality certificate willcome into force with a valid stamp.',
|
||||
};
|
||||
this.addCertificateDialogVisible = true;
|
||||
},
|
||||
submitCertificateForm() {
|
||||
addCertificate(this.certificateForm).then(response => {
|
||||
this.$message({
|
||||
message: "新增成功",
|
||||
type: "success"
|
||||
});
|
||||
this.addCertificateDialogVisible = false;
|
||||
this.getCertificateList();
|
||||
}).catch(error => {
|
||||
this.$message({
|
||||
message: "新增失败",
|
||||
type: "error"
|
||||
});
|
||||
});
|
||||
},
|
||||
handleCertificateInfoChange() {
|
||||
if (!this.currentCertificateId) return;
|
||||
updateCertificate(this.currentCertificateInfo).then(response => {
|
||||
this.$message({
|
||||
message: "保存成功",
|
||||
type: "success"
|
||||
});
|
||||
}).catch(error => {
|
||||
this.$message({
|
||||
message: "保存失败",
|
||||
type: "error"
|
||||
});
|
||||
this.getCertificateDetail(this.currentCertificateId);
|
||||
});
|
||||
},
|
||||
handleSave(row) {
|
||||
updateCertificateItem(row).then(response => {
|
||||
this.$message({
|
||||
message: "保存成功",
|
||||
type: "success"
|
||||
});
|
||||
}).catch(error => {
|
||||
this.$message({
|
||||
message: "保存失败,正在重新获取数据",
|
||||
type: "error"
|
||||
});
|
||||
this.getList();
|
||||
});
|
||||
},
|
||||
handleDelete(row) {
|
||||
this.$confirm('是否确认删除该质保书明细?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.buttonLoading = true;
|
||||
delCertificateItem(row.itemId).then(response => {
|
||||
this.$message({
|
||||
message: "删除成功",
|
||||
type: "success"
|
||||
});
|
||||
this.buttonLoading = false;
|
||||
this.getList();
|
||||
});
|
||||
});
|
||||
},
|
||||
handleSelectionChange(selection) {
|
||||
this.selectedRows = selection;
|
||||
},
|
||||
handleBatchDelete() {
|
||||
if (this.selectedRows.length === 0) {
|
||||
this.$message.warning('请至少选择一条明细');
|
||||
return;
|
||||
}
|
||||
|
||||
this.$confirm(`确认删除选中的 ${this.selectedRows.length} 条明细?`, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
const ids = this.selectedRows.map(row => row.itemId).join(',');
|
||||
this.buttonLoading = true;
|
||||
delCertificateItem(ids).then(() => {
|
||||
this.$message.success('批量删除成功');
|
||||
this.getList();
|
||||
this.buttonLoading = false;
|
||||
}).catch(error => {
|
||||
this.$message.error('批量删除失败');
|
||||
this.buttonLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
async handlePrint() {
|
||||
this.printCertificateData = this.currentCertificateInfo;
|
||||
this.printItemsData = this.certificateItemList || [];
|
||||
this.$nextTick(() => {
|
||||
const el = this.$refs.certificatePrint.$refs.certificateContent;
|
||||
console.log(el);
|
||||
printPdf(el);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tab-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.select-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 10px 16px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #f9f9f9;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
user-select: none;
|
||||
margin-right: 10px;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.select-button:hover {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #c6e2ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.custom-tabs {
|
||||
flex: 1;
|
||||
border-bottom: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.tab-nav {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 52px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-bottom: none;
|
||||
border-radius: 4px 4px 0 0;
|
||||
background-color: #f9f9f9;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.nav-btn:hover {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #c6e2ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.tab-header {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
padding: 4px 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-bottom: none;
|
||||
border-radius: 4px 4px 0 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
background-color: #f9f9f9;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.tab-item:hover {
|
||||
background-color: #ecf5ff;
|
||||
border-color: #c6e2ff;
|
||||
}
|
||||
|
||||
.tab-item.active {
|
||||
background-color: #ffffff;
|
||||
border-color: #409eff;
|
||||
border-bottom-color: #ffffff;
|
||||
color: #409eff;
|
||||
box-shadow: 0 -2px 0 0 #409eff inset;
|
||||
}
|
||||
|
||||
.tab-item.disabled {
|
||||
cursor: not-allowed;
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
border-color: #ebeef5;
|
||||
}
|
||||
|
||||
.tab-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 1px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.tab-info {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tab-info .date {
|
||||
color: #606266;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.card-header h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.certificate-info {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.certificate-detail-container {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.el-table .cell {
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.dialog-toolbar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.appempty {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
::v-deep .el-table .cell {
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user