|
|
<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>
|