Files
geg-gas-web/src/views/erp/purchase/components/OrderInfoModal.vue
‘huanghaiixia’ 7377464207 提示英文优化
2026-03-27 14:59:14 +08:00

666 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<BasicModal v-bind="$attrs" @register="registerModal" title="查看订单详情" @cancel="handleCancel">
<div class="info-box">
<a-card :bordered="false">
<div class="title-name">{{ baseInfo?.theme }}</div>
<div class="title-info">
<span>创建人{{ baseInfo?.createUserName }}</span>
<span>创建时间{{ baseInfo?.createDate }}</span>
<span>最后修改人{{ baseInfo?.modifyUserName }}</span>
<span>修改时间{{ baseInfo?.modifyDate }}</span>
</div>
<div>
<a-button size="small" class="title-btn" @click="handlePrint">打印</a-button>
</div>
</a-card>
<a-card :bordered="false">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="订单信息">
<a-row>基础信息</a-row>
<a-row>
<a-col :span="12">采购单号{{ baseInfo?.purchaseNumber }}</a-col>
<a-col :span="12">订单主题{{ baseInfo?.theme }}</a-col>
</a-row>
<a-row>
<a-col :span="12">采购日期{{ baseInfo?.purchaseDate }}</a-col>
<a-col :span="12">供应商名称{{ baseInfo?.supplierName }}</a-col>
</a-row>
<a-row>
<a-col :span="12">联系人{{ baseInfo?.supplierPerson }}</a-col>
<a-col :span="12">联系方式{{ baseInfo?.supplierWay }}</a-col>
</a-row>
<a-row>
<a-col :span="12">采购部门{{ baseInfo?.purchaseDeptName }}</a-col>
<a-col :span="12">采购人员{{ baseInfo?.purchasePersonName }}</a-col>
</a-row>
<a-row>
<a-col :span="12">联系电话{{ baseInfo?.purchasePhone }}</a-col>
<a-col :span="12">关联项目{{ baseInfo?.relatedProjectName }}</a-col>
</a-row>
<a-row> 结算方式{{ baseInfo?.payTypeName }} </a-row>
<a-row> 交货地址{{ baseInfo?.payAddress }} </a-row>
<a-row> 备注{{ baseInfo?.remark }} </a-row>
<BasicTable @register="registerPurchaseTable">
<template #toolbar>
<a-button type="primary" @click="handleExport('purchase')">导出</a-button>
</template>
</BasicTable>
<div class="table-bottom">
<span>合计</span>
<div>
<span>总量{{ baseInfo?.countSum }}</span>
<span> 总金额{{ baseInfo?.amountSum }}</span>
</div>
</div>
<div>
附件
<Upload v-if="baseInfo?.filePath" v-model:value="baseInfo.filePath" listType="dragger" :style="{ width: '200px', display: 'none' }" :showRemoveIcon="false" />
</div>
</a-tab-pane>
<a-tab-pane key="2">
<template #tab>
<span>
入库记录
<Icon icon="ant-design:check-circle-filled" :size="20" v-if="baseInfo?.inStoreState === 1" />
<Icon icon="ant-design:exclamation-circle-filled" color="#FF1A2E" :size="20" v-else />
</span>
</template>
<BasicTable @register="registerInstoreTable">
<template #toolbar>
<a-button type="primary" @click="handleExport('instore')">导出</a-button>
</template>
</BasicTable>
</a-tab-pane>
<a-tab-pane key="3">
<template #tab>
<span>
到票记录
<Icon icon="ant-design:check-circle-filled" :size="20" v-if="baseInfo?.ticketState === 1" />
<Icon icon="ant-design:exclamation-circle-filled" color="#FF1A2E" :size="20" v-else />
</span>
</template>
<BasicTable @register="registerTicketTable">
<template #toolbar>
<a-button type="primary" @click="handleExport('ticket')">导出</a-button>
</template>
</BasicTable>
</a-tab-pane>
<a-tab-pane key="4">
<template #tab>
<span>
付款记录
<Icon icon="ant-design:check-circle-filled" :size="20" v-if="baseInfo?.payState === 1" />
<Icon icon="ant-design:exclamation-circle-filled" color="#FF1A2E" :size="20" v-else />
</span>
</template>
<BasicTable @register="registerPayTable">
<template #toolbar>
<a-button type="primary" @click="handleExport('pay')">导出</a-button>
</template>
</BasicTable>
</a-tab-pane>
<a-tab-pane key="5" tab="审批记录">
<FlowRecord v-if="isReady" :list="workflowList" :processInstanceId="baseInfo.processInstanceId" />
</a-tab-pane>
<a-tab-pane key="6" tab="操作记录">
<BasicTable @register="registerLogTable">
<template #toolbar>
<a-button type="primary" @click="handleExport('log')">导出</a-button>
</template>
</BasicTable>
</a-tab-pane>
</a-tabs>
</a-card>
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { BasicTable, useTable, BasicColumn, FormSchema } from '/@/components/Table';
import { BasicModal, useModalInner } from '/@/components/Modal';
import { exportPurchaseInfo, exportInstoreInfo, exportTicketInfo, exportPayInfo, exportLogInfo } from '/@/api/erp/purchase/order';
import { getPurchaseCheckInfo } from '/@/api/erp/purchase/order';
import { getRecordList } from '/@/api/erp/purchase/order';
import { getFileList } from '/@/api/system/file';
import { useMessage } from '/@/hooks/web/useMessage';
import { downloadByData } from '/@/utils/file/download';
import FlowRecord from '/@/views/workflow/task/components/flow/FlowRecord.vue';
import Icon from '/@/components/Icon/index';
import Upload from '/@/components/Form/src/components/Upload.vue';
import printJS from 'print-js';
import domtoimage from 'dom-to-image';
import { isNil } from 'lodash-es';
const purchaseColumns: BasicColumn[] = [
{
title: '物料编码',
dataIndex: 'code'
},
{
title: '物料名称',
dataIndex: 'name'
},
{
title: '规格型号',
dataIndex: 'model'
},
{
title: '单位',
dataIndex: 'unitName'
},
{
title: '单价',
dataIndex: 'price'
},
{
title: '采购数量',
dataIndex: 'count'
},
{
title: '折扣',
dataIndex: 'discount'
},
{
title: '税率',
dataIndex: 'taxRate'
},
{
title: '税费',
dataIndex: 'taxBreak'
},
{
title: '税后金额',
dataIndex: 'afterTaxAmount'
},
{
title: '已入库数量',
dataIndex: 'inStoreCount'
},
{
title: '未入库数量',
dataIndex: 'noInStoreCount'
},
{
title: '退货数量',
dataIndex: 'returnCount'
},
{
title: '交付日期',
dataIndex: 'deliveryDate'
}
];
const instoreColumns: BasicColumn[] = [
{
dataIndex: 'code',
title: '入库单号',
align: 'center',
width: 100
},
{
dataIndex: 'theme',
title: '入库订单主题',
align: 'center',
width: 100
},
{
dataIndex: 'date',
title: '入库日期',
align: 'center',
width: 100
},
{
dataIndex: 'name',
title: '供应商名称',
align: 'center',
width: 100
},
{
dataIndex: 'person',
title: '入库人员',
align: 'center',
width: 100
},
{
dataIndex: 'store',
title: '入库仓库',
align: 'center',
width: 100
}
];
const ticketColumns: BasicColumn[] = [
{
dataIndex: 'code',
title: '到票编号',
align: 'center',
width: 100
},
{
dataIndex: 'theme',
title: '到票主题',
align: 'center',
width: 100
},
{
dataIndex: 'date',
title: '到票日期',
align: 'center',
width: 100
},
{
dataIndex: 'name',
title: '开票方',
align: 'center',
width: 100
},
{
dataIndex: 'ticketNum',
title: '发票号码',
align: 'center',
width: 100
},
{
dataIndex: 'ticketAmout',
title: '到票金额',
align: 'center',
width: 100
}
];
const payColumns: BasicColumn[] = [
{
dataIndex: 'code',
title: '付款编号',
align: 'center',
width: 100
},
{
dataIndex: 'theme',
title: '付款主题',
align: 'center',
width: 100
},
{
dataIndex: 'date',
title: '付款日期',
align: 'center',
width: 100
},
{
dataIndex: 'amount',
title: '付款总额',
align: 'center',
width: 100
},
{
dataIndex: 'payer',
title: '收款方',
align: 'center',
width: 100
},
{
dataIndex: 'account',
title: '银行账号',
align: 'center',
width: 100
}
];
const logColumns: BasicColumn[] = [
{
dataIndex: 'operateUserAccount',
title: '操作人',
align: 'center'
},
{
dataIndex: 'createDate',
title: '操作时间',
align: 'center'
},
{
dataIndex: 'executeResultJson',
title: '操作类型',
align: 'center'
}
];
const searchFormSchema: FormSchema[] = [
{
field: 'keyword',
label: '',
component: 'Input',
colProps: { span: 8 },
componentProps: {
placeholder: '请输入要查询的关键字'
}
}
];
const purchaseInfoDataSource = ref<any>([]);
const instoreDataSource = ref<any>([]);
const ticketDataSource = ref<any>([]);
const payDataSource = ref<any>([]);
const logInfoDataSource = ref<any>([]);
const isReady = ref(false);
const rowId = ref('');
const activeKey = ref('1');
const baseInfo = ref();
const workflowList = ref();
const imgList = ref<any>([]);
const { notification } = useMessage();
const [registerModal, { setModalProps }] = useModalInner(async (data) => {
setModalProps({
confirmLoading: false,
destroyOnClose: true,
showCancelBtn: false,
showOkBtn: false,
width: 1000,
fixedHeight: true,
footer: null
});
rowId.value = data.id;
getInfo();
});
const [registerPurchaseTable, { getSelectRowKeys: getPurchaseRowKeys }] = useTable({
title: '采购物料',
dataSource: purchaseInfoDataSource,
rowKey: 'id',
columns: purchaseColumns,
bordered: true,
pagination: false,
rowSelection: {
type: 'checkbox'
}
});
const [registerInstoreTable, { getSelectRowKeys: getInstoreRowKeys, setProps: setInstoreProps }] = useTable({
dataSource: instoreDataSource,
rowKey: 'id',
columns: instoreColumns,
handleSearchInfoFn(info) {
const filterData = instoreDataSource.value.filter((item) => {
for (const key in item) {
if (!isNil(item[key]) && item[key].toString().indexOf(info.keyword) > -1) {
return item;
}
}
});
setInstoreProps({ dataSource: filterData });
return info;
},
formConfig: {
schemas: searchFormSchema
},
bordered: true,
pagination: false,
useSearchForm: true,
rowSelection: {
type: 'checkbox'
}
});
const [registerTicketTable, { getSelectRowKeys: getTicketRowKeys, setProps: setTicketProps }] = useTable({
dataSource: ticketDataSource,
rowKey: 'id',
columns: ticketColumns,
handleSearchInfoFn(info) {
const filterData = ticketDataSource.value.filter((item) => {
for (const key in item) {
if (!isNil(item[key]) && item[key].toString().indexOf(info.keyword) > -1) {
return item;
}
}
});
setTicketProps({ dataSource: filterData });
return info;
},
formConfig: {
schemas: searchFormSchema
},
bordered: true,
pagination: false,
useSearchForm: true,
rowSelection: {
type: 'checkbox'
}
});
const [registerPayTable, { getSelectRowKeys: getPayRowKeys, setProps: setPayProps }] = useTable({
dataSource: payDataSource,
rowKey: 'id',
columns: payColumns,
handleSearchInfoFn(info) {
const filterData = payDataSource.value.filter((item) => {
for (const key in item) {
if (!isNil(item[key]) && item[key].toString().indexOf(info.keyword) > -1) {
return item;
}
}
});
setPayProps({ dataSource: filterData });
return info;
},
formConfig: {
schemas: searchFormSchema
},
bordered: true,
pagination: false,
useSearchForm: true,
rowSelection: {
type: 'checkbox'
}
});
const [registerLogTable, { getSelectRowKeys: getLogRowKeys, setProps: setLogProps }] = useTable({
dataSource: logInfoDataSource,
rowKey: 'id',
columns: logColumns,
handleSearchInfoFn(info) {
const filterData = logInfoDataSource.value.filter((item) => {
for (const key in item) {
if (!isNil(item[key]) && item[key].toString().indexOf(info.keyword) > -1) {
return item;
}
}
});
setLogProps({ dataSource: filterData });
return info;
},
formConfig: {
schemas: searchFormSchema
},
useSearchForm: true,
bordered: true,
pagination: false,
rowSelection: {
type: 'checkbox'
}
});
const getInfo = async () => {
const res = await getPurchaseCheckInfo(rowId.value);
baseInfo.value = res;
purchaseInfoDataSource.value = res?.caseErpPurchaseDetailList;
instoreDataSource.value = res?.inStoreLogVoList.map((x) => {
return {
code: x.code,
theme: x.theme,
date: x.date,
name: x.name,
person: x.person,
store: x.store
};
});
ticketDataSource.value = res?.ticketLogVoList.map((x) => {
return {
code: x.code,
theme: x.theme,
date: x.date,
name: x.name,
ticketNum: x.ticketNum,
ticketAmout: x.ticketAmout
};
});
payDataSource.value = res?.payLogVoList.map((x) => {
return {
code: x.code,
theme: x.theme,
date: x.date,
amount: x.amount,
payer: x.payer,
account: x.account
};
});
logInfoDataSource.value = res?.logList.map((x) => {
return {
operateUserAccount: x.operateUserAccount,
createDate: x.createDate,
executeResultJson: x.executeResultJson
};
});
if (baseInfo.value.processInstanceId) {
const res = await getRecordList(baseInfo.value.processInstanceId);
workflowList.value = [
{
records: res.taskRecords,
schemaName: '当前流程'
}
];
}
isReady.value = true;
if (baseInfo.value.filePath) {
imgList.value = await getFileList({ tableId: baseInfo.value.filePath });
}
};
const handleCancel = () => {
isReady.value = false;
workflowList.value = [];
activeKey.value = '1';
};
const handleExport = async (type) => {
const params: any = {
saleId: rowId.value
};
let title = '';
let res;
switch (type) {
case 'purchase':
if (!notice(getPurchaseRowKeys().length)) return;
title = '采购信息';
params.ids = getPurchaseRowKeys();
res = await exportPurchaseInfo(params);
break;
case 'instore':
if (!notice(getInstoreRowKeys().length)) return;
title = '入库记录';
params.ids = getInstoreRowKeys();
res = await exportInstoreInfo(params);
break;
case 'ticket':
if (!notice(getTicketRowKeys().length)) return;
title = '到票记录';
params.ids = getTicketRowKeys();
res = await exportTicketInfo(params);
break;
case 'pay':
if (!notice(getPayRowKeys().length)) return;
title = '付款记录';
params.ids = getPayRowKeys();
res = await exportPayInfo(params);
break;
case 'log':
title = '操作记录';
params.ids = getLogRowKeys();
res = await exportLogInfo(params);
break;
}
downloadByData(res.data, `${title}.xlsx`, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
};
const notice = (length) => {
if (!length) {
notification.warning({
message: '提示',
description: '请选择需要导出的数据'
});
return false;
}
return true;
};
const handlePrint = async () => {
const element: HTMLElement = window.document.querySelector('.info-box')!;
const url = await domtoimage.toPng(element);
printJS({
printable: url,
type: 'image',
documentTitle: '打印'
});
};
</script>
<style lang="less" scoped>
.info-box {
background-color: #fff;
width: 100%;
height: 100%;
padding: 16px;
margin-right: 8px;
.title-name {
font-size: 18px;
color: #444;
font-weight: 700;
}
.title-info {
margin: 10px 0;
span {
margin-right: 40px;
}
}
.table-bottom {
display: flex;
justify-content: space-between;
margin: 10px 0;
& > div > span {
margin-left: 40px;
}
}
.title-btn {
margin-right: 5px;
}
}
.ant-row {
margin-bottom: 15px;
}
:deep(.vben-basic-table) {
height: 300px;
}
:deep(.ant-table-wrapper),
:deep(.ant-table-title) {
background-color: #f8f8f8;
}
:deep(.ant-card-body) {
background-color: #f8f8f8;
margin-bottom: 12px;
padding: 15px;
}
:deep(.ant-tabs) {
height: 70%;
}
:deep(.ant-tabs-content) {
height: 100%;
}
</style>