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.

342 lines
11 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">
<approvalButton
@submitForm="submitForm"
@approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="form.acceptanceId"
:status="form.flowStatus"
:pageType="routeParams.type"
:mode="false"
/>
</el-card>
<el-card shadow="never" style="margin-top: 0">
<el-form ref="formRef" :model="form" :disabled="formDisabled" :rules="rules" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="验收确认编号" prop="acceptanceCode">
<el-input v-model="form.acceptanceCode" placeholder="由系统自动生成" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请选择项目" readonly :disabled="routeParams.type !== 'add'">
<template #suffix>
<el-icon v-if="routeParams.type === 'add'" style="cursor: pointer" @click="openProjectSelect">
<Search />
</el-icon>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="form.projectCode" placeholder="自动带出" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目经理" prop="managerId">
<el-input v-model="form.projectManagerName" placeholder="自动带出" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="验收日期" prop="acceptanceDate">
<el-date-picker
v-model="form.acceptanceDate"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择验收日期"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="验收单附件" prop="ossId">
<FileUpload v-model="ossIdString" :limit="5" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门负责人" prop="chargeId">
<el-input v-model="form.chargeName" placeholder="自动带出" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分管副总" prop="deputyId">
<el-input v-model="form.deputyName" placeholder="自动带出" disabled />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="确认该项目达到客户验收节点,可以进行发货款收取(如设计)。" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<ApprovalRecord ref="approvalRecordRef" />
<SubmitVerify ref="submitVerifyRef" @submit-callback="submitCallback" />
<!-- 项目选择弹窗 -->
<ProjectSelect ref="projectSelectRef" :multiple="false" @confirm-call-back="projectInfoSelectCallBack" />
</div>
</template>
<script setup lang="ts" name="ProjectAcceptanceEdit">
import ApprovalButton from '@/components/Process/approvalButton.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import FileUpload from '@/components/FileUpload/index.vue';
import ProjectSelect from '@/components/ProjectSelect/index.vue';
import { useRoute, useRouter } from 'vue-router';
import { useUserStore } from '@/store/modules/user';
import type { ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
import {
addProjectAcceptance,
getProjectAcceptance,
prepareProjectAcceptanceByProjectId,
submitProjectAcceptanceAndFlowStart,
updateProjectAcceptance
} from '@/api/oa/erp/projectAcceptance';
import type { ProjectAcceptanceForm } from '@/api/oa/erp/projectAcceptance/types';
import { FlowCodeEnum } from '@/enums/OAEnum';
import SubmitVerify from '@/components/Process/submitVerify.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
// 路由参数(与项目信息保持一致)
const routeParams = ref<Record<string, any>>({});
const userStore = useUserStore();
const refreshFlagKey = 'projectAcceptanceListShouldRefresh';
/** 通知列表页刷新 */
const notifyListRefresh = () => {
sessionStorage.setItem(refreshFlagKey, Date.now().toString());
};
const isSuperAdmin = computed(() => {
const roles = userStore.roles || [];
return roles.includes('admin') || roles.includes('superadmin');
});
const buttonLoading = ref(false);
const formRef = ref<ElFormInstance>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
const initFormData: ProjectAcceptanceForm = {
acceptanceId: undefined,
projectId: undefined,
projectCode: undefined,
projectName: undefined,
managerId: undefined,
projectManagerName: undefined,
acceptanceDate: undefined,
ossId: undefined,
chargeId: undefined,
chargeName: undefined as any,
deputyId: undefined,
deputyName: undefined as any,
remark: undefined,
acceptanceStatus: '1',
flowStatus: 'draft' as any,
flowCode: FlowCodeEnum.PROJECT_ACCEPTANCE_CODE,
variables: {},
bizExt: {}
};
const form = ref<ProjectAcceptanceForm>({ ...initFormData });
const rules = {
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
projectCode: [{ required: true, message: '项目号不能为空', trigger: 'blur' }],
acceptanceDate: [{ required: true, message: '验收日期不能为空', trigger: 'change' }]
} as any;
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 openProjectSelect = () => {
if (routeParams.value.type !== 'add') return;
projectSelectRef.value?.open();
};
/** 项目选择回调,自动填充项目相关信息 */
const projectInfoSelectCallBack = async (data: ProjectInfoVO[]) => {
if (data && data.length > 0) {
const project = data[0];
form.value.projectId = project.projectId;
form.value.projectName = project.projectName || '';
form.value.projectCode = project.projectCode || '';
// 调用 onProjectChange 填充其他关联字段
await onProjectChange(project.projectId);
}
};
const onProjectChange = async (val: any) => {
if (!val) return;
const { data } = await prepareProjectAcceptanceByProjectId(val);
Object.assign(form.value, data);
form.value.projectId = val;
applyLeaderFromManager();
};
const applyLeaderFromManager = () => {};
const loadDetail = async () => {
if (!routeParams.value.id) return;
const res = await getProjectAcceptance(routeParams.value.id);
Object.assign(form.value, res.data);
};
const submitForm = (status: string, mode: boolean) => {
formRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
// 前端权限校验:只有项目经理才能暂存或提交(超级管理员除外)
if (!form.value.managerId) {
proxy?.$modal.msgError('请先选择项目');
buttonLoading.value = false;
return;
}
if (!isSuperAdmin.value && userStore.userId !== form.value.managerId) {
proxy?.$modal.msgError('只有项目经理才能提交或暂存项目验收确认');
buttonLoading.value = false;
return;
}
buttonLoading.value = true;
try {
// 提交审批(与项目信息保持一致)
if (status !== 'draft') {
// 提交流程:设置业务状态为审批中,流程状态为 waiting
form.value.acceptanceStatus = '2';
form.value.flowStatus = 'waiting' as any;
form.value.flowCode = FlowCodeEnum.PROJECT_ACCEPTANCE_CODE; //OAPA
form.value.variables = {
projectId: form.value.projectId,
projectCode: form.value.projectCode,
projectName: form.value.projectName,
managerId: form.value.managerId,
managerName: form.value.projectManagerName,
chargeId: form.value.chargeId,
deputyId: form.value.deputyId
};
form.value.bizExt = {
businessCode: form.value.acceptanceCode,
businessTitle: form.value.projectName
};
await submitProjectAcceptanceAndFlowStart(form.value);
proxy?.$modal.msgSuccess('操作成功');
notifyListRefresh();
proxy?.$tab.closePage();
router.go(-1);
} else {
// 暂存:显式设置流程状态为 draft
form.value.flowStatus = 'draft' as any;
form.value.acceptanceStatus = '1'; // 业务状态:暂存
if (form.value.acceptanceId) {
await updateProjectAcceptance(form.value);
} else {
await addProjectAcceptance(form.value);
}
proxy?.$modal.msgSuccess('暂存成功');
notifyListRefresh();
proxy?.$tab.closePage();
router.go(-1);
}
} finally {
buttonLoading.value = false;
}
});
};
const submitCallback = async () => {
await proxy?.$tab.closePage(route);
router.go(-1);
};
const approvalVerifyOpen = async () => {
await submitVerifyRef.value?.openDialog(routeParams.value.taskId);
};
const handleApprovalRecord = () => {
if (form.value.acceptanceId) {
approvalRecordRef.value?.init(form.value.acceptanceId);
}
};
// 表单禁用逻辑(与项目信息保持一致,且只有草稿状态可编辑)
const formDisabled = computed(() => {
if (routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
return true;
}
// 仅草稿状态acceptanceStatus === '1')允许编辑,其余状态只读
if (!form.value.acceptanceStatus) {
return false;
}
return form.value.acceptanceStatus !== '1';
});
const setNowIfAdd = () => {
const d = new Date();
const s = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
form.value.acceptanceDate = s as any;
};
const loadFormData = async () => {
// 获取路由参数(与项目信息保持一致)
routeParams.value = route.query;
// 重置表单
form.value = { ...initFormData };
await loadDetail();
if (routeParams.value.type === 'add') {
setNowIfAdd();
// 如果传递了projectId参数自动加载项目信息
const projectId = routeParams.value.projectId;
if (projectId) {
await onProjectChange(projectId);
}
}
};
watch(
() => route.fullPath,
() => {
loadFormData();
}
);
onMounted(async () => {
proxy?.$modal.loading('正在加载数据,请稍后...');
try {
await loadFormData();
} finally {
proxy?.$modal.closeLoading();
}
});
</script>
<style scoped lang="scss">
.card-title {
font-weight: bold;
font-size: 16px;
color: #303133;
}
</style>