Files
klp-oa/klp-ui/src/views/crm/contract/components/ContractTabs.vue

307 lines
11 KiB
Vue
Raw Normal View History

<template>
<div class="contract-tabs">
<div v-if="orderId" class="tabs-content">
<el-tabs v-model="activeTab" type="border-card">
<el-tab-pane label="财务状态" name="finance" v-hasPermi="['crm:order:finance']">
<div class="order-finance" v-if="activeTab === 'finance'">
<!-- 财务状态内容 -->
<ReceiveTable :order="currentOrder" />
</div>
</el-tab-pane>
<el-tab-pane label="订单异议" name="dispute" v-hasPermi="['crm:order:objection']">
<div class="order-dispute" v-if="activeTab === 'dispute'">
<!-- 订单异议内容 -->
<OrderObjection :order="currentOrder" />
</div>
</el-tab-pane>
<el-tab-pane label="生产成果" name="product">
<div class="order-record" v-if="activeTab === 'product'" v-loading="productCoilLoading">
<!-- 生产成果内容 -->
<CoilTable ref="productCoilTable" :data="productCoilList || []" :showSelection="true"
:pagination="productPagination" :total-statistics="productTotalStatistics"
@selection-change="handleProductSelectionChange"
@page-change="handleProductPageChange">
<template slot="filter-actions" slot-scope="{ selectedRows }">
<el-button type="primary" size="mini" icon="el-icon-refresh"
:disabled="!selectedRows.length" @click="handleBatchTransferContract(selectedRows)">
批量转单
</el-button>
</template>
</CoilTable>
</div>
</el-tab-pane>
<el-tab-pane label="发货配卷" name="coil">
<div class="order-record" v-if="activeTab === 'coil'" v-loading="deliveryCoilLoading">
<!-- 发货配卷内容 -->
<CoilTable :data="deliveryCoilList || []"
:pagination="deliveryPagination" :total-statistics="deliveryTotalStatistics"
@page-change="handleDeliveryPageChange" />
</div>
</el-tab-pane>
<el-tab-pane label="发货单据" name="delivery">
<div class="order-record" v-if="activeTab === 'delivery'">
<!-- 发货单内容 -->
<DeliveryTable :data="deliveryWaybillList || []" />
</div>
</el-tab-pane>
<el-tab-pane label="合同附件" name="attachment" v-hasPermi="['crm:order:record']">
<div class="attachment-item">
<h4>商务附件</h4>
<FileList :oss-ids="contractAttachment" />
</div>
<div class="attachment-item">
<h4>技术附件</h4>
<FileList :oss-ids="technicalAgreement" />
</div>
<div class="attachment-item">
<h4>排产函</h4>
<FileList :oss-ids="otherAttachment" />
</div>
<div class="attachment-item">
<h4>其他附件</h4>
<FileList :oss-ids="form.annexFiles" />
</div>
</el-tab-pane>
</el-tabs>
<!-- 批量转单 - 选择目标合同弹窗 -->
<el-dialog title="批量转单" :visible.sync="batchTransferDialogVisible" width="500px" append-to-body
@closed="batchTargetContractId = ''">
<div style="margin-bottom: 12px;">
已选择 <strong>{{ (batchTransferCoilIds || []).length }}</strong> 卷钢卷请选择目标合同
</div>
<ContractSelect v-model="batchTargetContractId" mode="all" />
<span slot="footer">
<el-button @click="batchTransferDialogVisible = false">取消</el-button>
<el-button type="primary" :disabled="!batchTargetContractId" :loading="batchTransferLoading"
@click="confirmBatchTransfer">确认转单</el-button>
</span>
</el-dialog>
</div>
<div v-else class="no-selection" style="display: flex; align-items: center; justify-content: center; height: 100%;">
<el-empty description="请先选择合同" />
</div>
</div>
</template>
<script>
import CoilTable from "../../components/CoilTable.vue";
import ContractSelect from "@/components/KLPService/ContractSelect";
import { batchUpdateContractCoil } from "@/api/wms/coil";
import FileList from "@/components/FileList";
import DeliveryTable from "../../components/DeliveryTable.vue";
// 导入可能需要的组件
import OrderDetail from "../../components/OrderDetail.vue";
import OrderEdit from "../../components/OrderEdit.vue";
import ReceiveTable from "../../components/ReceiveTable.vue";
import OrderObjection from "../../components/OrderObjection.vue";
import OrderRecord from "../../components/OrderRecord.vue";
import { listDeliveryCoilsByOrder, getDeliveryCoilsStatisticsByOrder, listProductCoilsByContract, getProductCoilsStatisticsByContract } from "@/api/crm/coil";
export default {
name: "ContractTabs",
components: {
CoilTable,
ContractSelect,
FileList,
DeliveryTable,
OrderDetail,
OrderEdit,
ReceiveTable,
OrderObjection,
OrderRecord
},
props: {
orderId: {
type: [Number, String],
default: null
},
loading: {
type: Boolean,
default: false
},
// 附件字段
contractAttachment: {
type: String,
default: ''
},
technicalAgreement: {
type: String,
default: ''
},
otherAttachment: {
type: String,
default: ''
},
// 新增必要的props
form: {
type: Object,
default: () => ({})
},
currentOrder: {
type: Object,
default: () => ({})
},
deliveryWaybillList: {
type: Array,
default: () => []
}
},
data() {
return {
// 活动tab
activeTab: "finance",
selectedProductRows: [],
batchTransferDialogVisible: false,
batchTargetContractId: '',
batchTransferCoilIds: [],
batchTransferLoading: false,
productCoilList: [],
productCoilStatistics: {},
productPagination: { total: 0, currentPage: 1, pageSize: 20 },
productCoilLoading: false,
deliveryCoilList: [],
deliveryCoilStatistics: {},
deliveryPagination: { total: 0, currentPage: 1, pageSize: 20 },
deliveryCoilLoading: false,
};
},
computed: {
productTotalStatistics() {
const stats = this.productCoilStatistics;
if (!stats || Object.keys(stats).length === 0) return null;
return {
totalCoils: stats.total_count || 0,
totalNetWeight: stats.total_net_weight || 0
};
},
deliveryTotalStatistics() {
const stats = this.deliveryCoilStatistics;
if (!stats || Object.keys(stats).length === 0) return null;
return {
totalCoils: stats.total_count || 0,
totalNetWeight: stats.total_net_weight || 0
};
}
},
watch: {
orderId: {
handler(newVal, oldVal) {
if (newVal && newVal !== oldVal) {
this.productPagination.currentPage = 1;
this.deliveryPagination.currentPage = 1;
this.fetchDeliveryCoils();
this.fetchProductCoils();
this.fetchDeliveryCoilStatistics();
this.fetchProductCoilStatistics();
}
},
immediate: true
}
},
methods: {
handleProductSelectionChange(selection) {
this.selectedProductRows = selection;
},
handleBatchTransferContract(selectedRows) {
if (!selectedRows || !selectedRows.length) {
this.$message.warning('请先选择需要转单的钢卷');
return;
}
this.batchTransferCoilIds = selectedRows.map(row => row.coilId);
this.batchTargetContractId = '';
this.batchTransferDialogVisible = true;
},
confirmBatchTransfer() {
const coilIds = this.batchTransferCoilIds;
const contractId = this.batchTargetContractId;
if (!contractId) {
this.$message.warning('请选择目标合同');
return;
}
this.batchTransferLoading = true;
batchUpdateContractCoil(contractId, coilIds).then(res => {
this.$message.success(`成功将 ${coilIds.length} 卷钢卷转入目标合同`);
this.batchTransferDialogVisible = false;
// 刷新生产成果列表
this.fetchProductCoilStatistics();
this.fetchProductCoils();
// 清除选中
if (this.$refs.productCoilTable) {
this.$refs.productCoilTable.clearSelection();
}
}).catch(err => {
console.error('批量转单失败:', err);
this.$message.error('批量转单失败,请重试');
}).finally(() => {
this.batchTransferLoading = false;
});
},
// 解析时间
parseTime(time, pattern) {
if (!time) return '';
const d = new Date(time);
const year = d.getFullYear();
const month = (d.getMonth() + 1).toString().padStart(2, '0');
const day = d.getDate().toString().padStart(2, '0');
const hours = d.getHours().toString().padStart(2, '0');
const minutes = d.getMinutes().toString().padStart(2, '0');
const seconds = d.getSeconds().toString().padStart(2, '0');
return pattern
.replace('{y}', year)
.replace('{m}', month)
.replace('{d}', day)
.replace('{h}', hours)
.replace('{i}', minutes)
.replace('{s}', seconds);
},
fetchDeliveryCoils() {
this.deliveryCoilLoading = true;
listDeliveryCoilsByOrder(this.orderId, {
pageNum: this.deliveryPagination.currentPage,
pageSize: this.deliveryPagination.pageSize
}).then(res => {
this.deliveryCoilList = res.rows || [];
this.deliveryPagination.total = res.total || 0;
}).finally(() => {
this.deliveryCoilLoading = false;
});
},
fetchProductCoils() {
this.productCoilLoading = true;
listProductCoilsByContract(this.orderId, {
pageNum: this.productPagination.currentPage,
pageSize: this.productPagination.pageSize
}).then(res => {
this.productCoilList = res.rows || [];
this.productPagination.total = res.total || 0;
}).finally(() => {
this.productCoilLoading = false;
});
},
fetchDeliveryCoilStatistics() {
getDeliveryCoilsStatisticsByOrder(this.orderId).then(res => {
this.deliveryCoilStatistics = res.data || {};
});
},
fetchProductCoilStatistics() {
getProductCoilsStatisticsByContract(this.orderId).then(res => {
this.productCoilStatistics = res.data || {};
});
},
handleProductPageChange({ currentPage, pageSize }) {
this.productPagination.currentPage = currentPage;
this.productPagination.pageSize = pageSize;
this.fetchProductCoils();
},
handleDeliveryPageChange({ currentPage, pageSize }) {
this.deliveryPagination.currentPage = currentPage;
this.deliveryPagination.pageSize = pageSize;
this.fetchDeliveryCoils();
},
}
};
</script>