1.0.99 合同订单台账添加采购、开票信息

dev
yinq 3 months ago
parent a75de0cbe0
commit 615c164b4e

@ -3,7 +3,7 @@
<el-card shadow="never" class="main-card">
<template #header>
<div class="card-header">
<span class="header-title">订单管理台账</span>
<span class="header-title">合同订单管理台账</span>
<el-button size="default" type="primary" icon="ArrowLeft" @click="handleBack"></el-button>
</div>
</template>
@ -35,6 +35,18 @@
<el-descriptions-item label="合同状态">
<dict-tag :options="contract_status" :value="contractInfo?.contractStatus" />
</el-descriptions-item>
<el-descriptions-item label="采购状态">
<dict-tag :options="order_purchase_status" :value="orderInfo?.orderPurchaseStatus" />
</el-descriptions-item>
<el-descriptions-item label="发货状态">
<dict-tag :options="order_delivery_status" :value="orderInfo?.orderDeliveryStatus" />
</el-descriptions-item>
<el-descriptions-item label="开票状态">
<dict-tag :options="order_invoice_status" :value="orderInfo?.orderInvoiceStatus" />
</el-descriptions-item>
<el-descriptions-item label="回款百分比">
<span>{{ orderInfo?.orderPaymentRate ?? 0 }}%</span>
</el-descriptions-item>
<el-descriptions-item label="合同时间">{{ contractInfo?.contractDate || '-' }}</el-descriptions-item>
<el-descriptions-item label="合同总价" :span="1">
<span class="value-text value-amount">
@ -58,6 +70,66 @@
</div>
</el-tab-pane>
<!-- 采购信息 Tab -->
<el-tab-pane label="采购信息" name="purchase">
<div v-loading="loadingPurchase" class="tab-content">
<div class="section-header">
<div class="header-left">
<i class="el-icon-shopping-cart-full section-icon"></i>
<span class="section-title">采购信息</span>
<el-tag v-if="purchaseTotal > 0" type="info" size="small" class="count-tag"> {{ purchaseTotal }} </el-tag>
</div>
<div class="header-actions">
<el-button size="default" type="primary" plain icon="Link" @click="openPurchasePage"></el-button>
<el-button size="default" icon="Refresh" @click="loadPurchaseList"></el-button>
</div>
</div>
<el-table :data="purchaseList" size="default" border stripe v-loading="loadingPurchase" class="data-table">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="采购编号" prop="purchaseCode" width="160" show-overflow-tooltip />
<el-table-column label="项目号" prop="projectCode" width="150" show-overflow-tooltip />
<el-table-column label="项目名称" prop="projectName" min-width="180" show-overflow-tooltip />
<el-table-column label="项目经理" prop="managerName" width="120" />
<el-table-column label="收货人" prop="consigneeUser" width="120" />
<el-table-column label="收货地址" prop="consigneeAddress" min-width="180" show-overflow-tooltip />
<el-table-column label="收货人联系方式" prop="consigneeContact" width="150" />
<el-table-column label="项目采购状态" prop="projectPurchaseStatus" width="130" align="center">
<template #default="scope">
<dict-tag :options="project_purchase_status" :value="scope.row.projectPurchaseStatus" />
</template>
</el-table-column>
<el-table-column label="流程状态" prop="flowStatus" width="120" align="center">
<template #default="scope">
<dict-tag :options="wf_business_status" :value="scope.row.flowStatus" />
</template>
</el-table-column>
<el-table-column label="是否备件类" prop="spareFlag" width="110" align="center">
<template #default="scope">
<dict-tag :options="spare_flag" :value="scope.row.spareFlag" />
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="150" show-overflow-tooltip />
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<el-button size="default" type="primary" text @click="viewPurchase(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!loadingPurchase && purchaseList.length === 0" description="暂无采购信息" class="empty-state" />
<pagination
v-show="purchaseTotal > 0"
:total="purchaseTotal"
v-model:page="purchaseQuery.pageNum"
v-model:limit="purchaseQuery.pageSize"
@pagination="loadPurchaseList"
class="pagination-wrapper"
/>
</div>
</el-tab-pane>
<!-- 发货信息 Tab -->
<el-tab-pane label="发货信息" name="shipping">
<div v-loading="loadingShipping" class="tab-content">
@ -136,7 +208,70 @@
<!-- 开票信息 Tab -->
<el-tab-pane label="开票信息" name="invoice">
<div class="tab-content">
<el-empty description="暂无开票信息,功能开发中" class="empty-state" />
<div v-loading="loadingInvoice" class="tab-content">
<div class="section-header">
<div class="header-left">
<i class="el-icon-document section-icon"></i>
<span class="section-title">开票信息</span>
<el-tag v-if="invoiceTotal > 0" type="info" size="small" class="count-tag"> {{ invoiceTotal }} </el-tag>
</div>
</div>
<el-table :data="invoiceList" size="default" border stripe v-loading="loadingInvoice" class="data-table">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="开票申请编号" prop="invoiceCode" width="200" show-overflow-tooltip />
<el-table-column label="项目号" prop="projectCode" width="150" show-overflow-tooltip />
<el-table-column label="项目名称" prop="projectName" min-width="180" show-overflow-tooltip />
<el-table-column label="项目类型" prop="invoiceCategory" width="120" align="center">
<template #default="scope">
<dict-tag :options="invoice_category" :value="scope.row.invoiceCategory" />
</template>
</el-table-column>
<el-table-column label="提前开票标识" prop="earlyFlag" width="140" align="center">
<template #default="scope">
<dict-tag :options="early_flag" :value="scope.row.earlyFlag" />
</template>
</el-table-column>
<el-table-column label="发票类型" prop="invoiceType" width="120" align="center" />
<el-table-column label="本次开具金额" prop="issueAmount" width="140" align="right">
<template #default="scope">
{{ scope.row.issueAmount != null ? formatNumber(scope.row.issueAmount) + ' 元' : '-' }}
</template>
</el-table-column>
<el-table-column label="验收日期" prop="acceptanceDate" width="150" align="center">
<template #default="scope">
<span>{{ parseTime(scope.row.acceptanceDate, '{y}-{m}-{d}') || '-' }}</span>
</template>
</el-table-column>
<el-table-column label="开票状态" prop="invoiceStatus" width="130" align="center">
<template #default="scope">
<dict-tag :options="invoice_status" :value="scope.row.invoiceStatus" />
</template>
</el-table-column>
<el-table-column label="流程状态" prop="flowStatus" width="130" align="center">
<template #default="scope">
<dict-tag :options="wf_business_status" :value="scope.row.flowStatus" />
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="160" show-overflow-tooltip />
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<el-button size="default" type="primary" text @click="viewInvoice(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<el-empty v-if="!loadingInvoice && invoiceList.length === 0" description="暂无开票信息" class="empty-state" />
<pagination
v-show="invoiceTotal > 0"
:total="invoiceTotal"
v-model:page="invoiceQuery.pageNum"
v-model:limit="invoiceQuery.pageSize"
@pagination="loadInvoiceList"
class="pagination-wrapper"
/>
</div>
</div>
</el-tab-pane>
</el-tabs>
@ -151,6 +286,10 @@ import { getContractOrder } from '@/api/oa/erp/contractOrder';
import { getContractInfo } from '@/api/oa/erp/contractInfo';
import { ContractInfoVO } from '@/api/oa/erp/contractInfo/types';
import { ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
import { listProjectPurchase } from '@/api/oa/erp/projectPurchase';
import { ProjectPurchaseVO } from '@/api/oa/erp/projectPurchase/types';
import { listFinInvoiceInfo } from '@/api/oa/erp/finInvoiceInfo';
import { FinInvoiceInfoVO } from '@/api/oa/erp/finInvoiceInfo/types';
import { listWmsShippingBill } from '@/api/wms/wmsShippingBill';
import { WmsShippingBillVO } from '@/api/wms/wmsShippingBill/types';
import { getErpProjectPlanStageList } from '@/api/oa/erp/erpProjectPlanStage';
@ -162,8 +301,40 @@ const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
const { business_direction, contract_category, contract_type, contract_status, shipping_mode, shipping_status } = toRefs<any>(
proxy?.useDict('business_direction', 'contract_category', 'contract_type', 'contract_status', 'shipping_mode', 'shipping_status')
const {
business_direction,
contract_category,
contract_type,
contract_status,
shipping_mode,
shipping_status,
order_purchase_status,
order_delivery_status,
order_invoice_status,
project_purchase_status,
spare_flag,
wf_business_status,
invoice_status,
invoice_category,
early_flag
} = toRefs<any>(
proxy?.useDict(
'business_direction',
'contract_category',
'contract_type',
'contract_status',
'shipping_mode',
'shipping_status',
'order_purchase_status',
'order_delivery_status',
'order_invoice_status',
'project_purchase_status',
'spare_flag',
'wf_business_status',
'invoice_status',
'invoice_category',
'early_flag'
)
);
const projectId = computed(() => route.params.projectId as string | number | undefined);
@ -172,6 +343,8 @@ const contractInfo = ref<ContractInfoVO | null>(null);
const shippingList = ref<WmsShippingBillVO[]>([]);
const planStageList = ref<ErpProjectPlanStageForm[]>([]);
const paymentStageList = ref<PaymentStageVO[]>([]);
const purchaseList = ref<ProjectPurchaseVO[]>([]);
const invoiceList = ref<FinInvoiceInfoVO[]>([]);
const activeTab = ref('contract');
const loadedTabs = ref<Set<string>>(new Set(['contract']));
@ -179,9 +352,15 @@ const loadedTabs = ref<Set<string>>(new Set(['contract']));
const loadingContract = ref(false);
const loadingShipping = ref(false);
const loadingPayment = ref(false);
const loadingPurchase = ref(false);
const loadingInvoice = ref(false);
const shippingTotal = ref(0);
const shippingQuery = reactive({ pageNum: 1, pageSize: 10 });
const purchaseTotal = ref(0);
const purchaseQuery = reactive({ pageNum: 1, pageSize: 10, projectId: undefined as string | number | undefined });
const invoiceTotal = ref(0);
const invoiceQuery = reactive({ pageNum: 1, pageSize: 10, projectId: undefined as string | number | undefined, contractId: undefined as string | number | undefined });
/** 格式化数字 */
const formatNumber = (num: number) => {
@ -199,6 +378,29 @@ const handleViewShipping = (row: WmsShippingBillVO) => {
router.push({ path: '/shipping/wmsShippingBill/edit', query: { type: 'view', id: row.shippingBillId as string } });
};
/** 前往采购页面 */
const openPurchasePage = () => {
proxy?.$tab.openPage('/purchase/projectPurchase', '采购管理');
};
/** 查看采购信息 */
const viewPurchase = (row: ProjectPurchaseVO) => {
if (!row?.projectPurchaseId) return;
proxy?.$tab.openPage('/purchase/projectPurchase/edit', '采购信息', {
id: row.projectPurchaseId,
type: 'view'
});
};
/** 查看开票信息 */
const viewInvoice = (row: FinInvoiceInfoVO) => {
if (!row?.invoiceId) return;
proxy?.$tab.openPage('/fin/finInvoiceInfo/edit', '开票信息', {
id: row.invoiceId,
type: 'view'
});
};
/** 加载订单基本信息和合同信息 */
const loadOrderAndContract = async () => {
if (!projectId.value) return;
@ -217,6 +419,49 @@ const loadOrderAndContract = async () => {
}
};
/** 加载采购信息 */
const loadPurchaseList = async () => {
if (!projectId.value) {
purchaseList.value = [];
purchaseTotal.value = 0;
return;
}
loadingPurchase.value = true;
try {
const res: any = await listProjectPurchase({
...purchaseQuery,
projectId: projectId.value
});
purchaseList.value = res.rows || [];
purchaseTotal.value = res.total || 0;
} finally {
loadingPurchase.value = false;
}
};
/** 加载开票信息 */
const loadInvoiceList = async () => {
if (!projectId.value) {
invoiceList.value = [];
invoiceTotal.value = 0;
return;
}
// IDVOcontractIdID
const contractId = orderInfo.value?.contractId ?? contractInfo.value?.contractId;
invoiceQuery.projectId = contractId ? undefined : projectId.value;
invoiceQuery.contractId = contractId ? contractId : undefined;
loadingInvoice.value = true;
try {
const res: any = await listFinInvoiceInfo(invoiceQuery);
invoiceList.value = res.rows || [];
invoiceTotal.value = res.total || 0;
} finally {
loadingInvoice.value = false;
}
};
/** 加载发货信息 */
const loadShippingList = async () => {
if (!orderInfo.value?.contractId) {
@ -287,6 +532,15 @@ const handleTabChange = (tabName: string) => {
if (!loadedTabs.value.has(tabName)) {
loadedTabs.value.add(tabName);
switch (tabName) {
case 'invoice':
invoiceQuery.pageNum = 1;
loadInvoiceList();
break;
case 'purchase':
purchaseQuery.pageNum = 1;
purchaseQuery.projectId = projectId.value;
loadPurchaseList();
break;
case 'shipping':
shippingQuery.pageNum = 1;
loadShippingList();
@ -360,6 +614,37 @@ watch(
}
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #e4e7ed;
.header-left {
display: flex;
align-items: center;
gap: 10px;
.section-icon {
font-size: 16px;
color: #409eff;
}
.section-title {
font-size: 15px;
font-weight: 600;
color: #303133;
}
}
.header-actions {
display: flex;
gap: 8px;
}
}
.data-table {
:deep(.el-table__header) {
th {

Loading…
Cancel
Save