perf(mp): 移除 Zod 依赖,轻量验证替代 — 包体积 -300KB

- 新增 utils/validate.ts 轻量验证工具(<1KB vs Zod 360KB)
- daily-monitoring: Zod schema → validateNum() 直接验证
- input: Zod schema → num()/validateStr() 直接验证
- config/index.ts: 移除 Zod include 编译配置

效果:总体积 1.8MB→1.5MB(-17%),pkg-health 分包 432KB→84KB(-81%)
This commit is contained in:
iven
2026-05-13 23:56:12 +08:00
parent 0f6f7a2851
commit 9faccac9eb
4 changed files with 88 additions and 37 deletions

View File

@@ -1,7 +1,7 @@
import { useState } from 'react';
import { View, Text, Input, Picker } from '@tarojs/components';
import Taro, { useDidShow } from '@tarojs/taro';
import { z } from 'zod';
import { num, validateStr } from '@/utils/validate';
import { inputVitalSign, getHealthThresholds, findThreshold, DEFAULT_THRESHOLDS, type HealthThreshold } from '../../../services/health';
import { useAuthStore } from '../../../stores/auth';
import { useHealthStore } from '@/stores/health';
@@ -23,15 +23,9 @@ const INDICATORS = [
const BP_INDICATORS = ['blood_pressure', 'blood_pressure_evening'];
const vitalSignSchema = z.object({
indicator_type: z.enum(['blood_pressure', 'blood_pressure_evening', 'heart_rate', 'blood_sugar_fasting', 'blood_sugar_postprandial', 'weight', 'temperature']),
value: z.number().positive({ message: '请输入有效数值' }),
extra: z.object({
systolic: z.number().min(60, '收缩压过低').max(250, '收缩压过高,请及时就医').optional(),
diastolic: z.number().min(40, '舒张压过低').max(150, '舒张压过高,请及时就医').optional(),
}).optional(),
note: z.string().max(200, '备注不能超过200字').optional(),
});
const valueCheck = num({ posMsg: '请输入有效数值' });
const systolicCheck = num({ min: 60, minMsg: '收缩压过低', max: 250, maxMsg: '收缩压过高,请及时就医', optional: true });
const diastolicCheck = num({ min: 40, minMsg: '舒张压过低', max: 150, maxMsg: '舒张压过高,请及时就医', optional: true });
/** 根据动态阈值生成警告配置 */
function getWarnForIndicator(
@@ -120,11 +114,23 @@ export default function HealthInput() {
? { indicator_type: currentIndicator as 'blood_pressure' | 'blood_pressure_evening', value: parseFloat(systolic), extra: { systolic: parseFloat(systolic), diastolic: parseFloat(diastolic) } }
: { indicator_type: currentIndicator as any, value: parseFloat(value) };
const result = vitalSignSchema.safeParse(input);
if (!result.success) {
Taro.showToast({ title: result.error.issues[0].message, icon: 'none' });
const valueResult = valueCheck.safeParse(input.value);
if (!valueResult.ok) {
Taro.showToast({ title: valueResult.message, icon: 'none' });
return;
}
if (input.extra?.systolic !== undefined) {
const r = systolicCheck.safeParse(input.extra.systolic);
if (!r.ok) { Taro.showToast({ title: r.message, icon: 'none' }); return; }
}
if (input.extra?.diastolic !== undefined) {
const r = diastolicCheck.safeParse(input.extra.diastolic);
if (!r.ok) { Taro.showToast({ title: r.message, icon: 'none' }); return; }
}
if (note) {
const err = validateStr(note, 200, '备注');
if (err) { Taro.showToast({ title: err, icon: 'none' }); return; }
}
const threshold = getWarnForIndicator(thresholds, currentIndicator);
if (threshold) {