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.
698 lines
26 KiB
Vue
698 lines
26 KiB
Vue
|
3 days ago
|
<template>
|
||
|
|
<div class="p-2" v-loading="pageLoading">
|
||
|
|
<approvalButton
|
||
|
|
class="mb-4"
|
||
|
|
@submitForm="submitForm"
|
||
|
|
@approvalVerifyOpen="approvalVerifyOpen"
|
||
|
|
@handleApprovalRecord="handleApprovalRecord"
|
||
|
|
:buttonLoading="buttonLoading"
|
||
|
|
:id="form.tempTaskId as any"
|
||
|
|
:status="form.flowStatus as any"
|
||
|
|
:pageType="pageType"
|
||
|
|
:mode="false"
|
||
|
|
/>
|
||
|
|
|
||
|
|
<el-card shadow="never" class="mb-4">
|
||
|
|
<template #header>
|
||
|
|
<div class="card-header">
|
||
|
|
<span>临时任务</span>
|
||
|
|
<div v-if="form.tempTaskId" class="header-actions">
|
||
|
|
<el-button type="warning" icon="RefreshRight" @click="openChangeDialog" v-hasPermi="['oa:erp:tempTask:change']">发起变更</el-button>
|
||
|
|
<el-button type="danger" icon="CircleClose" @click="openCloseDialog" v-hasPermi="['oa:erp:tempTask:close']">关闭任务</el-button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
<el-form ref="tempTaskFormRef" :model="form" :rules="rules" label-width="120px" :disabled="isReadOnly">
|
||
|
|
<el-row :gutter="20">
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="任务编号" prop="tempTaskCode">
|
||
|
|
<el-input v-model="form.tempTaskCode" placeholder="保存后自动生成" disabled />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="任务标题" prop="taskTitle">
|
||
|
|
<el-input v-model="form.taskTitle" placeholder="请输入任务标题" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="24">
|
||
|
|
<el-form-item label="任务描述" prop="taskDesc">
|
||
|
|
<el-input v-model="form.taskDesc" type="textarea" :rows="4" placeholder="请输入任务描述" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="优先级" prop="priority">
|
||
|
|
<el-select v-model="form.priority" placeholder="请选择优先级" clearable>
|
||
|
|
<el-option v-for="dict in temp_task_priority" :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="requireTime">
|
||
|
|
<el-date-picker
|
||
|
|
v-model="form.requireTime"
|
||
|
|
type="datetime"
|
||
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||
|
|
placeholder="请选择需求时间"
|
||
|
|
class="w-full"
|
||
|
|
/>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col v-if="form.priority === '3' || form.priority === '4'" :span="24">
|
||
|
|
<el-form-item label="紧急原因" prop="urgentReason">
|
||
|
|
<el-input v-model="form.urgentReason" type="textarea" :rows="2" placeholder="紧急/特急必须填写原因" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="主报工项目" prop="projectName">
|
||
|
|
<el-input v-model="form.projectName" placeholder="请选择项目" readonly>
|
||
|
|
<template #append>
|
||
|
|
<el-button icon="Search" @click="openProjectSelect" />
|
||
|
|
</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="dispatcherName">
|
||
|
|
<el-input v-model="form.dispatcherName" placeholder="可选,选择后先走指派确认" readonly>
|
||
|
|
<template #append>
|
||
|
|
<el-button icon="User" @click="openUserSelect('dispatcher')" />
|
||
|
|
</template>
|
||
|
|
</el-input>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="软件部领导" prop="softwareLeaderName">
|
||
|
|
<el-input v-model="form.softwareLeaderName" placeholder="请选择软件部领导" readonly>
|
||
|
|
<template #append>
|
||
|
|
<el-button icon="User" @click="openUserSelect('leader')" />
|
||
|
|
</template>
|
||
|
|
</el-input>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="主执行人" prop="assigneeName">
|
||
|
|
<el-input v-model="form.assigneeName" placeholder="领导审核确定" readonly>
|
||
|
|
<template #append>
|
||
|
|
<el-button icon="User" @click="openUserSelect('assignee')" />
|
||
|
|
</template>
|
||
|
|
</el-input>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="预计工时" prop="estimateWorkload">
|
||
|
|
<el-input-number v-model="form.estimateWorkload" :min="0" :step="0.5" :precision="1" class="w-full" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="确认完成" prop="confirmFinishTime">
|
||
|
|
<el-date-picker
|
||
|
|
v-model="form.confirmFinishTime"
|
||
|
|
type="datetime"
|
||
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||
|
|
placeholder="领导确认完成时间"
|
||
|
|
class="w-full"
|
||
|
|
/>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="实际开始" prop="actualStartTime">
|
||
|
|
<el-date-picker
|
||
|
|
v-model="form.actualStartTime"
|
||
|
|
type="datetime"
|
||
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||
|
|
placeholder="只记录周期,不推算工时"
|
||
|
|
class="w-full"
|
||
|
|
/>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="关联原任务" prop="relatedTaskCode">
|
||
|
|
<el-input v-model="form.relatedTaskCode" placeholder="输入已结束原任务编号" clearable />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="原任务ID" prop="relatedTaskId">
|
||
|
|
<el-input v-model="form.relatedTaskId" placeholder="关联原任务ID" clearable />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="关联原因" prop="relateReason">
|
||
|
|
<el-select v-model="form.relateReason" placeholder="请选择关联原因" clearable>
|
||
|
|
<el-option v-for="dict in temp_task_relate_reason" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="24">
|
||
|
|
<el-form-item label="附件" prop="ossId">
|
||
|
|
<file-upload v-model="form.ossId" :disabled="isReadOnly" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="24">
|
||
|
|
<el-form-item label="备注" prop="remark">
|
||
|
|
<el-input v-model="form.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
</el-row>
|
||
|
|
</el-form>
|
||
|
|
</el-card>
|
||
|
|
|
||
|
|
<el-card v-if="form.tempTaskId" shadow="never">
|
||
|
|
<template #header>
|
||
|
|
<span>变更历史</span>
|
||
|
|
</template>
|
||
|
|
<el-table :data="changeList" border>
|
||
|
|
<el-table-column type="index" label="序号" width="60" align="center" />
|
||
|
|
<el-table-column label="变更类型" prop="changeType" width="130" align="center">
|
||
|
|
<template #default="scope">
|
||
|
|
<dict-tag :options="temp_task_change_type" :value="scope.row.changeType" />
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column label="变更原因" prop="changeReason" min-width="160" show-overflow-tooltip />
|
||
|
|
<el-table-column label="变更前" prop="beforeContent" min-width="160" show-overflow-tooltip />
|
||
|
|
<el-table-column label="变更后" prop="afterContent" min-width="160" show-overflow-tooltip />
|
||
|
|
<el-table-column label="工时影响" prop="workloadEffect" min-width="120" show-overflow-tooltip />
|
||
|
|
<el-table-column label="时间影响" prop="timeEffect" min-width="120" show-overflow-tooltip />
|
||
|
|
<el-table-column label="审批结论" prop="approveResult" width="120" align="center">
|
||
|
|
<template #default="scope">
|
||
|
|
<dict-tag :options="temp_task_change_result" :value="scope.row.approveResult" />
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column label="流程状态" prop="flowStatus" width="110" align="center">
|
||
|
|
<template #default="scope">
|
||
|
|
<dict-tag :options="wf_business_status" :value="scope.row.flowStatus" />
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
<el-table-column label="操作" width="90" align="center">
|
||
|
|
<template #default="scope">
|
||
|
|
<el-button
|
||
|
|
v-if="!scope.row.approveResult"
|
||
|
|
link
|
||
|
|
type="primary"
|
||
|
|
@click="openApproveDialog(scope.row)"
|
||
|
|
v-hasPermi="['oa:erp:tempTask:changeApprove']"
|
||
|
|
>审批</el-button
|
||
|
|
>
|
||
|
|
</template>
|
||
|
|
</el-table-column>
|
||
|
|
</el-table>
|
||
|
|
</el-card>
|
||
|
|
|
||
|
|
<el-dialog v-model="changeDialog.visible" title="发起变更" width="760px" append-to-body>
|
||
|
|
<el-form ref="changeFormRef" :model="changeForm" :rules="changeRules" label-width="110px">
|
||
|
|
<el-row :gutter="20">
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="变更类型" prop="changeType">
|
||
|
|
<el-select v-model="changeForm.changeType" placeholder="请选择变更类型">
|
||
|
|
<el-option v-for="dict in temp_task_change_type" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="24">
|
||
|
|
<el-form-item label="变更原因" prop="changeReason">
|
||
|
|
<el-input v-model="changeForm.changeReason" type="textarea" :rows="2" placeholder="请输入变更原因" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="变更前" prop="beforeContent">
|
||
|
|
<el-input v-model="changeForm.beforeContent" type="textarea" :rows="3" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="变更后" prop="afterContent">
|
||
|
|
<el-input v-model="changeForm.afterContent" type="textarea" :rows="3" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="工时影响" prop="workloadEffect">
|
||
|
|
<el-input v-model="changeForm.workloadEffect" placeholder="例如:预计工时调整为 8" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="12">
|
||
|
|
<el-form-item label="时间影响" prop="timeEffect">
|
||
|
|
<el-input v-model="changeForm.timeEffect" placeholder="请输入时间影响" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
<el-col :span="24">
|
||
|
|
<el-form-item label="执行影响" prop="scopeEffect">
|
||
|
|
<el-input v-model="changeForm.scopeEffect" type="textarea" :rows="2" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-col>
|
||
|
|
</el-row>
|
||
|
|
</el-form>
|
||
|
|
<template #footer>
|
||
|
|
<el-button @click="changeDialog.visible = false">取消</el-button>
|
||
|
|
<el-button type="primary" :loading="buttonLoading" @click="submitChange">确定</el-button>
|
||
|
|
</template>
|
||
|
|
</el-dialog>
|
||
|
|
|
||
|
|
<el-dialog v-model="approveDialog.visible" title="变更审批" width="560px" append-to-body>
|
||
|
|
<el-form ref="approveFormRef" :model="approveForm" :rules="approveRules" label-width="100px">
|
||
|
|
<el-form-item label="审批结论" prop="approveResult">
|
||
|
|
<el-select v-model="approveForm.approveResult" placeholder="请选择审批结论">
|
||
|
|
<el-option v-for="dict in temp_task_change_result" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item label="审批意见" prop="approveComment">
|
||
|
|
<el-input v-model="approveForm.approveComment" type="textarea" :rows="3" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-form>
|
||
|
|
<template #footer>
|
||
|
|
<el-button @click="approveDialog.visible = false">取消</el-button>
|
||
|
|
<el-button type="primary" :loading="buttonLoading" @click="submitApprove">确定</el-button>
|
||
|
|
</template>
|
||
|
|
</el-dialog>
|
||
|
|
|
||
|
|
<el-dialog v-model="closeDialog.visible" title="关闭临时任务" width="680px" append-to-body>
|
||
|
|
<el-form ref="closeFormRef" :model="closeForm" :rules="closeRules" label-width="120px">
|
||
|
|
<el-form-item label="实际消耗工时" prop="actualWorkload">
|
||
|
|
<el-input-number v-model="closeForm.actualWorkload" :min="0" :step="0.5" :precision="1" class="w-full" />
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item label="完成结果" prop="finishResult">
|
||
|
|
<el-select v-model="closeForm.finishResult" placeholder="请选择完成结果">
|
||
|
|
<el-option v-for="dict in temp_task_finish_result" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item v-if="closeForm.finishResult === '2' || closeForm.finishResult === '3'" label="终止原因" prop="terminateReason">
|
||
|
|
<el-select v-model="closeForm.terminateReason" placeholder="请选择终止原因">
|
||
|
|
<el-option v-for="dict in temp_task_terminate_reason" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||
|
|
</el-select>
|
||
|
|
</el-form-item>
|
||
|
|
<el-form-item label="完成说明" prop="finishRemark">
|
||
|
|
<el-input v-model="closeForm.finishRemark" type="textarea" :rows="4" />
|
||
|
|
</el-form-item>
|
||
|
|
</el-form>
|
||
|
|
<template #footer>
|
||
|
|
<el-button @click="closeDialog.visible = false">取消</el-button>
|
||
|
|
<el-button type="primary" :loading="buttonLoading" @click="submitClose">确定</el-button>
|
||
|
|
</template>
|
||
|
|
</el-dialog>
|
||
|
|
|
||
|
|
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
|
||
|
|
<approvalRecord ref="approvalRecordRef" />
|
||
|
|
<ProjectSelect ref="projectSelectRef" :multiple="false" @confirm-call-back="handleProjectSelect" />
|
||
|
|
<UserSelect ref="userSelectRef" :multiple="false" @confirm-call-back="handleUserSelect" />
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup name="TempTaskEdit" lang="ts">
|
||
|
|
import { FlowCodeEnum } from '@/enums/OAEnum';
|
||
|
|
import {
|
||
|
|
addTempTask,
|
||
|
|
approveTempTaskChange,
|
||
|
|
closeTempTask,
|
||
|
|
getTempTask,
|
||
|
|
listTempTaskChanges,
|
||
|
|
saveTempTaskChange,
|
||
|
|
submitTempTask,
|
||
|
|
updateTempTask
|
||
|
|
} from '@/api/oa/erp/tempTask';
|
||
|
|
import { TempTaskChangeForm, TempTaskChangeVO, TempTaskForm } from '@/api/oa/erp/tempTask/types';
|
||
|
|
import SubmitVerify from '@/components/Process/submitVerify.vue';
|
||
|
|
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
|
||
|
|
import ApprovalButton from '@/components/Process/approvalButton.vue';
|
||
|
|
import ProjectSelect from '@/components/ProjectSelect/index.vue';
|
||
|
|
import UserSelect from '@/components/UserSelect/index.vue';
|
||
|
|
import type { ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
|
||
|
|
import type { UserVO } from '@/api/system/user/types';
|
||
|
|
|
||
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||
|
|
const route = useRoute();
|
||
|
|
const router = useRouter();
|
||
|
|
|
||
|
|
const {
|
||
|
|
temp_task_priority,
|
||
|
|
temp_task_finish_result,
|
||
|
|
temp_task_terminate_reason,
|
||
|
|
temp_task_relate_reason,
|
||
|
|
temp_task_change_type,
|
||
|
|
temp_task_change_result,
|
||
|
|
wf_business_status
|
||
|
|
} = toRefs<any>(
|
||
|
|
proxy?.useDict(
|
||
|
|
'temp_task_priority',
|
||
|
|
'temp_task_finish_result',
|
||
|
|
'temp_task_terminate_reason',
|
||
|
|
'temp_task_relate_reason',
|
||
|
|
'temp_task_change_type',
|
||
|
|
'temp_task_change_result',
|
||
|
|
'wf_business_status'
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
const pageType = ref<string>((route.query.type as string) || 'add');
|
||
|
|
const isReadOnly = computed(() => pageType.value === 'view');
|
||
|
|
const pageLoading = ref(false);
|
||
|
|
const buttonLoading = ref(false);
|
||
|
|
const tempTaskFormRef = ref<ElFormInstance>();
|
||
|
|
const changeFormRef = ref<ElFormInstance>();
|
||
|
|
const approveFormRef = ref<ElFormInstance>();
|
||
|
|
const closeFormRef = ref<ElFormInstance>();
|
||
|
|
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
|
||
|
|
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
|
||
|
|
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
|
||
|
|
const userSelectRef = ref<InstanceType<typeof UserSelect>>();
|
||
|
|
const taskVariables = ref<Record<string, unknown>>({});
|
||
|
|
const changeList = ref<TempTaskChangeVO[]>([]);
|
||
|
|
const userSelectTarget = ref<'dispatcher' | 'leader' | 'assignee'>('dispatcher');
|
||
|
|
|
||
|
|
const initFormData: TempTaskForm = {
|
||
|
|
tempTaskId: undefined,
|
||
|
|
tempTaskCode: undefined,
|
||
|
|
taskTitle: undefined,
|
||
|
|
taskDesc: undefined,
|
||
|
|
priority: '1',
|
||
|
|
urgentReason: undefined,
|
||
|
|
requireTime: undefined,
|
||
|
|
confirmFinishTime: undefined,
|
||
|
|
actualStartTime: undefined,
|
||
|
|
projectId: undefined,
|
||
|
|
projectCode: undefined,
|
||
|
|
projectName: undefined,
|
||
|
|
pmId: undefined,
|
||
|
|
pmName: undefined,
|
||
|
|
requesterId: undefined,
|
||
|
|
requesterName: undefined,
|
||
|
|
requestDeptId: undefined,
|
||
|
|
requestDeptName: undefined,
|
||
|
|
dispatcherId: undefined,
|
||
|
|
dispatcherName: undefined,
|
||
|
|
softwareLeaderId: undefined,
|
||
|
|
softwareLeaderName: undefined,
|
||
|
|
assigneeId: undefined,
|
||
|
|
assigneeName: undefined,
|
||
|
|
estimateWorkload: undefined,
|
||
|
|
actualWorkload: undefined,
|
||
|
|
finishResult: undefined,
|
||
|
|
terminateReason: undefined,
|
||
|
|
finishRemark: undefined,
|
||
|
|
relatedTaskId: undefined,
|
||
|
|
relatedTaskCode: undefined,
|
||
|
|
relateReason: undefined,
|
||
|
|
taskStatus: '1',
|
||
|
|
flowStatus: 'draft',
|
||
|
|
ccUserIds: undefined,
|
||
|
|
ossId: undefined,
|
||
|
|
remark: undefined
|
||
|
|
};
|
||
|
|
|
||
|
|
const form = ref<TempTaskForm>({ ...initFormData });
|
||
|
|
const rules = {
|
||
|
|
taskDesc: [{ required: true, message: '任务描述不能为空', trigger: 'blur' }],
|
||
|
|
requireTime: [{ required: true, message: '需求时间不能为空', trigger: 'change' }],
|
||
|
|
priority: [{ required: true, message: '优先级不能为空', trigger: 'change' }],
|
||
|
|
urgentReason: [
|
||
|
|
{
|
||
|
|
validator: (_rule: unknown, value: string, callback: (error?: Error) => void) => {
|
||
|
|
if ((form.value.priority === '3' || form.value.priority === '4') && !value) {
|
||
|
|
callback(new Error('紧急/特急必须填写紧急原因'));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
callback();
|
||
|
|
},
|
||
|
|
trigger: 'blur'
|
||
|
|
}
|
||
|
|
]
|
||
|
|
};
|
||
|
|
|
||
|
|
const changeDialog = reactive({ visible: false });
|
||
|
|
const changeForm = ref<TempTaskChangeForm>({});
|
||
|
|
const changeRules = {
|
||
|
|
changeType: [{ required: true, message: '变更类型不能为空', trigger: 'change' }],
|
||
|
|
changeReason: [{ required: true, message: '变更原因不能为空', trigger: 'blur' }]
|
||
|
|
};
|
||
|
|
|
||
|
|
const approveDialog = reactive({ visible: false });
|
||
|
|
const approveForm = ref<TempTaskChangeForm>({});
|
||
|
|
const approveRules = {
|
||
|
|
approveResult: [{ required: true, message: '审批结论不能为空', trigger: 'change' }]
|
||
|
|
};
|
||
|
|
|
||
|
|
const closeDialog = reactive({ visible: false });
|
||
|
|
const closeForm = ref<TempTaskForm>({});
|
||
|
|
const closeRules = {
|
||
|
|
actualWorkload: [{ required: true, message: '实际消耗工时不能为空', trigger: 'blur' }],
|
||
|
|
finishResult: [{ required: true, message: '完成结果不能为空', trigger: 'change' }],
|
||
|
|
terminateReason: [
|
||
|
|
{
|
||
|
|
validator: (_rule: unknown, value: string, callback: (error?: Error) => void) => {
|
||
|
|
if ((closeForm.value.finishResult === '2' || closeForm.value.finishResult === '3') && !value) {
|
||
|
|
callback(new Error('终止类完成结果必须选择终止原因'));
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
callback();
|
||
|
|
},
|
||
|
|
trigger: 'change'
|
||
|
|
}
|
||
|
|
],
|
||
|
|
finishRemark: [{ required: true, message: '完成说明不能为空', trigger: 'blur' }]
|
||
|
|
};
|
||
|
|
|
||
|
|
const resetForm = () => {
|
||
|
|
form.value = { ...initFormData };
|
||
|
|
};
|
||
|
|
|
||
|
|
const loadChanges = async () => {
|
||
|
|
if (!form.value.tempTaskId) {
|
||
|
|
changeList.value = [];
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const res = await listTempTaskChanges(form.value.tempTaskId);
|
||
|
|
changeList.value = res.data || [];
|
||
|
|
};
|
||
|
|
|
||
|
|
const loadDetail = async (id?: string | number) => {
|
||
|
|
resetForm();
|
||
|
|
if (!id) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const res = await getTempTask(id);
|
||
|
|
Object.assign(form.value, res.data || {});
|
||
|
|
await loadChanges();
|
||
|
|
};
|
||
|
|
|
||
|
|
const buildPayload = (): TempTaskForm => {
|
||
|
|
return {
|
||
|
|
...form.value,
|
||
|
|
flowCode: FlowCodeEnum.TEMP_TASK_CODE,
|
||
|
|
variables: {
|
||
|
|
has_dispatcher: form.value.dispatcherId ? '1' : '0',
|
||
|
|
extra_approval_required: '0',
|
||
|
|
has_change: '0',
|
||
|
|
dispatcherId: form.value.dispatcherId,
|
||
|
|
requesterId: form.value.requesterId,
|
||
|
|
softwareLeaderId: form.value.softwareLeaderId,
|
||
|
|
assigneeId: form.value.assigneeId,
|
||
|
|
taskTitle: form.value.taskTitle,
|
||
|
|
taskDesc: form.value.taskDesc,
|
||
|
|
projectId: form.value.projectId,
|
||
|
|
contractId: form.value.contractId,
|
||
|
|
priority: form.value.priority,
|
||
|
|
urgentReason: form.value.urgentReason,
|
||
|
|
requireTime: form.value.requireTime,
|
||
|
|
estimateWorkload: form.value.estimateWorkload,
|
||
|
|
confirmFinishTime: form.value.confirmFinishTime,
|
||
|
|
actualStartTime: form.value.actualStartTime,
|
||
|
|
actualWorkload: form.value.actualWorkload,
|
||
|
|
finishResult: form.value.finishResult,
|
||
|
|
terminateReason: form.value.terminateReason,
|
||
|
|
finishRemark: form.value.finishRemark,
|
||
|
|
ccUserIds: form.value.ccUserIds
|
||
|
|
},
|
||
|
|
bizExt: {
|
||
|
|
businessId: form.value.tempTaskId,
|
||
|
|
businessCode: form.value.tempTaskCode,
|
||
|
|
businessTitle: `${form.value.tempTaskCode || '临时任务'}-${form.value.taskDesc || form.value.taskTitle || ''}`
|
||
|
|
}
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
const submitForm = async (status: string) => {
|
||
|
|
await tempTaskFormRef.value?.validate();
|
||
|
|
if (status !== 'draft' && !form.value.softwareLeaderId) {
|
||
|
|
proxy?.$modal.msgError('提交审批前必须选择软件部领导');
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
buttonLoading.value = true;
|
||
|
|
try {
|
||
|
|
const payload = buildPayload();
|
||
|
|
if (status !== 'draft') {
|
||
|
|
const res = await submitTempTask(payload);
|
||
|
|
Object.assign(form.value, res.data || {});
|
||
|
|
proxy?.$modal.msgSuccess('提交成功');
|
||
|
|
} else if (payload.tempTaskId) {
|
||
|
|
await updateTempTask(payload);
|
||
|
|
proxy?.$modal.msgSuccess('暂存成功');
|
||
|
|
} else {
|
||
|
|
await addTempTask(payload);
|
||
|
|
proxy?.$modal.msgSuccess('暂存成功');
|
||
|
|
}
|
||
|
|
proxy?.$tab.closePage();
|
||
|
|
router.go(-1);
|
||
|
|
} finally {
|
||
|
|
buttonLoading.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const approvalVerifyOpen = async () => {
|
||
|
|
taskVariables.value = buildPayload().variables || {};
|
||
|
|
const taskId = route.query.taskId as string;
|
||
|
|
if (taskId) {
|
||
|
|
await submitVerifyRef.value?.openDialog(taskId);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleApprovalRecord = () => {
|
||
|
|
if (form.value.tempTaskId) {
|
||
|
|
approvalRecordRef.value?.init(form.value.tempTaskId);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const submitCallback = async () => {
|
||
|
|
await proxy?.$tab.closePage(route);
|
||
|
|
router.go(-1);
|
||
|
|
};
|
||
|
|
|
||
|
|
const openProjectSelect = () => {
|
||
|
|
if (!isReadOnly.value) {
|
||
|
|
projectSelectRef.value?.open();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleProjectSelect = (data: ProjectInfoVO[]) => {
|
||
|
|
if (!data?.length) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const project = data[0];
|
||
|
|
form.value.projectId = project.projectId;
|
||
|
|
form.value.projectCode = project.projectCode;
|
||
|
|
form.value.projectName = project.projectName;
|
||
|
|
form.value.pmId = project.managerId;
|
||
|
|
form.value.pmName = project.managerName;
|
||
|
|
};
|
||
|
|
|
||
|
|
const openUserSelect = (target: 'dispatcher' | 'leader' | 'assignee') => {
|
||
|
|
if (isReadOnly.value) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
userSelectTarget.value = target;
|
||
|
|
userSelectRef.value?.open();
|
||
|
|
};
|
||
|
|
|
||
|
|
const handleUserSelect = (users: UserVO[]) => {
|
||
|
|
const user = users?.[0];
|
||
|
|
if (!user) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (userSelectTarget.value === 'dispatcher') {
|
||
|
|
form.value.dispatcherId = user.userId;
|
||
|
|
form.value.dispatcherName = user.nickName;
|
||
|
|
} else if (userSelectTarget.value === 'leader') {
|
||
|
|
form.value.softwareLeaderId = user.userId;
|
||
|
|
form.value.softwareLeaderName = user.nickName;
|
||
|
|
} else {
|
||
|
|
form.value.assigneeId = user.userId;
|
||
|
|
form.value.assigneeName = user.nickName;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const openChangeDialog = () => {
|
||
|
|
changeForm.value = {
|
||
|
|
tempTaskId: form.value.tempTaskId,
|
||
|
|
tempTaskCode: form.value.tempTaskCode,
|
||
|
|
beforeContent: form.value.taskDesc
|
||
|
|
};
|
||
|
|
changeDialog.visible = true;
|
||
|
|
};
|
||
|
|
|
||
|
|
const submitChange = async () => {
|
||
|
|
await changeFormRef.value?.validate();
|
||
|
|
buttonLoading.value = true;
|
||
|
|
try {
|
||
|
|
await saveTempTaskChange(changeForm.value);
|
||
|
|
proxy?.$modal.msgSuccess('变更已提交');
|
||
|
|
changeDialog.visible = false;
|
||
|
|
await loadChanges();
|
||
|
|
} finally {
|
||
|
|
buttonLoading.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const openApproveDialog = (row: TempTaskChangeVO) => {
|
||
|
|
approveForm.value = {
|
||
|
|
changeId: row.changeId,
|
||
|
|
approveResult: undefined,
|
||
|
|
approveComment: undefined
|
||
|
|
};
|
||
|
|
approveDialog.visible = true;
|
||
|
|
};
|
||
|
|
|
||
|
|
const submitApprove = async () => {
|
||
|
|
await approveFormRef.value?.validate();
|
||
|
|
buttonLoading.value = true;
|
||
|
|
try {
|
||
|
|
await approveTempTaskChange(approveForm.value);
|
||
|
|
proxy?.$modal.msgSuccess('审批成功');
|
||
|
|
approveDialog.visible = false;
|
||
|
|
await loadDetail(form.value.tempTaskId);
|
||
|
|
} finally {
|
||
|
|
buttonLoading.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
const openCloseDialog = () => {
|
||
|
|
closeForm.value = {
|
||
|
|
tempTaskId: form.value.tempTaskId,
|
||
|
|
actualWorkload: form.value.actualWorkload,
|
||
|
|
finishResult: form.value.finishResult,
|
||
|
|
terminateReason: form.value.terminateReason,
|
||
|
|
finishRemark: form.value.finishRemark
|
||
|
|
};
|
||
|
|
closeDialog.visible = true;
|
||
|
|
};
|
||
|
|
|
||
|
|
const submitClose = async () => {
|
||
|
|
await closeFormRef.value?.validate();
|
||
|
|
buttonLoading.value = true;
|
||
|
|
try {
|
||
|
|
await closeTempTask(closeForm.value);
|
||
|
|
proxy?.$modal.msgSuccess('关闭成功');
|
||
|
|
closeDialog.visible = false;
|
||
|
|
proxy?.$tab.closePage();
|
||
|
|
router.go(-1);
|
||
|
|
} finally {
|
||
|
|
buttonLoading.value = false;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
onMounted(async () => {
|
||
|
|
pageLoading.value = true;
|
||
|
|
try {
|
||
|
|
pageType.value = (route.query.type as string) || 'add';
|
||
|
|
await loadDetail(route.query.id as string | number | undefined);
|
||
|
|
if (pageType.value === 'change' && form.value.tempTaskId) {
|
||
|
|
openChangeDialog();
|
||
|
|
}
|
||
|
|
if (pageType.value === 'close' && form.value.tempTaskId) {
|
||
|
|
openCloseDialog();
|
||
|
|
}
|
||
|
|
} finally {
|
||
|
|
pageLoading.value = false;
|
||
|
|
}
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
.card-header,
|
||
|
|
.header-actions {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: space-between;
|
||
|
|
gap: 12px;
|
||
|
|
}
|
||
|
|
</style>
|