feat(contract): 添加合同审批单导出word功能

- 新增 exportContractApprovalWord API 接口用于导出合同审批单Word文档
- 在合同信息表格中增加审批单导出按钮,当合同状态为3时显示
- 扩展操作列宽度以容纳新增按钮
- 实现 handleExportApprovalWord 方法处理审批单导出逻辑
- 添加文件下载和错误处理机制
- 优化类型定义文件格式
dev
zangch@mesnac.com 1 week ago
parent c862a2860b
commit 5d76ed6d78

@ -1,6 +1,6 @@
import request from '@/utils/request'; import request from '@/utils/request';
import { AxiosPromise } from 'axios'; import { AxiosPromise } from 'axios';
import { ContractInfoVO, ContractInfoForm, ContractInfoQuery } from '@/api/oa/erp/contractInfo/types'; import { ContractInfoForm, ContractInfoQuery, ContractInfoVO } from '@/api/oa/erp/contractInfo/types';
/** /**
* *
@ -86,3 +86,15 @@ export const contractSubmitAndFlowStart = (data: ContractInfoForm): AxiosPromise
data: data data: data
}); });
}; };
/**
* Word
* @param contractId ID
*/
export const exportContractApprovalWord = (contractId: string | number) => {
return request({
url: '/oa/erp/contractInfo/exportApprovalWord/' + contractId,
method: 'get',
responseType: 'blob'
});
};

@ -432,7 +432,6 @@ export interface ContractInfoForm extends BaseEntity {
} }
export interface ContractInfoQuery extends PageQuery { export interface ContractInfoQuery extends PageQuery {
/** /**
* 1 2 * 1 2
*/ */
@ -603,6 +602,3 @@ export interface ContractInfoQuery extends PageQuery {
*/ */
params?: any; params?: any;
} }

@ -187,7 +187,7 @@
<span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span> <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="200" fixed="right" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" width="240" fixed="right" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="查看详情" placement="top" v-if="canViewDetail(scope.row)"> <el-tooltip content="查看详情" placement="top" v-if="canViewDetail(scope.row)">
<el-button link type="info" icon="DocumentChecked" @click="handleView(scope.row)"></el-button> <el-button link type="info" icon="DocumentChecked" @click="handleView(scope.row)"></el-button>
@ -201,22 +201,20 @@
<el-tooltip content="合同模板" placement="top" v-if="scope.row.templateId != null"> <el-tooltip content="合同模板" placement="top" v-if="scope.row.templateId != null">
<el-button link type="info" icon="Download" @click="contractView(scope.row)"></el-button> <el-button link type="info" icon="Download" @click="contractView(scope.row)"></el-button>
</el-tooltip> </el-tooltip>
<!-- <el-tooltip content="合同激活" placement="top" v-if="showUploadButton(scope.row)">--> <el-tooltip content="审批单导出" placement="top" v-if="scope.row.contractStatus == 3">
<!-- <el-button--> <el-button link type="primary" icon="Tickets" @click="handleExportApprovalWord(scope.row)"></el-button>
<!-- link--> </el-tooltip>
<!-- type="success"--> <!-- <el-tooltip content="合同激活" placement="top" v-if="showUploadButton(scope.row)">-->
<!-- icon="Upload"--> <!-- <el-button-->
<!-- @click="openUploadFinalDialog(scope.row)"--> <!-- link-->
<!-- v-hasPermi="['oa/erp:contractInfo:edit']"--> <!-- type="success"-->
<!-- ></el-button>--> <!-- icon="Upload"-->
<!-- </el-tooltip>--> <!-- @click="openUploadFinalDialog(scope.row)"-->
<!-- v-hasPermi="['oa/erp:contractInfo:edit']"-->
<!-- ></el-button>-->
<!-- </el-tooltip>-->
<el-tooltip content="合同订单激活" placement="top" v-if="canActivateOrder(scope.row)"> <el-tooltip content="合同订单激活" placement="top" v-if="canActivateOrder(scope.row)">
<el-button <el-button link type="warning" icon="CircleCheck" @click="handleOrderActivate(scope.row)"></el-button>
link
type="warning"
icon="CircleCheck"
@click="handleOrderActivate(scope.row)"
></el-button>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
@ -229,8 +227,7 @@
<el-form ref="uploadFormRef" :model="uploadDialog.form" :rules="uploadFormRules" label-width="120px"> <el-form ref="uploadFormRef" :model="uploadDialog.form" :rules="uploadFormRules" label-width="120px">
<el-form-item label="部门" prop="contractDeptId" required> <el-form-item label="部门" prop="contractDeptId" required>
<el-select v-model="uploadDialog.form.contractDeptId" placeholder="请选择部门" style="width: 100%"> <el-select v-model="uploadDialog.form.contractDeptId" placeholder="请选择部门" style="width: 100%">
<el-option v-for="item in deptInfoList" :key="item.deptId" :label="item.deptName" <el-option v-for="item in deptInfoList" :key="item.deptId" :label="item.deptName" :value="item.deptId" />
:value="item.deptId" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="签字合同附件" prop="oss" required> <el-form-item label="签字合同附件" prop="oss" required>
@ -282,9 +279,8 @@
</template> </template>
<script setup name="ContractInfo" lang="ts"> <script setup name="ContractInfo" lang="ts">
import { listContractInfo, delContractInfo } from '@/api/oa/erp/contractInfo'; import { delContractInfo, exportContractApprovalWord, listContractInfo, updateContractInfo } from '@/api/oa/erp/contractInfo';
import { ContractInfoVO, ContractInfoQuery } from '@/api/oa/erp/contractInfo/types'; import { ContractInfoQuery, ContractInfoVO } from '@/api/oa/erp/contractInfo/types';
import { updateContractInfo } from '@/api/oa/erp/contractInfo';
import download from '@/plugins/download'; import download from '@/plugins/download';
import ApprovalRecord from '@/components/Process/approvalRecord.vue'; import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import { allListDept } from '@/api/system/dept'; import { allListDept } from '@/api/system/dept';
@ -293,7 +289,15 @@ const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const { contract_category, business_direction, active_flag, contract_flag, contract_type, contract_status, contract_template_flag } = toRefs<any>( const { contract_category, business_direction, active_flag, contract_flag, contract_type, contract_status, contract_template_flag } = toRefs<any>(
proxy?.useDict('contract_category', 'business_direction', 'active_flag', 'contract_flag', 'contract_type', 'contract_status', 'contract_template_flag') proxy?.useDict(
'contract_category',
'business_direction',
'active_flag',
'contract_flag',
'contract_type',
'contract_status',
'contract_template_flag'
)
); );
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>(); const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
@ -531,6 +535,26 @@ const handleExport = () => {
); );
}; };
const handleExportApprovalWord = async (row: ContractInfoVO) => {
try {
const res = await exportContractApprovalWord(row.contractId);
const blob = new Blob([res as BlobPart], {
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
});
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `合同审批单_${row.contractCode || row.contractId}.docx`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
proxy?.$modal.msgSuccess('审批单导出成功');
} catch (error) {
proxy?.$modal.msgError('审批单导出失败,请检查合同状态或模板配置');
}
};
onMounted(() => { onMounted(() => {
getList(); getList();
getDeptInfoListSelect(); getDeptInfoListSelect();
@ -647,11 +671,7 @@ const canActivateOrder = (row: ContractInfoVO) => {
/** 判断是否可以激活合同订单上传终版合同附件 */ /** 判断是否可以激活合同订单上传终版合同附件 */
const showUploadButton = (row: ContractInfoVO) => { const showUploadButton = (row: ContractInfoVO) => {
return ( return !row.signatureAppendix && row.contractStatus === '3' && row.contractCategory === '1';
!row.signatureAppendix &&
row.contractStatus === '3' &&
row.contractCategory === '1'
)
}; };
/** 订单激活按钮操作 */ /** 订单激活按钮操作 */
@ -662,7 +682,7 @@ const handleOrderActivate = (row?: ContractInfoVO) => {
path: '/contract/contractInfo/orderActivate', path: '/contract/contractInfo/orderActivate',
query: { query: {
contractId: _contractId, contractId: _contractId,
type: 'add', type: 'add'
} }
}); });
}; };

@ -511,6 +511,7 @@ const isCurrentTaskBusinessMatched = computed(() => {
const taskBusinessId = String(currentTask.value?.businessId || '').trim(); const taskBusinessId = String(currentTask.value?.businessId || '').trim();
const shippingBillId = String(form.value.shippingBillId || '').trim(); const shippingBillId = String(form.value.shippingBillId || '').trim();
if (!taskBusinessId) { if (!taskBusinessId) {
// businessId
return true; return true;
} }
return taskBusinessId === shippingBillId; return taskBusinessId === shippingBillId;

Loading…
Cancel
Save