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.

1503 lines
57 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">
<!-- 审批按钮组件 -->
<approvalButton
@submitForm="submitForm"
@approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="projectReportForm.reportDetailId"
:status="projectReportForm.flowStatus"
:pageType="routeParams.type"
:mode="false"
/>
</el-card>
<el-card shadow="never">
<el-form
ref="projectFormRef"
:model="form"
:loading="buttonLoading"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
:rules="rules"
label-width="120px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" :disabled="routeParams.reportData && routeParams.type === 'add'">
<template #suffix>
<el-icon
style="cursor: pointer; margin-right: 4px; font-size: 14px"
@click="openProjectSelect"
v-show="!routeParams.reportData && routeParams.type === 'add'"
>
<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="请输入项目编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="里程碑计划" prop="milestonePlan">
<el-input v-model="form.milestonePlan" placeholder="请输入里程碑计划" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目经理" prop="managerName">
<el-input v-model="form.managerName" placeholder="请输入项目经理" :disabled="routeParams.type === 'add'" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入部门" :disabled="routeParams.type === 'add'" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门负责人" prop="chargeName">
<el-input v-model="form.chargeName" placeholder="请输入部门负责人" :disabled="routeParams.type === 'add'" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="分管副总" prop="deputyName">
<el-input v-model="form.deputyName" placeholder="请输入分管副总" :disabled="routeParams.type === 'add'" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="附件" prop="ossId">
<el-button type="primary" plain icon="Upload" @click="handleFile">上传周报附件</el-button>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="周报情况说明" prop="informationNote">
<el-input v-model="form.informationNote" type="textarea" 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" v-show="false">
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="form.projectId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="项目经理ID" prop="managerId">
<el-input v-model="form.managerId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="部门ID" prop="deptId">
<el-input v-model="form.deptId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="部门负责人ID" prop="chargeId">
<el-input v-model="form.chargeId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="分管副总ID" prop="deputyId">
<el-input v-model="form.deputyId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="附件ID" prop="ossId">
<el-input v-model="form.ossId" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="form.sortOrder" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="激活标识" prop="activeFlag">
<el-input v-model="form.activeFlag" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="周报说明" prop="informationNote">
<el-input v-model="form.informationNote" placeholder="请点击右侧图标选择项目" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<ProjectSelect ref="projectSelectRef" :multiple="false" @confirm-call-back="projectInfoSelectCallBack"></ProjectSelect>
<!-- 项目周报具体信息管理区域 -->
<el-card shadow="hover" style="margin-top: 20px">
<div style="text-align: left; font-weight: bold; font-size: 18px">项目周报具体信息</div>
</el-card>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate()"
v-if="routeParams.type === 'view' && routeParams.reportData"
v-hasPermi="['oa/erp:projectReportDetail:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete()"
v-if="routeParams.type === 'view' && routeParams.reportData"
v-hasPermi="['oa/erp:projectReportDetail:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['oa/erp:projectReportDetail:export']"
v-if="routeParams.type === 'view'"
>导出</el-button
>
</el-col>
<right-toolbar
v-model:showSearch="showSearch"
v-if="routeParams.type === 'view' && routeParams.reportData"
:columns="columns"
:search="false"
@queryTable="getProjectDetail"
></right-toolbar>
</el-row>
</template>
<el-table
v-loading="loading"
border
:data="projectReportDetailList"
v-if="routeParams.type !== 'add' && routeParams.type !== 'approval'"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目周报明细ID" align="center" prop="reportDetailId" v-if="columns[0].visible" />
<el-table-column label="项目周报ID" align="center" prop="reportId" v-if="columns[1].visible" />
<el-table-column label="项目ID" align="center" prop="projectId" v-if="columns[2].visible" />
<el-table-column label="填写日期" align="center" prop="fillTime" width="180" v-if="columns[3].visible">
<template #default="scope">
<span>{{ parseTime(scope.row.fillTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
</template>
</el-table-column>
<el-table-column label="所在的工作周" align="center" prop="currentWorkWeek" v-if="columns[4].visible" />
<el-table-column label="所属里程碑" align="center" prop="milestonePlan" v-if="columns[5].visible" />
<el-table-column label="二级进度阶段" align="center" prop="secondaryPhase" v-if="columns[6].visible" />
<el-table-column label="本周完成工作" align="center" prop="tasksCompleted" v-if="columns[7].visible" />
<el-table-column label="下周计划" align="center" prop="nextPlan" v-if="columns[8].visible" />
<el-table-column label="风险及解决措施" align="center" prop="riskResolution" v-if="columns[9].visible" />
<el-table-column label="项目状态" align="center" prop="scheduleStatus" v-if="columns[12].visible">
<template #default="scope">
<dict-tag :options="project_risk_status" :value="scope.row.scheduleStatus" />
</template>
</el-table-column>
<el-table-column label="计划完成率" align="center" prop="plannedCompletionRate" v-if="columns[10].visible" />
<el-table-column label="周报情况说明" align="center" prop="informationNote" v-if="columns[11].visible" />
<el-table-column label="周报状态(1暂存 2审批中 3可用)" align="center" prop="projectReportStatus" v-if="columns[13].visible">
<template #default="scope">
<dict-tag :options="project_report_status" :value="scope.row.projectReportStatus" />
</template>
</el-table-column>
<el-table-column label="流程状态" align="center" prop="flowStatus" v-if="columns[14].visible" />
<el-table-column label="排序号" align="center" prop="sortOrder" v-if="columns[15].visible" />
<el-table-column label="项目阶段(预留)" align="center" prop="projectPhases" v-if="columns[16].visible" />
<el-table-column label="合同ID(预留)" align="center" prop="contractId" v-if="columns[17].visible" />
<el-table-column label="附件ID" align="center" prop="ossId" v-if="columns[18].visible" />
<el-table-column label="备注" align="center" prop="remark" v-if="columns[19].visible" />
<el-table-column label="激活标识" align="center" prop="activeFlag" v-if="columns[20].visible" />
<el-table-column label="操作" align="center" fixed="right" width="150" v-if="routeParams.type !== 'view' && routeParams.type != 'approval'">
<!-- <template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleEditMaterial(scope.row)">编辑</el-button>
<el-button link type="danger" icon="Delete" @click="handleDeleteMaterial(scope.row)">删除</el-button>
</template> -->
</el-table-column>
</el-table>
<pagination
v-show="total > 0 && routeParams.type === 'view'"
:total="total"
v-model:page="projectReportFormQuery.pageNum"
v-model:limit="projectReportFormQuery.pageSize"
@pagination="getProjectDetail"
/>
<el-form
ref="projectReportDetailFormRef"
:model="projectReportForm"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
:rules="reportRules"
label-width="120px"
v-if="routeParams.type == 'add' || routeParams.type === 'approval'"
>
<el-row :gutter="20">
<el-col :span="12" v-show="false">
<el-form-item label="项目周报ID" prop="reportId">
<el-input v-model="projectReportForm.reportId" placeholder="请输入项目周报ID" clearable />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="projectReportForm.projectId" placeholder="请输入项目ID" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="填写日期" prop="fillTime">
<el-date-picker
clearable
v-model="datePart"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="请选择填写日期"
@change="handleDateChange"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在的工作周" prop="currentWorkWeek">
<el-input v-model="projectReportForm.currentWorkWeek" placeholder="请输入所在的工作周" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所属里程碑" prop="milestonePlan">
<el-input v-model="projectReportForm.milestonePlan" placeholder="请输入所属里程碑" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="二级进度阶段" prop="secondaryPhase">
<el-input v-model="projectReportForm.secondaryPhase" placeholder="请输入二级进度阶段" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目状态" prop="scheduleStatus">
<el-select v-model="projectReportForm.scheduleStatus" placeholder="请选择项目状态" clearable>
<el-option v-for="dict in project_risk_status" :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="plannedCompletionRate">
<el-input
v-model="projectReportForm.plannedCompletionRate"
placeholder="请输入0-1之间的数字"
clearable
type="number"
:min="0"
:max="1"
:step="0.01"
@input="validatePlannedCompletionRate"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="本周完成工作" prop="tasksCompleted">
<el-input v-model="projectReportForm.tasksCompleted" type="textarea" placeholder="请输入本周完成工作" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="下周计划" prop="nextPlan">
<el-input v-model="projectReportForm.nextPlan" type="textarea" placeholder="请输入下周计划" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="风险及解决措施" prop="riskResolution">
<el-input v-model="projectReportForm.riskResolution" type="textarea" placeholder="请输入风险及解决措施" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="周报情况说明" prop="informationNote">
<el-input v-model="projectReportForm.informationNote" type="textarea" placeholder="请输入周报情况说明" />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="projectReportForm.sortOrder" placeholder="请输入排序号" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同ID" prop="contractId">
<el-input v-model="projectReportForm.contractId" placeholder="请输入合同ID" clearable />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="附件ID" prop="ossId">
<el-input v-model="projectReportForm.ossId" placeholder="请输入附件ID" clearable />
</el-form-item>
</el-col>
<el-col :span="12" v-show="false">
<el-form-item label="激活标识" prop="activeFlag">
<el-input v-model="projectReportForm.activeFlag" placeholder="请输入激活标识" clearable />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 修改项目周报明细对话框 -->
<el-dialog :title="ReportDialog.title" v-model="ReportDialog.visible" width="800px" append-to-body>
<el-form ref="projectReportDetailDialogFormRef" :model="detailForm" :rules="detailRules" label-width="120px">
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="项目周报ID" prop="reportId">
<el-input v-model="detailForm.reportId" placeholder="请输入项目周报ID" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="detailForm.projectId" placeholder="请输入项目ID" :disabled="true" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<!-- 修改对话框中的日期选择器 -->
<el-col :span="12">
<el-form-item label="填写日期" prop="fillTime">
<el-date-picker
clearable
v-model="modifyDatePart"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="请选择填写日期"
style="width: 100%"
@change="handleModifyDateChange"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="所在的工作周" prop="currentWorkWeek">
<el-input v-model="detailForm.currentWorkWeek" placeholder="请输入所在的工作周" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="所属里程碑" prop="milestonePlan">
<el-input v-model="detailForm.milestonePlan" placeholder="请输入所属里程碑" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="二级进度阶段" prop="secondaryPhase">
<el-input v-model="detailForm.secondaryPhase" placeholder="请输入二级进度阶段" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="24">
<el-form-item label="本周完成工作" prop="tasksCompleted">
<el-input v-model="detailForm.tasksCompleted" type="textarea" placeholder="请输入内容" :rows="4" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="24">
<el-form-item label="下周计划" prop="nextPlan">
<el-input v-model="detailForm.nextPlan" type="textarea" placeholder="请输入内容" :rows="4" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="24">
<el-form-item label="风险及解决措施" prop="riskResolution">
<el-input v-model="detailForm.riskResolution" type="textarea" placeholder="请输入内容" :rows="4" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="计划完成率" prop="plannedCompletionRate">
<el-input
v-model="detailForm.plannedCompletionRate"
placeholder="请输入0-1之间的数字"
clearable
type="number"
:min="0"
:max="1"
:step="0.01"
@input="validateModifyPlannedCompletionRate"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目状态" prop="scheduleStatus">
<el-select v-model="detailForm.scheduleStatus" placeholder="请选择项目状态">
<el-option label="正常" value="1" />
<el-option label="拖期风险" value="2" />
<el-option label="已拖期" value="3" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="周报状态" prop="projectReportStatus">
<el-select v-model="detailForm.projectReportStatus" placeholder="请选择周报状态" :disabled="true">
<el-option label="暂存" value="1" />
<el-option label="审批中" value="2" />
<el-option label="可用" value="3" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="流程状态" prop="flowStatus">
<el-input v-model="detailForm.flowStatus" placeholder="流程状态" :disabled="true" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="项目阶段" prop="projectPhases">
<el-input v-model="detailForm.projectPhases" placeholder="请输入项目阶段(预留)" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="合同ID" prop="contractId">
<el-input v-model="detailForm.contractId" placeholder="请输入合同ID(预留)" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="12">
<el-form-item label="排序号" prop="sortOrder">
<el-input v-model="detailForm.sortOrder" placeholder="请输入排序号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="附件" prop="ossId">
<el-button type="primary" plain icon="Upload" @click="handleFile">上传附件</el-button>
<span v-if="detailForm.ossId" style="margin-left: 10px; color: #409eff">已上传</span>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="24">
<el-form-item label="周报情况说明" prop="informationNote">
<el-input v-model="detailForm.informationNote" type="textarea" placeholder="请输入内容" :rows="3" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="10" class="form-row">
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="detailForm.remark" type="textarea" placeholder="请输入备注" :rows="3" />
</el-form-item>
</el-col>
</el-row>
<!-- 隐藏字段 -->
<el-row :gutter="10" class="form-row" v-show="false">
<el-col :span="12">
<el-form-item label="激活标识" prop="activeFlag">
<el-input v-model="detailForm.activeFlag" placeholder="请输入激活标识" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitProjectReportForm">确 定</el-button>
<el-button @click="cancelProjectReportForm">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 添加或修改OSS对象存储对话框 -->
<el-dialog v-model="dialog.visible" :title="dialog.title" width="500px" append-to-body>
<el-form ref="ossFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="文件名">
<fileUpload v-if="type === 0" v-model="ossFileModel" />
<imageUpload v-if="type === 1" v-model="ossFileModel" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitOss">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 提交审批组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<!-- 审批记录 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="ProjectReportEdit" lang="ts">
import { getRuleGenerateCode } from '@/api/system/codeRule';
import { StartProcessBo } from '@/api/workflow/workflowCommon/types';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import { ref } from 'vue';
import { CodeRuleEnum, FlowCodeEnum } from '@/enums/OAEnum';
import { ProjectReportVO, ProjectReportQuery, ProjectReportForm } from '@/api/oa/erp/projectReport/types';
import { listProjectReport, getProjectReport, delProjectReport, addProjectReport, updateProjectReport } from '@/api/oa/erp/projectReport';
import {
listProjectReportDetail,
getProjectReportDetail,
delProjectReportDetail,
addProjectReportDetail,
updateProjectReportDetail,
projectReportSubmitAndFlowStart
} from '@/api/oa/erp/projectReportDetail/index';
import {
ProjectReportDetailVO,
ProjectReportDetailQuery,
ProjectReportDetailForm,
ProjectReportDetailFormEx
} from '@/api/oa/erp/projectReportDetail/types';
import ProjectSelect from '@/components/ProjectSelect/index.vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
//
const routeParams = ref<Record<string, any>>({});
const { project_report_status, project_risk_status } = toRefs<any>(proxy?.useDict('project_report_status', 'project_risk_status'));
const buttonLoading = ref(false);
const projectFormRef = ref<ElFormInstance>();
// 根据项目名称选择项目组件引用
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
// 审批相关组件引用
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
// 流程相关数据
const submitFormData = ref<StartProcessBo>({
businessId: '',
flowCode: 'XMZB',
variables: {},
bizExt: {}
});
// 任务变量
const taskVariables = ref<Record<string, any>>({});
const flowInstanceBizExtBo = ref<Record<string, any>>({});
const type = ref(0);
const total = ref(0);
const loading = ref(false);
// 定义缓存键
const CACHE_KEYS = {
PROJECT_REPORT_DRAFT: 'project_report_draft_data',
PROJECT_REPORT_DETAIL_DRAFT: 'project_report_detail_draft_data'
};
// 项目周报上半部分
const initFormData: ProjectReportForm = {
reportId: undefined,
projectId: undefined,
projectName: undefined,
projectCode: undefined,
milestonePlan: undefined,
managerId: undefined,
deptId: undefined,
chargeId: undefined,
deputyId: undefined,
informationNote: undefined,
sortOrder: undefined,
ossId: undefined,
remark: undefined,
activeFlag: undefined,
deptName: undefined,
managerName: undefined,
chargeName: undefined,
deputyName: undefined
};
const data = reactive<PageData<ProjectReportForm, ProjectReportQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
reportId: undefined,
projectId: undefined,
projectName: undefined,
projectCode: undefined,
milestonePlan: undefined,
managerId: undefined,
deptId: undefined,
chargeId: undefined,
deputyId: undefined,
informationNote: undefined,
sortOrder: undefined,
ossId: undefined,
activeFlag: undefined,
deptName: undefined,
managerName: undefined,
chargeName: undefined,
deputyName: undefined,
params: {}
},
rules: {
projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }],
projectCode: [{ required: true, message: '项目编号不能为空', trigger: 'blur' }],
deptName: [{ required: true, message: '部门名称不能为空', trigger: 'blur' }],
managerName: [{ required: true, message: '项目经理不能为空', trigger: 'blur' }],
chargeName: [{ required: true, message: '部门负责人不能为空', trigger: 'blur' }],
deputyName: [{ required: true, message: '分管副总不能为空', trigger: 'blur' }]
}
});
const { form, queryParams, rules } = toRefs(data);
const initProjectReportDetailFormData: ProjectReportDetailForm = {
reportDetailId: undefined,
reportId: undefined,
projectId: undefined,
fillTime: undefined,
currentWorkWeek: undefined,
milestonePlan: undefined,
secondaryPhase: undefined,
tasksCompleted: undefined,
nextPlan: undefined,
riskResolution: undefined,
plannedCompletionRate: undefined,
informationNote: undefined,
scheduleStatus: undefined,
projectReportStatus: undefined,
flowStatus: undefined,
sortOrder: undefined,
projectPhases: undefined,
contractId: undefined,
ossId: undefined,
remark: undefined,
activeFlag: undefined
};
const projectReportDetailData = reactive<PageData<ProjectReportDetailForm, ProjectReportDetailQuery>>({
form: { ...initProjectReportDetailFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
reportId: undefined,
projectId: undefined,
fillTime: undefined,
currentWorkWeek: undefined,
milestonePlan: undefined,
secondaryPhase: undefined,
tasksCompleted: undefined,
nextPlan: undefined,
riskResolution: undefined,
plannedCompletionRate: undefined,
informationNote: undefined,
scheduleStatus: undefined,
projectReportStatus: undefined,
flowStatus: undefined,
sortOrder: undefined,
projectPhases: undefined,
contractId: undefined,
ossId: undefined,
activeFlag: undefined,
params: {}
},
rules: {
tasksCompleted: [{ required: true, message: '本周完成工作不能为空', trigger: 'blur' }],
nextPlan: [{ required: true, message: '下周计划不能为空', trigger: 'blur' }],
secondaryPhase: [{ required: true, message: '二级进度阶段不能为空', trigger: 'blur' }],
// 在 detailRules 中添加计划完成率的验证规则
plannedCompletionRate: [
{ required: false, message: '请填写计划完成率', trigger: 'blur' },
{
validator: (rule: any, value: any, callback: any) => {
if (value === null || value === undefined || value === '') {
callback();
return;
}
// 转换为数字
const numValue = Number(value);
// 检查是否为数字
if (isNaN(numValue)) {
callback(new Error('请输入有效的数字'));
return;
}
// 检查是否在0-1之间
if (numValue < 0 || numValue > 1) {
callback(new Error('请输入0-1之间的数字'));
return;
}
// 检查小数位数(可选)
const decimalPlaces = value.toString().split('.')[1];
if (decimalPlaces && decimalPlaces.length > 2) {
callback(new Error('最多支持两位小数'));
return;
}
callback();
},
trigger: 'blur'
}
]
}
});
// 解构明细数据
const { form: detailForm, queryParams: detailQueryParams, rules: detailRules } = toRefs(projectReportDetailData);
// 验证修改对话框中的计划完成率输入
const validateModifyPlannedCompletionRate = (value: string) => {
if (!value) return;
// 转换为数字
const numValue = Number(value);
// 如果输入无效或超出范围,重置为有效值
if (isNaN(numValue)) {
detailForm.value.plannedCompletionRate = 0;
return;
}
// 限制在0-1之间
if (numValue < 0) {
detailForm.value.plannedCompletionRate = 0;
} else if (numValue > 1) {
detailForm.value.plannedCompletionRate = 1;
} else {
// 限制小数位数(可选)
const decimalPlaces = value.split('.')[1];
if (decimalPlaces && decimalPlaces.length > 2) {
detailForm.value.plannedCompletionRate = parseFloat(numValue.toFixed(2));
}
}
};
// OSS功能
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const projectReportList = ref<ProjectReportVO[]>([]);
// 打开项目选择框
const openProjectSelect = () => {
projectSelectRef.value.open();
};
//根据项目名称回调项目信息
const projectInfoSelectCallBack = (data: any) => {
if (data.length > 0) {
Object.assign(form.value, data[0]);
} else {
projectFormRef.value?.resetFields();
proxy?.$modal.msgWarning('请选择项目信息');
}
};
/** 文件按钮操作 */
const handleFile = () => {
type.value = 0;
dialog.visible = true;
dialog.title = '上传周报附件';
// 打开时回显已有附件
ossFileModel.value = form.value.ossId as any;
};
// OSS 上传内部 v-model 中转,避免直接绑定到 form 的未知属性
const ossFileModel = ref<string | string[] | undefined>(undefined);
/** 取消按钮 */
function cancel() {
dialog.visible = false;
}
// 确认上传,仅关闭弹窗并依赖 v-model 同步到 ossId
const submitOss = () => {
// 将上传组件返回的 ossId 串写回表单
form.value.ossId = ossFileModel.value as any;
dialog.visible = false;
proxy?.$modal.msgSuccess('附件已更新');
};
// 监听上传组件返回的文件ossId 串)并同步到表单字段
// 同步表单初值到上传模型
watch(
() => form.value.ossId,
(val) => {
if (!dialog.visible) {
ossFileModel.value = val as any;
projectReportForm.value.ossId = val as any;
}
}
);
const ReportDialog = reactive<DialogOption>({
visible: false,
title: ''
});
const projectReportDetailFormRef = ref<ElFormInstance>();
const projectReportDetailList = ref<ProjectReportDetailVO[]>([]);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
/** 多选框选中数据 */
const handleSelectionChange = (selection: ProjectReportDetailVO[]) => {
ids.value = selection.map((item) => item.reportDetailId);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
// 列显隐信息
const columns = ref<FieldOption[]>([
{ key: 0, label: `项目周报明细ID`, visible: false },
{ key: 1, label: `项目周报ID`, visible: false },
{ key: 2, label: `项目ID`, visible: false },
{ key: 3, label: `填写日期`, visible: true },
{ key: 4, label: `所在的工作周`, visible: true },
{ key: 5, label: `所属里程碑`, visible: true },
{ key: 6, label: `二级进度阶段`, visible: true },
{ key: 7, label: `本周完成工作`, visible: true },
{ key: 8, label: `下周计划`, visible: true },
{ key: 9, label: `风险及解决措施`, visible: true },
{ key: 10, label: `计划完成率`, visible: true },
{ key: 11, label: `周报情况说明`, visible: true },
{ key: 12, label: `项目状态`, visible: true },
{ key: 13, label: `周报状态(1暂存 2审批中 3可用)`, visible: true },
{ key: 14, label: `流程状态`, visible: true },
{ key: 15, label: `排序号`, visible: false },
{ key: 16, label: `项目阶段(预留)`, visible: false },
{ key: 17, label: `合同ID(预留)`, visible: false },
{ key: 18, label: `附件ID`, visible: true },
{ key: 19, label: `备注`, visible: true },
{ key: 20, label: `激活标识`, visible: false }
// { key: 21, label: `删除标志`, visible: true },
// { key: 22, label: `创建部门`, visible: true },
// { key: 23, label: `创建时间`, visible: true },
// { key: 24, label: `创建人`, visible: true },
// { key: 25, label: `更新人`, visible: true },
// { key: 26, label: `更新时间`, visible: true }
]);
// 项目周报明细表单引用
const projectReportFormRef = ref<ElFormInstance>();
const projectReportDetailDialogFormRef = ref<ElFormInstance>();
// 项目周报明细表单数据
const initProjectReportFormData: ProjectReportDetailFormEx = {
reportDetailId: undefined,
reportId: undefined,
projectId: undefined,
fillTime: undefined,
currentWorkWeek: undefined,
milestonePlan: undefined,
secondaryPhase: undefined,
tasksCompleted: undefined,
nextPlan: undefined,
riskResolution: undefined,
plannedCompletionRate: undefined,
informationNote: undefined,
scheduleStatus: undefined,
projectReportStatus: undefined,
flowStatus: undefined,
sortOrder: undefined,
projectPhases: undefined,
contractId: undefined,
ossId: undefined,
remark: undefined,
activeFlag: undefined,
flowCode: undefined,
bizExt: undefined,
variables: undefined
} as any;
const projectReportForm = ref<ProjectReportDetailFormEx>({ ...initProjectReportFormData });
const projectReportFormQuery = ref<ProjectReportDetailQuery>({
pageNum: 1,
pageSize: 10,
reportId: undefined,
projectId: undefined,
fillTime: undefined,
currentWorkWeek: undefined,
milestonePlan: undefined,
secondaryPhase: undefined,
tasksCompleted: undefined,
nextPlan: undefined,
riskResolution: undefined,
plannedCompletionRate: undefined,
informationNote: undefined,
scheduleStatus: undefined,
projectReportStatus: undefined,
flowStatus: undefined,
sortOrder: undefined,
projectPhases: undefined,
contractId: undefined,
ossId: undefined,
activeFlag: undefined,
params: {}
});
// 项目周报明细表单规则验证
const reportRules = {
tasksCompleted: [{ required: true, message: '本周完成工作不能为空', trigger: 'blur' }],
nextPlan: [{ required: true, message: '下周计划不能为空', trigger: 'blur' }],
secondaryPhase: [{ required: true, message: '二级进度阶段不能为空', trigger: 'blur' }],
plannedCompletionRate: [
{ required: false, message: '请填写计划完成率', trigger: 'blur' },
{
validator: (rule: any, value: any, callback: any) => {
if (value === null || value === undefined || value === '') {
callback();
return;
}
// 转换为数字
const numValue = Number(value);
// 检查是否为数字
if (isNaN(numValue)) {
callback(new Error('请输入有效的数字'));
return;
}
// 检查是否在0-1之间
if (numValue < 0 || numValue > 1) {
callback(new Error('请输入0-1之间的数字'));
return;
}
// 检查小数位数(可选)
const decimalPlaces = value.toString().split('.')[1];
if (decimalPlaces && decimalPlaces.length > 2) {
callback(new Error('最多支持两位小数'));
return;
}
callback();
},
trigger: 'blur'
}
]
};
// 验证计划完成率输入
const validatePlannedCompletionRate = (value: string) => {
if (!value) return;
// 转换为数字
const numValue = Number(value);
// 如果输入无效或超出范围,重置为有效值
if (isNaN(numValue)) {
projectReportForm.value.plannedCompletionRate = 0;
return;
}
// 限制在0-1之间
if (numValue < 0) {
projectReportForm.value.plannedCompletionRate = 0;
} else if (numValue > 1) {
projectReportForm.value.plannedCompletionRate = 1;
} else {
// 限制小数位数(可选)
const decimalPlaces = value.split('.')[1];
if (decimalPlaces && decimalPlaces.length > 2) {
projectReportForm.value.plannedCompletionRate = parseFloat(numValue.toFixed(2));
}
}
};
// 计算属性:格式化显示计划完成率
const formattedPlannedCompletionRate = computed(() => {
if (projectReportForm.value.plannedCompletionRate === null || projectReportForm.value.plannedCompletionRate === undefined) {
return '';
}
const value = Number(projectReportForm.value.plannedCompletionRate);
if (isNaN(value)) return '';
// 转换为百分比显示保留2位小数
return `${(value * 100).toFixed(2)}%`;
});
/** 表单重置 */
const reset = () => {
detailForm.value = { ...initProjectReportDetailFormData };
modifyDatePart.value = ''; // 重置修改对话框的日期部分
projectReportDetailDialogFormRef.value?.resetFields();
};
/** 修改按钮操作 */
const handleUpdate = async (row?: ProjectReportDetailVO) => {
reset();
const _reportDetailId = row?.reportDetailId || ids.value[0];
const res = await getProjectReportDetail(_reportDetailId);
Object.assign(detailForm.value, res.data);
// 从 fillTime 中提取日期部分,用于日期选择器
if (detailForm.value.fillTime) {
const [date] = detailForm.value.fillTime.split(' ');
if (date) {
modifyDatePart.value = date;
// 计算工作周
detailForm.value.currentWorkWeek = getWorkWeek(date);
}
} else {
// 如果没有日期,设置当前日期
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const dateStr = `${year}-${month}-${day}`;
// 设置当前时间
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const timeStr = `${hours}:${minutes}:${seconds}`;
modifyDatePart.value = dateStr;
detailForm.value.fillTime = `${dateStr} ${timeStr}`;
detailForm.value.currentWorkWeek = getWorkWeek(dateStr);
}
ReportDialog.visible = true;
ReportDialog.title = '修改项目周报明细';
};
/** 删除按钮操作 */
const handleDelete = async (row?: ProjectReportDetailVO) => {
const _reportDetailIds = row?.reportDetailId || ids.value;
await proxy?.$modal.confirm('是否确认删除项目周报明细编号为"' + _reportDetailIds + '"的数据项?').finally(() => (buttonLoading.value = false));
await delProjectReportDetail(_reportDetailIds);
proxy?.$modal.msgSuccess('删除成功');
await getProjectDetail();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'oa/erp/projectReportDetail/export',
{
reportId: form.value.reportId
},
`projectReportDetail_${new Date().getTime()}.xlsx`
);
};
// 重置项目周报添加对话框
const resetProjectReportForm = () => {
detailForm.value = { ...initProjectReportDetailFormData };
projectReportDetailDialogFormRef.value?.resetFields();
};
// 取消项目周报添加对话框
const cancelProjectReportForm = () => {
resetProjectReportForm();
ReportDialog.visible = false;
};
/** 提交按钮 */
const submitProjectReportForm = () => {
projectReportDetailDialogFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (detailForm.value.reportDetailId) {
await updateProjectReportDetail(detailForm.value).finally(() => (buttonLoading.value = false));
} else {
await addProjectReportDetail(detailForm.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
ReportDialog.visible = false;
await getProjectDetail();
}
});
};
// 添加响应式变量来存储日期部分
const datePart = ref(''); // 日期部分YYYY-MM-DD
// 工作周计算函数 - 包含星期几
const getWorkWeek = (dateString) => {
if (!dateString) return '';
const date = new Date(dateString);
if (isNaN(date.getTime())) {
return '';
}
const year = date.getFullYear();
const firstDayOfYear = new Date(year, 0, 1);
// 使用时间戳计算天数差
const timeDiff = date.getTime() - firstDayOfYear.getTime();
const days = Math.floor(timeDiff / (24 * 60 * 60 * 1000)) + 1;
// 计算周数
const firstDayWeek = firstDayOfYear.getDay();
const isoFirstDayWeek = firstDayWeek === 0 ? 7 : firstDayWeek;
const weekNumber = Math.ceil((days + isoFirstDayWeek - 1) / 7);
// 获取星期几0-周日1-周一,...6-周六)
const weekday = date.getDay();
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return `${weekdays[weekday]}`;
};
// 初始化默认日期
const initDefaultDate = () => {
if (routeParams.value.type === 'add') {
// 如果有传入的 reportData使用传入的数据不读取缓存
if (!routeParams.value.reportData) {
// 没有传入数据,尝试从缓存读取
const cachedFormData = proxy?.$cache.local.getJSON(CACHE_KEYS.PROJECT_REPORT_DRAFT);
const cachedDetailData = proxy?.$cache.local.getJSON(CACHE_KEYS.PROJECT_REPORT_DETAIL_DRAFT);
if (cachedFormData) {
// 恢复表单数据
Object.assign(form.value, cachedFormData);
}
if (cachedDetailData) {
// 恢复明细数据
Object.assign(projectReportForm.value, cachedDetailData);
}
}
// 设置日期部分和 fillTime
const now = new Date();
// 格式化日期为 YYYY-MM-DD
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const dateStr = `${year}-${month}-${day}`;
// 格式化时间为 HH:mm:ss用于保存
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const timeStr = `${hours}:${minutes}:${seconds}`;
// 设置日期部分
datePart.value = dateStr;
// 组合成完整的日期时间字符串(带当前时间)
// 如果已有 fillTime从缓存或传入数据使用已有的否则设置新的
if (!projectReportForm.value.fillTime) {
projectReportForm.value.fillTime = `${dateStr} ${timeStr}`;
} else {
// 确保 fillTime 是 DateTime 格式,如果只有日期部分,添加时间部分
if (projectReportForm.value.fillTime && !projectReportForm.value.fillTime.includes(' ')) {
projectReportForm.value.fillTime = `${projectReportForm.value.fillTime} ${timeStr}`;
}
}
// 计算工作周
projectReportForm.value.currentWorkWeek = getWorkWeek(dateStr);
}
};
// 处理日期变化
const handleDateChange = (selectedDate) => {
if (selectedDate) {
// 获取当前时间(用户提交流程的时间)
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const timeStr = `${hours}:${minutes}:${seconds}`;
// 组合成完整的日期时间字符串(日期为用户选择的,时间为当前时间)
projectReportForm.value.fillTime = `${selectedDate} ${timeStr}`;
// 计算工作周
projectReportForm.value.currentWorkWeek = getWorkWeek(selectedDate);
} else {
// 如果清空了日期
projectReportForm.value.fillTime = '';
projectReportForm.value.currentWorkWeek = '';
}
};
// 监听 fillTime 变化,当从后端获取数据时设置日期部分
watch(
() => projectReportForm.value.fillTime,
(newValue) => {
if (newValue && (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval')) {
// 解析日期时间字符串,只取日期部分
const [date] = newValue.split(' ');
if (date) {
datePart.value = date;
}
}
},
{ immediate: true }
);
// 添加修改对话框的日期部分变量
const modifyDatePart = ref('');
// 处理修改对话框日期变化
const handleModifyDateChange = (selectedDate) => {
if (selectedDate) {
// 获取当前时间(保持原有时间或使用当前时间)
let timeStr = '';
if (detailForm.value.fillTime && detailForm.value.fillTime.includes(' ')) {
const [, time] = detailForm.value.fillTime.split(' ');
if (time) {
timeStr = time;
} else {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
timeStr = `${hours}:${minutes}:${seconds}`;
}
} else {
const now = new Date();
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
timeStr = `${hours}:${minutes}:${seconds}`;
}
// 组合成完整的日期时间字符串
detailForm.value.fillTime = `${selectedDate} ${timeStr}`;
// 计算工作周
detailForm.value.currentWorkWeek = getWorkWeek(selectedDate);
} else {
// 如果清空了日期
detailForm.value.fillTime = '';
detailForm.value.currentWorkWeek = '';
}
};
// 审批记录
const handleApprovalRecord = () => {
approvalRecordRef.value.init(projectReportForm.value.reportDetailId);
};
// 提交回调
const submitCallback = async () => {
await proxy.$tab.closePage(route);
router.go(-1);
};
// 审批
const approvalVerifyOpen = async () => {
await submitVerifyRef.value.openDialog(routeParams.value.taskId);
};
const isCodeGenerated = ref(false);
// 生成项目周报编号
const generateCode = async () => {
if (isCodeGenerated.value) return; // 如果已经生成过,直接返回
try {
const params = { codeRuleCode: CodeRuleEnum.PROJECT_REPORT } as any;
const res = await getRuleGenerateCode(params);
isCodeGenerated.value = true; // 标记为已生成
return res.msg;
} catch (error) {
console.error('生成业务编号失败:', error);
proxy?.$modal.msgError('生成业务编号失败');
}
};
// 保存草稿到缓存
const saveToDraftCache = () => {
try {
// 保存主表单数据
proxy?.$cache.local.setJSON(CACHE_KEYS.PROJECT_REPORT_DRAFT, form.value);
// 保存明细表单数据
proxy?.$cache.local.setJSON(CACHE_KEYS.PROJECT_REPORT_DETAIL_DRAFT, projectReportForm.value);
} catch (error) {
console.error('保存草稿到缓存失败:', error);
}
};
// 从缓存加载草稿
const loadFromDraftCache = () => {
try {
const cachedFormData = proxy?.$cache.local.getJSON(CACHE_KEYS.PROJECT_REPORT_DRAFT);
const cachedDetailData = proxy?.$cache.local.getJSON(CACHE_KEYS.PROJECT_REPORT_DETAIL_DRAFT);
if (cachedFormData) {
Object.assign(form.value, cachedFormData);
}
if (cachedDetailData) {
Object.assign(projectReportForm.value, cachedDetailData);
// 恢复日期显示
if (projectReportForm.value.fillTime) {
const [date] = projectReportForm.value.fillTime.split(' ');
if (date) {
datePart.value = date;
projectReportForm.value.currentWorkWeek = getWorkWeek(date);
}
}
}
return !!cachedFormData || !!cachedDetailData;
} catch (error) {
console.error('从缓存加载草稿失败:', error);
return false;
}
};
// 清除草稿缓存
const clearDraftCache = () => {
try {
proxy?.$cache.local.remove(CACHE_KEYS.PROJECT_REPORT_DRAFT);
proxy?.$cache.local.remove(CACHE_KEYS.PROJECT_REPORT_DETAIL_DRAFT);
} catch (error) {
console.error('清除草稿缓存失败:', error);
}
};
// 添加缓存操作按钮(可选,用于手动清除缓存)
const handleClearDraft = () => {
clearDraftCache();
proxy?.$modal.msgSuccess('草稿缓存已清除');
// 重置表单
projectFormRef.value?.resetFields();
projectReportDetailFormRef.value?.resetFields();
datePart.value = '';
initDefaultDate();
};
const getProjectDetail = async () => {
loading.value = true;
const res = await listProjectReportDetail({ pageNum: 1, pageSize: 10, reportId: form.value.reportId });
projectReportDetailList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 提交按钮 */
const submitForm = async (status: string, mode: boolean) => {
try {
buttonLoading.value = true;
// 验证两个表单
let formValid = false;
let detailFormValid = false;
// 验证第一个表单
await new Promise((resolve) => {
projectFormRef.value?.validate((valid: boolean) => {
formValid = valid;
resolve(null);
});
});
if (!formValid) {
proxy?.$modal.msgError('请完善项目周报信息');
// 滚动到第一个错误字段
const errorFields = document.querySelector('.el-form-item__error');
if (errorFields) {
errorFields.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
return;
}
// 验证第二个表单
await new Promise((resolve) => {
projectReportDetailFormRef.value?.validate((valid: boolean) => {
detailFormValid = valid;
resolve(null);
});
});
if (!detailFormValid) {
proxy?.$modal.msgError('请完善项目周报明细信息');
// 滚动到第一个错误字段
const errorFields = document.querySelector('.el-form-item__error');
if (errorFields) {
errorFields.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
return;
}
// 设置后端发起和不等于草稿状态 直接走流程发起
if (status != 'draft') {
// 后端发起流程模式
projectReportForm.value.flowCode = FlowCodeEnum.PROJECT_REPRORT_CODE;
const msg = await generateCode();
// 流程变量
projectReportForm.value.variables = {
projectId: form.value.projectId
};
// 流程实例业务扩展字段
projectReportForm.value.bizExt = {
businessTitle: '项目周报明细',
businessCode: msg
};
// 直接使用现有的两个表单数据
projectReportForm.value.projectId = form.value.projectId;
const requestData = {
projectReport: form.value, // 项目周报数据
projectDetailReport: projectReportForm.value // 项目周报明细数据
};
projectReportForm.value.flowStatus = 'waiting';
const res = await projectReportSubmitAndFlowStart(requestData);
projectReportForm.value = { ...projectReportForm.value, ...res.data };
// 提交成功后清除缓存
clearDraftCache();
proxy?.$modal.msgSuccess('操作成功');
proxy?.$tab.closePage();
router.go(-1);
} else {
// 暂存逻辑
if (status === 'draft') {
projectReportForm.value.flowStatus = 'draft';
// 暂存时保存到缓存
saveToDraftCache();
}
buttonLoading.value = false;
proxy?.$modal.msgSuccess('暂存成功');
proxy?.$tab.closePage();
router.go(-1);
}
} catch (error) {
console.error('提交失败:', error);
proxy?.$modal.msgError('提交失败');
} finally {
buttonLoading.value = false;
}
};
onMounted(async () => {
nextTick(async () => {
// 获取路由参数
routeParams.value = route.query;
// 是否为查看或更新
const reportDataStr = routeParams.value.reportData as string;
if (reportDataStr && (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'add')) {
proxy?.$modal.loading('正在加载数据,请稍后...');
const reportData = JSON.parse(decodeURIComponent(reportDataStr));
Object.assign(form.value, reportData);
if (routeParams.value.type === 'add') {
initDefaultDate();
Object.assign(projectReportForm.value, reportData);
projectReportForm.value.informationNote = '';
} else if (routeParams.value.type === 'view') {
await getProjectDetail();
}
proxy?.$modal.closeLoading();
} else if (routeParams.value.type === 'add') {
// 纯新增模式,初始化默认日期和时间,会检查缓存
initDefaultDate();
} else if (routeParams.value.type === 'approval' || routeParams.value.type === 'view') {
// 编辑或审批模式:从接口获取数据
const projectDetailReportId = routeParams.value.id;
if (projectDetailReportId) {
proxy?.$modal.loading('正在加载数据,请稍后...');
const reportDetailRes = await getProjectReportDetail(projectDetailReportId);
const reportId = reportDetailRes.data.reportId;
if (reportId && routeParams.value.type === 'view') {
const reportRes = await getProjectReport(reportId);
Object.assign(form.value, reportRes.data);
Object.assign(projectReportForm.value, reportDetailRes.data);
projectReportDetailList.value = [reportDetailRes.data];
}
if (reportId && routeParams.value.type === 'approval') {
const reportRes = await getProjectReport(reportId);
Object.assign(form.value, reportRes.data);
Object.assign(projectReportForm.value, reportDetailRes.data);
}
proxy?.$modal.closeLoading();
}
}
});
});
</script>