|
|
|
|
@ -23,8 +23,21 @@
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :span="12">
|
|
|
|
|
<el-form-item label="项目名称" prop="projectName">
|
|
|
|
|
<el-select v-model="selectedProjectId" filterable clearable placeholder="请选择项目" :disabled="routeParams.type !== 'add'" :remote-method="remoteSearchProject" @change="onProjectChange">
|
|
|
|
|
<el-option v-for="item in projectOptions" :key="item.projectId" :label="item.projectName + ' / ' + item.projectCode" :value="item.projectId" />
|
|
|
|
|
<el-select
|
|
|
|
|
v-model="selectedProjectId"
|
|
|
|
|
filterable
|
|
|
|
|
clearable
|
|
|
|
|
placeholder="请选择项目"
|
|
|
|
|
:disabled="routeParams.type !== 'add'"
|
|
|
|
|
:remote-method="remoteSearchProject"
|
|
|
|
|
@change="onProjectChange"
|
|
|
|
|
>
|
|
|
|
|
<el-option
|
|
|
|
|
v-for="item in projectOptions"
|
|
|
|
|
:key="item.projectId"
|
|
|
|
|
:label="item.projectName + ' / ' + item.projectCode"
|
|
|
|
|
:value="item.projectId"
|
|
|
|
|
/>
|
|
|
|
|
</el-select>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -38,10 +51,16 @@
|
|
|
|
|
<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-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">
|
|
|
|
|
@ -71,43 +90,48 @@
|
|
|
|
|
<ApprovalRecord ref="approvalRecordRef" />
|
|
|
|
|
<SubmitVerify ref="submitVerifyRef" @submit-callback="submitCallback" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import ApprovalButton from '@/components/Process/approvalButton.vue'
|
|
|
|
|
import ApprovalRecord from '@/components/Process/approvalRecord.vue'
|
|
|
|
|
import FileUpload from '@/components/FileUpload/index.vue'
|
|
|
|
|
import { useRoute } from 'vue-router'
|
|
|
|
|
import { useUserStore } from '@/store/modules/user'
|
|
|
|
|
import { getErpProjectInfoList } from '@/api/oa/erp/projectInfo'
|
|
|
|
|
import { getProjectAcceptance, addProjectAcceptance, updateProjectAcceptance, submitProjectAcceptanceAndFlowStart, prepareProjectAcceptanceByProjectId } from '@/api/oa/erp/projectAcceptance'
|
|
|
|
|
import type { ProjectAcceptanceForm } from '@/api/oa/erp/projectAcceptance/types'
|
|
|
|
|
import SubmitVerify from '@/components/Process/submitVerify.vue'
|
|
|
|
|
import ApprovalButton from '@/components/Process/approvalButton.vue';
|
|
|
|
|
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
|
|
|
|
|
import FileUpload from '@/components/FileUpload/index.vue';
|
|
|
|
|
import { useRoute } from 'vue-router';
|
|
|
|
|
import { useUserStore } from '@/store/modules/user';
|
|
|
|
|
import { getErpProjectInfoList } from '@/api/oa/erp/projectInfo';
|
|
|
|
|
import {
|
|
|
|
|
addProjectAcceptance,
|
|
|
|
|
getProjectAcceptance,
|
|
|
|
|
prepareProjectAcceptanceByProjectId,
|
|
|
|
|
submitProjectAcceptanceAndFlowStart,
|
|
|
|
|
updateProjectAcceptance
|
|
|
|
|
} from '@/api/oa/erp/projectAcceptance';
|
|
|
|
|
import type { ProjectAcceptanceForm } from '@/api/oa/erp/projectAcceptance/types';
|
|
|
|
|
import SubmitVerify from '@/components/Process/submitVerify.vue';
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as any
|
|
|
|
|
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'))
|
|
|
|
|
const route = useRoute()
|
|
|
|
|
const { proxy } = getCurrentInstance() as any;
|
|
|
|
|
const { wf_business_status } = toRefs<any>(proxy?.useDict('wf_business_status'));
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
// 兼容 path 参数 :acceptanceId 和 query 参数 id
|
|
|
|
|
const routeParams = reactive<{ id?: string | number; type?: string; taskId?: string | number }>({
|
|
|
|
|
id: (route.params.acceptanceId || route.query.id) as any,
|
|
|
|
|
type: (route.query.type as any) || 'add',
|
|
|
|
|
taskId: route.query.taskId as any
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const userStore = useUserStore()
|
|
|
|
|
const userStore = useUserStore();
|
|
|
|
|
const isSuperAdmin = computed(() => {
|
|
|
|
|
const roles = userStore.roles || []
|
|
|
|
|
return roles.includes('admin') || roles.includes('superadmin')
|
|
|
|
|
})
|
|
|
|
|
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 buttonLoading = ref(false);
|
|
|
|
|
const formRef = ref<ElFormInstance>();
|
|
|
|
|
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
|
|
|
|
|
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
|
|
|
|
|
|
|
|
|
|
const projectOptions = ref<any[]>([])
|
|
|
|
|
const selectedProjectId = ref<any>()
|
|
|
|
|
const projectOptions = ref<any[]>([]);
|
|
|
|
|
const selectedProjectId = ref<any>();
|
|
|
|
|
|
|
|
|
|
const initFormData: ProjectAcceptanceForm = {
|
|
|
|
|
acceptanceId: undefined,
|
|
|
|
|
@ -126,165 +150,173 @@ const initFormData: ProjectAcceptanceForm = {
|
|
|
|
|
flowCode: 'OAPA',
|
|
|
|
|
variables: {},
|
|
|
|
|
bizExt: {}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const form = ref<ProjectAcceptanceForm>({ ...initFormData })
|
|
|
|
|
const form = ref<ProjectAcceptanceForm>({ ...initFormData });
|
|
|
|
|
|
|
|
|
|
const normalizeFlowStatus = (status?: string) => {
|
|
|
|
|
if (!status) return 'draft'
|
|
|
|
|
const dictList = wf_business_status.value || []
|
|
|
|
|
const match = dictList.find((item: any) => item?.value === status || item?.label === status)
|
|
|
|
|
return match?.value || status
|
|
|
|
|
}
|
|
|
|
|
if (!status) return 'draft';
|
|
|
|
|
const dictList = wf_business_status.value || [];
|
|
|
|
|
const match = dictList.find((item: any) => item?.value === status || item?.label === status);
|
|
|
|
|
return match?.value || status;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 将后端返回的流程状态统一映射为审批按钮组件需要的英文状态
|
|
|
|
|
const approvalStatus = computed(() => normalizeFlowStatus(form.value.flowStatus as any))
|
|
|
|
|
const approvalStatus = computed(() => normalizeFlowStatus(form.value.flowStatus as any));
|
|
|
|
|
|
|
|
|
|
const pageTypeForButton = computed(() => {
|
|
|
|
|
if (routeParams.taskId) {
|
|
|
|
|
return 'approval'
|
|
|
|
|
return 'approval';
|
|
|
|
|
}
|
|
|
|
|
return routeParams.type
|
|
|
|
|
})
|
|
|
|
|
return routeParams.type;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const rules = {
|
|
|
|
|
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
|
|
|
|
|
projectCode: [{ required: true, message: '项目号不能为空', trigger: 'blur' }],
|
|
|
|
|
acceptanceDate: [{ required: true, message: '验收日期不能为空', trigger: 'change' }]
|
|
|
|
|
} as any
|
|
|
|
|
} as any;
|
|
|
|
|
|
|
|
|
|
const ossIdString = computed({
|
|
|
|
|
get() {
|
|
|
|
|
const v = form.value.ossId as any
|
|
|
|
|
return v === undefined || v === null ? '' : String(v)
|
|
|
|
|
const v = form.value.ossId as any;
|
|
|
|
|
return v === undefined || v === null ? '' : String(v);
|
|
|
|
|
},
|
|
|
|
|
set(val: string) {
|
|
|
|
|
form.value.ossId = val || undefined as any
|
|
|
|
|
form.value.ossId = val || (undefined as any);
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const preloadProjectList = async () => {
|
|
|
|
|
const res = await getErpProjectInfoList({})
|
|
|
|
|
projectOptions.value = res.data || []
|
|
|
|
|
}
|
|
|
|
|
const res = await getErpProjectInfoList({});
|
|
|
|
|
projectOptions.value = res.data || [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const remoteSearchProject = async (query: string) => {
|
|
|
|
|
const res = await getErpProjectInfoList({ projectName: query })
|
|
|
|
|
projectOptions.value = res.data || []
|
|
|
|
|
}
|
|
|
|
|
const res = await getErpProjectInfoList({ projectName: query });
|
|
|
|
|
projectOptions.value = res.data || [];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onProjectChange = async (val: any) => {
|
|
|
|
|
if (!val) return
|
|
|
|
|
const { data } = await prepareProjectAcceptanceByProjectId(val)
|
|
|
|
|
Object.assign(form.value, data)
|
|
|
|
|
form.value.projectId = val
|
|
|
|
|
applyLeaderFromManager()
|
|
|
|
|
}
|
|
|
|
|
if (!val) return;
|
|
|
|
|
const { data } = await prepareProjectAcceptanceByProjectId(val);
|
|
|
|
|
Object.assign(form.value, data);
|
|
|
|
|
form.value.projectId = val;
|
|
|
|
|
applyLeaderFromManager();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const applyLeaderFromManager = () => {
|
|
|
|
|
}
|
|
|
|
|
const applyLeaderFromManager = () => {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const loadDetail = async () => {
|
|
|
|
|
if (!routeParams.id || Number(routeParams.id) === 0) return
|
|
|
|
|
const res = await getProjectAcceptance(routeParams.id as any)
|
|
|
|
|
Object.assign(form.value, res.data)
|
|
|
|
|
selectedProjectId.value = form.value.projectId
|
|
|
|
|
}
|
|
|
|
|
const loadDetail = async () => {
|
|
|
|
|
if (!routeParams.id || Number(routeParams.id) === 0) return;
|
|
|
|
|
const res = await getProjectAcceptance(routeParams.id as any);
|
|
|
|
|
Object.assign(form.value, res.data);
|
|
|
|
|
selectedProjectId.value = form.value.projectId;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const submitForm = (status: string, mode: boolean) => {
|
|
|
|
|
formRef.value?.validate(async (valid: boolean) => {
|
|
|
|
|
if (!valid) return
|
|
|
|
|
if (!valid) return;
|
|
|
|
|
// 前端权限校验:只有项目经理才能暂存或提交(超级管理员除外)
|
|
|
|
|
if (!form.value.managerId) {
|
|
|
|
|
proxy?.$modal.msgError('请先选择项目')
|
|
|
|
|
return
|
|
|
|
|
proxy?.$modal.msgError('请先选择项目');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!isSuperAdmin.value && userStore.userId !== form.value.managerId) {
|
|
|
|
|
proxy?.$modal.msgError('只有项目经理才能提交或暂存项目验收确认')
|
|
|
|
|
return
|
|
|
|
|
proxy?.$modal.msgError('只有项目经理才能提交或暂存项目验收确认');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
buttonLoading.value = true
|
|
|
|
|
buttonLoading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
if (status === 'draft') {
|
|
|
|
|
// 参考项目信息:显式设置流程状态为 draft
|
|
|
|
|
form.value.flowStatus = 'draft' as any
|
|
|
|
|
form.value.acceptanceStatus = '1' // 业务状态:暂存
|
|
|
|
|
|
|
|
|
|
form.value.flowStatus = 'draft' as any;
|
|
|
|
|
form.value.acceptanceStatus = '1'; // 业务状态:暂存
|
|
|
|
|
|
|
|
|
|
if (form.value.acceptanceId) {
|
|
|
|
|
await updateProjectAcceptance(form.value)
|
|
|
|
|
await updateProjectAcceptance(form.value);
|
|
|
|
|
} else {
|
|
|
|
|
await addProjectAcceptance(form.value)
|
|
|
|
|
await addProjectAcceptance(form.value);
|
|
|
|
|
}
|
|
|
|
|
proxy?.$modal.msgSuccess('暂存成功')
|
|
|
|
|
proxy?.$tab.closePage(proxy.$route)
|
|
|
|
|
proxy?.$router.go(-1)
|
|
|
|
|
proxy?.$modal.msgSuccess('暂存成功');
|
|
|
|
|
proxy?.$tab.closePage(proxy.$route);
|
|
|
|
|
proxy?.$router.go(-1);
|
|
|
|
|
} else {
|
|
|
|
|
const variables: any = { managerId: form.value.managerId, managerName: form.value.projectManagerName }
|
|
|
|
|
const payload: ProjectAcceptanceForm = { ...form.value, flowCode: 'OAPA', variables, bizExt: { businessCode: form.value.acceptanceCode } } as any
|
|
|
|
|
await submitProjectAcceptanceAndFlowStart(payload)
|
|
|
|
|
proxy?.$modal.msgSuccess('已提交并发起流程')
|
|
|
|
|
proxy?.$tab.closePage(proxy.$route)
|
|
|
|
|
proxy?.$router.go(-1)
|
|
|
|
|
const variables: any = { managerId: form.value.managerId, managerName: form.value.projectManagerName };
|
|
|
|
|
const payload: ProjectAcceptanceForm = {
|
|
|
|
|
...form.value,
|
|
|
|
|
flowCode: 'OAPA',
|
|
|
|
|
variables,
|
|
|
|
|
bizExt: { businessCode: form.value.acceptanceCode, businessTitle: form.value.projectName }
|
|
|
|
|
} as any;
|
|
|
|
|
await submitProjectAcceptanceAndFlowStart(payload);
|
|
|
|
|
proxy?.$modal.msgSuccess('已提交并发起流程');
|
|
|
|
|
proxy?.$tab.closePage(proxy.$route);
|
|
|
|
|
proxy?.$router.go(-1);
|
|
|
|
|
}
|
|
|
|
|
} finally {
|
|
|
|
|
buttonLoading.value = false
|
|
|
|
|
buttonLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const submitCallback = async () => {
|
|
|
|
|
await proxy?.$tab.closePage(proxy.$route)
|
|
|
|
|
proxy?.$router.go(-1)
|
|
|
|
|
}
|
|
|
|
|
await proxy?.$tab.closePage(proxy.$route);
|
|
|
|
|
proxy?.$router.go(-1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const approvalVerifyOpen = async () => {
|
|
|
|
|
await submitVerifyRef.value?.openDialog(routeParams.taskId as any)
|
|
|
|
|
}
|
|
|
|
|
await submitVerifyRef.value?.openDialog(routeParams.taskId as any);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const submitAndStartFlow = async () => {
|
|
|
|
|
formRef.value?.validate(async (valid: boolean) => {
|
|
|
|
|
if (!valid) return
|
|
|
|
|
buttonLoading.value = true
|
|
|
|
|
if (!valid) return;
|
|
|
|
|
buttonLoading.value = true;
|
|
|
|
|
try {
|
|
|
|
|
const payload: ProjectAcceptanceForm = { ...form.value, flowCode: 'OAPA', variables: {}, bizExt: { businessCode: form.value.acceptanceCode } } as any
|
|
|
|
|
await submitProjectAcceptanceAndFlowStart(payload)
|
|
|
|
|
proxy?.$modal.msgSuccess('已提交并发起流程')
|
|
|
|
|
const payload: ProjectAcceptanceForm = {
|
|
|
|
|
...form.value,
|
|
|
|
|
flowCode: 'OAPA',
|
|
|
|
|
variables: {},
|
|
|
|
|
bizExt: { businessCode: form.value.acceptanceCode, businessTitle: form.value.projectName }
|
|
|
|
|
} as any;
|
|
|
|
|
await submitProjectAcceptanceAndFlowStart(payload);
|
|
|
|
|
proxy?.$modal.msgSuccess('已提交并发起流程');
|
|
|
|
|
} finally {
|
|
|
|
|
buttonLoading.value = false
|
|
|
|
|
buttonLoading.value = false;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleApprovalRecord = () => {
|
|
|
|
|
if (form.value.acceptanceId) {
|
|
|
|
|
approvalRecordRef.value?.init(form.value.acceptanceId)
|
|
|
|
|
approvalRecordRef.value?.init(form.value.acceptanceId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const formDisabled = computed(() => {
|
|
|
|
|
const status = normalizeFlowStatus(form.value.flowStatus as any)
|
|
|
|
|
const byStatus = !!status && status !== 'draft' && status !== 'back'
|
|
|
|
|
return pageTypeForButton.value === 'view' || pageTypeForButton.value === 'approval' || byStatus
|
|
|
|
|
})
|
|
|
|
|
const status = normalizeFlowStatus(form.value.flowStatus as any);
|
|
|
|
|
const byStatus = !!status && status !== 'draft' && status !== 'back';
|
|
|
|
|
return pageTypeForButton.value === 'view' || pageTypeForButton.value === 'approval' || byStatus;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
|
// 初始化页面模式与任务ID,优先使用 path 中的 :acceptanceId,其次使用 query.id
|
|
|
|
|
routeParams.id = (route.params.acceptanceId || route.query.id) as any
|
|
|
|
|
routeParams.type = (route.query.type as any) || (routeParams.id && Number(routeParams.id) !== 0 ? 'update' : 'add')
|
|
|
|
|
routeParams.taskId = route.query.taskId as any
|
|
|
|
|
|
|
|
|
|
routeParams.id = (route.params.acceptanceId || route.query.id) as any;
|
|
|
|
|
routeParams.type = (route.query.type as any) || (routeParams.id && Number(routeParams.id) !== 0 ? 'update' : 'add');
|
|
|
|
|
routeParams.taskId = route.query.taskId as any;
|
|
|
|
|
|
|
|
|
|
// 预加载项目列表
|
|
|
|
|
await preloadProjectList()
|
|
|
|
|
|
|
|
|
|
await preloadProjectList();
|
|
|
|
|
|
|
|
|
|
// 加载详情数据
|
|
|
|
|
await loadDetail()
|
|
|
|
|
|
|
|
|
|
await loadDetail();
|
|
|
|
|
|
|
|
|
|
// 新增模式下设置默认验收日期为当前时间
|
|
|
|
|
if (routeParams.type === 'add') {
|
|
|
|
|
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 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;
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|