diff --git a/docs/hanke-pilot-plan-20260829.md b/docs/hanke-pilot-plan-20260829.md new file mode 100644 index 00000000..c44bb049 --- /dev/null +++ b/docs/hanke-pilot-plan-20260829.md @@ -0,0 +1,29 @@ +# 酣客 CMA 真实业务试点方案(2026-08-29) + +> 提出:项目Bot | 目标:CMA 从测试数据切换为酣客真实业务运行 + +## 一、试点范围(阶段一:跑通核心链路) + +| 模块 | 试点内容 | 数据来源 | +|:--|:--|:--| +| **KPI 体系** | 8 个核心 KPI 真实目标设定(营收/净利/费用率/现金流/渠补/新客/应收/自动化) | 管理团队确认目标 | +| **预算** | 2026H2 真实预算(已建 2026H2 版本,值待校准) | 财务团队确认预算值 | +| **实际值录入** | 月度真实经营数据(营收/费用/渠补等) | 财务/业务录入 | +| **战略地图** | 地图53 目标细化(8KPI 目标值对齐战略) | 管理团队 | +| **现金流** | 真实应收/应付计划(预算联动+手动) | 财务 | +| **行动方案** | 5 条试点行动推进 | 业务/财务 | + +## 二、启动步骤(分 3 天) + +- **Day1 数据校准**:确认 KPI 目标值 + 预算值(当前 2026H2 版本:营收2000/净利60/费用率900 等,与战略目标对比校准) +- **Day2 实际数据**:录入 2026-07/08 真实实际值(或从现有 kpi_values 中甄别真实数据) +- **Day3 闭环跑通**:执行报告→差异告警→现金流同步→行动确认→周复盘 + +## 三、需要你确认 +1. **KPI 目标**:8 个 KPI 的目标值(用当前 2026H2 预算值,还是你/管理团队给新的) +2. **真实数据范围**:实际值从哪来(现有数据可用 vs 需要新录) +3. **试点节奏**:3 天节奏是否合适 + +## 四、成功后 +- 输出酣客试点报告(数据/闭环/问题) +- 沉淀为"真实客户上线"标准流程(可复制到博海账套) diff --git a/frontend/src/components/CountUp.vue b/frontend/src/components/CountUp.vue new file mode 100644 index 00000000..a346ba68 --- /dev/null +++ b/frontend/src/components/CountUp.vue @@ -0,0 +1,77 @@ + + + diff --git a/frontend/src/main.ts b/frontend/src/main.ts index 0c54ee6c..f6302858 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -6,6 +6,7 @@ import { createPinia } from 'pinia' import App from './App.vue' import router from './router' import './style.css' +import './styles/transitions.css' const app = createApp(App) diff --git a/frontend/src/styles/transitions.css b/frontend/src/styles/transitions.css new file mode 100644 index 00000000..fe0817e9 --- /dev/null +++ b/frontend/src/styles/transitions.css @@ -0,0 +1,103 @@ +/* ============================================ + CMA 全局动效 — 借鉴 Transitions.dev / BeUI 模式 + 纯CSS实现,Vue3 + Element Plus 覆盖层 + ============================================ */ + +/* ── 1. 表单校验失败抖动 ── */ +@keyframes cma-shake { + 0%, 100% { transform: translateX(0); } + 20% { transform: translateX(-6px); } + 40% { transform: translateX(6px); } + 60% { transform: translateX(-4px); } + 80% { transform: translateX(4px); } +} +.el-form-item.is-error .el-input__wrapper, +.el-form-item.is-error .el-select__wrapper, +.el-form-item.is-error .el-textarea__inner { + animation: cma-shake 0.4s ease-in-out; +} + +/* ── 2. 按钮状态机:成功/错误反馈 ── */ +@keyframes cma-btn-success { + 0% { transform: scale(1); } + 50% { transform: scale(1.05); } + 100% { transform: scale(1); } +} +.el-button.is-success-pop { + background: #67c23a !important; + border-color: #67c23a !important; + animation: cma-btn-success 0.3s ease; +} +.el-button.is-error-pop { + background: #f56c6c !important; + border-color: #f56c6c !important; + animation: cma-btn-success 0.3s ease; +} + +/* ── 3. 数字滚动时高亮 ── */ +@keyframes cma-count-flash { + 0% { color: #409eff; } + 100% { color: inherit; } +} +.cma-count-up { + font-variant-numeric: tabular-nums; + transition: color 0.3s; +} +.cma-count-up.is-flashing { + animation: cma-count-flash 0.6s ease; +} + +/* ── 4. 弹窗/抽屉开合过渡(缩放+淡入,从触发点展开) ── */ +.cma-dialog-fade-enter-active { + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); +} +.cma-dialog-fade-leave-active { + transition: all 0.15s ease; +} +.cma-dialog-fade-enter-from { + opacity: 0; + transform: scale(0.95) translateY(-8px); +} +.cma-dialog-fade-leave-to { + opacity: 0; + transform: scale(0.97); +} + +/* ── 5. 骨架屏 → 内容交叉淡入 ── */ +.cma-skeleton-fade-enter-active { + transition: opacity 0.35s ease; +} +.cma-skeleton-fade-enter-from { + opacity: 0; +} + +/* ── 6. 列表行进入动画 ── */ +@keyframes cma-row-in { + from { opacity: 0; transform: translateY(6px); } + to { opacity: 1; transform: translateY(0); } +} +.cma-row-enter { + animation: cma-row-in 0.3s ease both; +} + +/* ── 7. 卡片悬浮提升 ── */ +.cma-card-hover { + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s ease; +} +.cma-card-hover:hover { + transform: translateY(-2px); + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1); +} + +/* ── 8. 无障碍:用户偏好减少动效时关闭 ── */ +@media (prefers-reduced-motion: reduce) { + .el-form-item.is-error .el-input__wrapper, + .el-form-item.is-error .el-select__wrapper, + .el-form-item.is-error .el-textarea__inner, + .cma-count-up.is-flashing, + .cma-row-enter, + .cma-card-hover { + animation: none !important; + transition: none !important; + } +} diff --git a/frontend/src/views/Dashboard.vue b/frontend/src/views/Dashboard.vue index da7855a1..daa9da29 100644 --- a/frontend/src/views/Dashboard.vue +++ b/frontend/src/views/Dashboard.vue @@ -44,10 +44,10 @@