张诺
6 天以前 c8b65690b946b28b179796fbe2f020e732043c58
src/views/oaSystem/projectManagement/projectDetail.vue
@@ -8,7 +8,8 @@
          <span>项目基本信息</span>
        </div>
      </template>
      <el-descriptions :column="2" border>
      <el-descriptions :column="2"
                       border>
        <el-descriptions-item label="项目名称">{{ projectInfo.projectName }}</el-descriptions-item>
        <el-descriptions-item label="项目负责人">{{ projectInfo.managerName }}</el-descriptions-item>
        <el-descriptions-item label="开始日期">{{ projectInfo.startDate }}</el-descriptions-item>
@@ -17,12 +18,13 @@
          <el-tag :type="getStatusType(projectInfo.status)">{{ getStatusText(projectInfo.status) }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="完成度">
          <el-progress :percentage="projectInfo.completionRate" :stroke-width="6" />
          <el-progress :percentage="projectInfo.completionRate"
                       :stroke-width="6" />
        </el-descriptions-item>
        <el-descriptions-item label="项目描述" :span="2">{{ projectInfo.description || '-' }}</el-descriptions-item>
        <el-descriptions-item label="项目描述"
                              :span="2">{{ projectInfo.description || '-' }}</el-descriptions-item>
      </el-descriptions>
    </el-card>
    <!-- 项目进度概览 -->
    <el-card class="mb20">
      <template #header>
@@ -57,7 +59,6 @@
        </el-col>
      </el-row>
    </el-card>
    <!-- 阶段和任务管理 -->
    <!-- <el-card class="mb20">
      <template #header>
@@ -68,162 +69,175 @@
      </template>
      <task-tree :project-id="projectId" @refresh="getProjectDetail" />
    </el-card> -->
    <!-- 里程碑管理 -->
    <el-card class="mb20">
      <template #header>
        <div class="card-header">
          <span>项目阶段里程碑</span>
          <el-button type="primary" size="small" @click="handleAddMilestone">添加里程碑</el-button>
          <el-button type="primary"
                     size="small"
                     @click="handleAddMilestone">添加里程碑</el-button>
        </div>
      </template>
      <milestone-list :project-id="projectId" @refresh="getProjectDetail" :key="`milestone-${refreshProjectId}`"/>
      <milestone-list :project-id="projectId"
                      @refresh="getProjectDetail"
                      :key="`milestone-${refreshProjectId}`" />
    </el-card>
    <!-- 阶段目标管理 -->
    <el-card>
      <template #header>
        <div class="card-header">
          <span>阶段任务</span>
          <el-button type="primary" size="small" @click="handleAddPhaseGoal">添加阶段目标</el-button>
          <el-button type="primary"
                     size="small"
                     @click="handleAddPhaseGoal">添加阶段目标</el-button>
        </div>
      </template>
      <phase-goal-list :project-id="projectId" @refresh="getProjectDetail" @editGoal="handleEditPhaseGoal" :key="`phaseGoal-${refreshProjectId}`"/>
      <phase-goal-list :project-id="projectId"
                       @refresh="getProjectDetail"
                       @editGoal="handleEditPhaseGoal"
                       :key="`phaseGoal-${refreshProjectId}`" />
    </el-card>
    <!-- 里程碑管理弹框 -->
    <el-dialog :title="title" v-model="open" width="600px" append-to-body>
      <el-form :model="form" ref="formRef" label-width="100px">
    <el-form-item label="项目阶段名称" prop="phaseName">
      <el-input
        v-model="form.phaseName"
        placeholder="请输入项目阶段名称"
        maxlength="50"
      />
    </el-form-item>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-form-item label="开始日期" prop="startDate">
          <el-date-picker
            v-model="form.startDate"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="选择开始日期"
            style="width: 100%"
          />
    <!-- 里程碑管理弹框 -->
    <el-dialog :title="title"
               v-model="open"
               width="600px"
               append-to-body>
      <el-form :model="form"
               ref="formRef"
               label-width="100px">
        <el-form-item label="项目阶段名称"
                      prop="phaseName">
          <el-input v-model="form.phaseName"
                    placeholder="请输入项目阶段名称"
                    maxlength="50" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="结束日期" prop="endDate">
          <el-date-picker
            v-model="form.endDate"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="选择结束日期"
            style="width: 100%"
          />
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="开始日期"
                          prop="startDate">
              <el-date-picker v-model="form.startDate"
                              type="date"
                              format="YYYY-MM-DD"
                              value-format="YYYY-MM-DD"
                              placeholder="选择开始日期"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束日期"
                          prop="endDate">
              <el-date-picker v-model="form.endDate"
                              type="date"
                              format="YYYY-MM-DD"
                              value-format="YYYY-MM-DD"
                              placeholder="选择结束日期"
                              style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="状态"
                      prop="status">
          <el-radio-group v-model="form.status">
            <el-radio label="notStarted">未开始</el-radio>
            <el-radio label="completed">已完成</el-radio>
            <el-radio label="delayed">已延迟</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-col>
    </el-row>
    <el-form-item label="状态" prop="status">
      <el-radio-group v-model="form.status">
        <el-radio label="notStarted">未开始</el-radio>
        <el-radio label="completed">已完成</el-radio>
        <el-radio label="delayed">已延迟</el-radio>
      </el-radio-group>
    </el-form-item>
  </el-form>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="submitForm">确定</el-button>
          <el-button @click="cancel">取消</el-button>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 阶段任务管理弹框 -->
    <el-dialog :title="goalTitle" v-model="goalOpen" width="600px" append-to-body>
      <el-form :model="goalForm" ref="goalFormRef" label-width="100px">
        <el-form-item label="所属阶段" prop="phaseId">
          <el-select v-model="goalForm.phaseId" placeholder="请选择所属阶段">
            <el-option
              v-for="phase in phaseList"
              :key="phase.phaseId"
              :label="phase.phaseName"
              :value="phase.phaseId"
            />
    <el-dialog :title="goalTitle"
               v-model="goalOpen"
               width="600px"
               append-to-body>
      <el-form :model="goalForm"
               ref="goalFormRef"
               label-width="100px">
        <el-form-item label="所属阶段"
                      prop="phaseId">
          <el-select v-model="goalForm.phaseId"
                     placeholder="请选择所属阶段">
            <el-option v-for="phase in phaseList"
                       :key="phase.phaseId"
                       :label="phase.phaseName"
                       :value="phase.phaseId" />
          </el-select>
        </el-form-item>
        <el-form-item label="目标名称" prop="taskName">
          <el-input
            v-model="goalForm.taskName"
            placeholder="请输入目标名称"
            maxlength="50"
          />
        <el-form-item label="目标名称"
                      prop="taskName">
          <el-input v-model="goalForm.taskName"
                    placeholder="请输入目标名称"
                    maxlength="50" />
        </el-form-item>
        <el-form-item label="目标值" prop="targetValue">
          <el-input-number
            v-model="goalForm.targetValue"
            :min="0"
            :precision="2"
            placeholder="请输入目标值"
            style="width: 100%"
          />
        <el-form-item label="目标值"
                      prop="targetValue">
          <el-input-number v-model="goalForm.targetValue"
                           :min="0"
                           :precision="2"
                           placeholder="请输入目标值"
                           style="width: 100%" />
        </el-form-item>
        <el-form-item label="当前值" prop="currentValue">
          <el-input-number
            v-model="goalForm.currentValue"
            :min="0"
            :precision="2"
            placeholder="请输入当前值"
            style="width: 100%"
          />
        <el-form-item label="当前值"
                      prop="currentValue">
          <el-input-number v-model="goalForm.currentValue"
                           :min="0"
                           :precision="2"
                           placeholder="请输入当前值"
                           style="width: 100%" />
        </el-form-item>
        <el-form-item label="单位" prop="unit">
          <el-input
            v-model="goalForm.unit"
            placeholder="请输入单位"
            maxlength="10"
          />
        <el-form-item label="单位"
                      prop="unit">
          <el-input v-model="goalForm.unit"
                    placeholder="请输入单位"
                    maxlength="10" />
        </el-form-item>
        <el-form-item label="任务完成日期" prop="targetDate">
          <el-date-picker
            v-model="goalForm.targetDate"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="选择目标日期"
            style="width: 100%"
          />
        <el-form-item label="任务完成日期"
                      prop="targetDate">
          <el-date-picker v-model="goalForm.targetDate"
                          type="date"
                          format="YYYY-MM-DD"
                          value-format="YYYY-MM-DD"
                          placeholder="选择目标日期"
                          style="width: 100%" />
        </el-form-item>
        <el-form-item label="开始日期" prop="startDate">
          <el-date-picker
            v-model="goalForm.startDate"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="选择目标日期"
            style="width: 100%"
          />
        <el-form-item label="开始日期"
                      prop="startDate">
          <el-date-picker v-model="goalForm.startDate"
                          type="date"
                          format="YYYY-MM-DD"
                          value-format="YYYY-MM-DD"
                          placeholder="选择目标日期"
                          style="width: 100%" />
        </el-form-item>
        <el-form-item label="结束日期" prop="endDate">
          <el-date-picker
            v-model="goalForm.endDate"
            type="date"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            placeholder="选择目标日期"
            style="width: 100%"
          />
        <el-form-item label="结束日期"
                      prop="endDate">
          <el-date-picker v-model="goalForm.endDate"
                          type="date"
                          format="YYYY-MM-DD"
                          value-format="YYYY-MM-DD"
                          placeholder="选择目标日期"
                          style="width: 100%" />
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <el-select v-model="goalForm.status" placeholder="请选择状态">
            <el-option label="未开始" value="notStarted" />
            <el-option label="进行中" value="inProgress" />
            <el-option label="已完成" value="completed" />
            <el-option label="已延迟" value="delayed" />
        <el-form-item label="状态"
                      prop="status">
          <el-select v-model="goalForm.status"
                     placeholder="请选择状态">
            <el-option label="未开始"
                       value="notStarted" />
            <el-option label="进行中"
                       value="inProgress" />
            <el-option label="已完成"
                       value="completed" />
            <el-option label="已延迟"
                       value="delayed" />
          </el-select>
        </el-form-item>
        <!-- <el-form-item label="完成度" prop="completionRate">
@@ -239,8 +253,9 @@
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="submitGoalForm">确定</el-button>
          <el-button @click="cancelGoal">取消</el-button>
          <el-button type="primary" @click="submitGoalForm">确定</el-button>
        </div>
      </template>
    </el-dialog>
@@ -248,318 +263,331 @@
</template>
<script setup>
import { ref, reactive, onMounted, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import TaskTree from './components/taskTree.vue';
import MilestoneList from './components/milestoneList.vue';
import ProjectForm from './components/projectForm.vue';
import PhaseGoalList from './components/phaseGoalList.vue';
import { getProject, addProjectPhase, listProjectPhase, addProjectTask, updateProjectTask } from '@/api/oaSystem/projectManagement';
  import { ref, reactive, onMounted, watch } from "vue";
  import { useRoute, useRouter } from "vue-router";
  import { ElMessage } from "element-plus";
  import TaskTree from "./components/taskTree.vue";
  import MilestoneList from "./components/milestoneList.vue";
  import ProjectForm from "./components/projectForm.vue";
  import PhaseGoalList from "./components/phaseGoalList.vue";
  import {
    getProject,
    addProjectPhase,
    listProjectPhase,
    addProjectTask,
    updateProjectTask,
  } from "@/api/oaSystem/projectManagement";
const route = useRoute();
const router = useRouter();
const open = ref(false);
const title = ref('');
const projectFormRef = ref();
const formRef = ref();
// 项目ID
// 在其他ref定义附近添加
const refreshProjectId = ref(0);
  const route = useRoute();
  const router = useRouter();
  const open = ref(false);
  const title = ref("");
  const projectFormRef = ref();
  const formRef = ref();
  // 项目ID
  // 在其他ref定义附近添加
  const refreshProjectId = ref(0);
const projectId = ref(route.params.projectId);
  const projectId = ref(route.params.projectId);
// 项目信息
const projectInfo = reactive({
  projectId: '',
  projectName: '',
  description: '',
  startDate: '',
  endDate: '',
  managerId: '',
  managerName: '',
  status: 'planning',
  completionRate: 0
});
  // 项目信息
  const projectInfo = reactive({
    projectId: "",
    projectName: "",
    description: "",
    startDate: "",
    endDate: "",
    managerId: "",
    managerName: "",
    status: "planning",
    completionRate: 0,
  });
// 统计信息
const statistics = reactive({
  totalPhases: 0,
  totalTasks: 0,
  completedTasks: 0
});
const form = reactive({
  phaseId: '',
  phaseName: '',
  startDate: '',
  endDate: '',
  status: 'planning',
  oaProjectId: projectId.value,
})
  // 统计信息
  const statistics = reactive({
    totalPhases: 0,
    totalTasks: 0,
    completedTasks: 0,
  });
  const form = reactive({
    phaseId: "",
    phaseName: "",
    startDate: "",
    endDate: "",
    status: "planning",
    oaProjectId: projectId.value,
  });
// 阶段目标相关
const goalOpen = ref(false);
const goalTitle = ref('');
const goalFormRef = ref();
const phaseList = ref([]);
const goalForm = reactive({
  taskId: '',
  phaseId: '',
  taskName: '',
  targetValue: 100,
  currentValue: 0,
  unit: '%',
  targetDate: '',
  startDate: '',
  endDate: '',
  status: 'notStarted',
  completionRate: 0
});
  // 阶段目标相关
  const goalOpen = ref(false);
  const goalTitle = ref("");
  const goalFormRef = ref();
  const phaseList = ref([]);
  const goalForm = reactive({
    taskId: "",
    phaseId: "",
    taskName: "",
    targetValue: 100,
    currentValue: 0,
    unit: "%",
    targetDate: "",
    startDate: "",
    endDate: "",
    status: "notStarted",
    completionRate: 0,
  });
// 获取项目详情
const getProjectDetail = async () => {
  try {
    getProject().then((res)=>{
      console.log("项目详情",res)
      const projectData = res.data[projectId.value];
      // 更新项目信息
      Object.assign(projectInfo, projectData);
      // 更新统计信息
      updateStatistics(projectData);
  // 获取项目详情
  const getProjectDetail = async () => {
    try {
      getProject().then(res => {
        console.log("项目详情", res);
        const projectData = res.data[projectId.value];
        // 更新项目信息
        Object.assign(projectInfo, projectData);
      // 强制更新DOM以确保子组件能正确刷新
      // 这里通过触发refreshProjectId事件来强制刷新子组件
      refreshProjectId.value++;
    })
  } catch (error) {
    ElMessage.error('获取项目详情失败');
    console.error('获取项目详情失败:', error);
  }
};
        // 更新统计信息
        updateStatistics(projectData);
// 更新统计信息
const updateStatistics = (projectData) => {
  // 这里假设projectData中包含了统计信息
  // 如果没有,需要单独请求统计数据
  statistics.totalPhases = projectData.phases ? projectData.phases.length : 0;
  statistics.totalTasks = projectData.tasks ? projectData.tasks.length : 0;
  statistics.completedTasks = projectData.tasks ?
    projectData.tasks.filter(task => task.status === 'completed').length : 0;
};
        // 强制更新DOM以确保子组件能正确刷新
        // 这里通过触发refreshProjectId事件来强制刷新子组件
        refreshProjectId.value++;
      });
    } catch (error) {
      ElMessage.error("获取项目详情失败");
      console.error("获取项目详情失败:", error);
    }
  };
// 获取项目阶段列表
const getPhaseList = async () => {
  try {
    const { data } = await listProjectPhase(projectId.value);
    phaseList.value = data.rows || data;
  } catch (error) {
    ElMessage.error('获取项目阶段列表失败');
    console.error('获取项目阶段列表失败:', error);
  }
};
  // 更新统计信息
  const updateStatistics = projectData => {
    // 这里假设projectData中包含了统计信息
    // 如果没有,需要单独请求统计数据
    statistics.totalPhases = projectData.phases ? projectData.phases.length : 0;
    statistics.totalTasks = projectData.tasks ? projectData.tasks.length : 0;
    statistics.completedTasks = projectData.tasks
      ? projectData.tasks.filter(task => task.status === "completed").length
      : 0;
  };
// 计算完成度
const calculateCompletionRate = () => {
  if (goalForm.targetValue > 0) {
    goalForm.completionRate = Math.min(Math.round((goalForm.currentValue / goalForm.targetValue) * 100), 100);
  } else {
    goalForm.completionRate = 0;
  }
};
  // 获取项目阶段列表
  const getPhaseList = async () => {
    try {
      const { data } = await listProjectPhase(projectId.value);
      phaseList.value = data.rows || data;
    } catch (error) {
      ElMessage.error("获取项目阶段列表失败");
      console.error("获取项目阶段列表失败:", error);
    }
  };
// 添加阶段
const handleAddPhase = () => {
  // resetForm();
  ElMessage.info('添加阶段功能待实现');
};
// 添加里程碑
const handleAddMilestone = () => {
  resetForm();
  open.value = true;
  title.value = '新增项目阶段';
};
// 添加阶段任务
const handleAddPhaseGoal = () => {
  goalForm.taskId = '';
  goalForm.phaseId = '';
  goalForm.taskName = '';
  goalForm.targetValue = 0;
  goalForm.currentValue = 0;
  goalForm.unit = '%';
  goalForm.targetDate = '';
  goalForm.startDate = '';
  goalForm.endDate = '';
  goalForm.status = 'notStarted';
  goalForm.completionRate = 0;
  if (goalFormRef.value) {
    goalFormRef.value.resetFields();
  }
  getPhaseList();
  goalTitle.value = '新增阶段目标';
  goalOpen.value = true;
};
// 提交表单
const submitForm = async () => {
  try {
    await formRef.value.validate();
    if (form.phaseId) {
      // await updateProject(form);
      // ElMessage.success('修改项目阶段成功');
  // 计算完成度
  const calculateCompletionRate = () => {
    if (goalForm.targetValue > 0) {
      goalForm.completionRate = Math.min(
        Math.round((goalForm.currentValue / goalForm.targetValue) * 100),
        100
      );
    } else {
      console.log("form",form);
      await addProjectPhase(form);
      ElMessage.success('新增项目阶段成功');
      goalForm.completionRate = 0;
    }
  };
  // 添加阶段
  const handleAddPhase = () => {
    // resetForm();
    ElMessage.info("添加阶段功能待实现");
  };
  // 添加里程碑
  const handleAddMilestone = () => {
    resetForm();
    open.value = true;
    title.value = "新增项目阶段";
  };
  // 添加阶段任务
  const handleAddPhaseGoal = () => {
    goalForm.taskId = "";
    goalForm.phaseId = "";
    goalForm.taskName = "";
    goalForm.targetValue = 0;
    goalForm.currentValue = 0;
    goalForm.unit = "%";
    goalForm.targetDate = "";
    goalForm.startDate = "";
    goalForm.endDate = "";
    goalForm.status = "notStarted";
    goalForm.completionRate = 0;
    if (goalFormRef.value) {
      goalFormRef.value.resetFields();
    }
    getPhaseList();
    goalTitle.value = "新增阶段目标";
    goalOpen.value = true;
  };
  // 提交表单
  const submitForm = async () => {
    try {
      await formRef.value.validate();
      if (form.phaseId) {
        // await updateProject(form);
        // ElMessage.success('修改项目阶段成功');
      } else {
        console.log("form", form);
        await addProjectPhase(form);
        ElMessage.success("新增项目阶段成功");
        getProjectDetail();
      }
      open.value = false;
    } catch (error) {
      console.error("提交表单失败:", error);
    }
  };
  // 提交阶段任务表单
  const submitGoalForm = async () => {
    try {
      await goalFormRef.value.validate();
      calculateCompletionRate();
      const goalData = {
        ...goalForm,
        oaProjectId: projectId.value,
      };
      if (goalForm.taskId) {
        await updateProjectTask(goalData);
        ElMessage.success("修改阶段目标成功");
      } else {
        await addProjectTask(goalData);
        ElMessage.success("新增阶段目标成功");
      }
      // 调用getProjectDetail刷新所有相关数据
      getProjectDetail();
      goalOpen.value = false;
    } catch (error) {
      console.error("提交阶段目标表单失败:", error);
    }
  };
  // 重置里程碑表单
  const resetForm = () => {
    form.phaseId = "";
    form.phaseName = "";
    form.startDate = "";
    form.endDate = "";
    form.status = "planning";
    form.oaProjectId = projectId.value;
    if (formRef.value) {
      formRef.value.resetFields();
    }
  };
  // 取消阶段任务操作
  const cancelGoal = () => {
    goalOpen.value = false;
  };
  // 取消操作
  const cancel = () => {
    open.value = false;
  };
  // 编辑阶段任务
  const handleEditPhaseGoal = async goal => {
    // 复制目标数据到表单
    Object.assign(goalForm, goal);
    // 获取项目阶段列表
    await getPhaseList();
    // 打开编辑弹窗
    goalTitle.value = "编辑阶段目标";
    goalOpen.value = true;
  };
  // 获取状态标签类型
  const getStatusType = status => {
    const statusTypeMap = {
      planning: "info",
      inProgress: "primary",
      completed: "success",
      paused: "warning",
    };
    return statusTypeMap[status] || "default";
  };
  // 获取状态文本
  const getStatusText = status => {
    const statusTextMap = {
      planning: "规划中",
      inProgress: "进行中",
      completed: "已完成",
      paused: "已暂停",
    };
    return statusTextMap[status] || status;
  };
  // 监听路由参数变化
  watch(
    () => route.params.projectId,
    newProjectId => {
      // console.log('路由参数变化:', projectId);
      if (newProjectId) {
        projectId.value = newProjectId;
        getProjectDetail();
      }
    }
  );
  // 监听当前值和目标值变化,重新计算完成度
  watch(
    () => [goalForm.currentValue, goalForm.targetValue],
    () => {
      calculateCompletionRate();
    }
  );
  // 初始化
  onMounted(() => {
    if (projectId.value) {
      getProjectDetail();
    }
    open.value = false;
  } catch (error) {
    console.error('提交表单失败:', error);
  }
};
// 提交阶段任务表单
const submitGoalForm = async () => {
  try {
    await goalFormRef.value.validate();
    calculateCompletionRate();
    const goalData = {
      ...goalForm,
      oaProjectId: projectId.value
    };
    if (goalForm.taskId) {
      await updateProjectTask(goalData);
      ElMessage.success('修改阶段目标成功');
    } else {
      await addProjectTask(goalData);
      ElMessage.success('新增阶段目标成功');
    }
    // 调用getProjectDetail刷新所有相关数据
    getProjectDetail();
    goalOpen.value = false;
  } catch (error) {
    console.error('提交阶段目标表单失败:', error);
  }
};
// 重置里程碑表单
const resetForm = () => {
  form.phaseId = '';
  form.phaseName = '';
  form.startDate = '';
  form.endDate = '';
  form.status = 'planning';
  form.oaProjectId = projectId.value;
  if (formRef.value) {
    formRef.value.resetFields();
  }
};
// 取消阶段任务操作
const cancelGoal = () => {
  goalOpen.value = false;
};
// 取消操作
const cancel = () => {
  open.value = false;
};
// 编辑阶段任务
const handleEditPhaseGoal = async (goal) => {
  // 复制目标数据到表单
  Object.assign(goalForm, goal);
  // 获取项目阶段列表
  await getPhaseList();
  // 打开编辑弹窗
  goalTitle.value = '编辑阶段目标';
  goalOpen.value = true;
};
// 获取状态标签类型
const getStatusType = (status) => {
  const statusTypeMap = {
    planning: 'info',
    inProgress: 'primary',
    completed: 'success',
    paused: 'warning'
  };
  return statusTypeMap[status] || 'default';
};
// 获取状态文本
const getStatusText = (status) => {
  const statusTextMap = {
    planning: '规划中',
    inProgress: '进行中',
    completed: '已完成',
    paused: '已暂停'
  };
  return statusTextMap[status] || status;
};
// 监听路由参数变化
watch(() => route.params.projectId, (newProjectId) => {
  // console.log('路由参数变化:', projectId);
  if (newProjectId) {
    projectId.value = newProjectId;
    getProjectDetail();
  }
});
// 监听当前值和目标值变化,重新计算完成度
watch(() => [goalForm.currentValue, goalForm.targetValue], () => {
  calculateCompletionRate();
});
// 初始化
onMounted(() => {
  if (projectId.value) {
    getProjectDetail();
  }
});
  });
</script>
<style scoped>
.app-container {
  padding: 20px;
}
  .app-container {
    padding: 20px;
  }
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
.progress-item {
  text-align: center;
  padding: 20px;
  background-color: #f5f7fa;
  border-radius: 8px;
}
  .progress-item {
    text-align: center;
    padding: 20px;
    background-color: #f5f7fa;
    border-radius: 8px;
  }
.progress-title {
  font-size: 14px;
  color: #606266;
  margin-bottom: 10px;
}
  .progress-title {
    font-size: 14px;
    color: #606266;
    margin-bottom: 10px;
  }
.progress-number {
  font-size: 24px;
  font-weight: bold;
  color: #409eff;
}
  .progress-number {
    font-size: 24px;
    font-weight: bold;
    color: #409eff;
  }
.mb20 {
  margin-bottom: 20px;
}
  .mb20 {
    margin-bottom: 20px;
  }
</style>