From 00100d130c240c191d87d3b6cfb2415f47b9c2d0 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期二, 19 八月 2025 10:17:00 +0800 Subject: [PATCH] 中强恒兴数据修改 --- src/views/collaborativeApproval/planTemplate/index.vue | 750 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 750 insertions(+), 0 deletions(-) diff --git a/src/views/collaborativeApproval/planTemplate/index.vue b/src/views/collaborativeApproval/planTemplate/index.vue new file mode 100644 index 0000000..bfb9cae --- /dev/null +++ b/src/views/collaborativeApproval/planTemplate/index.vue @@ -0,0 +1,750 @@ +<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="閫夋嫨鏃ユ湡" + 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="handleMoreAction"> + <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="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-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" + 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> + <el-form-item label="璐熻矗浜�" prop="assignee"> + <el-input v-model="planForm.assignee" placeholder="璇疯緭鍏ヨ礋璐d汉" /> + </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> + <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> + </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' + +// 鍝嶅簲寮忔暟鎹� +const currentLevel = ref('personal') +const currentPeriod = ref('week') +const currentDate = ref(new Date()) +const planDialogVisible = ref(false) +const dialogTitle = ref('鏂板璁″垝') +const planFormRef = ref() + +// 琛ㄥ崟鏁版嵁 +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: '璇疯緭鍏ヨ礋璐d汉', 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: '璁捐绯荤粺鎶�鏈灦鏋勶紝鍖呮嫭鏁版嵁搴撹璁°�佹帴鍙h璁$瓑', + 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', + 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 handleLevelChange = (value) => { + console.log('璁″垝绾у埆鍙樻洿:', value) + // 杩欓噷鍙互鏍规嵁绾у埆绛涢�夋暟鎹� +} + +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 handleViewDetail = (plan) => { + ElMessage.info(`鏌ョ湅璁″垝璇︽儏: ${plan.title}`) +} + +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('璁″垝宸插垹闄�') + }) + break + } +} + +const handleSavePlan = async () => { + try { + await planFormRef.value.validate() + ElMessage.success('璁″垝淇濆瓨鎴愬姛') + planDialogVisible.value = false + } catch (error) { + console.log('琛ㄥ崟楠岃瘉澶辫触:', error) + } +} + +const handleDialogClose = () => { + planFormRef.value?.resetFields() +} + +const handleRefresh = () => { + ElMessage.success('鏁版嵁宸插埛鏂�') +} + +const handleFilter = () => { + ElMessage.info('鎵撳紑绛涢�夐潰鏉�') +} + +const handleExport = () => { + ElMessage.success('璁″垝宸插鍑�') +} + +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' +} + +onMounted(() => { + 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> -- Gitblit v1.9.3