feat: M3-M7 全模块落地 + 集成接线
- M3 认证/权限/审计/限流 + 全部 REST 接口 - M4 管理面板(MIUIx + 成绩录入/积分榜下钻/大屏控制) - M5a 大屏页面(六页 + 明细覆盖层 + 缩放适配) - M6 WebSocket 实时同步中心 - M7 xlsx 导出 + 赛事包 zip + 备份 - 规则包 YAML 导入导出(差异预览) - 字体 vendor 子集化(4 套 x2 字重) - 集成:realtime/export/rules 接入 main+httpapi;backup 子命令 - 修复:中间件包装 ResponseWriter 丢失 Hijacker,导致 WS 握手 501
This commit is contained in:
1 parent
d0e3b93e76
commit
bc8b1ee6c0
145 files changed
+25159
-321
No files matched your search
+87
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env bash
|
||||
# 字体子集化脚本 —— 把 ~/Fonts 下的中文字体裁剪成 woff2 并写入 vendor/fonts/
|
||||
#
|
||||
# 用途:离线部署,字体必须随仓库分发,禁止 CDN。
|
||||
# 产物:vendor/fonts/<id>-<weight>.woff2 + vendor/fonts/manifest.json
|
||||
#
|
||||
# 依赖:python3 + fonttools + brotli
|
||||
# pip install fonttools brotli
|
||||
# # 系统 Python 受 PEP 668 保护时用虚拟环境:
|
||||
# # python3 -m venv --system-site-packages ~/.tmp/fontenv
|
||||
# # ~/.tmp/fontenv/bin/pip install brotli
|
||||
# # PYTHON=~/.tmp/fontenv/bin/python vendor/fonts/tools/subset-fonts.sh
|
||||
#
|
||||
# 用法:
|
||||
# vendor/fonts/tools/subset-fonts.sh
|
||||
# FONT_SRC=~/Fonts PYTHON=python3 vendor/fonts/tools/subset-fonts.sh
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
OUT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
FONT_SRC="${FONT_SRC:-$HOME/Fonts}"
|
||||
PYTHON="${PYTHON:-python3}"
|
||||
FONTS_CONF="$SCRIPT_DIR/fonts.conf"
|
||||
|
||||
# 子集字符集:ASCII + GB2312 一级/二级汉字 + 中文标点 + 数字/全角符号
|
||||
CHARSET="$("$PYTHON" - <<'PY'
|
||||
import sys
|
||||
|
||||
chars = set()
|
||||
# 1) ASCII 可打印字符
|
||||
for c in range(0x20, 0x7F):
|
||||
chars.add(chr(c))
|
||||
# 2) GB2312 全部合法双字节码位(一级 3755 + 二级 3008 汉字,及全角标点/希腊/俄文等)
|
||||
for hi in range(0xA1, 0xFF):
|
||||
for lo in range(0xA1, 0xFF):
|
||||
try:
|
||||
chars.add(bytes((hi, lo)).decode("gb2312"))
|
||||
except UnicodeDecodeError:
|
||||
pass
|
||||
# 3) 常用中文标点 / 数字符号补充
|
||||
chars.update(
|
||||
" ·—…‘’“”※→←↑↓√×÷±≈≠≤≥∞°℃℉¥€£©®™№§¶†‡•‰′″〇"
|
||||
"「」『』【】〔〕〖〗《》〈〉"
|
||||
"0123456789"
|
||||
"!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~"
|
||||
)
|
||||
sys.stdout.write("".join(sorted(chars)))
|
||||
PY
|
||||
)"
|
||||
CHAR_COUNT="$(printf '%s' "$CHARSET" | "$PYTHON" -c 'import sys; print(len(sys.stdin.read()))')"
|
||||
|
||||
# 子集化参数:
|
||||
# --flavor=woff2 输出 woff2(需 brotli)
|
||||
# --layout-features 保留字距/连字等,丢弃 CJK 竖排等无用特性以压体积
|
||||
# --name-IDs='*' 保留完整 name 表(含本地化族名)
|
||||
# --recommended-glyphs 保留 .notdef/.null 等推荐字形
|
||||
# --drop-tables+=DSIG 丢弃无用的数字签名表
|
||||
SUBSET_OPTS=(
|
||||
--flavor=woff2
|
||||
--layout-features='kern,liga,clig,calt,ccmp,locl,mark,mkmk'
|
||||
--name-IDs='*'
|
||||
--name-languages='*'
|
||||
--recommended-glyphs
|
||||
--drop-tables+=DSIG
|
||||
)
|
||||
|
||||
mkdir -p "$OUT_DIR"
|
||||
echo "charset: ${CHAR_COUNT} 个字符(ASCII + GB2312 一级/二级 + 中文标点 + 数字符号)"
|
||||
|
||||
while IFS='|' read -r id name family category license source_note reg_src bold_src; do
|
||||
case "$id" in ''|'#'*) continue ;; esac
|
||||
for pair in "regular:400:$reg_src" "bold:700:$bold_src"; do
|
||||
IFS=':' read -r weight_name weight_class src_rel <<<"$pair"
|
||||
src="$FONT_SRC/$src_rel"
|
||||
out="$OUT_DIR/$id-$weight_name.woff2"
|
||||
[ -f "$src" ] || { echo "缺少源字体: $src" >&2; exit 1; }
|
||||
printf ' %-26s %s -> %s\n' "$id-$weight_name" "$(basename "$src")" "$(basename "$out")"
|
||||
"$PYTHON" -m fontTools.subset "$src" "${SUBSET_OPTS[@]}" \
|
||||
--text="$CHARSET" --output-file="$out"
|
||||
done
|
||||
done < "$FONTS_CONF"
|
||||
|
||||
"$PYTHON" "$SCRIPT_DIR/normalize-names.py"
|
||||
"$PYTHON" "$SCRIPT_DIR/gen-manifest.py"
|
||||
|
||||
echo "完成。产物目录:$OUT_DIR"
|
||||
ls -la "$OUT_DIR"/*.woff2
|
||||
Reference in new issue
Block a user