feat: P0/P1/P2全部功能 — 四层泳道/视角切换/KPI看板/预警/差异反打/预算/知识面板/回顾会/情景预测/Excel导入/角色权限

This commit is contained in:
Hermes CI Fix
2026-07-12 17:46:08 +08:00
parent cdf00efd69
commit ee25d5fa1d
8871 changed files with 1778433 additions and 0 deletions
+161
View File
@@ -0,0 +1,161 @@
<template>
<el-dialog v-model="visible" title="" :width="560" :show-close="true" :close-on-click-modal="false" class="cma-welcome-dialog">
<div class="welcome-body">
<div class="welcome-header">
<div class="welcome-icon">👋</div>
<h2>欢迎使用管理会计OS</h2>
<p class="welcome-sub">三步开启从战略到执行的管理闭环</p>
</div>
<div class="steps-wrap">
<div class="step-item" :class="{ active: currentStep === 0, done: currentStep > 0 }">
<div class="step-num">
<span v-if="currentStep > 0"></span>
<span v-else>1</span>
</div>
<div class="step-content">
<h4> 绘制战略地图</h4>
<p>在战略画布上定义财务客户内部流程学习成长四个维度的战略主题和因果关系链让战略"可视化"</p>
<div class="step-preview">🗺 战略地图 KPI目标对齐 预算配置</div>
</div>
</div>
<div class="step-connector" :class="{ active: currentStep >= 1 }"></div>
<div class="step-item" :class="{ active: currentStep === 1, done: currentStep > 1 }">
<div class="step-num">
<span v-if="currentStep > 1"></span>
<span v-else>2</span>
</div>
<div class="step-content">
<h4> 对齐KPI目标</h4>
<p>将战略地图上的战略主题分解为可衡量的KPI支持纵向分解公司部门横向支撑因果传导和BSC瀑布链三种对齐模式</p>
<div class="step-preview">🎯 KPI目标对齐 资源按目标分配</div>
</div>
</div>
<div class="step-connector" :class="{ active: currentStep >= 2 }"></div>
<div class="step-item" :class="{ active: currentStep === 2, done: currentStep > 2 }">
<div class="step-num">
<span v-if="currentStep > 2"></span>
<span v-else>3</span>
</div>
<div class="step-content">
<h4> 编制全面预算</h4>
<p>按对齐后的目标分配资源编制收入/成本/费用/投资预算从此预算不再是财务部闭门造而是从战略自上而下对齐出来的</p>
<div class="step-preview">💰 预算管理 驾驶舱监控执行 差异分析 改善行动</div>
</div>
</div>
</div>
<!-- 完整闭环说明 -->
<div class="pdca-hint" v-if="currentStep >= 2">
<div class="hint-title">三步走完后系统进入持续管理闭环</div>
<div class="hint-flow">
<span>🎯 P 战略规划</span>
<span></span>
<span>📊 D 执行监控</span>
<span></span>
<span>🔍 C 复盘评估</span>
<span></span>
<span>🔄 A 优化调整</span>
</div>
</div>
<div class="welcome-footer">
<el-button v-if="currentStep < 2" type="primary" size="large" @click="currentStep++">继续了解 </el-button>
<el-button v-else type="primary" size="large" @click="startUsing">开始使用 </el-button>
<el-button text @click="skip">跳过引导</el-button>
</div>
</div>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const visible = ref(false)
const currentStep = ref(0)
const GUIDE_SHOWN_KEY = 'cma_guide_shown'
function show() {
visible.value = true
currentStep.value = 0
}
function skip() {
visible.value = false
localStorage.setItem(GUIDE_SHOWN_KEY, '1')
}
function startUsing() {
visible.value = false
localStorage.setItem(GUIDE_SHOWN_KEY, '1')
router.push('/maps')
}
// 暴露show方法供父组件调用
defineExpose({ show })
onMounted(() => {
// 自动检测是否显示过引导
const shown = localStorage.getItem(GUIDE_SHOWN_KEY)
if (!shown) {
// 延迟弹窗让页面先渲染
setTimeout(() => { visible.value = true }, 500)
}
})
</script>
<style scoped>
.welcome-body { text-align: center; }
.welcome-header { margin-bottom: 24px; }
.welcome-icon { font-size: 48px; margin-bottom: 8px; }
.welcome-header h2 { margin: 0 0 6px; font-size: 22px; }
.welcome-sub { color: #666; font-size: 14px; margin: 0; }
.steps-wrap { text-align: left; margin-bottom: 20px; }
.step-item {
display: flex; gap: 14px; padding: 14px 16px;
border: 1px solid #eee; border-radius: 10px;
margin-bottom: 4px; transition: all 0.3s;
}
.step-item.active { border-color: #409eff; background: #f0f7ff; }
.step-item.done { border-color: #b7eb8f; background: #f6ffed; }
.step-num {
flex-shrink: 0; width: 32px; height: 32px;
display: flex; align-items: center; justify-content: center;
border-radius: 50%; font-weight: 700; font-size: 14px;
background: #eee; color: #999;
}
.step-item.active .step-num { background: #409eff; color: #fff; }
.step-item.done .step-num { background: transparent; }
.step-content { flex: 1; }
.step-content h4 { margin: 0 0 4px; font-size: 15px; }
.step-content p { margin: 0 0 6px; font-size: 13px; color: #666; line-height: 1.5; }
.step-preview {
font-size: 12px; color: #909399;
background: #f5f7fa; padding: 4px 8px; border-radius: 4px;
display: inline-block;
}
.step-connector { text-align: center; color: #ddd; font-size: 18px; padding: 2px 0; }
.step-connector.active { color: #409eff; }
.pdca-hint {
background: #f0f7ff; border: 1px solid #d9ecff; border-radius: 10px;
padding: 14px; margin-bottom: 20px;
}
.hint-title { font-size: 14px; font-weight: 600; margin-bottom: 8px; }
.hint-flow {
display: flex; align-items: center; justify-content: center;
gap: 8px; font-size: 13px; flex-wrap: wrap;
}
.hint-flow span { white-space: nowrap; }
.welcome-footer { display: flex; align-items: center; justify-content: center; gap: 12px; }
</style>