gaoluyang
6 天以前 71a9eef518f2f2f1a1eb2fb90f2eb8ab7b155bc8
src/views/collaborativeApproval/planTemplate/index.vue
@@ -3,32 +3,45 @@
    <!-- 顶部操作栏 -->
    <div class="header-actions">
      <div class="left-actions">
        <el-select v-model="currentLevel" placeholder="选择计划级别" style="width: 150px" @change="handleLevelChange">
          <el-option label="个人计划" value="personal" />
          <el-option label="小组计划" value="group" />
          <el-option label="部门计划" value="department" />
          <el-option label="公司计划" value="company" />
        <el-select v-model="currentLevel"
                   placeholder="选择计划级别"
                   style="width: 150px"
                   @change="handleLevelChange">
          <el-option label="个人计划"
                     value="personal" />
          <el-option label="小组计划"
                     value="group" />
          <el-option label="部门计划"
                     value="department" />
          <el-option label="公司计划"
                     value="company" />
        </el-select>
        <el-select v-model="currentPeriod" placeholder="选择时间周期" style="width: 120px; margin-left: 10px" @change="handlePeriodChange">
          <el-option label="周计划" value="week" />
          <el-option label="月计划" value="month" />
          <el-option label="年计划" value="year" />
        <el-select v-model="currentPeriod"
                   placeholder="选择时间周期"
                   style="width: 120px; margin-left: 10px"
                   @change="handlePeriodChange">
          <el-option label="周计划"
                     value="week" />
          <el-option label="月计划"
                     value="month" />
          <el-option label="年计划"
                     value="year" />
        </el-select>
        <el-date-picker
          v-model="currentDate"
          :type="datePickerType"
          placeholder="选择日期"
          style="width: 180px; margin-left: 10px"
          @change="handleDateChange"
        />
        <el-date-picker v-model="currentDate"
                        :type="datePickerType"
                        placeholder="选择日期"
                        format="YYYY-MM-DD"
                        value-format="YYYY-MM-DD"
                        style="width: 180px; margin-left: 10px"
                        @change="handleDateChange" />
      </div>
      <div class="right-actions">
        <el-button type="primary" @click="handleAddPlan">新增计划</el-button>
        <el-button type="primary"
                   @click="handleAddPlan">新增计划</el-button>
        <el-button @click="handleExport">导出计划</el-button>
        <el-button @click="handleShare">共享计划</el-button>
        <!-- <el-button @click="handleShare">共享计划@</el-button> -->
      </div>
    </div>
    <!-- 计划概览卡片 -->
    <div class="overview-cards">
      <el-row :gutter="20">
@@ -36,13 +49,16 @@
          <el-card class="overview-card">
            <div class="card-content">
              <div class="card-icon personal">
                <el-icon><User /></el-icon>
                <el-icon>
                  <User />
                </el-icon>
              </div>
              <div class="card-info">
                <div class="card-title">个人计划</div>
                <div class="card-number">{{ overviewData.personal.total }}</div>
                <div class="card-progress">
                  <el-progress :percentage="overviewData.personal.completion" :stroke-width="6" />
                  <el-progress :percentage="overviewData.personal.completion"
                               :stroke-width="6" />
                </div>
              </div>
            </div>
@@ -52,13 +68,16 @@
          <el-card class="overview-card">
            <div class="card-content">
              <div class="card-icon group">
                <el-icon><UserFilled /></el-icon>
                <el-icon>
                  <UserFilled />
                </el-icon>
              </div>
              <div class="card-info">
                <div class="card-title">小组计划</div>
                <div class="card-number">{{ overviewData.group.total }}</div>
                <div class="card-progress">
                  <el-progress :percentage="overviewData.group.completion" :stroke-width="6" />
                  <el-progress :percentage="overviewData.group.completion"
                               :stroke-width="6" />
                </div>
              </div>
            </div>
@@ -68,13 +87,16 @@
          <el-card class="overview-card">
            <div class="card-content">
              <div class="card-icon department">
                <el-icon><OfficeBuilding /></el-icon>
                <el-icon>
                  <OfficeBuilding />
                </el-icon>
              </div>
              <div class="card-info">
                <div class="card-title">部门计划</div>
                <div class="card-number">{{ overviewData.department.total }}</div>
                <div class="card-progress">
                  <el-progress :percentage="overviewData.department.completion" :stroke-width="6" />
                  <el-progress :percentage="overviewData.department.completion"
                               :stroke-width="6" />
                </div>
              </div>
            </div>
@@ -84,13 +106,16 @@
          <el-card class="overview-card">
            <div class="card-content">
              <div class="card-icon company">
                <el-icon><House /></el-icon>
                <el-icon>
                  <House />
                </el-icon>
              </div>
              <div class="card-info">
                <div class="card-title">公司计划</div>
                <div class="card-number">{{ overviewData.company.total }}</div>
                <div class="card-progress">
                  <el-progress :percentage="overviewData.company.completion" :stroke-width="6" />
                  <el-progress :percentage="overviewData.company.completion"
                               :stroke-width="6" />
                </div>
              </div>
            </div>
@@ -98,7 +123,6 @@
        </el-col>
      </el-row>
    </div>
    <!-- 计划列表 -->
    <div class="plan-content">
      <el-card>
@@ -106,68 +130,82 @@
          <div class="card-header">
            <span>{{ getCurrentLevelText() }} - {{ getCurrentPeriodText() }}</span>
            <div>
              <el-button size="small" @click="handleRefresh">刷新</el-button>
              <el-button size="small" @click="handleFilter">筛选</el-button>
              <el-button size="small"
                         @click="handleRefresh">刷新</el-button>
              <!-- <el-button size="small" @click="handleFilter">筛选@</el-button> -->
            </div>
          </div>
        </template>
        <div class="plan-list">
          <div v-for="plan in planList" :key="plan.id" class="plan-item">
          <div v-for="plan in planList"
               :key="plan.id"
               class="plan-item">
            <div class="plan-header">
              <div class="plan-title">
                <el-tag :type="getPriorityType(plan.priority)" size="small">{{ getPriorityText(plan.priority) }}</el-tag>
                <el-tag :type="getPriorityType(plan.priority)"
                        size="small">{{ getPriorityText(plan.priority) }}</el-tag>
                <span class="title-text">{{ plan.title }}</span>
              </div>
              <div class="plan-actions">
                <el-button size="small" @click="handleEditPlan(plan)">编辑</el-button>
                <el-button size="small" @click="handleViewDetail(plan)">详情</el-button>
                <el-dropdown @command="handleMoreAction">
                <el-button size="small"
                           @click="handleEditPlan(plan)">编辑</el-button>
                <el-button size="small"
                           @click="handleViewDetail(plan)">详情</el-button>
                <el-dropdown @command="(command) => handleMoreAction(plan, command)">
                  <el-button size="small">
                    更多<el-icon class="el-icon--right"><ArrowDown /></el-icon>
                    更多<el-icon class="el-icon--right">
                      <ArrowDown />
                    </el-icon>
                  </el-button>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item command="share">共享</el-dropdown-item>
                      <!-- <el-dropdown-item command="share">共享@</el-dropdown-item> -->
                      <el-dropdown-item command="copy">复制</el-dropdown-item>
                      <el-dropdown-item command="delete" divided>删除</el-dropdown-item>
                      <el-dropdown-item command="delete"
                                        divided>删除</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </div>
            </div>
            <div class="plan-content">
              <div class="plan-description">{{ plan.description }}</div>
              <div class="plan-meta">
                <div class="meta-item">
                  <el-icon><Calendar /></el-icon>
                  <el-icon>
                    <Calendar />
                  </el-icon>
                  <span>{{ plan.startDate }} - {{ plan.endDate }}</span>
                </div>
                <div class="meta-item">
                  <el-icon><User /></el-icon>
                  <el-icon>
                    <User />
                  </el-icon>
                  <span>{{ plan.assignee }}</span>
                </div>
                <div class="meta-item">
                  <el-icon><Clock /></el-icon>
                  <el-icon>
                    <Clock />
                  </el-icon>
                  <span>进度: {{ plan.progress }}%</span>
                </div>
                <div class="meta-item">
                  <el-icon><Flag /></el-icon>
                  <el-icon>
                    <Flag />
                  </el-icon>
                  <span>{{ getStatusText(plan.status) }}</span>
                </div>
              </div>
              <div class="plan-progress">
                <el-progress
                  :percentage="plan.progress"
                  :color="getProgressColor(plan.progress)"
                  :stroke-width="8"
                />
                <el-progress :percentage="plan.progress"
                             :color="getProgressColor(plan.progress)"
                             :stroke-width="8" />
              </div>
              <div class="plan-tags">
                <el-tag v-for="tag in plan.tags" :key="tag" size="small" style="margin-right: 5px">
                <el-tag v-for="tag in plan.tags"
                        :key="tag"
                        size="small"
                        style="margin-right: 5px">
                  {{ tag }}
                </el-tag>
              </div>
@@ -176,575 +214,739 @@
        </div>
      </el-card>
    </div>
    <!-- 新增/编辑计划对话框 -->
    <el-dialog
      v-model="planDialogVisible"
      :title="dialogTitle"
      width="600px"
      @close="handleDialogClose"
    >
      <el-form :model="planForm" :rules="planRules" ref="planFormRef" label-width="100px">
        <el-form-item label="计划标题" prop="title">
          <el-input v-model="planForm.title" placeholder="请输入计划标题" />
    <el-dialog v-model="planDialogVisible"
               :title="operationType === 'add' ? '发布计划' : '编辑计划'"
               width="600px"
               @close="handleDialogClose">
      <el-form :model="planForm"
               :rules="planRules"
               ref="planFormRef"
               label-width="100px">
        <el-form-item label="计划标题"
                      prop="title">
          <el-input v-model="planForm.title"
                    placeholder="请输入计划标题" />
        </el-form-item>
        <el-form-item label="计划描述" prop="description">
          <el-input
            v-model="planForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入计划描述"
          />
        <el-form-item label="计划描述"
                      prop="description">
          <el-input v-model="planForm.description"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入计划描述" />
        </el-form-item>
        <el-form-item label="计划级别" prop="level">
          <el-select v-model="planForm.level" placeholder="选择计划级别" style="width: 100%">
            <el-option label="个人计划" value="personal" />
            <el-option label="小组计划" value="group" />
            <el-option label="部门计划" value="department" />
            <el-option label="公司计划" value="company" />
        <el-form-item label="计划级别"
                      prop="level">
          <el-select v-model="planForm.level"
                     placeholder="选择计划级别"
                     style="width: 100%">
            <el-option label="个人计划"
                       value="personal" />
            <el-option label="小组计划"
                       value="group" />
            <el-option label="部门计划"
                       value="department" />
            <el-option label="公司计划"
                       value="company" />
          </el-select>
        </el-form-item>
        <el-form-item label="时间周期" prop="period">
          <el-select v-model="planForm.period" placeholder="选择时间周期" style="width: 100%">
            <el-option label="周计划" value="week" />
            <el-option label="月计划" value="month" />
            <el-option label="年计划" value="year" />
        <el-form-item label="时间周期"
                      prop="period">
          <el-select v-model="planForm.period"
                     placeholder="选择时间周期"
                     style="width: 100%">
            <el-option label="周计划"
                       value="week" />
            <el-option label="月计划"
                       value="month" />
            <el-option label="年计划"
                       value="year" />
          </el-select>
        </el-form-item>
        <el-form-item label="开始时间" prop="startDate">
          <el-date-picker
            v-model="planForm.startDate"
            type="date"
            placeholder="选择开始时间"
            style="width: 100%"
          />
        <el-form-item label="开始时间"
                      prop="startDate">
          <el-date-picker v-model="planForm.startDate"
                          type="date"
                          value-format="YYYY-MM-DD"
                          format="YYYY-MM-DD"
                          placeholder="选择开始时间"
                          style="width: 100%" />
        </el-form-item>
        <el-form-item label="结束时间" prop="endDate">
          <el-date-picker
            v-model="planForm.endDate"
            type="date"
            placeholder="选择结束时间"
            style="width: 100%"
          />
        <el-form-item label="结束时间"
                      prop="endDate">
          <el-date-picker v-model="planForm.endDate"
                          type="date"
                          value-format="YYYY-MM-DD"
                          format="YYYY-MM-DD"
                          placeholder="选择结束时间"
                          style="width: 100%" />
        </el-form-item>
        <el-form-item label="负责人" prop="assignee">
          <el-input v-model="planForm.assignee" placeholder="请输入负责人" />
        <el-form-item label="负责人"
                      prop="assignee">
          <el-input v-model="planForm.assignee"
                    placeholder="请输入负责人" />
        </el-form-item>
        <el-form-item label="优先级" prop="priority">
          <el-select v-model="planForm.priority" placeholder="选择优先级" style="width: 100%">
            <el-option label="高" value="high" />
            <el-option label="中" value="medium" />
            <el-option label="低" value="low" />
        <el-form-item label="优先级"
                      prop="priority">
          <el-select v-model="planForm.priority"
                     placeholder="选择优先级"
                     style="width: 100%">
            <el-option label="高"
                       value="high" />
            <el-option label="中"
                       value="medium" />
            <el-option label="低"
                       value="low" />
          </el-select>
        </el-form-item>
        <el-form-item label="标签">
        <!-- <el-form-item label="标签">
          <el-input v-model="planForm.tags" placeholder="请输入标签,用逗号分隔" />
        </el-form-item> -->
        <el-form-item label="标签"
                      prop="tags">
          <!-- <el-checkbox-group v-model="planForm.tags">
            <el-checkbox label="all"></el-checkbox>
            <el-checkbox label="manager">管理层</el-checkbox>
            <el-checkbox label="hr">人事部门</el-checkbox>
            <el-checkbox label="finance">财务部门</el-checkbox>
            <el-checkbox label="tech">技术部门</el-checkbox>
          </el-checkbox-group> -->
          <el-select v-model="planForm.tags"
                     multiple
                     placeholder="请选择标签"
                     style="width: 100%">
            <el-option v-for="dept in departments"
                       :key="dept"
                       :label="dept"
                       :value="dept" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态"
                      prop="status">
          <el-select v-model="planForm.status"
                     placeholder="选择状态"
                     style="width: 100%">
            <el-option label="未开始"
                       value="not_started" />
            <el-option label="进行中"
                       value="in_progress" />
            <el-option label="已完成"
                       value="completed" />
            <el-option label="已暂停"
                       value="paused" />
          </el-select>
        </el-form-item>
        <el-form-item label="进度"
                      prop="progress">
          <el-input-number v-model="planForm.progress"
                           min="0"
                           max="100"
                           step="1"
                           placeholder="请输入进度"
                           style="width: 100%" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button type="primary"
                     @click="handleSavePlan">保存</el-button>
          <el-button @click="planDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="handleSavePlan">保存</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 计划详情对话框 -->
    <el-dialog v-model="showPlanDetailDialog"
               title="计划详情"
               width="700px">
      <div v-if="currentPlanDetail"
           class="mb10">
        <el-descriptions :column="2"
                         border>
          <el-descriptions-item label="计划标题">{{ currentPlanDetail.title }}</el-descriptions-item>
          <el-descriptions-item label="计划描述">{{ currentPlanDetail.description }}</el-descriptions-item>
          <el-descriptions-item label="计划级别">{{ getCurrentLevelText(currentPlanDetail.level) }}</el-descriptions-item>
          <el-descriptions-item label="时间周期">{{ getCurrentPeriodText(currentPlanDetail.period) }}</el-descriptions-item>
          <el-descriptions-item label="开始时间">{{ currentPlanDetail.startDate }}</el-descriptions-item>
          <el-descriptions-item label="结束时间">{{ currentPlanDetail.endDate }}</el-descriptions-item>
          <el-descriptions-item label="负责人">{{ currentPlanDetail.assignee }}</el-descriptions-item>
          <el-descriptions-item label="优先级">{{ getPriorityText(currentPlanDetail.priority) }}</el-descriptions-item>
          <el-descriptions-item label="标签">{{ currentPlanDetail.tags.join(', ') }}</el-descriptions-item>
          <el-descriptions-item label="状态">{{ getStatusText(currentPlanDetail.status) }}</el-descriptions-item>
          <el-descriptions-item label="进度">{{ currentPlanDetail.progress }}%</el-descriptions-item>
        </el-descriptions>
      </div>
    </el-dialog>
  </div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  User,
  UserFilled,
  OfficeBuilding,
  House,
  Calendar,
  Clock,
  Flag,
  ArrowDown
} from '@element-plus/icons-vue'
  import { ref, reactive, computed, onMounted } from "vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  const { proxy } = getCurrentInstance();
  import {
    User,
    UserFilled,
    OfficeBuilding,
    House,
    Calendar,
    Clock,
    Flag,
    ArrowDown,
  } from "@element-plus/icons-vue";
  import {
    listDutyPlan,
    addDutyPlan,
    updateDutyPlan,
    delDutyPlan,
    NumDutyPlan,
    exportDutyPlan,
  } from "@/api/collaborativeApproval/planTemplate.js";
// 响应式数据
const currentLevel = ref('personal')
const currentPeriod = ref('week')
const currentDate = ref(new Date())
const planDialogVisible = ref(false)
const dialogTitle = ref('新增计划')
const planFormRef = ref()
  // 响应式数据
  const operationType = ref("add");
  const currentLevel = ref("personal");
  const currentPeriod = ref("week");
  const currentDate = ref(new Date());
  const planDialogVisible = ref(false);
  const dialogTitle = ref("新增计划");
  const planFormRef = ref();
  const showPlanDetailDialog = ref(false);
  const currentPlanDetail = ref(null);
// 表单数据
const planForm = reactive({
  title: '',
  description: '',
  level: 'personal',
  period: 'week',
  startDate: '',
  endDate: '',
  assignee: '',
  priority: 'medium',
  tags: ''
})
// 表单验证规则
const planRules = {
  title: [{ required: true, message: '请输入计划标题', trigger: 'blur' }],
  description: [{ required: true, message: '请输入计划描述', trigger: 'blur' }],
  level: [{ required: true, message: '请选择计划级别', trigger: 'change' }],
  period: [{ required: true, message: '请选择时间周期', trigger: 'change' }],
  startDate: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
  endDate: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
  assignee: [{ required: true, message: '请输入负责人', trigger: 'blur' }],
  priority: [{ required: true, message: '请选择优先级', trigger: 'change' }]
}
// 概览数据
const overviewData = reactive({
  personal: { total: 12, completion: 75 },
  group: { total: 8, completion: 60 },
  department: { total: 15, completion: 45 },
  company: { total: 6, completion: 30 }
})
// 计划列表数据
const planList = ref([
  {
    id: 1,
    title: '产品需求分析',
    description: '对新产品进行详细的需求分析和市场调研,制定产品规划方案',
    level: 'personal',
    period: 'week',
    startDate: '2024-01-15',
    endDate: '2024-01-21',
    assignee: '陈志强',
    priority: 'high',
    status: 'in_progress',
    progress: 80,
    tags: ['产品', '分析', '调研']
  },
  {
    id: 2,
    title: '技术架构设计',
    description: '设计系统技术架构,包括数据库设计、接口设计等',
    level: 'group',
    period: 'month',
    startDate: '2024-01-01',
    endDate: '2024-01-31',
    assignee: '刘雅婷',
    priority: 'high',
    status: 'completed',
    progress: 100,
    tags: ['技术', '架构', '设计']
  },
  {
    id: 3,
    title: '市场推广计划',
    description: '制定年度市场推广策略和营销计划',
    level: 'department',
    period: 'year',
    startDate: '2024-01-01',
    endDate: '2024-12-31',
    assignee: '王建国',
    priority: 'medium',
    status: 'not_started',
  // 表单数据
  const planForm = reactive({
    id: "",
    title: "",
    description: "",
    level: "personal",
    period: "week",
    startDate: "",
    endDate: "",
    assignee: "",
    priority: "medium",
    tags: [],
    status: "",
    progress: 0,
    tags: ['市场', '推广', '营销']
  },
  {
    id: 4,
    title: '团队建设活动',
    description: '组织团队建设活动,提升团队凝聚力和协作效率',
    level: 'company',
    period: 'month',
    startDate: '2024-01-15',
    endDate: '2024-02-15',
    assignee: '赵丽华',
    priority: 'low',
    status: 'in_progress',
    progress: 30,
    tags: ['团队', '建设', '活动']
  }
])
  });
// 计算属性
const datePickerType = computed(() => {
  switch (currentPeriod.value) {
    case 'week':
      return 'week'
    case 'month':
      return 'month'
    case 'year':
      return 'year'
    default:
      return 'date'
  }
})
  // 表单验证规则
  const planRules = {
    title: [{ required: true, message: "请输入计划标题", trigger: "blur" }],
    description: [{ required: true, message: "请输入计划描述", trigger: "blur" }],
    level: [{ required: true, message: "请选择计划级别", trigger: "change" }],
    period: [{ required: true, message: "请选择时间周期", trigger: "change" }],
    startDate: [{ required: true, message: "请选择开始时间", trigger: "change" }],
    endDate: [{ required: true, message: "请选择结束时间", trigger: "change" }],
    assignee: [{ required: true, message: "请输入负责人", trigger: "blur" }],
    priority: [{ required: true, message: "请选择优先级", trigger: "change" }],
  };
  const departments = [
    "产品",
    "分析",
    "调研",
    "技术",
    "架构",
    "设计",
    "市场",
    "推广",
    "营销",
  ];
  // 概览数据
  const overviewData = reactive({
    personal: { total: 0, completion: 0 },
    group: { total: 0, completion: 0 },
    department: { total: 0, completion: 0 },
    company: { total: 0, completion: 0 },
  });
// 方法
const handleLevelChange = (value) => {
  console.log('计划级别变更:', value)
  // 这里可以根据级别筛选数据
}
  // 计划列表数据
  const planList = ref([]);
const handlePeriodChange = (value) => {
  console.log('时间周期变更:', value)
  // 这里可以根据周期筛选数据
}
const handleDateChange = (value) => {
  console.log('日期变更:', value)
  // 这里可以根据日期筛选数据
}
const handleAddPlan = () => {
  dialogTitle.value = '新增计划'
  planDialogVisible.value = true
  // 重置表单
  Object.keys(planForm).forEach(key => {
    planForm[key] = ''
  })
  planForm.level = 'personal'
  planForm.period = 'week'
  planForm.priority = 'medium'
}
const handleEditPlan = (plan) => {
  dialogTitle.value = '编辑计划'
  planDialogVisible.value = true
  // 填充表单数据
  Object.keys(planForm).forEach(key => {
    if (key === 'tags') {
      planForm[key] = plan[key].join(', ')
    } else {
      planForm[key] = plan[key]
  // 计算属性
  const datePickerType = computed(() => {
    switch (currentPeriod.value) {
      case "week":
        return "week";
      case "month":
        return "month";
      case "year":
        return "year";
      default:
        return "date";
    }
  })
}
  });
const handleViewDetail = (plan) => {
  ElMessage.info(`查看计划详情: ${plan.title}`)
}
  // 方法
  const handleLevelChange = value => {
    console.log("计划级别变更:", value);
    getPlanList();
    // 这里可以根据级别筛选数据
  };
const handleMoreAction = (command) => {
  switch (command) {
    case 'share':
      ElMessage.success('计划已共享')
      break
    case 'copy':
      ElMessage.success('计划已复制')
      break
    case 'delete':
      ElMessageBox.confirm('确定要删除这个计划吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        ElMessage.success('计划已删除')
  const handlePeriodChange = value => {
    console.log("时间周期变更:", value);
    getPlanList();
    // 这里可以根据周期筛选数据
  };
  const handleDateChange = value => {
    console.log("日期变更:", value);
    getPlanList();
    // 这里可以根据日期筛选数据
  };
  const handleAddPlan = () => {
    operationType.value = "add";
    dialogTitle.value = "新增计划";
    planDialogVisible.value = true;
    // 重置表单
    Object.keys(planForm).forEach(key => {
      planForm[key] = "";
    });
    planForm.level = "personal";
    planForm.period = "week";
    planForm.priority = "medium";
    planForm.status = "not_started";
    planForm.progress = 0;
  };
  const handleEditPlan = plan => {
    operationType.value = "edit";
    dialogTitle.value = "编辑计划";
    planDialogVisible.value = true;
    Object.assign(planForm, plan);
    // // 填充表单数据
    // Object.keys(planForm).forEach(key => {
    //   if (key === 'tags') {
    //     planForm[key] = plan[key].join(', ')
    //   } else {
    //     planForm[key] = plan[key]
    //   }
    // })
  };
  const handleViewDetail = plan => {
    currentPlanDetail.value = plan;
    showPlanDetailDialog.value = true;
    // ElMessage.info(`查看计划详情: ${plan.title}`)
  };
  const handleMoreAction = async (plan, command) => {
    let ids = [];
    ids.push(plan.id);
    console.log("ids", ids);
    switch (command) {
      case "share":
        ElMessage.success("计划已共享");
        break;
      case "copy":
        const knowledgeText = `
          计划标题:${plan.title}
          计划描述:${plan.description}
          计划级别:${getCurrentLevelText(plan.level)}
          时间周期:${getCurrentPeriodText(plan.period)}
          开始时间:${plan.startDate}
          结束时间:${plan.endDate}
          负责人:${plan.assignee}
          优先级:${getPriorityText(plan.priority)}
          标签:${plan.tags.join(", ")}
          状态:${getStatusText(plan.status)}
          进度:${plan.progress}%
        `.trim();
        // 复制到剪贴板
        navigator.clipboard
          .writeText(knowledgeText)
          .then(() => {
            ElMessage.success("知识内容已复制到剪贴板");
          })
          .catch(() => {
            ElMessage.error("复制失败,请手动复制");
          });
        // ElMessage.success('计划已复制')
        break;
      case "delete":
        ElMessageBox.confirm("确定要删除这个计划吗?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        }).then(() => {
          delDutyPlan(ids).then(res => {
            if (res.code === 200) {
              ElMessage.success("计划已删除");
              ids.value = [];
              getPlanList();
            }
          });
        });
        break;
    }
  };
  //
  const handleSavePlan = async () => {
    try {
      await planFormRef.value.validate();
      if (operationType.value === "add") {
        addDutyPlan(planForm).then(res => {
          if (res.code === 200) {
            ElMessage.success("计划保存成功");
            planDialogVisible.value = false;
          }
          getPlanList();
        });
      } else {
        updateDutyPlan(planForm).then(res => {
          if (res.code === 200) {
            ElMessage.success("计划保存成功");
            planDialogVisible.value = false;
          }
          getPlanList();
        });
      }
    } catch (error) {
      console.log("表单验证失败:", error);
    }
  };
  const handleDialogClose = () => {
    planFormRef.value?.resetFields();
  };
  const handleRefresh = () => {
    getPlanList();
    // ElMessage.success('数据已刷新')
  };
  const handleFilter = () => {
    ElMessage.info("打开筛选面板");
  };
  const handleExport = () => {
    ElMessageBox.confirm("是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        // exportDutyPlan().then(res => {
        // })
        proxy.download("/dutyPlan/export", {}, "计划管理.xlsx");
      })
      break
  }
}
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  const handleShare = () => {
    ElMessage.success("计划已共享");
  };
const handleSavePlan = async () => {
  try {
    await planFormRef.value.validate()
    ElMessage.success('计划保存成功')
    planDialogVisible.value = false
  } catch (error) {
    console.log('表单验证失败:', error)
  }
}
  const getCurrentLevelText = () => {
    const levelMap = {
      personal: "个人计划",
      group: "小组计划",
      department: "部门计划",
      company: "公司计划",
    };
    return levelMap[currentLevel.value] || "个人计划";
  };
const handleDialogClose = () => {
  planFormRef.value?.resetFields()
}
  const getCurrentPeriodText = () => {
    const periodMap = {
      week: "周计划",
      month: "月计划",
      year: "年计划",
    };
    return periodMap[currentPeriod.value] || "周计划";
  };
const handleRefresh = () => {
  ElMessage.success('数据已刷新')
}
  const getPriorityType = priority => {
    const typeMap = {
      high: "danger",
      medium: "warning",
      low: "info",
    };
    return typeMap[priority] || "info";
  };
const handleFilter = () => {
  ElMessage.info('打开筛选面板')
}
  const getPriorityText = priority => {
    const textMap = {
      high: "高",
      medium: "中",
      low: "低",
    };
    return textMap[priority] || "中";
  };
const handleExport = () => {
  ElMessage.success('计划已导出')
}
  const getStatusText = status => {
    const statusMap = {
      not_started: "未开始",
      in_progress: "进行中",
      completed: "已完成",
      paused: "已暂停",
    };
    return statusMap[status] || "未知";
  };
const handleShare = () => {
  ElMessage.success('计划已共享')
}
  const getProgressColor = progress => {
    if (progress >= 80) return "#67C23A";
    if (progress >= 50) return "#E6A23C";
    return "#F56C6C";
  };
  //获取数据列表
  const getPlanList = async () => {
    const params = {
      level: currentLevel.value,
      period: currentPeriod.value,
      queryDate: currentDate.value,
    };
    listDutyPlan(params)
      .then(res => {
        if (res.code === 200) {
          planList.value = res.data.records;
        }
      })
      .catch(err => {
        console.log(err);
      });
  };
  //获取数据
  const getPlanNum = async () => {
    NumDutyPlan()
      .then(res => {
        if (res.code === 200) {
          // console.log(res.data)
          //讲结果里面的数据根据level 赋值给overviewData
          res.data.forEach(item => {
            overviewData[item.level].total = item.num;
            overviewData[item.level].completion = item.completion;
          });
        }
      })
      .catch(err => {
        console.log(err);
      });
  };
const getCurrentLevelText = () => {
  const levelMap = {
    personal: '个人计划',
    group: '小组计划',
    department: '部门计划',
    company: '公司计划'
  }
  return levelMap[currentLevel.value] || '个人计划'
}
const getCurrentPeriodText = () => {
  const periodMap = {
    week: '周计划',
    month: '月计划',
    year: '年计划'
  }
  return periodMap[currentPeriod.value] || '周计划'
}
const getPriorityType = (priority) => {
  const typeMap = {
    high: 'danger',
    medium: 'warning',
    low: 'info'
  }
  return typeMap[priority] || 'info'
}
const getPriorityText = (priority) => {
  const textMap = {
    high: '高',
    medium: '中',
    low: '低'
  }
  return textMap[priority] || '中'
}
const getStatusText = (status) => {
  const statusMap = {
    not_started: '未开始',
    in_progress: '进行中',
    completed: '已完成',
    paused: '已暂停'
  }
  return statusMap[status] || '未知'
}
const getProgressColor = (progress) => {
  if (progress >= 80) return '#67C23A'
  if (progress >= 50) return '#E6A23C'
  return '#F56C6C'
}
onMounted(() => {
  console.log('多级计划模板页面已加载')
})
  onMounted(() => {
    getPlanList();
    getPlanNum();
    console.log("多级计划模板页面已加载");
  });
</script>
<style scoped>
.app-container {
  padding: 20px;
  background-color: #f5f5f5;
  min-height: 100vh;
}
  .app-container {
    padding: 20px;
    background-color: #f5f5f5;
    min-height: 100vh;
  }
.header-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  background: white;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.left-actions {
  display: flex;
  align-items: center;
}
.right-actions {
  display: flex;
  gap: 10px;
}
.overview-cards {
  margin-bottom: 20px;
}
.overview-card {
  height: 120px;
}
.card-content {
  display: flex;
  align-items: center;
  height: 100%;
}
.card-icon {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-right: 15px;
  font-size: 24px;
  color: white;
}
.card-icon.personal {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.card-icon.group {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}
.card-icon.department {
  background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
.card-icon.company {
  background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
}
.card-info {
  flex: 1;
}
.card-title {
  font-size: 14px;
  color: #666;
  margin-bottom: 5px;
}
.card-number {
  font-size: 24px;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
}
.card-progress {
  width: 100%;
}
.plan-content {
  background: white;
  border-radius: 8px;
  overflow: hidden;
}
.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: bold;
  color: #333;
}
.header-actions {
  display: flex;
  gap: 10px;
}
.plan-list {
  padding: 20px 0;
}
.plan-item {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  margin-bottom: 15px;
  padding: 20px;
  transition: all 0.3s ease;
}
.plan-item:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}
.plan-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}
.plan-title {
  display: flex;
  align-items: center;
  gap: 10px;
}
.title-text {
  font-size: 16px;
  font-weight: bold;
  color: #333;
}
.plan-actions {
  display: flex;
  gap: 10px;
}
.plan-content {
  margin-bottom: 15px;
}
.plan-description {
  color: #666;
  margin-bottom: 15px;
  line-height: 1.6;
}
.plan-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  margin-bottom: 15px;
}
.meta-item {
  display: flex;
  align-items: center;
  gap: 5px;
  color: #666;
  font-size: 14px;
}
.plan-progress {
  margin-bottom: 15px;
}
.plan-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}
.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
/* 响应式设计 */
@media (max-width: 768px) {
  .header-actions {
    flex-direction: column;
    gap: 15px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    background: white;
    padding: 20px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }
  .left-actions {
    flex-wrap: wrap;
    display: flex;
    align-items: center;
  }
  .right-actions {
    display: flex;
    gap: 10px;
  }
  .plan-meta {
    flex-direction: column;
  .overview-cards {
    margin-bottom: 20px;
  }
  .overview-card {
    height: 120px;
  }
  .card-content {
    display: flex;
    align-items: center;
    height: 100%;
  }
  .card-icon {
    width: 60px;
    height: 60px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 15px;
    font-size: 24px;
    color: white;
  }
  .card-icon.personal {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  }
  .card-icon.group {
    background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  }
  .card-icon.department {
    background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
  }
  .card-icon.company {
    background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
  }
  .card-info {
    flex: 1;
  }
  .card-title {
    font-size: 14px;
    color: #666;
    margin-bottom: 5px;
  }
  .card-number {
    font-size: 24px;
    font-weight: bold;
    color: #333;
    margin-bottom: 10px;
  }
  .card-progress {
    width: 100%;
  }
  .plan-content {
    background: white;
    border-radius: 8px;
    overflow: hidden;
  }
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: bold;
    color: #333;
  }
  .header-actions {
    display: flex;
    gap: 10px;
  }
  .plan-list {
    padding: 20px 0;
  }
  .plan-item {
    border: 1px solid #e4e7ed;
    border-radius: 8px;
    margin-bottom: 15px;
    padding: 20px;
    transition: all 0.3s ease;
  }
  .plan-item:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    transform: translateY(-2px);
  }
  .plan-header {
    flex-direction: column;
    align-items: flex-start;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
  }
  .plan-title {
    display: flex;
    align-items: center;
    gap: 10px;
  }
}
  .title-text {
    font-size: 16px;
    font-weight: bold;
    color: #333;
  }
  .plan-actions {
    display: flex;
    gap: 10px;
  }
  .plan-content {
    margin-bottom: 15px;
  }
  .plan-description {
    color: #666;
    margin-bottom: 15px;
    line-height: 1.6;
  }
  .plan-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
    margin-bottom: 15px;
  }
  .meta-item {
    display: flex;
    align-items: center;
    gap: 5px;
    color: #666;
    font-size: 14px;
  }
  .plan-progress {
    margin-bottom: 15px;
  }
  .plan-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
  }
  .dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
  }
  /* 响应式设计 */
  @media (max-width: 768px) {
    .header-actions {
      flex-direction: column;
      gap: 15px;
    }
    .left-actions {
      flex-wrap: wrap;
      gap: 10px;
    }
    .plan-meta {
      flex-direction: column;
      gap: 10px;
    }
    .plan-header {
      flex-direction: column;
      align-items: flex-start;
      gap: 10px;
    }
  }
</style>