|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="p-2">
|
|
|
|
|
|
<el-card shadow="never" style="margin-top: 0">
|
|
|
|
|
|
<!-- 审批按钮组件 -->
|
|
|
|
|
|
<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" :disabled="isFormDisabled">
|
|
|
|
|
|
<el-row :gutter="20">
|
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
|
<el-form-item label="机票预订编号" prop="applyCode">
|
|
|
|
|
|
<el-input v-model="form.applyCode" placeholder="请输入机票预订编号">
|
|
|
|
|
|
<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="passengerId">
|
|
|
|
|
|
<el-select v-model="form.passengerId" placeholder="请选择乘机人" filterable>
|
|
|
|
|
|
<el-option v-for="item in userInfoList" :key="item.userId" :label="item.nickName" :value="item.userId" />
|
|
|
|
|
|
</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="flightBooking" lang="ts">
|
|
|
|
|
|
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 { getFlightBooking, delFlightBooking, addFlightBooking, updateFlightBooking, submitAndFlowStart } 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: {
|
|
|
|
|
|
passengerId: [{ required: true, message: '乘机人ID不能为空', trigger: 'blur' }],
|
|
|
|
|
|
applyCode: [{ required: true, message: '机票编码不能为空', 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: 1016 } 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('机票编号生成成功');
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
watch(
|
|
|
|
|
|
() => form.value.passengerId, // 监听 passengerId
|
|
|
|
|
|
(newPassengerId) => {
|
|
|
|
|
|
if (newPassengerId && userInfoList.value.length > 0) {
|
|
|
|
|
|
// 在用户列表中查找对应的用户
|
|
|
|
|
|
const selectedUser = userInfoList.value.find((user) => user.userId === newPassengerId);
|
|
|
|
|
|
if (selectedUser) {
|
|
|
|
|
|
// 自动设置 passengerName
|
|
|
|
|
|
form.value.passengerName = selectedUser.nickName;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
// 如果 passengerId 为空,清空 passengerName
|
|
|
|
|
|
form.value.passengerName = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{ immediate: true } // 立即执行一次,用于编辑模式的数据回显
|
|
|
|
|
|
);
|
|
|
|
|
|
/** 提交按钮 */
|
|
|
|
|
|
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 = {
|
|
|
|
|
|
flightDiscount: form.value.flightDiscount
|
|
|
|
|
|
};
|
|
|
|
|
|
// 流程实例业务扩展字段
|
|
|
|
|
|
form.value.bizExt = {
|
|
|
|
|
|
businessTitle: '机票预订',
|
|
|
|
|
|
businessCode: form.value.applyCode
|
|
|
|
|
|
};
|
|
|
|
|
|
form.value.flowStatus = 'waiting';
|
|
|
|
|
|
form.value.bookingStatus = '2';
|
|
|
|
|
|
const res = await submitAndFlowStart(form.value).finally(() => (buttonLoading.value = false));
|
|
|
|
|
|
form.value = res.data;
|
|
|
|
|
|
proxy?.$modal.msgSuccess('操作成功');
|
|
|
|
|
|
proxy?.$tab.closePage();
|
|
|
|
|
|
router.go(-1);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
form.value.flowStatus = 'draft';
|
|
|
|
|
|
form.value.bookingStatus = '1';
|
|
|
|
|
|
|
|
|
|
|
|
if (form.value.bookingId) {
|
|
|
|
|
|
await updateFlightBooking(form.value).finally(() => (buttonLoading.value = false));
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await addFlightBooking(form.value).finally(() => (buttonLoading.value = false));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
proxy?.$modal.msgSuccess('暂存成功');
|
|
|
|
|
|
proxy?.$tab.closePage();
|
|
|
|
|
|
router.go(-1);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
buttonLoading.value = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
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 getFlightBooking(id);
|
|
|
|
|
|
Object.assign(form.value, res.data);
|
|
|
|
|
|
|
|
|
|
|
|
proxy?.$modal.closeLoading();
|
|
|
|
|
|
// 编辑模式:如果已有合同编号,禁用生成按钮
|
|
|
|
|
|
if (form.value.applyCode) {
|
|
|
|
|
|
isCodeGenerated.value = true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
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>
|