fix: QA 第二轮修复 — PatientDetail 重构/测试覆盖/id_number 列宽/小程序 URL 规范化
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

- refactor(web): PatientDetail.tsx 拆分为 4 个子组件(737→334行)
- refactor(web): 提取 usePaginatedData hook 消除重复分页状态
- feat(db): patient.id_number varchar(20)→varchar(255) 容纳加密值
- test(health): 添加预约模块集成测试(创建/列表/租户隔离)
- test(plugin): 添加 6 个 SQL 注入 sanitize 测试
- fix(miniprogram): 7 个 service 文件 URL 构建规范化(params 对象)
- fix(miniprogram): 跨平台字段名对齐(birth_date/start_time/end_time)
This commit is contained in:
iven
2026-04-25 10:22:44 +08:00
parent 55a3fd32d0
commit 0bf1822fa9
34 changed files with 1110 additions and 641 deletions

View File

@@ -1,5 +1,5 @@
import { useState } from 'react';
import { View, Text, Button, Image } from '@tarojs/components';
import { View, Text, Button, ScrollView } from '@tarojs/components';
import Taro from '@tarojs/taro';
import { useAuthStore } from '../../stores/auth';
import './index.scss';
@@ -16,15 +16,16 @@ export default function Login() {
}
try {
const { code } = await Taro.login();
const success = await login(code);
if (success) {
const result = await login(code);
if (result) {
Taro.switchTab({ url: '/pages/index/index' });
} else {
// 未绑定需要获取手机号openid 已由 store 缓存到 Storage
setNeedBind(true);
Taro.showToast({ title: '请授权手机号完成绑定', icon: 'none' });
}
} catch {
Taro.showToast({ title: '登录失败', icon: 'none' });
} catch (err: any) {
const msg = err?.message || '登录失败,请重试';
Taro.showToast({ title: msg.substring(0, 20), icon: 'none', duration: 3000 });
}
};
@@ -42,48 +43,50 @@ export default function Login() {
if (success) {
Taro.switchTab({ url: '/pages/index/index' });
} else {
Taro.showToast({ title: '绑定失败', icon: 'none' });
Taro.showToast({ title: '绑定失败,请重试', icon: 'none' });
}
};
return (
<View className='login-page'>
<View className='login-header'>
<View className='login-logo'>
<Text className='login-logo-text'>+</Text>
<ScrollView scrollY className='login-scroll'>
<View className='login-page'>
<View className='login-header'>
<View className='login-logo'>
<Text className='login-logo-text'>+</Text>
</View>
<Text className='login-title'></Text>
<Text className='login-subtitle'></Text>
</View>
<Text className='login-title'></Text>
<Text className='login-subtitle'></Text>
</View>
<View className='login-body'>
{!needBind ? (
<Button className='login-btn' onClick={handleWechatLogin} loading={loading}>
</Button>
) : (
<Button
className='login-btn'
openType='getPhoneNumber'
onGetPhoneNumber={handleGetPhone}
loading={loading}
>
</Button>
)}
</View>
<View className='agreement-row'>
<View className={`checkbox ${agreed ? 'checked' : ''}`} onClick={() => setAgreed(!agreed)}>
{agreed && <Text className='check-mark'>&#10003;</Text>}
<View className='login-body'>
{!needBind ? (
<Button className='login-btn' onClick={handleWechatLogin} loading={loading}>
</Button>
) : (
<Button
className='login-btn'
openType='getPhoneNumber'
onGetPhoneNumber={handleGetPhone}
loading={loading}
>
</Button>
)}
</View>
<View className='agreement-row'>
<View className={`checkbox ${agreed ? 'checked' : ''}`} onClick={() => setAgreed(!agreed)}>
{agreed && <Text className='check-mark'>&#10003;</Text>}
</View>
<Text className='agreement-text'>
<Text className='agreement-link' onClick={() => Taro.navigateTo({ url: '/pages/legal/user-agreement' })}></Text>
<Text className='agreement-link' onClick={() => Taro.navigateTo({ url: '/pages/legal/privacy-policy' })}></Text>
</Text>
</View>
<Text className='agreement-text'>
<Text className='agreement-link' onClick={() => Taro.navigateTo({ url: '/pages/legal/user-agreement' })}></Text>
<Text className='agreement-link' onClick={() => Taro.navigateTo({ url: '/pages/legal/privacy-policy' })}></Text>
</Text>
</View>
</View>
</ScrollView>
);
}