<template>
|
<div class="app-container">
|
<!-- 顶部操作栏 -->
|
<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>
|
<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="选择日期"
|
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 @click="handleExport">导出计划</el-button>
|
<!-- <el-button @click="handleShare">共享计划@</el-button> -->
|
</div>
|
</div>
|
|
<!-- 计划概览卡片 -->
|
<div class="overview-cards">
|
<el-row :gutter="20">
|
<el-col :span="6">
|
<el-card class="overview-card">
|
<div class="card-content">
|
<div class="card-icon personal">
|
<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" />
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card class="overview-card">
|
<div class="card-content">
|
<div class="card-icon group">
|
<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" />
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card class="overview-card">
|
<div class="card-content">
|
<div class="card-icon department">
|
<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" />
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="6">
|
<el-card class="overview-card">
|
<div class="card-content">
|
<div class="card-icon company">
|
<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" />
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
</div>
|
|
<!-- 计划列表 -->
|
<div class="plan-content">
|
<el-card>
|
<template #header>
|
<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> -->
|
</div>
|
</div>
|
</template>
|
|
<div class="plan-list">
|
<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>
|
<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="(command) => handleMoreAction(plan, command)">
|
<el-button size="small">
|
更多<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="copy">复制@</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>
|
<span>{{ plan.startDate }} - {{ plan.endDate }}</span>
|
</div>
|
<div class="meta-item">
|
<el-icon><User /></el-icon>
|
<span>{{ plan.assignee }}</span>
|
</div>
|
<div class="meta-item">
|
<el-icon><Clock /></el-icon>
|
<span>进度: {{ plan.progress }}%</span>
|
</div>
|
<div class="meta-item">
|
<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"
|
/>
|
</div>
|
|
<div class="plan-tags">
|
<el-tag v-for="tag in plan.tags" :key="tag" size="small" style="margin-right: 5px">
|
{{ tag }}
|
</el-tag>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
|
<!-- 新增/编辑计划对话框 -->
|
<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>
|
<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-select>
|
</el-form-item>
|
<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"
|
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>
|
<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-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 @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'
|
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 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({
|
id: '',
|
title: '',
|
description: '',
|
level: 'personal',
|
period: 'week',
|
startDate: '',
|
endDate: '',
|
assignee: '',
|
priority: 'medium',
|
tags: [],
|
status: '',
|
progress: 0
|
})
|
|
// 表单验证规则
|
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 planList = ref([])
|
|
// 计算属性
|
const datePickerType = computed(() => {
|
switch (currentPeriod.value) {
|
case 'week':
|
return 'week'
|
case 'month':
|
return 'month'
|
case 'year':
|
return 'year'
|
default:
|
return 'date'
|
}
|
})
|
|
// 方法
|
const handleLevelChange = (value) => {
|
console.log('计划级别变更:', value)
|
getPlanList()
|
// 这里可以根据级别筛选数据
|
}
|
|
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':
|
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");
|
})
|
.catch(() => {
|
proxy.$modal.msg("已取消");
|
});
|
};
|
const handleShare = () => {
|
ElMessage.success('计划已共享')
|
}
|
|
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'
|
}
|
//获取数据列表
|
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)
|
})
|
}
|
|
onMounted(() => {
|
getPlanList()
|
getPlanNum()
|
console.log('多级计划模板页面已加载')
|
})
|
</script>
|
|
<style scoped>
|
.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;
|
}
|
|
.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>
|