fix(mp): T40 UI 审计修复 — 28 项设计系统合规 + 安全加固 + 讨论记录
T40 UI 审计修复(60 页面全覆盖): - 新增 $acc-d/$wrn-d 渐变中间色变量,修复首页轮播渐变硬编码 - 替换 8 处裸 white 为 $white 设计变量(5 个 SCSS 文件) - 修复 7 处触摸目标 40/44px → 48px(健康/消息/咨询/预约/首页) - 3 页面新增 Loading 状态(体征录入/个人中心/就诊人添加) - statusTag 移除硬编码布局值,改用 SCSS mixin 控制 - 医生端 14 页面架构 Hook 层补充(useThrottledDidShow 替换 useEffect) - 移除 action-inbox 未使用 import 安全 P0 修复: - JWT 中间件加固:token 类型校验 + 过期预检 + 类型别名简化 - 速率限制增强:滑动窗口 + 暴力破解防护 - analytics handler 错误处理完善 文档: - T40 审计报告(24 PASS / 36 PASS_WITH_ISSUES / 0 NEEDS_WORK) - 5 份 DevTools/性能审计讨论记录 - wiki 症状导航 + 小程序章节更新
This commit is contained in:
@@ -1,98 +0,0 @@
|
||||
import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
|
||||
import { Canvas, View } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
MarkAreaComponent,
|
||||
MarkPointComponent,
|
||||
} from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
|
||||
echarts.use([
|
||||
LineChart,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
MarkAreaComponent,
|
||||
MarkPointComponent,
|
||||
CanvasRenderer,
|
||||
]);
|
||||
|
||||
interface EcCanvasProps {
|
||||
canvasId: string;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
export interface EcCanvasRef {
|
||||
setOption: (option: echarts.EChartsOption) => void;
|
||||
}
|
||||
|
||||
const EcCanvas = React.memo(React.forwardRef<EcCanvasRef, EcCanvasProps>(
|
||||
({ canvasId, height = 300 }, ref) => {
|
||||
const chartInstance = useRef<echarts.ECharts | null>(null);
|
||||
const canvasNode = useRef<any>(null);
|
||||
|
||||
const initChart = async () => {
|
||||
try {
|
||||
const query = Taro.createSelectorQuery();
|
||||
query
|
||||
.select(`#${canvasId}`)
|
||||
.node()
|
||||
.exec((res) => {
|
||||
const node = res[0]?.node;
|
||||
if (!node) return;
|
||||
|
||||
canvasNode.current = node;
|
||||
const dpr = Taro.getSystemInfoSync().pixelRatio;
|
||||
const width = node.width || 350;
|
||||
const heightVal = node.height || height;
|
||||
|
||||
node.width = width * dpr;
|
||||
node.height = heightVal * dpr;
|
||||
|
||||
const ctx = node.getContext('2d');
|
||||
|
||||
chartInstance.current = echarts.init(ctx as any, undefined, {
|
||||
renderer: 'canvas',
|
||||
width,
|
||||
height: heightVal,
|
||||
devicePixelRatio: dpr,
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('EcCanvas init failed:', e);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
initChart();
|
||||
return () => {
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
setOption: (option: echarts.EChartsOption) => {
|
||||
if (chartInstance.current) {
|
||||
chartInstance.current.setOption(option);
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<View style={{ width: '100%', height: `${height}rpx` }}>
|
||||
<Canvas
|
||||
type='2d'
|
||||
id={canvasId}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
));
|
||||
|
||||
EcCanvas.displayName = 'EcCanvas';
|
||||
|
||||
export default EcCanvas;
|
||||
@@ -11,7 +11,11 @@ interface TrendChartProps {
|
||||
height?: number;
|
||||
}
|
||||
|
||||
const DPR = Taro.getSystemInfoSync().pixelRatio || 2;
|
||||
let _dpr = 0;
|
||||
function getDPR(): number {
|
||||
if (!_dpr) _dpr = Taro.getSystemInfoSync().pixelRatio || 2;
|
||||
return _dpr;
|
||||
}
|
||||
|
||||
function drawLine(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
@@ -42,22 +46,22 @@ export default React.memo(function TrendChart({
|
||||
const node = canvasRef.current;
|
||||
if (!node || !data || data.length === 0) return;
|
||||
|
||||
const w = node.width / DPR;
|
||||
const h = node.height / DPR;
|
||||
const w = node.width / getDPR();
|
||||
const h = node.height / getDPR();
|
||||
const ctx = node.getContext('2d');
|
||||
if (!ctx) return;
|
||||
|
||||
ctx.clearRect(0, 0, node.width, node.height);
|
||||
ctx.save();
|
||||
ctx.scale(DPR, DPR);
|
||||
ctx.scale(getDPR(), getDPR());
|
||||
|
||||
const pad = { left: 45, right: 15, top: 20, bottom: 30 };
|
||||
const cw = w - pad.left - pad.right;
|
||||
const ch = h - pad.top - pad.bottom;
|
||||
|
||||
const values = data.map((d) => d.value);
|
||||
let yMin = Math.min(...values);
|
||||
let yMax = Math.max(...values);
|
||||
let yMin = values.reduce((a, b) => Math.min(a, b), Infinity);
|
||||
let yMax = values.reduce((a, b) => Math.max(a, b), -Infinity);
|
||||
if (referenceMin != null) yMin = Math.min(yMin, referenceMin);
|
||||
if (referenceMax != null) yMax = Math.max(yMax, referenceMax);
|
||||
const yRange = yMax - yMin || 1;
|
||||
@@ -157,8 +161,8 @@ export default React.memo(function TrendChart({
|
||||
canvasRef.current = node;
|
||||
const sysInfo = Taro.getSystemInfoSync();
|
||||
const canvasW = (sysInfo.windowWidth * 750) / sysInfo.windowWidth;
|
||||
node.width = sysInfo.windowWidth * DPR;
|
||||
node.height = ((height / 750) * sysInfo.windowWidth) * DPR;
|
||||
node.width = sysInfo.windowWidth * getDPR();
|
||||
node.height = ((height / 750) * sysInfo.windowWidth) * getDPR();
|
||||
draw();
|
||||
});
|
||||
}, [draw, height]);
|
||||
|
||||
Reference in New Issue
Block a user