DevandCursor 60daff2365 搭建轻舟一期门户、后台和统一登录。
让分类、会员和示例工具共用同一账号,本地即可跑通登录与授权。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-09 16:46:35 +08:00

轻舟(Qingzhou)功能说明

状态:一期已可在本地运行。目录按现有工程分为 backend、frontend、admin。下文仍是功能边界;支付渠道、自动开云主机和团队席位仍留在后续阶段。

参考站点:蜘蛛导航。借鉴它的门户信息架构:顶栏检索、左侧分类、分区标题、工具卡片(图标、名称、简介、标签)。轻舟的产品是「实用工具与软件服务平台」:把多个在线工具汇到同一套账号下,用会员订阅、云端部署和增值服务盈利。


1. 产品一句话

轻舟提供统一账号和会员权益。用户在平台登录一次,即可带着同一身份、同一会员权限进入各个已接入工具;工具可以有独立网址,也可以用不同语言开发。

品牌名:轻舟。项目目录名 qztool 只作工程名,前台展示使用「轻舟」。

2. 谁在用、靠什么赚钱

2.1 用户

角色 能做什么
访客 浏览首页、分类、搜索、工具介绍、价格、帮助文章
注册用户 登录、管理资料与安全、打开已接入工具、使用免费额度
会员 在免费能力之上使用付费工具、更高额度、会员标识
企业/团队管理员(后期) 管理席位、查看团队用量、为成员分配工具权限
平台运营 后台维护分类、工具、内容、会员、订单、接入应用
工具服务端 作为 OAuth 客户端,向账号中心换取用户身份和权益,不保存轻舟密码

2.2 收入

  1. 会员订阅:按月/按年开通平台会员,解锁工具和额度。
  2. 增值服务:额外额度、去广告、优先支持、定制二开、私有化部署咨询。
  3. 云端部署:把开源软件二次开发后的工具,以共享 SaaS 或独立实例提供给用户。
  4. 二开交付:用户提交需求,平台报价、排期、交付一个接入统一账号的工具或功能包。

首期把「能登录、能区分会员、能在后台配置工具和内容」做完整。自动开通云主机、在线支付渠道、团队席位放到后续阶段,但数据结构和页面入口按全文预留,避免返工。

3. 门户上借鉴参考站的部分

首页结构:

  • 顶部:品牌、主导航、搜索框、登录/注册或头像菜单。
  • 搜索框下方可用范围切换:站内工具、我的常用、文档帮助。常用和帮助在登录后更有意义;未登录时「我的常用」引导登录。
  • 左侧分类导航,可收起。分类、子分类、排序全部来自后台。
  • 主区域按分区排列工具卡片。分区示例:热门推荐、效率办公、文件处理、开发辅助、多媒体、学习笔记。具体分区由后台配置,不写死。
  • 卡片内容:图标、名称、一句话简介、标签、会员角标(免费 / 会员 / 企业)。点击进入工具详情,再「打开工具」。
  • 页脚:关于、协议、隐私、帮助、备案占位。

轻舟不做参考站里的「站外搜索引擎切换」和资源下载导航。工具分两类,后台可切换:

类型 行为 登录
接入工具 平台自己的工具,或二开后部署的工具 打开时走统一登录,携带账号和会员权益
收录链接 仅介绍并跳转到外部网站 只统计点击,不共享登录态

盈利和权限只针对「接入工具」。收录链接用于内容完整度,不能冒充已打通账号。

4. 信息架构

4.1 前台页面

路径 页面 要点
/ 首页 搜索、分类、运营分区、工具卡片
/c/:slug 分类页 子分类、排序(推荐、最新、名称)、分页
/search 搜索页 名称、简介、标签;空结果给出热门工具
/t/:slug 工具详情 介绍、截图、使用说明、所需会员、额度说明、打开按钮、相关工具
/pricing 会员方案 方案对比、当前身份、开通/续费
/account 账号概览 身份、会员到期、最近使用的工具
/account/profile 资料 昵称、头像
/account/security 安全 绑定邮箱/手机、改密、登录方式
/account/sessions 登录设备 当前设备与各工具会话,可单独下线
/account/membership 会员与额度 方案、到期、各工具剩余额度
/account/orders 订单 订阅订单、增值服务订单、状态
/account/services 我的服务 云端实例、二开工单
/help /help/:slug 帮助中心 后台文章
/login /register /forgot 认证 也可做成首页上的对话框,地址仍可直达
/oauth/authorize 授权中转 工具跳回账号中心;已登录则直接签发授权码
/agreements/:type 协议 用户协议、隐私政策,后台可改

打开工具的路径固定为:卡片或详情 → 账号中心确认登录 → 带授权码跳回该工具。未登录先完成登录,登录后回到刚才要打开的工具。

4.2 后台页面

后台入口 /admin,与前台同一 Vue 工程、独立布局。未登录或非运营角色不可进入。

模块 功能
概览 新增用户、有效会员、今日登录、工具打开次数、待处理工单
内容分区 首页分区的标题、排序、展示数量、手动置顶工具、上下架
分类 多级分类、图标、排序、是否在侧栏显示
工具 接入工具与收录链接的全部字段,见第 6 节
标签 标签库,工具多选
文章与公告 帮助文章、首页公告、协议正文,草稿/发布
导航与页脚 菜单项、外链、排序
轮播与推荐位 图片、链接、生效时间
用户 查询、禁用、重置登录失败次数、代开/延长会员、查看绑定身份
会员方案 名称、价格、周期、权益项、排序、上下架
订单 查询、备注、线下开通标记、退款状态(支付渠道接入前可手工改状态)
工单与部署 二开需求、云端实例状态
应用接入 每个工具一个 OAuth 客户端:client_id、回调地址白名单、密钥重置
短信与邮件 模板、发送记录、失败原因。密钥只在环境变量,不在页面回显
系统设置 站点名、SEO、注册开关、验证码策略、会员到期宽限天数
审计 谁在何时改了工具、会员、用户状态

列表统一具备:关键词、状态筛选、排序、分页。表单校验失败时停在当前页并指出字段。

5. 账号、登录与会话

5.1 身份

一个用户一条主账号,可同时绑定:

  • 一个邮箱
  • 一个中国大陆手机号

至少绑定其中一项才能完成注册。两项都绑定后,任一方式都能登录进同一个用户。解绑时必须还留有另一项,避免账号丢失。

昵称默认用脱敏手机号或邮箱前缀,用户可改。头像首期用内置色块字标,上传放到二期。

5.2 两种登录

密码登录

  • 账号框接受邮箱或手机号。
  • 密码不明文落库,也不在接口日志里出现。
  • 浏览器提交前,用账号中心下发的 RSA 公钥做 RSA-OAEP 加密,服务端私钥解密后再校验。
  • 库存 Argon2id 哈希。
  • 全程 HTTPS。应用层加密用来满足「加密登录」,避免口令以明文形式进入应用日志和转发链路。

手机号 + 验证码登录

  • 已注册手机号可直接登录。
  • 未注册手机号:验证码通过后创建账号并登录(免密注册)。是否允许「验证码即注册」默认开启,可在后台关掉,关掉后只允许已注册号码登录。
  • 验证码 6 位,5 分钟内有效,用完即废。同一号码 60 秒内不可重发。同一号码、同一 IP 有每日上限。
  • 验证码只存哈希,后台发送记录展示掩码手机号,不展示验证码本身。

5.3 注册、找回、绑定

  • 邮箱注册:邮箱 + 邮箱验证码 + 密码。邮件通道未配置时,后台可暂时关闭邮箱注册,只留手机号。
  • 找回密码:已验证的邮箱或手机号收验证码,通过后设置新密码,并清掉该用户全部刷新令牌。
  • 修改密码:校验原密码(同样走公钥加密)。
  • 绑定新手机/新邮箱:验证码确认后写入;该手机或邮箱若属于别的账号,拒绝绑定并提示登录原账号。

5.4 安全策略

  • 同一账号连续密码失败 5 次,锁定 15 分钟,并要求图形验证码。图形验证码在失败 3 次后提前出现。
  • 验证码错误单独计数,不与密码计数混用。
  • 登录成功写登录日志:时间、IP、UA、方式(密码/短信)、结果。
  • 用户可在「登录设备」看到账号中心会话,以及仍有效的工具会话,支持单端下线或全部下线。
  • 禁用用户:立即无法刷新令牌,已发出的访问令牌靠短有效期和权益版本号失效,见 5.6。

短信服务商、邮件服务商做成驱动接口。首期默认预留阿里云短信、SMTP 邮件,密钥放 .env。供应商未定时,本地环境用固定调试验证码(仅 APP_DEBUG 且非生产)。

6. 统一登录:一次登录,多工具共用

这是平台和其他导航站的分界。工具域名可以不同,语言可以是 PHP、Node、Python、Go 或静态前端加任意后端。账号中心不要求工具与主站同域,也不靠把密码同步给工具。

6.1 角色划分

  • 账号中心(IdP):Laravel 应用。负责人、会话、会员、授权码、令牌、退出。
  • 门户:Vue3。负责人找工具、发起「打开」。
  • 工具(客户端):独立部署的业务系统。只信任账号中心签发的授权码和令牌。

协议采用 OAuth 2.0 授权码 + PKCE,身份声明对齐 OpenID Connect 的最小子集(iss、sub、aud、exp、nonce)。不自造一套「把 token 放进 URL 里跳转」的私有协议。任意语言用标准库即可接入,平台再为 PHP 与 Node 提供一份参考示例(开发阶段编写)。

6.2 打开工具的过程

用户点击「打开工具」
  → 门户把浏览器转到账号中心 /oauth/authorize
      client_id、redirect_uri、scope、state、nonce、code_challenge
  → 无轻舟会话:先完成第 5 节登录,登录后回到本次授权
  → 有会话:校验 client_id 与 redirect_uri 白名单
  → 签发一次性授权码(约 60 秒),重定向回工具
  → 工具服务端用授权码 + code_verifier + client_secret(机密客户端)
      向账号中心换 access_token、refresh_token、id_token
  → 工具建立自己的本地会话,之后页面不再带令牌

自有工具默认 免确认页(后台标记为内部应用)。第三方或尚未审核的客户端必须经用户点一次「同意」。

scope 首期只有:

  • openid:身份
  • profile:昵称、头像
  • membership:会员等级、到期时间、权益版本号、该工具可用的权益键和额度

工具拿不到密码,也拿不到其他工具的额度明细。手机号、邮箱默认不放进令牌;工具需要时走单独 scope,并在接入申请里写明理由,后台勾选后才签发。签发值仍可配置为掩码。

6.3 令牌与权限何时生效

令牌 建议寿命 存放
授权码 60 秒,一次有效 服务端
access_token 15 分钟 工具服务端会话,不下发到前端脚本
refresh_token 14 天,轮换 只存哈希;用过即废,旧令牌重用则整串作废
账号中心会话 Cookie 14 天,滑动 HttpOnly + Secure + SameSite=Lax,主机仅限账号中心域名

会员被升级、降级、禁用时,用户记录上的 entitlement_version 加一。access_token 内带上签发时的版本号。工具在关键操作前调用内省接口;版本不一致或用户已禁用,则拒绝并要求重新换票。15 分钟内的普通页面可以只信本地会话,避免每个请求都打账号中心。

额度扣减由工具自己记账,账号中心提供「本周期上限」和「重置时间」。跨工具的总账若要平台统一扣,使用后续的额度接口,首期不强制所有工具接入。

6.4 退出

  • 只退出当前工具:工具销毁本地会话,账号中心会话保留,其他工具不受影响。
  • 退出轻舟:账号中心销毁会话、作废全部刷新令牌,并按每个客户端登记的退出回调地址做后端通知。用户下次打开任一工具都要重新登录。
  • 设备页「下线」与退出轻舟同一套作废逻辑,可针对单条会话。

6.5 同父域时的补充

若某些工具部署在 tool.example.com,主站在 www.example.com,仍然走授权码,不改用共享 Cookie 传递登录态。这样独立域名的工具与子域名工具是同一条接入路径。账号中心会话 Cookie 只存在于账号中心主机,不设到父域给工具读取。

6.6 工具侧必须实现的行为

  1. 注册回调地址,只接受白名单上的 redirect_uri。
  2. 校验 state,防止跨站请求伪造。
  3. 用 PKCE 校验 code_verifier。
  4. 服务端换票,client_secret 不进浏览器。
  5. 纯前端、没有服务端的工具:使用公共客户端 + PKCE,access_token 只留在内存,并限制 scope 不含敏感字段。此类工具不能承接付费额度扣减。
  6. 展示会员不足时,跳回轻舟定价页,并带上 return_to 工具地址。登录与权限是两件事:登录始终成功,功能是否可用看权益。

7. 会员、订单与增值服务

7.1 方案

后台可配置,首期预置三档,价格上线前再填:

方案 默认权益方向
免费 打开免费工具;付费工具可看介绍,功能内提示升级
会员 方案中勾选的工具与月度额度;去平台内广告位
企业 会员全部能力 + 更高额度 + 工单优先。团队席位二期再做

权益项是键值,不把「能否使用」写死在代码分支里。例如:

  • tool:{slug}:access 是否可进入该工具的付费功能
  • quota:{slug}:monthly 月额度数字
  • support:priority 是否优先支持
  • deploy:instance 是否可申请独立实例

工具详情和定价页读取同一份配置。

7.2 订阅状态

未开通 → 有效 → 到期宽限 → 已过期
                  ↘ 续费成功回到有效
有效 → 后台停用 → 已停用
  • 有效:按权益放行。
  • 宽限:默认 3 天,后台可改。宽限内保持权益,界面提示续费。
  • 已过期:付费功能关闭,账号和免费功能保留,数据不删。
  • 已停用:运营手工关闭,立即失效。

同一用户同一时刻只有一个生效订阅。升级按剩余天数折算差价的规则放到支付阶段;首期运营可在后台直接改等级和到期时间,并写审计。

7.3 订单

订单类型:subscription(订阅)、addon(增值,如加额度)、service(二开/部署)。

状态:pending 待支付、paid 已支付、closed 已关闭、refunded 已退款。

首期没有支付渠道时,用户提交订单后状态为待支付;运营在后台确认收款并标为已支付,系统同时延长订阅或创建工单。支付渠道(微信支付或支付宝)作为可替换驱动,接入时只补「下单、回调验签、关单」,不改会员状态机。

7.4 云端部署与二开

云端实例字段:所属用户、工具、规格、访问地址、状态(待开通、运行中、已暂停、已释放)、到期时间、备注。首期由运营在后台改状态和回填地址,不自动调用云厂商 API。

二开工单字段:需求说明、联系方式、关联工具、报价、状态(待受理、已报价、进行中、待验收、已完成、已关闭)、交付说明。用户在「我的服务」查看进度,运营在后台流转。

这两项是服务目录,用来接住「开源二开 + 云端部署」的收入,首期不做自动交付。

8. 工具与动态内容的字段

工具由后台创建,前台不提供用户投稿。

字段 说明
名称、slug、图标、简介、详细介绍 介绍支持安全的富文本(白名单标签)
类型 接入工具 / 收录链接
分类、标签 多对多
打开地址 收录链接为外链;接入工具为该工具的启动地址
开发语言、仓库或备注 仅后台可见,便于识别二开项目
会员角标 免费 / 会员 / 企业,用于卡片展示
所需权益键 空表示登录即可用全部功能
OAuth 客户端 仅接入工具;未配置客户端时「打开」按钮不可用
排序、是否推荐、上架状态、上架时间 首页分区另行挑选

动态内容还包括:分类、标签、首页分区、轮播、公告、帮助文章、协议、导航、页脚、SEO 标题与描述。全部可排序、可下架。下架内容前台立即不可见,已打开的工具不因此被强制关闭。

搜索首期用 MySQL FULLTEXT(ngram 解析器,以支持中文)覆盖名称、简介、标签名。数据量上来后再换专门搜索引擎,接口保持「关键词进、工具列表出」。

9. 技术架构与约束

9.1 选型

层 选择
接口与账号中心 PHP 8.4、Laravel 11(兼容 MySQL 5.7;不使用仅 MySQL 8 才有的窗口函数和 CTE)
数据库 MySQL 5.7,字符集 utf8mb4,排序规则 utf8mb4_unicode_ci
缓存与会话 Redis。生产环境账号会话、验证码计数、令牌黑名单放 Redis;本地可退回数据库驱动
前台与后台 一个 Vue 3 + TypeScript + Vite 工程,Vue Router、Pinia
组件库 Element Plus。门户用其表单、分页、对话框、消息;卡片和首页布局用自有样式,避免整个站点长成默认后台皮肤
HTTP 前台通过 Laravel API 取数,Laravel 提供 /api 与 /oauth。页面路由由 Vue 承接

Laravel 11 同时支持 PHP 8.4 与 MySQL 5.7。业务 SQL 明确不依赖 MySQL 8 语法,避免以后迁库时才发现写死了版本特性。

9.2 目录

qztool/
  backend/     Laravel 11:API、账号中心、示例工具 demo-tool
  frontend/    Vue 3 门户
  admin/       Vue 3 后台
  README.md    本说明

本地启动(MySQL 5.7 库名 qztool,连接写在 backend/.env):

cd backend && php artisan serve --host=127.0.0.1 --port=8000
cd frontend && npm run dev
cd admin && npm run dev
cd backend/demo-tool && php -S 127.0.0.1:8090 index.php

门户 http://127.0.0.1:5173 ,后台 http://127.0.0.1:5174 。本地短信驱动是 debug,验证码为 123456。体验用户 13900139000 / User123456,超级管理员 13800138000 / Admin123456。示例工具的客户端密钥写在 backend/demo-tool/config.php,只用于本机演示。

工具仓库不放进本项目。每个工具独立部署,只按第 6 节接入。

9.3 接口风格

  • 门户与后台:JSON API,/api/v1/...,后台加 /api/v1/admin/...。
  • 认证:账号中心会话 Cookie(同站)签发后,SPA 使用 HttpOnly 会话,CSRF 沿用 Laravel 的 SPA 方案(/sanctum/csrf-cookie 一类流程,实现时按所选官方包落地)。
  • 工具换票:走 OAuth 端点,不复用后台管理员令牌。
  • 错误体统一:code、message、errors(字段级)。业务失败用 4xx,不把堆栈返回给浏览器。
  • 时间统一存 UTC,接口返回 ISO 8601,前端按浏览器时区显示。

9.4 关键数据表(逻辑模型)

实现时可以拆分或补索引,职责保持如下:

  • users:状态、昵称、权益版本、禁用原因
  • user_identities:类型(email/phone)、标识、是否已验证
  • password_resets / verification_codes:只存哈希、过期时间、场景(登录、注册、绑定、找回)
  • user_sessions:账号中心会话、设备摘要、过期时间
  • oauth_clients、oauth_auth_codes、oauth_access_tokens、oauth_refresh_tokens:标准授权码流程所需数据;刷新令牌存哈希
  • categories、tags、tools、tool_tag、tool_category
  • home_sections、home_section_tools、banners、navigations
  • articles、agreements
  • plans、plan_entitlements、subscriptions
  • orders、order_items
  • service_tickets、deployments
  • login_logs、audit_logs、message_logs

手机号若需满足更严的存储要求,可在 user_identities 对标识再做应用层加密,并另存用于登录查找的哈希。默认先明文存手机号(访问受权限控制),等你明确要做静态加密再加,避免首期无法按手机号查询。

10. 权限

能力 访客 用户 会员 运营 超级管理员
浏览上架内容 是 是 是 是 是
登录并打开免费工具 否 是 是 是 是
使用付费权益 否 否 按方案 可被代开 可被代开
改自己的资料与会话 否 是 是 是 是
后台内容与工具 否 否 否 是 是
改用户状态、代开会员、重置密钥 否 否 否 否 是

运营与超级管理员是后台角色,用独立权限表,不把「是会员」当成后台权限。超级管理员账号由部署时的初始化命令创建,不在注册页开放。

11. 非功能要求

  • 门户首页在常规宽带下可交互时间以 3 秒内为目标;工具列表接口分页,默认 24 条。
  • 验证码、登录、换票接口按 IP 与账号限流。
  • 管理操作写审计:操作者、对象、动作、前后差异摘要。
  • 富文本入库前过滤脚本与事件属性。
  • 外链卡片使用 rel="noopener noreferrer"。
  • 生产关闭调试、固定调试验证码和详细错误页。
  • 备份:MySQL 每日全量。上传文件若首期不用对象存储,则只允许后台上传图标和文章图片到 storage,并限制类型与大小(图片 2MB 内,png/jpg/webp/svg)。

12. 分期

一期(确认后立刻做)

  • Laravel API、Vue 门户与后台骨架、登录注册(密码加密提交 + 手机验证码)。
  • 分类、工具、标签、首页分区、文章、公告的动态配置。
  • 账号中心按第 6 节签发授权码;附一个最小示例工具(独立端口)验证「登录一次,两个站点识别为同一用户,并读到会员等级」。
  • 会员方案、订阅状态、后台代开通;订单可创建,支付标为线下确认。
  • 个人中心:资料、安全、会话、会员、订单。

二期

  • 微信支付或支付宝(以你指定的渠道为准)、续费与升级差价。
  • 邮件验证码全流程、头像上传。
  • 额度查询接口、工具侧扣减约定。
  • 云端实例与二开工单的前台进度。

三期

  • 团队席位。
  • 云厂商自动开通。
  • 更细的数据统计与搜索引擎替换。

13. 验收时怎么算做对

一期完成时,应能手工走通:

  1. 后台新建分类和两个接入工具,前台首页与分类页按排序出现,下架后消失。
  2. 用手机验证码注册,再用同一手机号密码登录,进入同一账号。
  3. 绑定邮箱后,邮箱+密码也能进入该账号。抓包可见密码字段为密文,数据库中密码为哈希。
  4. 未登录点击「打开工具」,登录后落到该工具,工具页显示同一用户编号和昵称。
  5. 再打开第二个工具,不再输入密码,仍是该用户。
  6. 后台把用户开通为会员,15 分钟内(或重新打开工具后)第二个工具能读到新等级。
  7. 在轻舟退出后,两个工具的刷新令牌失效,再次打开需要登录。
  8. 运营账号能改文章并在前台看到;普通用户访问 /admin 被拒绝。

14. 明确不做(除非你另提)

  • 用户自行提交导航、评论、社区、积分商城。
  • 把百度、Google 等搜索引擎嵌进首页。
  • 网盘、盗版资源、未授权软件下载类栏目。
  • 工具之间直接互通数据库。
  • 微信扫码等第三方登录。
  • 首期自动云主机开通、自动开票。

15. 请你确认的默认决定

下面按推荐方案写死。回复「按推荐开发」即按此开工;若要改,直接指出序号和新决定即可。

  1. 品牌与范围:前台品牌为「轻舟」。门户借鉴参考站的分类 + 搜索 + 卡片,产品主体是统一账号和可运营的工具服务。
  2. 工具形态:同时支持「接入工具」和「收录链接」。只有接入工具共享登录与会员。
  3. 登录:邮箱或手机号 + 密码(RSA-OAEP 后提交,Argon2id 存储);手机号 + 短信验证码。验证码登录默认可自动注册。
  4. 暂不接入:微信登录、邮箱验证码可先留接口,SMTP 未配置时关闭邮箱注册。
  5. 单点登录:OAuth 2.0 授权码 + PKCE。工具不同域名、不同语言都走这条协议。登录与「有没有会员」分开:没有权益也能登录,付费功能再拦截。
  6. 会员:免费 / 会员 / 企业三档,价格与权益后台配置。首期支付用「待支付 + 后台确认收款」。
  7. 云部署与二开:一期只做工单和实例记录,运营手工改状态。
  8. 工程:server(Laravel 11、PHP 8.4、MySQL 5.7)+ web(Vue 3、TypeScript、Element Plus)。SQL 保持 5.7 兼容。
  9. 短信:抽象成驱动,供应商与密钥你在开工时提供;未提供前仅本地调试码。
  10. 示例工具:一期用一个独立的小型示例站点证明两个工具共用同一账号和会员信息。真实业务工具名单你后续给出再接入。

确认后下一步是:建库表与接口契约,再实现一期页面和示例工具,并用第 13 节的路径做验收。

S
Description
No description provided
Readme
204 KiB
Languages
PHP 64.1%
Vue 19%
Blade 11.8%
TypeScript 3.5%
CSS 1.3%
Other 0.2%