ci/woodpecker/push/woodpecker Pipeline was successful
- 新增 components/RotatingFooterHint:统一文案+蓝色脉冲,4 秒轮换
- 新增 components/FeedbackFab:右下角悬浮按钮(渐变 + 心形信封 + 黄色脉冲点),
点击打开 4 步引导式弹窗
Step 1 选类型(💡新维度 / 🐛bug / 🎨界面 / 📝其他)
Step 2 描述需求 + 选当前板块(chip)
Step 3 留联系方式(可选)+ 提交概览
Step 4 ❤️ 成功页(弹簧 √ 动画)
顶部 spring 进度条,底部上一步/下一步,下拉手柄,背景点击或 X 关闭
- 后端 routes/feedback:bi_user_feedback 表(自动建表,含 status 字段)
POST /api/feedback/submit + GET /api/feedback/list
- Shell 全局挂载 FeedbackFab,自动从 hash 检测当前模块
- 各模块底部追加 RotatingFooterHint:
AssetsModule / MileageModule / SchedulingModule / EleImportPage
HydrogenOverview / HydrogenDaily / ElectricOverview / ElectricDaily
(HydrogenOverview 旧的内嵌实现已替换为共享组件)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
52 lines
1.7 KiB
TypeScript
52 lines
1.7 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
|
|
const FOOTER_HINTS = [
|
|
'想看哪个角度的数据?告诉我们一下嘛',
|
|
'更多统计维度接入中,欢迎您的建议 ~',
|
|
'下一个图表,可能就是您建议的那个',
|
|
'数据科学家正在深夜挖掘新维度…',
|
|
'维度灵感正在路上,钉一下产品同学也行',
|
|
'数字背后还有故事,等下一次上线揭晓',
|
|
];
|
|
|
|
interface Props {
|
|
/** 自定义提示词集合,默认使用通用文案 */
|
|
hints?: string[];
|
|
/** 切换间隔,默认 4 秒 */
|
|
intervalMs?: number;
|
|
/** 额外类名 */
|
|
className?: string;
|
|
/** 点击时回调(一般用来打开反馈弹窗) */
|
|
onClick?: () => void;
|
|
}
|
|
|
|
export default function RotatingFooterHint({ hints = FOOTER_HINTS, intervalMs = 4000, className = '', onClick }: Props) {
|
|
const [idx, setIdx] = useState(0);
|
|
useEffect(() => {
|
|
if (hints.length <= 1) return;
|
|
const t = setInterval(() => setIdx(i => (i + 1) % hints.length), intervalMs);
|
|
return () => clearInterval(t);
|
|
}, [hints, intervalMs]);
|
|
|
|
return (
|
|
<div
|
|
className={`mt-1 flex items-center justify-center gap-1.5 text-[11px] text-slate-400 font-bold ${onClick ? 'cursor-pointer hover:text-blue-500 transition-colors' : ''} ${className}`}
|
|
onClick={onClick}
|
|
>
|
|
<span className="inline-block w-1.5 h-1.5 rounded-full bg-blue-400 animate-pulse" />
|
|
<span
|
|
key={idx}
|
|
style={{ animation: 'rotatingHintFade 0.5s ease' }}
|
|
>
|
|
{hints[idx]}
|
|
</span>
|
|
<style>{`
|
|
@keyframes rotatingHintFade {
|
|
from { opacity: 0; transform: translateY(2px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
`}</style>
|
|
</div>
|
|
);
|
|
}
|