健行会综合活动管理平台(SoHike-Next)设计说明书 V4.1

更新日期:2026-06-28 版本:V4.3(热度序列等级命名、头像组件、账户设置页全面重构) 基于V3.2(2026-06-11)+ 6月12~24日全部讨论整合 每个条目标注完成阶段


一、品牌与VI

1.1 协会信息

1.2 视觉规范

项目 规范 完成阶段
主色 春绿 #5AA56E / 天蓝 #008CD2 / 橘红 #F08219 ✅ Sprint 1a
布局 顶部Header(56px) + 汉堡菜单 ✅ Sprint 1a
背景色 #F5F5F5 ✅ Sprint 1a
文字色 主#333333 / 辅#888888 ✅ Sprint 1a
组件动效 hover上移/点击缩放/淡入 📅 Sprint 1b

1.3 Logo使用

版本 用途 完成阶段
山水路虹标准版 首页Banner ✅ Sprint 1a
Logo图标 Header品牌区 ✅ Sprint 1a
立体徽章 用户头像 ✅ Sprint 1a

二、系统架构

2.1 技术栈

技术 完成阶段
前端框架 React + TypeScript + Vite ✅ Sprint 1a
后端框架 Python FastAPI ✅ Sprint 0
数据库 PostgreSQL + SQLAlchemy ✅ Sprint 0
缓存 Redis ✅ Sprint 0
Web服务器 Nginx (Ubuntu) ✅ Sprint 0
前端构建 生产构建 + nginx静态服务 ✅ Sprint 1a

2.2 基础设施

项目 状态 完成阶段
域名 szjxzxh.cn ✅ 已配 Sprint 0
SSL证书(Let's Encrypt) ✅ 已配 Sprint 0
ICP备案 ⏳ 待管局审批 外部
华为云OBS(sohike-images) ✅ 已配 Sprint 0
健行会公众号 ✅ 已配 Sprint 0
深健协服务号 ⏳ 待微信认证 外部

三、前端组件规范

3.1 用户角色与会员体系

角色定义

角色 达成条件 入口
游客 微信OAuth登录+绑定介绍人 注册资料(昵称/头像/手机+介绍人)
临时队员 游客绑定介绍人后 注册资料
预备会员 填写会员登记表 注册资料
准会员 预备会员3个月内参加活动≥3次(自动) 注册资料
正式会员 准会员→理事会投票→缴费 会员信息(完整资料+等级+健行分)
领队 正式会员+领队认证 会员信息+活动管理
管理员 协会指定 全后台权限

菜单规则

会员内部分级(1-10级)

会员级别体系以热度序列来冠名。拟以"温热阳"三温区、"将初仲至"四程度构建会员热度序列。

温:将温 → 初温 → 仲温 → 至温 热:将热 → 初热 → 仲热 → 至热 阳:将阳 → 骄阳

温→热→阳 将(欲)→初(始)→仲(中)→至(极)→骄阳(巅峰)

等级 名称 健行分门槛 级差 含义
Lv.1 将温 0 温度将升而未升,喻初入会籍
Lv.2 初温 51 50 温之始,开始积累
Lv.3 仲温 101 50 温之中段,渐入佳境
Lv.4 至温 151 50 温之极致,温润圆满
Lv.5 将热 201 50 热情将起,蓄势待发
Lv.6 初热 301 100 热之始,活力初现
Lv.7 仲热 601 300 热之中段,炽热进行时
Lv.8 至热 901 300 热之极致,热情饱满
Lv.9 将阳 1301 400 阳光将现,蓄势待升
Lv.10 骄阳 1801 500 骄阳当空,巅峰之境

视觉颜色渐变

为配合等级递进感,使用VI三色渐变呈现热度变化:

温区 色值 感受
将温 → 至温 天蓝 #008CD2春绿 #5AA56E 冷→暖,初入暖境
将热 → 至热 春绿 #5AA56E橘红 #F08219 暖→热,热情升温
将阳 → 骄阳 橘红 #F08219红橙 #E05530 热→炽,巅峰之境

配色逻辑:温区从蓝色起步(冷静),向绿色过渡(温暖);热区从绿色转向橘红(热情);阳区升至红橙(炽烈巅峰)。整体呈现「蓝→绿→橙→红」的自然升温曲线,在会员中心等级Modal中通过等级徽章的颜色即可一目了然。

显示方式:Lv.5 将热(等级号+名称同时显示)

健行分获取规则

活动类型 分值 说明
一日例行户外 5分 基础分值
一日挑战/探险 10分 高难度、高风险
多日活动 每天5分 按天数累计
特别加分 规划师定 人数少、路线罕见的酌情加分

3.2 组件库(Sprint 1a已实现)

组件 规范 状态
Header 通栏,左品牌区+中标题+右头像,56px高
汉堡菜单 三条杠,点击展开,点击外部关闭
轮播图(Carousel) 自动播放+手动滑动,5张照片+标语
功能宫格(FunctionGrid) 2x5布局,彩色渐变卡片,SVG图标
活动卡片(ActivityCard) 显示日期/标题/地点/规划师/健行分/报名状态
Footer 简洁深色,Logo+品牌+备案号左对齐
用户头像 立体徽章,圆形,点击跳转会员页

3.2 组件库(待优化 Sprint 1b)

组件 待优化内容
按钮 统一圆角8px、hover上移、点击缩放
表单输入框 圆角8px、聚焦春绿边框
标签/徽章 统一圆角12px、状态色规范
卡片 统一阴影规范、hover动效

四、页面清单

4.1 已完成(Sprint 1a ✅)

页面 路由 核心功能
🏠 首页 / 轮播→功能宫格(5个)→活动列表→Footer
📋 活动列表 /activities 排序+筛选+搜索+题图切换
📄 活动详情 /activity/:id 富文本风格、报名列表、免责声明、全部字段

4.2 待开发

页面 路由 优先级 计划阶段 核心内容
👤 会员资料 /member P0 Sprint 1a 正式会员完整资料编辑(含等级/健行分/手机验证)
🔐 登录/注册 /login P0 Sprint 1b 微信OAuth + 手机验证
📝 我的活动 /my-activities P1 Sprint 1b 已报名/已签到列表
⚙️ 活动管理 /admin/activities P1 Sprint 1c 创建/编辑活动
📰 协会资讯 /news P2 Sprint 1c 公告列表
🌤️ 天气详情 /weather P1 Sprint 1b 活动地点实时天气+预报
⚙️ 账户设置 /settings P0 Sprint 1b 非会员账户设置(角色显示+改昵称+选头像)

五、活动模板设计

5.1 数据库字段(20个)

详见活动模板设计_v3文档(工具箱链接) - 长文本字段(内容/路线/行程/装备/注意事项/免责声明/费用明细)支持HTML - 系统自动字段不显示在表单中

5.2 模板类型

模板 适用场景 特殊字段 计划阶段
A. 周末例行户外 当天来回周末活动 ✅ Sprint 1a
B. 假期出行 多日节假日活动 免责声明 📅 Sprint 1b
C. 专项出游 主题特色活动 免责声明 📅 Sprint 1b
D. 富文本报名 费用明细复杂 费用明细表+免责声明 📅 Sprint 1b

5.3 定制机制


六、功能预研

功能 方案 计划阶段
集合点跳导航 高德URI Scheme 📅 Sprint 1b 预研
路线轨迹预览 Leaflet.js + OSM 📅 Sprint 1b 预研
天气实时刷新 QWeather API + Redis 📅 Sprint 1b 预研
公交路线规划 高德公交API 📅 Sprint 1b 预研

七、公众号写作

项目 状态 计划阶段
图片上传到素材库 ✅ 已验证 Sprint 1a
创建草稿 ✅ 已验证 Sprint 1a
AI分析照片扩写文字 ❌ 待改进 Sprint 1b
一键发布 ❌ API权限不足 长期

八、工作模式

Step 1:设计文件迭代 ← 当前
  讨论 → 修改 → 确认

Step 2:按设计开发
  派单(统一模型)→ 验收 → 用户确认

Step 3:产品迭代
  测试 → 反馈 → 回到Step 1

确立时间:✅ Sprint 1a(2026-06-24)


九、Sprint规划总览

Sprint 1a(当前 — 已完成/进行中)

模块 状态
首页骨架(轮播+宫格+列表)
活动列表(排序+筛选+搜索)
活动详情(富文本+全部字段)
活动模板设计v3
Header(品牌区+用户头像)
Footer(简洁深色)
设计说明书V4.0 ✅ 本次
会员资料页 📅 进行中

Sprint 1b(下一步)

模块 依赖
登录/注册页 服务号认证
会员资料页完善
组件动效优化
报名/签到API 登录功能
功能预研(导航/天气/路线)

Sprint 1c

模块 依赖
活动管理后台 登录
我的活动 报名API
协会资讯
设置页 登录
模板定制管理

本版本为最新设计规范,所有开发需以此为准。


十、IMA个人知识库 + ClawBot集成

通过ClawBot(OpenClaw)调用IMA OpenAPI,实现对知识库和笔记的智能管理

10.1 已就绪的能力

能力 说明 场景
🔍 搜索知识库 全文搜索知识库内容 找文件、查资料
📂 浏览目录 列出知识库/文件夹内的文件和子文件夹 掌握知识库结构
📄 读取文件 获取PDF/Word/笔记等下载链接 查看原文
📝 创建笔记 新建笔记并写入内容 会议记录、灵感速记
✏️ 追加笔记 往已有笔记追加内容 持续记录
⬆️ 上传文件 上传PDF/Word/图片到知识库 归档
🌐 添加网页 收藏网页/微信文章到知识库 资料收集
🏷️ 标签管理 给文件打标签(#标签 分类筛选
🔗 笔记关联知识库 把笔记关联到指定知识库 结构化

10.2 不能做的

事项 原因
与IMA AI对话 聊天功能不对OpenAPI开放
管理知识库设置 创建/删除知识库需在IMA客户端操作
视频上传 不支持视频格式
批量操作 需逐条调用API

10.3 SoHike中的应用场景

场景 说明 阶段
活动资料归档 每次活动完成后,将活动方案/照片归入知识库 Sprint 1b
协会知识库整理 去重、分类、标签管理(SimHash扫描已验证) 待命
智能问答 ClawBot基于知识库回答协会相关问题 ✅ 已可用
公众号素材管理 文章草稿、历史文章存入知识库 Sprint 1b
会员知识自助 会员通过SoHike查询协会文档 Sprint 1c

10.4 数据流

IMA知识库 ←→ IMA OpenAPI ←→ ClawBot ←→ SoHike用户
                           ↕
                     SoHike-Next后端
                   (查询/归档接口)

10.5 当前配置

11.6 报名统计与导出

功能 说明 阶段
报名人数统计 总报名人数、车辆数 📅 Sprint 1b
晚餐人数统计 参加晚餐人数,默认参加 📅 Sprint 1b
规划师导出 导出报名表(含人数/车辆/晚餐/备注) 📅 Sprint 1b

天气集成详细需求

条件 显示内容 说明
活动开始前 活动当天天气预报 预报温度+天气状况
活动开始后 实时天气 当前温度+天气状况
任何时间 刷新时间 显示"更新于 HH:mm"
点击链接 天气详情 跳转到天气页面

后端API需要: - GET /api/v1/weather/now?location=xxx → 实时天气 - GET /api/v1/weather/forecast?location=xxx&date=xxx → 按日预报

会员入会申请相关

需求 说明 阶段 依赖
欢迎文字后台可修改(HTML富文本) 后台富文本编辑器 📅 Sprint 1c 申请表顶部的欢迎/说明文字从后台配置读取
菜单条件显示 仅预备会员登录后显示"会员入会申请"入口 📅 Sprint 1b 登录系统

预备会员入会引导(备忘)

触发条件: 预备会员(已参加3次活动)登录后 交互: 弹出提示 → "您已符合入会条件,是否申请入会?" 选项: [立即申请] [稍后再说] [不再提示] 技术方案: 登录接口返回用户状态 → 前端判断 → 弹出Modal 阶段: 📅 Sprint 1b(与登录系统同时实现)

六、数据库结构(会员模块)

6.1 完整数据库结构

6.1 完整数据库结构

表1:members(会员主表)

字段 类型 约束 说明
id UUID PK 主键
member_no VARCHAR(32) UNIQUE, NOT NULL 会员编号(如 JH-2026-0001)
name VARCHAR(64) NOT NULL 真实姓名
nickname VARCHAR(64) 户外昵称(选填)
call_sign VARCHAR(32) 业余无线电呼号(选填)
phone VARCHAR(16) UNIQUE, NOT NULL 手机号码
email VARCHAR(128) Email
qq VARCHAR(32) QQ号(选填)
work_unit VARCHAR(128) 工作单位及职务(选填)
district VARCHAR(64) 通常住址(区级)
id_number VARCHAR(32) NOT NULL 身份证号码(加密存储,AES-256)
emergency_contact VARCHAR(64) NOT NULL 紧急联系人姓名
emergency_relation VARCHAR(32) NOT NULL 紧急联系人与本人关系
emergency_phone VARCHAR(16) NOT NULL 紧急联系人电话
medical_history TEXT 个人病史(选填,加密存储)
photo VARCHAR(256) 个人标准照URL(选填)
introducer VARCHAR(64) NOT NULL 介绍人姓名
status ENUM('pending','active','suspended','resigned') NOT NULL, DEFAULT 'pending' 会员状态
level INT DEFAULT 1 会员等级
hiking_score DECIMAL(5,1) DEFAULT 0 健行分
join_date DATE 正式入会日期
expire_date DATE 会籍到期日
created_at TIMESTAMP DEFAULT NOW() 创建时间
updated_at TIMESTAMP DEFAULT NOW() 更新时间

表2:member_consents(同意记录)

字段 类型 约束 说明
id UUID PK 主键
member_id UUID FK → members.id 会员ID
consent_type VARCHAR(32) NOT NULL 类型:general/id_number/medical/photo/emergency
consent_text TEXT NOT NULL 同意的具体内容文本
ip_address VARCHAR(45) 提交时的IP
consented_at TIMESTAMP DEFAULT NOW() 同意时间
revoked_at TIMESTAMP 撤回时间(如有)

表3:member_activity_log(活动参与记录)

字段 类型 约束 说明
id UUID PK 主键
member_id UUID FK → members.id 会员ID
activity_id UUID FK → activities.id 活动ID
status ENUM('registered','checked_in','cancelled') NOT NULL 参与状态
dinner BOOLEAN DEFAULT TRUE 是否参加晚餐
participant_count INT DEFAULT 1 参加人数
vehicle VARCHAR(64) 车辆信息
note TEXT 备注
registered_at TIMESTAMP DEFAULT NOW() 报名时间
checked_in_at TIMESTAMP 签到时间

表4:activity_templates(活动模板配置)

字段 类型 约束 说明
id UUID PK 主键
template_key VARCHAR(32) UNIQUE, NOT NULL weekend/holiday/special/rich
template_name VARCHAR(64) NOT NULL 名称:周末例行户外等
field_config JSONB NOT NULL 字段配置(顺序、可见性、必填)
is_active BOOLEAN DEFAULT TRUE 是否启用
created_at TIMESTAMP DEFAULT NOW()

表5:disclaimer_versions(免责声明版本管理)

字段 类型 约束 说明
id UUID PK 主键
version VARCHAR(16) NOT NULL 版本号
content TEXT NOT NULL 免责声明HTML内容
is_default BOOLEAN DEFAULT FALSE 是否为当前默认版本
created_at TIMESTAMP DEFAULT NOW()

表6:site_settings(站点配置)

字段 类型 约束 说明
id UUID PK 主键
key VARCHAR(64) UNIQUE, NOT NULL 配置键
value TEXT NOT NULL 配置值(HTML)
description VARCHAR(256) 说明
updated_at TIMESTAMP DEFAULT NOW()

预置配置项: - register_welcome — 注册页欢迎文字(HTML) - register_privacy — 注册页隐私告知(HTML) - member_fee — 会费标准 - insurance_info — 保险说明



SQL建表语句

-- 会员主表
CREATE TABLE members (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    member_no VARCHAR(32) UNIQUE NOT NULL,
    name VARCHAR(64) NOT NULL,
    nickname VARCHAR(64),
    call_sign VARCHAR(32),
    phone VARCHAR(16) UNIQUE NOT NULL,
    email VARCHAR(128),
    qq VARCHAR(32),
    work_unit VARCHAR(128),
    district VARCHAR(64),
    id_number VARCHAR(32) NOT NULL,  -- AES-256加密存储
    emergency_contact VARCHAR(64) NOT NULL,
    emergency_relation VARCHAR(32) NOT NULL,
    emergency_phone VARCHAR(16) NOT NULL,
    medical_history TEXT,  -- AES-256加密存储
    photo VARCHAR(256),
    introducer VARCHAR(64) NOT NULL,
    status VARCHAR(16) NOT NULL DEFAULT 'pending',
    level INT DEFAULT 1,
    hiking_score DECIMAL(5,1) DEFAULT 0,
    join_date DATE,
    expire_date DATE,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

-- 同意记录表
CREATE TABLE member_consents (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    member_id UUID NOT NULL REFERENCES members(id),
    consent_type VARCHAR(32) NOT NULL,
    consent_text TEXT NOT NULL,
    ip_address VARCHAR(45),
    consented_at TIMESTAMP DEFAULT NOW(),
    revoked_at TIMESTAMP
);

-- 活动参与记录
CREATE TABLE member_activity_log (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    member_id UUID NOT NULL REFERENCES members(id),
    activity_id UUID NOT NULL REFERENCES activities(id),
    status VARCHAR(16) NOT NULL,
    dinner BOOLEAN DEFAULT TRUE,
    participant_count INT DEFAULT 1,
    vehicle VARCHAR(64),
    note TEXT,
    registered_at TIMESTAMP DEFAULT NOW(),
    checked_in_at TIMESTAMP
);

-- 活动模板配置
CREATE TABLE activity_templates (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    template_key VARCHAR(32) UNIQUE NOT NULL,
    template_name VARCHAR(64) NOT NULL,
    field_config JSONB NOT NULL,
    is_active BOOLEAN DEFAULT TRUE,
    created_at TIMESTAMP DEFAULT NOW()
);

-- 免责声明版本
CREATE TABLE disclaimer_versions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    version VARCHAR(16) NOT NULL,
    content TEXT NOT NULL,
    is_default BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP DEFAULT NOW()
);

-- 站点配置
CREATE TABLE site_settings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    key VARCHAR(64) UNIQUE NOT NULL,
    value TEXT NOT NULL,
    description VARCHAR(256),
    updated_at TIMESTAMP DEFAULT NOW()
);


字段加密说明

字段 加密方式 说明
id_number AES-256 应用层加密,密钥存环境变量
medical_history AES-256 应用层加密,密钥存环境变量
其他字段 TLS传输加密 数据库中明文存储,传输加密

QWeather API地点颗粒度测试结论

支持的最小级别:区/县级(district)

级别 示例ID 地区 是否支持
101280601 深圳
101280604 南山 最小颗粒度
101280602 罗湖
101280302 博罗
101280305 龙门
镇/村 横河镇
景区/山 梧桐山

深圳各区ID

ID
101280601 深圳(全市)
101280602 罗湖
101280603 福田
101280604 南山
101280605 宝安
101280606 龙岗
101280607 盐田
101280608 龙华
101280610 光明

惠州各区ID

ID 区/县
101280301 惠州(全市)
101280302 博罗
101280303 惠阳
101280304 惠东
101280305 龙门

天气地点精度选择(待研究)

问题: 规划师创建活动时,如何选择天气预报的精度级别?

方案探讨: 1. 自动匹配 — 根据活动地点文本自动匹配区级ID(如"博罗"→101280302) 2. 下拉选择 — 创建活动时增加"天气区域"下拉,列出附近区/县 3. GPS自动 — 根据活动集合点GPS坐标自动匹配辖区

下一步: Sprint 1b功能预研时测试自动匹配方案的可行性