feat(medications): 简化药品添加流程并优化AI相机交互体验

- 移除药品添加选项底部抽屉,直接跳转至AI识别相机
- 优化AI相机拍摄完成后的按钮交互,展开为"拍照"和"完成"两个按钮
- 添加相机引导提示本地存储,避免重复显示
- 修复相机页面布局跳动问题,固定相机高度
- 为医疗免责声明组件添加触觉反馈错误处理
- 实现活动热力图的国际化支持,包括月份标签和统计文本
This commit is contained in:
richarjiang
2025-11-25 14:09:24 +08:00
parent 3db2d39a58
commit 6f2b7eb45e
5 changed files with 518 additions and 125 deletions

View File

@@ -1,6 +1,5 @@
import CelebrationAnimation, { CelebrationAnimationRef } from '@/components/CelebrationAnimation';
import { DateSelector } from '@/components/DateSelector';
import { MedicationAddOptionsSheet } from '@/components/medication/MedicationAddOptionsSheet';
import { MedicationCard } from '@/components/medication/MedicationCard';
import { TakenMedicationsStack } from '@/components/medication/TakenMedicationsStack';
import { ThemedText } from '@/components/ThemedText';
@@ -59,7 +58,6 @@ export default function MedicationsScreen() {
const celebrationTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
const [isCelebrationVisible, setIsCelebrationVisible] = useState(false);
const [disclaimerVisible, setDisclaimerVisible] = useState(false);
const [addSheetVisible, setAddSheetVisible] = useState(false);
const [pendingAction, setPendingAction] = useState<'manual' | null>(null);
// 从 Redux 获取数据
@@ -72,37 +70,34 @@ export default function MedicationsScreen() {
);
const medicationsForDay = useAppSelector(medicationSelector);
const handleOpenAddSheet = useCallback(() => {
setAddSheetVisible(true);
}, []);
const handleManualAdd = useCallback(() => {
const hasRead = getItemSync(MEDICAL_DISCLAIMER_READ_KEY);
setPendingAction('manual');
if (hasRead === 'true') {
setAddSheetVisible(false);
setPendingAction(null);
router.push('/medications/add-medication');
} else {
setAddSheetVisible(false);
setDisclaimerVisible(true);
}
}, []);
const handleAiRecognize = useCallback(async () => {
setAddSheetVisible(false);
// 直接跳转到 AI 相机页面
const handleAddMedication = useCallback(async () => {
// 先检查登录状态
const isLoggedIn = await ensureLoggedIn();
if (!isLoggedIn) return;
// 检查 VIP 权限
const access = checkServiceAccess();
if (!access.canUseService) {
openMembershipModal();
return;
}
// 直接跳转到 AI 相机页面
router.push('/medications/ai-camera');
}, [checkServiceAccess, ensureLoggedIn, openMembershipModal, router]);
}, [checkServiceAccess, ensureLoggedIn, openMembershipModal]);
const handleManualAdd = useCallback(() => {
const hasRead = getItemSync(MEDICAL_DISCLAIMER_READ_KEY);
setPendingAction('manual');
if (hasRead === 'true') {
setPendingAction(null);
router.push('/medications/add-medication');
} else {
setDisclaimerVisible(true);
}
}, []);
const handleDisclaimerConfirm = useCallback(() => {
// 用户同意免责声明后,记录已读状态,关闭弹窗并跳转到添加页面
@@ -308,7 +303,7 @@ export default function MedicationsScreen() {
<TouchableOpacity
activeOpacity={0.7}
onPress={handleOpenAddSheet}
onPress={handleAddMedication}
>
{isLiquidGlassAvailable() ? (
<GlassView
@@ -425,13 +420,6 @@ export default function MedicationsScreen() {
)}
</ScrollView>
<MedicationAddOptionsSheet
visible={addSheetVisible}
onClose={() => setAddSheetVisible(false)}
onManualAdd={handleManualAdd}
onAiRecognize={handleAiRecognize}
/>
{/* 医疗免责声明弹窗 */}
<MedicalDisclaimerSheet
visible={disclaimerVisible}