You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

383 lines
14 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="p-2">
<el-card shadow="never" style="margin-top: 0">
<!-- <template #header>-->
<!-- <div style="text-align: left; font-weight: bold; font-size: 24px">合同{{ form.contractId ? ' - 修改' : ' - 新增' }}</div>-->
<!-- </template>-->
<!-- 审批按钮组件 -->
<approvalButton
@submitForm="submitForm"
@approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="form.bookingId"
:status="form.flowStatus"
:pageType="routeParams.type"
:mode="false"
/>
</el-card>
<el-card shadow="never" style="margin-top: 0">
<el-form ref="flightBookingFormRef" :model="form" :loading="buttonLoading" :rules="rules" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="机票预订编号" prop="applyCode">
<el-input v-model="form.applyCode" placeholder="请输入机票预订编号" :disabled="isFormDisabled">
<template #append>
<el-button type="primary" @click="generateContractCode" :disabled="isCodeGenerated">生成机票预订编号 </el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<!-- <el-form-item label="乘机人姓名" prop="passengerName">
<el-input v-model="form.passengerName" placeholder="请输入乘机人姓名" />
</el-form-item> -->
<el-form-item label="乘机人姓名" prop="passengerName">
<el-select v-model="queryParams.passengerName" placeholder="请选择乘机人" filterable>
<el-option v-for="item in userInfoList" :key="item.userId" :label="item.nickName" :value="item.nickName" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出行日期" prop="travelDate">
<el-date-picker clearable v-model="form.travelDate" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择出行日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="出发地点" prop="departureLocation">
<el-input v-model="form.departureLocation" placeholder="请输入出发地点" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="到达地点" prop="arrivalLocation">
<el-input v-model="form.arrivalLocation" placeholder="请输入到达地点" />
</el-form-item>
</el-col>
<el-col :span="12">
<!-- <el-form-item label="机票折扣" prop="flightDiscount">
<el-input v-model="form.flightDiscount" placeholder="请输入机票折扣" />
</el-form-item> -->
<el-form-item label="机票折扣" prop="flightDiscount">
<el-select v-model="form.flightDiscount" placeholder="请选择机票折扣">
<el-option v-for="dict in flight_discount" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="机票金额" prop="flightAmount">
<el-input v-model="form.flightAmount" placeholder="请输入机票金额" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="附件" prop="ossId">
<FileUpload
v-model="ossIdString"
:limit="5"
:fileSize="20"
:fileType="['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx', 'xls', 'xlsx']"
:isShowTip="true"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="乘机人ID" prop="passengerId" v-show="false">
<el-input v-model="form.passengerId" placeholder="请输入乘机人ID" />
</el-form-item>
<el-form-item label="机票ID" prop="bookingId" v-show="false">
<el-input v-model="form.bookingId" placeholder="请输入机票ID" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 提交审批组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<!-- 审批记录 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="ContractInfoEdit" lang="ts">
import { addContractInfo, contractSubmitAndFlowStart, getContractInfo, updateContractInfo } from '@/api/oa/erp/contractInfo';
import { ContractInfoForm } from '@/api/oa/erp/contractInfo/types';
import { getRuleGenerateCode } from '@/api/system/codeRule';
import { startWorkFlow } from '@/api/workflow/task';
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import ApprovalButton from '@/components/Process/approvalButton.vue';
import { ref } from 'vue';
import { getUserList } from '@/api/system/user';
import { CodeRuleEnum, FlowCodeEnum } from '@/enums/OAEnum';
import { getInfo } from '@/api/login';
import FileUpload from '@/components/FileUpload/index.vue';
import { listFlightBooking, getFlightBooking, delFlightBooking, addFlightBooking, updateFlightBooking } from '@/api/oa/crm/flightBooking';
import { FlightBookingVO, FlightBookingQuery, FlightBookingForm } from '@/api/oa/crm/flightBooking/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
//
const routeParams = ref<Record<string, any>>({});
const { flight_discount } = toRefs<any>(proxy?.useDict('flight_discount'));
const buttonLoading = ref(false);
// 审批相关组件引用
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
// 流程相关数据
const submitFormData = ref<StartProcessBo>({
businessId: '',
flowCode: 'JPYD',
variables: {},
bizExt: {}
});
// 任务变量
const taskVariables = ref<Record<string, any>>({});
const flowInstanceBizExtBo = ref<Record<string, any>>({});
const type = ref(0);
// 合同编号生成状态
const isCodeGenerated = ref(false);
/** 查询用户信息下拉框结构 */
const userInfoList = ref([]);
const getUserInfoListSelect = async () => {
const res = await getUserList({ pageNum: 1, pageSize: 1000 });
userInfoList.value = res.data;
};
// 判断表单是否禁用(查看或审批模式)
const isFormDisabled = computed(() => {
return routeParams.value.type === 'view' || routeParams.value.type === 'approval';
});
// 附件ID字符串转换用于FileUpload组件
const ossIdString = computed({
get() {
const v = form.value.ossId as any;
return v === undefined || v === null ? '' : String(v);
},
set(val: string) {
form.value.ossId = val || (undefined as any);
}
});
const initFormData: FlightBookingForm = {
bookingId: undefined,
applyCode: undefined,
passengerId: undefined,
passengerName: undefined,
travelDate: undefined,
departureLocation: undefined,
arrivalLocation: undefined,
flightDiscount: undefined,
flightAmount: undefined,
ossId: undefined,
bookingStatus: undefined,
flowStatus: undefined,
remark: undefined
};
const data = reactive<PageData<FlightBookingForm, FlightBookingQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
applyCode: undefined,
passengerId: undefined,
passengerName: undefined,
travelDate: undefined,
departureLocation: undefined,
arrivalLocation: undefined,
flightDiscount: undefined,
flightAmount: undefined,
ossId: undefined,
bookingStatus: undefined,
flowStatus: undefined,
params: {}
},
rules: {
bookingId: [{ required: true, message: '机票预订ID不能为空', trigger: 'blur' }],
passengerId: [{ required: true, message: '乘机人ID不能为空', trigger: 'blur' }],
travelDate: [{ required: true, message: '出行日期不能为空', trigger: 'blur' }],
departureLocation: [{ required: true, message: '出发地点不能为空', trigger: 'blur' }],
arrivalLocation: [{ required: true, message: '到达地点不能为空', trigger: 'blur' }],
flightDiscount: [{ required: true, message: '机票折扣不能为空', trigger: 'blur' }],
flightAmount: [{ required: true, message: '机票金额不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
const flightBookingFormRef = ref<ElFormInstance>();
// 生成合同编号
const generateContractCode = async () => {
if (isCodeGenerated.value) return; // 如果已经生成过,直接返回
try {
const params = { codeRuleCode: CodeRuleEnum.CONTRACT } as any;
const res = await getRuleGenerateCode(params);
form.value.applyCode = res.msg;
isCodeGenerated.value = true; // 标记为已生成
proxy?.$modal.msgSuccess('合同编号生成成功');
} catch (error) {
console.error('生成合同编号失败:', error);
proxy?.$modal.msgError('生成合同编号失败');
}
};
/** 提交按钮 */
const submitForm = (status: string, mode: boolean) => {
try {
buttonLoading.value = true;
flightBookingFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
// 设置后端发起和不等于草稿状态 直接走流程发起
if (status != 'draft') {
// 后端发起流程模式
form.value.flowCode = FlowCodeEnum.FLIGHT_BOOKING_CODE;
// 流程变量
form.value.variables = {
contractName: form.value.contractName,
totalPrice: form.value.totalPrice,
businessDirection: form.value.businessDirection,
contractCode: form.value.contractCode
};
// 流程实例业务扩展字段
form.value.bizExt = {
businessTitle: '合同审批',
businessCode: form.value.contractCode
};
form.value.contractStatus = '2';
form.value.flowStatus = 'waiting';
const res = await contractSubmitAndFlowStart(form.value).finally(() => (buttonLoading.value = false));
form.value = res.data;
proxy?.$modal.msgSuccess('操作成功');
proxy?.$tab.closePage();
router.go(-1);
} else {
if (status === 'draft') {
form.value.contractStatus = '1';
form.value.flowStatus = 'draft';
}
if (form.value.contractId) {
await updateContractInfo(form.value).finally(() => (buttonLoading.value = false));
} else {
await addContractInfo(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('暂存成功');
proxy?.$tab.closePage();
router.go(-1);
}
}
});
} finally {
buttonLoading.value = false;
}
};
// 提交申请
const handleStartWorkFlow = async (data: ContractInfoForm) => {
try {
submitFormData.value.flowCode = 'OAC';
submitFormData.value.businessId = data.contractId;
// 流程变量
taskVariables.value = {
contractId: data.contractId,
contractName: data.contractName,
totalPrice: data.totalPrice,
businessDirection: data.businessDirection,
contractCode: data.contractCode
};
// 流程实例业务扩展字段
flowInstanceBizExtBo.value = {
businessTitle: '合同审批',
businessCode: data.contractCode
};
submitFormData.value.variables = taskVariables.value;
submitFormData.value.bizExt = flowInstanceBizExtBo.value;
const resp = await startWorkFlow(submitFormData.value);
if (submitVerifyRef.value) {
buttonLoading.value = false;
await submitVerifyRef.value.openDialog(resp.data.taskId);
}
} finally {
buttonLoading.value = false;
router.go(-1);
}
};
onMounted(async () => {
nextTick(async () => {
// 获取路由参数
getUserInfoListSelect();
routeParams.value = route.query;
const id = routeParams.value.id as string | number;
if (id && (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval')) {
proxy?.$modal.loading('正在加载数据,请稍后...');
const res = await getContractInfo(id);
Object.assign(form.value, res.data);
proxy?.$modal.closeLoading();
// 编辑模式:如果已有合同编号,禁用生成按钮
if (form.value.contractCode) {
isCodeGenerated.value = true;
} else if (form.value.contractFlag === '1') {
// 如果有合同但没有编号,允许生成
isCodeGenerated.value = false;
}
} else {
// 新增模式获取登录用户部门ID并自动赋值
try {
const userInfoRes = await getInfo();
if (userInfoRes.data?.user?.deptId && !form.value.contractDeptId) {
form.value.contractDeptId = userInfoRes.data.user.deptId;
}
form.value.contractCategory = routeParams.value.contractCategory as string;
} catch (error) {
console.error('获取用户信息失败:', error);
}
// 新增模式:如果已有合同编号,禁用生成按钮
if (form.value.contractCode) {
isCodeGenerated.value = true;
} else if (form.value.contractFlag === '1') {
// 如果有合同但没有编号,允许生成
isCodeGenerated.value = false;
}
}
});
});
// 审批记录
const handleApprovalRecord = () => {
approvalRecordRef.value.init(form.value.bookingId);
};
// 提交回调
const submitCallback = async () => {
await proxy.$tab.closePage(route);
router.go(-1);
};
// 审批
const approvalVerifyOpen = async () => {
await submitVerifyRef.value.openDialog(routeParams.value.taskId);
};
</script>