编程导航交流话题讨论

交流

1.3k 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

用 uni-app + Vue3 做了一款照片交易小程序,AI 人脸识别帮你找回属于自己的照片

先说个场景:参加演唱会、马拉松、展会、婚礼、毕业典礼,现场摄影师拍了几千张照片,最后发个网盘或者朋友圈,让你自己去翻。想找到自己那张,全靠肉眼硬翻,翻几十页就放弃了。 我做的这个小程序,就是想把这件事变得简单一点:**摄影师上传照片、明码标价;用户上传一张自拍,AI 自动在照片库里匹配出所有带自己的照片;看中哪张买哪张,买完下载原图。** 项目叫「光影集市」,做完了也跑起来了,把过程中的一些东西分享出来,供同样在做小程序、或者有类似需求的朋友参考。 ## 项目是什么 一款基于 **uni-app(Vue 3)** 开发的照片交易小程序,目标平台是**微信小程序和 H5**。后端由 SaaS 服务驱动,不需要自己买服务器、不需要自己写接口,克隆项目后改两个配置项就能跑起来,属于典型的"开箱即用"型项目。 **技术参数一览:** | 项目 | 参数 | |------|------| | 前端框架 | uni-app + Vue 3 | | 目标平台 | 微信小程序 / H5 | | 后端服务 | SaaS 云端接口(apifm-uniapp ^26.9.15) | | 工具库 | dayjs(日期处理) | | 状态管理 | Vuex | | 开源协议 | MIT | | 当前版本 | v26.9.15 | ## 功能模块 - **首页**:Banner 轮播 + 双列瀑布流照片墙,支持下拉刷新和上拉加载更多,浏览体验接近主流内容类 App。 - **登录 / 注册**:用户名密码登录与注册,支持一键切换,含用户协议确认勾选。 - **照片详情**:大图预览(可点击查看原图)、价格展示,支持一键加购或立即购买。 - **人脸找照片**:核心功能。拍摄或上传自拍 → AI 提取人脸特征向量 → 在照片库中按相似度排序,精准匹配本人的照片。 - **购物车 / 结算**:批量选购、支持移除单张,账户余额一键确认支付。 - **购买记录**:已支付 / 待支付订单列表,待支付订单可直接跳转补款。 - **订单详情**:订单内照片以网格展示,点击预览,长按即可保存到相册。 - **个人中心**:头像昵称、账户余额展示,购买记录、购物车等快捷入口。 - **内容管理**:用户协议、隐私政策、关于我们等文案由 CMS 后台统一维护,改文案不用重新发版。 ## 几个客观参数,供参考 - 照片列表为双列瀑布流 + 分页加载,数据量大了也不会卡首页; - 人脸匹配基于人脸特征向量相似度排序,自拍清晰、正面、光线充足时匹配效果最佳; - 支付采用账户余额模式,余额由后端统一管理,接入第三方支付通道即可扩展; - 运行前只需要替换两个配置:后端子域名 / 商户 ID,以及微信小程序 AppID; - 内置测试账号,方便下载后直接体验完整流程。 ## 适合谁看 - **学小程序开发的同学**:这是一个完整的"商品浏览 + 购物车 + 支付 + 订单"闭环项目,页面结构清晰,适合当多页面实战模板学习; - **有照片分发需求的摄影师**:活动跟拍、婚礼、毕业照、证件照等场景,可以基于它改造成自己的"交照片"工具,客人自助选片、付费、下载; - **需要一套现成电商闭环代码的人**:购物车、订单、余额支付这些模块都是可以直接用的。 ## 怎么找到它 项目名称「**光影集市**」。感兴趣的朋友可以自行搜索(关键词:光影集市、uni-app 照片交易小程序),或者**私信我**交流——部署、改造、人脸识别测试、功能细节,都可以聊。 ---

任何人连上就能看卫星遥测?我们花一天补上了 WebSocket 鉴权与三层 RBAC

> **先想象一个画面**:你的卫星星座平台正在对外服务,数据接入链路通过 WebSocket 实时推送。这时,任何一个能访问到服务的人——不需要账号、不需要 token——只要连上 WebSocket 地址,就能安静地订阅走这些实时数据。而系统对此毫无察觉——因为大门本来就是开着的。 > > **这不是假设,这是我们平台此前的真实状态。** 上期《86 个 Lint 错误清零 + 空库一键迁移》把卫星平台 2.0 的地基修平(M0)。本期施工周记(二)进入 M1 上半场,直面上期盘点里最扎眼的两项缺陷: - **E4:WebSocket 无鉴权**——任何能连上总线的人,都能订阅平台的实时数据推送; - **E5:权限体系未闭环**——只要登录成功,人人都是"全能选手"。 我们用一天时间完成四连击:先用 Playwright 织一张 **10 条用例的 E2E 测试网**(端到端测试:像真实用户一样操作浏览器)兜住回归,再给 WebSocket 补上 **STOMP 协议层 JWT 鉴权**,然后把**用户管理从后端接口到前端按钮级 RBAC**(基于角色的权限控制:谁能看到什么、能点什么)一次闭环,最后顺带修复了一个"埋了很久"的角色鉴权 Bug。全程真实数据,文末附可直接抄作业的踩坑笔记——**建议先收藏,再慢慢看**。 ## 一、把"能用"升级成"可信" 上期排查出的 14 项工程缺陷中,有四项直接指向"安全与回归保障",本期逐项对账: | # | 上期盘点缺陷 | 本期对策 | 结果 | | -- | ------------------------------------- | ----------------------------------------------- | ------------------------------------ | | E4 | WebSocket 无鉴权(`/ws/**` 全放行) | STOMP CONNECT 帧校验 JWT | 4 类非法连接全部拒绝,单测 7/7 | | E5 | 前端路由仅登录态守卫,无角色权限 | 菜单 / 路由 / 按钮三层 RBAC + 后端注解收紧 | 权限全链路闭环,E2E 2 条专项通过 | | E2 | 后端零测试(历史欠账) | WS 拦截器 + 用户管理服务单测 | 后端 `mvn test` **14/14 全绿** | | — | 安全改造无自动化回归保障 | Playwright E2E 测试网 | **10 条用例**(7 条 mock + 3 条真后端)| 本期只守一条原则:**先设计,再改造**。鉴权改造是"动身份、动路由"的高危操作,先把改动纳入自动化回归网,再动核心链路——这是改完还敢睡觉的底气。 ![image.png](https://pic.code-nav.cn/post_picture/1944355748262088705/0uZvOCGyCAaHyYGs.webp) ## 二、先设计:Playwright E2E 测试网(10 条用例) ### 2.1 7 条 mock 用例:不依赖后端的"随时全绿" 前端 E2E 最大的落地障碍是"环境依赖":CI 上未必有后端和数据库。我们的解法是在**浏览器网络层 mock 全部 `/api` 请求**(`e2e/fixtures.ts` 提供兜底 mock + 具体接口 mock + 登录态预置),`playwright.config.ts` 里的 `webServer` 自动拉起 vite dev(前端开发服务器),端口可用 `E2E_PORT` 覆盖避让冲突。 覆盖矩阵——5 个页面 7 条用例: | 用例 | 断言要点 | | --------------------------- | ---------------------------------------------- | | 登录成功 | 跳转仪表盘 + token 写入 localStorage | | 登录失败 | 错误提示可见 + 停留登录页 | | 仪表盘加载 | 4 张统计卡片渲染出 mock 数值 | | 卫星列表 + 关键字筛选 | 行数收敛 + 命中目标卫星 | | 遥测页加载 | 5 张实时指标卡片(%、W、dB 单位逐一校验) | | 用户管理(ADMIN 视角) | 菜单可见 → 列表渲染 → 写操作按钮可见 | | 用户管理(OPERATOR 视角) | 菜单不可见 → 直连 URL 被重定向回仪表盘 | 结论:**CI 无需后端、无需数据库,`npm run test:e2e` 即可全绿**。接真实后端时去掉 mock 即可复用。 ### 2.2 3 条真后端联调:零 mock,期望值实时取自 API mock 能保证"UI 逻辑不坏",但保证不了"前后端契约不漂"。我们补了一套 `real-backend.spec.ts`(默认跳过,`E2E_REAL_BACKEND=1` 显式开启,不拖累 CI):**零 mock,请求经 vite 代理直达本机 8080 后端,所有期望值实时取自 API,不写死一条数据**。 联调当天就抓到一个"反直觉"的契约事实:**登录失败不是 HTTP 401,而是 HTTP 200 + 响应体内 `code: 401`**——因为业务异常走统一响应包装,HTTP 状态码仍是 200,前端真正的分支判断在业务码上。 处理方式:mock 用例保留 HTTP 401 形态,**反向覆盖 axios 异常分支**(HTTP 层报错路径);真后端用例断言业务码分支。两套断言、两条代码路径,全部覆盖。 ### 2.3 最值钱的坑:一个通配符让整个应用白屏 这是本批次最"贵"的一个坑,值得单独拿出来讲: > **Playwright 的 route 匹配不要用 glob 通配 `/api/` 前缀**。用 glob 拦截 `**/api/**` 时,会连带命中 vite dev 服务器的**源码模块请求** `/src/api/*.ts`——你的拦截器"好心"把这些源码请求也一并拦截、返回了 JSON,浏览器对模块做 MIME 类型校验对不上号,**整个应用直接白屏**。 正解:用 URL 谓词精确锚定根路径——`page.route((url) => url.pathname.startsWith('/api/'), ...)`。另有一条路由规则:**Playwright 中后注册的 route 先匹配**,所以兜底 mock 必须先注册、具体接口 mock 后注册,顺序反了就全部被兜底吞掉。 ### 2.4 结果 ```text 默认(CI 路径):7 passed + 3 skipped 联调模式: 3 passed(零 mock 直连真实后端) npm run lint → 0 error vue-tsc → 0 error ``` ![image.png](https://pic.code-nav.cn/post_picture/1944355748262088705/l2CskB3adSfkJhus.webp) ## 三、再改造(上):WebSocket 鉴权——让数据总线"查证入场" ### 3.1 问题现场 `SecurityConfig` 里 `/ws/**` 对所有请求放行:REST 接口有 JWT 过滤器把守,而 WebSocket 是一条**不查证的后门**——任何人拿到 SockJS 地址就能建立连接、订阅数据接入的实时推送。对卫星平台这类系统,"谁在听遥测"和"遥测本身"一样重要。 ### 3.2 为什么鉴权不能做在 HTTP 握手层? 先回答一个高频疑问:为什么不直接在 WebSocket 握手上校验?因为**浏览器原生 WebSocket / SockJS 握手无法携带自定义 `Authorization` 头**——这是浏览器标准的硬限制,不是工程偷懒。 所以鉴权必须**下沉到 STOMP 协议层**(STOMP 是运行在 WebSocket 之上的消息协议,可以理解为"信封格式"):拦截会话建立帧(CONNECT / STOMP),读取信封上的原生头。核心实现只有三个动作: ```java // WsAuthChannelInterceptor#preSend(节选) StompCommand command = accessor.getCommand(); if (command == StompCommand.CONNECT || command == StompCommand.STOMP) { String header = accessor.getFirstNativeHeader("Authorization"); if (!StringUtils.hasText(header) || !header.startsWith("Bearer ")) { throw new MessagingException("Unauthorized: missing bearer token"); // 连接被拒绝 } String token = header.substring("Bearer ".length()); Claims claims = jwtUtil.getClaimsFromToken(token); // 复用 REST 层同一把钥匙 // 注入 principal:ROLE_USER(兼容存量)+ ROLE_<role>(支撑细粒度校验) accessor.setUser(new UsernamePasswordAuthenticationToken(username, null, authorities)); } ``` 三个设计要点: 1. **非 CONNECT 帧直接透传**——鉴权只做在"入场"这一刻,订阅/心跳帧零开销; 2. **失败即抛 `MessagingException`**——连接被拒绝并向客户端发送 ERROR 帧,不留"半开"状态; 3. **给会话身份(principal)授予双权限**:`ROLE_USER` + `ROLE_<role>`,与 REST 层的权限模型完全对齐。 前端只改一行——STOMP 客户端连接头携带 token(重连时由 stompjs 自动附带): ```ts this.client = new Client({ webSocketFactory: () => new SockJS(url), connectHeaders: { Authorization: `Bearer ${token}` }, // 新增 reconnectDelay: 3000, }) ``` ### 3.3 单测 7 条:把"拒绝"也当成功能来验收 | # | 用例 | 断言 | | - | ------------------------------------------- | ------------------------ | | 1 | 有效 token 携带角色 | principal 含双角色 | | 2 | 无 role claim 的有效 token | 仅 ROLE_USER | | 3 | 缺 Authorization 头 | 拒绝 | | 4 | 非 Bearer 前缀(如 `Token xxx`) | 拒绝 | | 5 | 畸形 token(`Bearer not-a-jwt`) | 拒绝 | | 6 | 过期 token | 拒绝 | | 7 | 非 CONNECT 帧(如 SUBSCRIBE) | 原样透传、零开销 | > 工程视角:**"拒绝"必须是可测试的功能,而不是靠"应该不会出事"的侥幸**。4 类非法连接全部有单测背书,才算真正关上了这扇门。 ## 四、再改造(下):用户管理全栈 + 三层 RBAC ### 4.1 后端:5 个接口 + 两条安全红线 新增 `UserController`,5 个接口覆盖用户全生命周期: | 接口 | 能力 | 权限 | | ------------------------------- | ----------------------------- | -------- | | `GET /users` | 分页 + 关键字/角色/状态筛选 | 登录即可 | | `POST /users` | 新建用户 | ADMIN | | `PUT /users/{id}` | 编辑资料 | ADMIN | | `PUT /users/{id}/password` | 重置密码(BCrypt 重编码) | ADMIN | | `PUT /users/{id}/status` | 启用 / 停用 | ADMIN | 两条安全红线: 1. **写操作全部挂 `@PreAuthorize("hasRole('ADMIN')")`**——非管理员调用直接 403(统一异常映射); 2. **密码从不出现在响应里**——BCrypt 编码入库;列表、创建、更新、启停用的返回对象**统一置空 password 字段**。防泄漏是"默认动作",不是"记得才做"。 ### 4.2 意外收获:一个"埋了很久"的鉴权 Bug 为了让 `hasRole('ADMIN')` 真正生效,排查中发现了一个隐蔽的历史 Bug: > **JWT 的负载(claims)里一直带着 `role`,但 `JwtAuthenticationFilter` 只授予了 `ROLE_USER`。** > 也就是说:系统此前只认得"你登录了",不认得"你是谁"。所有细粒度权限注解写了也白写——**不是"没权限被放行",而是"有权限也进不去"**。 这是一种典型的 **fail-secure 型 Bug**:它不给攻击者开口子,最隐蔽、最容易被忽略;但一旦你想加细粒度权限,它会立刻"爆炸"——明明是该放行的管理员,却全场 403。 修复:单次解析 claims,一次授予 `ROLE_USER + ROLE_<role>` 双权限——**既兼容存量接口的 `hasRole('USER')`,又让 `hasRole('ADMIN')` 真正生效**。WebSocket 拦截器采用同一套授权模型,REST 与 WS 两条链路"一把尺子"。 ### 4.3 前端:一张管理页 + 三层防线 新增 `views/system/UserList.vue`(500+ 行):关键字/角色/状态三重筛选 + 分页表格 + 新建/编辑对话框(角色、部门、联系方式)+ 重置密码对话框(双输入一致性校验)+ 启停用开关(**先调接口、成功才翻转**,失败保持原状态,不留"界面说停了、后端还开着"的假象)。 ![image.png](https://pic.code-nav.cn/post_picture/1944355748262088705/MA5tqfWHhcZeEp72.webp) ![image.png](https://pic.code-nav.cn/post_picture/1944355748262088705/wxWBh7VbZtaqmKO5.webp) RBAC 做了三层: ```mermaid flowchart TB A["登录 → JWT 携带 role"] --> B["第 1 层 · 菜单:MainLayout 按角色过滤渲染<br/>OPERATOR 根本看不到『用户管理』入口"] B --> C["第 2 层 · 路由:meta.roles + 守卫拦截<br/>直连 /system/users 会被弹回仪表盘"] C --> D["第 3 层 · 元素:v-permission 指令<br/>角色不匹配的写按钮直接从 DOM 移除"] D --> E["边界 · 后端:@PreAuthorize('hasRole(ADMIN)')<br/>绕过前端直接调 API?照样 403"] ``` 配套改造:`stores/user.ts` 新增 `hasRole`(兼容单值/数组;角色经 localStorage 持久化,**刷新后权限保持**);路由 `meta.roles` 类型扩展 + 守卫;i18n 约 45 个文案键中英双语同步。 ### 4.4 一句话记住职责边界 **前端三层管"体验",后端注解管"边界"。** 菜单过滤、路由拦截、按钮隐藏都只是提高体验、减少误操作;即使有人绕过前端直接调 API,`@PreAuthorize` 依然兜底。E2E 用两个角色视角把这条链路钉死:ADMIN 可见可用,OPERATOR 不可见、直连被弹回。 ![image.png](https://pic.code-nav.cn/post_picture/1944355748262088705/SAMgWXw4vuFRyUN9.webp) ## 五、附赠:Flyway"既有库收编"——一次诚实的决策修订 上期我们把 `baseline-on-migrate=false` 称为"关键决策:不对非空库假装已迁移"。本期就撞上了它的现实代价: 本地历史库(结构由 V1 脚本手工重放建成、等价基线终态)**没有 `flyway_schema_history` 表**,启动直接报错: ```text Found non-empty schema(s) "public" but no schema history table ``` 修订方案(一次深思熟虑的"打脸"): ```yaml spring: flyway: baseline-on-migrate: true # 从 false 改为 true baseline-version: 1 ``` 两种场景被分开处理: | 场景 | 行为 | | ---------- | ----------------------------------------------------------- | | 空库 | 照常执行 V1(原有路径不变) | | 既有库 | 仅建历史表并把现有结构**登记**为 V1 基线,**不重放 V1**,数据零改动 | 这不是摇摆,而是把"默认拒绝"演进为"**核实后可通行**":M0 的 `false` 是防止未经核对的库被静默收编;现在改为 `true`,是因为明确知道该库就是 V1 的重放产物、结构可核对。**工程决策要跟着事实走,而不是跟着面子走**。 ![flyway验证.png](https://pic.code-nav.cn/post_picture/1944355748262088705/4ozUYwYdbNneuw2A.webp) ## 六、验收:数据说话 | 验收项 | 命令 / 方法 | 结果 | | ----------------------- | ------------------------------------ | --------------------------------- | | 后端单元测试 | `mvn test` | **14/14 全绿**(WS 7 + 用户 7) | | WS 未授权连接 | 4 类拒绝场景单测 | **全部拒绝** | | E2E(默认 mock 路径) | `npm run test:e2e` | **7 passed + 3 skipped** | | E2E(真实后端联调) | `E2E_REAL_BACKEND=1` | **3 passed**(零 mock 直连) | | RBAC 双视角 | E2E(ADMIN / OPERATOR) | 菜单、路由、按钮三层验证通过 | | 前端质量门禁 | `npm run lint` / `vue-tsc --noEmit` | **0 error** | ## 七、踩坑笔记(7 条,可直接抄作业,建议收藏) 1. **Playwright route 用 URL 谓词,别用 glob**。glob 通配 `/api/` 会误伤 vite 源码模块 `/src/api/*.ts`,把源码请求当接口返回 JSON → 应用白屏。 2. **route 注册顺序即优先级**:后注册先匹配——兜底 mock 先注册、具体接口 mock 后注册。 3. **统一响应包装下,"登录失败"是 HTTP 200 + `code:401`**。mock 断言别照抄直觉;建议 mock 覆盖异常分支、联调覆盖业务码分支,两条路径都测。 4. **WS 鉴权必须下沉到 STOMP 协议层**——浏览器 WebSocket/SockJS 握手无法携带自定义头,这是标准硬限制。 5. **鉴权链路的"隐性断点"**:token 里带了 role ≠ 过滤器授予了 role。凡是"角色没生效",先查授权对象(principal)里的 authorities,再查注解。 6. **前端权限只做体验,边界必须在后端注解**——纵深防御的正确姿势,而不是"前端藏了按钮就等于没有权限"。 7. **`baseline-on-migrate` 的两种语义要分清**:`false` = 拒绝未知非空库;`true + baseline-version` = 核实后收编。改动前想清楚自己的库属于哪种。 ## 八、下期预告:M1 收官之战 - **遥测导出**:流式 CSV / JSON 输出防 OOM(内存溢出),导出文件与页面数据抽样一致; - **审计日志**:`@AuditLog` 注解 + AOP 切面,写操作自动留痕(谁、何时、对什么、结果如何); - **M1 DoD(完成定义)验证**:全量回归 + 覆盖率门禁 + 权限与审计逐项核对; - 再往后是 M2 业务深化:遥测分区、告警引擎、SGP4 轨道预报…… ## 九、结语 上期最值得截图的是三行绿色输出;本期最值得截图的是两个画面: 一个是 **OPERATOR 视角的侧边栏——找不到"用户管理",直连 URL 也会被礼貌地弹回仪表盘**;另一个是 **未授权 WebSocket 连接被拦截器拒之门外**。安全最好用的样子,就是"该来的畅通无阻,不该来的连门都摸不到"。 从"功能齐全"到"工程可靠",再到"安全可信",跨越的从来不是代码量,而是把每一条安全约束变成**默认动作**的纪律:拒绝要可测试、密码永不出响应、权限有三层、每一次改动都有回归网。 施工还在继续,下期 M1 收官见。 > 📌 觉得这篇实战记录有价值?**点赞 + 在看 + 转发 + 收藏**,让更多航天与软件工程师看到! > 💬 留言聊聊:你们的 WebSocket 鉴权做在哪一层?有没有被"JWT 里有角色、注解却不生效"坑过? --- ***本文关键词:卫星平台 2.0 | WebSocket 鉴权 | STOMP | JWT | RBAC | 按钮级权限 | Playwright E2E | Spring Boot | Vue 3 | 工程化实战***

2026年待办清单软件推荐

在信息爆炸的工作节奏中,待办清单软件早已不是简单的“备忘录”,而是个人与团队的**第二大脑**。然而,面对市面上琳琅满目的选择,我们往往陷入两个极端:要么被SaaS订阅制“割韭菜”,要么担心任务数据被云端厂商“偷窥”。 **如何选择一款既高效又尊重隐私的待办工具?** 我们深度体验了市面上主流的十余款产品,结合**数据隐私、跨平台能力、功能深度与性价比**四个维度,为你筛选出以下5款值得关注的软件。其中,**PriTime** 凭借其独特的“私有化部署+全原生客户端”模式,成为本次推荐中最具颠覆性的选择。 --- ### 1. PriTime:把数据锁进保险箱的效率神器 **关键词:私有化部署、开源免费、多端同步、买断制** 在SaaS产品大行其道的今天,PriTime 像是一个“异类”。它主打**数据自主、隐私归你**,通过**后端API与Web端开源免费**的策略,让用户彻底摆脱了对云端服务的依赖。 **核心亮点:** - **极致的隐私保护:** 支持一键部署到自己的服务器、内网或家庭实验室(Docker/Kamal均可),任务数据完全掌握在自己手中,从根源杜绝数据泄露风险。代码以 **PolyForm Noncommercial 1.0.0** 协议开源,透明可审计。 - **全原生多端覆盖:** 不同于套壳的Hybrid应用,PriTime 提供**MacOS、IOS、Android、Windows、Web**五大平台的原生客户端。通过统一后端API共享数据,实现真正的“一套数据,三端生态”。 - **功能全面且克制:** 除了基础的清单、标签、优先级,还内置了**四象限(艾森豪威尔矩阵)、日历、课程表、番茄专注钟、习惯打卡、纪念日倒数**等高频功能。没有冗余的社交模块,专注于“把事情做完”。 - **付费模式良心:** **Web端与后端API永久免费**。桌面与移动客户端采用**买断制**(Windows/Apple系列限时¥99,全平台买断仅需¥159),一次购买,终身免费升级,无任何订阅陷阱。 **适用人群:** 对数据主权有极高要求的**程序员、设计师、律师、自由职业者**,以及希望摆脱订阅制负担的个人用户。 --- ### 2. Todoist:老牌跨平台标杆 **关键词:自然语言识别、协作、跨平台** 作为老牌劲旅,Todoist 依然是很多人心中的“白月光”。它的**自然语言输入**体验极佳,输入“明天下午3点交报告”即可自动识别时间。 **亮点:** 强大的**项目分层与协作功能**,适合团队任务管理。支持多达20+平台。 **痛点:** 高级功能需要订阅(约¥200+/年),且数据存储在官方云端,对于隐私敏感用户而言略有顾虑。 --- ### 3. Microsoft To Do:微软生态的轻量之选 **关键词:微软生态、与Outlook联动、简洁** 如果你深度使用Windows和Office 365,Microsoft To Do 是最高效的默认选项。它与Outlook邮件、日历深度集成,**“我的一天”** 视图能帮你快速聚焦当日重点。 **亮点:** 完全免费,界面清爽,同步稳定。 **痛点:** 功能相对基础,缺乏四象限、习惯打卡等进阶视图,自定义标签能力较弱。 --- --- ### 4. Notion:All-in-One 工作区 **关键词:数据库、笔记、Wiki、自定义** Notion 严格意义上不只是一款待办软件,而是一个**模块化的工作区**。你可以用Database功能搭建出极其复杂的任务看板、内容日历甚至CRM系统。 **亮点:** 极高的自定义自由度,适合构建个人知识库与项目管理中枢。 **痛点:** 学习曲线陡峭,网络加载依赖境外服务器(速度不稳定),且作为笔记软件,其**任务提醒功能较弱**,不适合作为纯粹的“行动派”工具。 --- ### 总结与推荐:谁才是2026年的效率首选? | 软件 | 核心优势 | 隐私保护 | 付费模式 | 推荐指数 | | :--- | :--- | :--- | :--- | :--- | | **PriTime** | **私有化部署、原生多端、买断制** | **★★★★★ (数据自主)** | **Web免费/客户端买断** | **9.8** | | Todoist | 自然语言、协作成熟 | ★★★☆☆ | 订阅制 | 8.5 | | Microsoft To Do | 微软生态集成 | ★★★☆☆ | 免费 | 8.0 | | Notion | 高度自定义、数据库 | ★★★☆☆ | 订阅制 | 8.2 | **编辑点评:** 如果你厌倦了每年动辄几百元的订阅费,更不希望自己的工作计划被厂商用于数据分析,那么 **PriTime** 无疑是2026年最值得尝试的选择。它通过**开源+自部署**的方式,将“数据主权”真正还给了用户。 虽然它目前对普通用户有一定上手门槛(需要简单的部署知识),但官方提供的 **Docker/Kamal 一键部署**脚本已将复杂度降至最低。**30秒跑起来,数据完全自主**,这种“踏实感”是任何云端SaaS都无法给予的。 **行动建议:** 如果你追求极致的隐私与长期性价比,不妨先去 **PriTime官网** 体验一下免费的Web版,感受一下它纯粹、无广告的流畅体验。 --- *免责声明:本文推荐基于产品公开信息与用户体验,付费政策请以各产品官网最新公告为准。*

86 个 Lint 错误清零 + 空库一键迁移:卫星平台 2.0 基线修复实战

注:86 个 Lint 错误清零 + 空库一键迁移:卫星平台 2.0 基线修复实战(第一周全记录) > 上期发布了《卫星星座管理平台 2.0:14 项缺陷复盘 + 工程级升级路线图》。本期进入"施工期",带来 M0 基线修复第一周的完整落地记录:数据库基线重建、Flyway 版本化迁移、ESLint 质量门禁落地、密钥全量外置、DoD 运行时验收。每个环节都附真实日志与量化数据,供正在做工程化改造的团队直接参考。 ## 一、M0 目标:一周修平"可构建、可运行、可审计"底座 回顾上期盘点的 14 项工程缺陷,M0 的靶心是其中 4 项 P0 缺陷加 README 一致性修正: | # | 缺陷 | 问题 | M0 对策 | | -- | --------------- | ------------------------------------------- | ------------------------------------ | | E1 | `init.sql` 缺失 | 数据库无法脚本化重建,Docker 初始化挂载失败 | 重建 V1 基线脚本 | | E3 | lint 配置缺失 | `npm run lint` 直接报错,无代码质量门禁 | ESLint 9 flat config 落地 + 存量清零 | | E6 | JWT 密钥硬编码 | 密钥泄露即全线沦陷 | 全部环境变量化,仓库零明文 | | E8 | 无迁移工具 | 表结构变更无法版本化演进 | Flyway 10 集成(M1-1 提前项) | 第一周任务卡与交付物: | 日期 | 任务 | 交付物 | | ---- | ------------------------------ | -------------------------------------------------------- | | D1 | M0-1 数据库基线重建 | `V1__baseline.sql`(542 行:10 表 + 23 索引 + 幂等种子) | | D2 | M1-1 Flyway 集成 + 验证 | pom / application.yml / compose 三处修改 | | D3 | M0-2 ESLint 9 flat config 落地 | `eslint.config.js` + 存量告警清零 | | D4 | M0-3/4 密钥外置 + README 修正 | 配置外置 + 文档与实际对齐 | | D5 | DoD 验收 | 构建/lint/密钥扫描/运行时演练全绿 | 目标是让平台完成从"功能演示级"到"工程级"的第一步跨越。 ![gnjg.png](https://pic.code-nav.cn/post_picture/1944355748262088705/BEgEnK5IYFvtks3q.webp) ## 二、D1-D2:数据库工程化——基线重建 + Flyway 落地 ### 2.1 问题现场 平台 10 张业务表长期"靠既存库活着":仓库里没有建表脚本,docker-compose 挂载的 `init.sql` 根本不存在,新环境无法从零复现。更棘手的是已经出现"文档与真实库不一致"的征兆——README 承诺的 operator 账号密码,在真实库里登录失败。 ### 2.2 V1__baseline.sql:以现状库为唯一事实源 重建策略不是"照着实体类理想化设计",而是三步对齐: 1. `pg_dump -s` 导出真实库结构; 2. 逐表比对 10 个实体类(字段名、类型、JSONB 列、索引、外键); 3. 差异清单显式记录、逐项决策。 最终产出 542 行脚本:**10 张表 + 23 个索引 + 全部表/列注释 + 幂等种子数据**。 关键设计一:**全脚本幂等**。它既是 Flyway 的 V1 迁移,也能手动 `psql -f` 重放: ```sql CREATE TABLE IF NOT EXISTS sys_user ( ... ); INSERT INTO sys_user (username, password, real_name, email, role, department, status) VALUES ('admin', '$2a$10$...', 'System Admin', 'admin@leo-platform.com', 'ADMIN', 'Mission Control', 1), ('operator', '$2a$10$...', 'Satellite Operator', 'operator@leo-platform.com', 'OPERATOR', 'Operations', 1) ON CONFLICT (username) DO NOTHING; ``` 关键设计二:**差异清单显式记录**。与现状库比对暴露了三个需要决策的差异,全部记录在脚本头部注释,而不是"悄悄处理": - **现状库无外键约束**(仅主键/唯一键)→ 基线保持"逻辑外键"、不新增硬 FK,避免改变既有删除行为(如删除数据源不级联删除日志),如需强一致约束留待后续版本迁移追加; - **operator 种子密码 hash 失效** → 经 BCrypt 实测不匹配,重新生成并验证后替换,让 README 承诺的登录成立(详见第六章踩坑笔记); - **`telemetry_data."timestamp"` 为关键字列** → 保持引号写法,与现状库一致。 > 工程视角:基线脚本的价值不在"建表语法",而在**把隐式的库结构变成显式的、可评审的、可重放的事实**。 ![v1基线.png](https://pic.code-nav.cn/post_picture/1944355748262088705/puK5TA4PK9Y9N581.webp) ### 2.3 Flyway 集成:三处改动,零侵入 | 位置 | 改动 | 说明 | | -------------------- | ------------------------------------------------------------------------------- | ---------------------------------- | | `pom.xml` | +`flyway-core`、`flyway-database-postgresql` | Spring Boot 3.3.5 管理版本 10.10.0 | | `application.yml` | `enabled=true`、`locations=classpath:db/migration`、`baseline-on-migrate=false` | 约束迁移来源、禁止"假装已迁移" | | `docker-compose.yml` | 移除对不存在`init.sql` 的挂载 | 建库完全交给应用启动时的迁移 | `baseline-on-migrate=false` 是一个关键决策:**不对非空库"假装已迁移"**,任何环境都必须从干净的 V1 起步,杜绝"脚本与库两张皮"的历史遗留。 ### 2.4 空库实测:迁移 + 幂等双验证 在 Docker 环境就绪之前,先用本机 PostgreSQL 17 建临时库做了完整演练,真实日志如下: ```text # 第一次启动(空库) Database: jdbc:postgresql://localhost:5432/leo_satellite_verify (PostgreSQL 17.5) Schema history table "public"."flyway_schema_history" does not exist yet Creating Schema History table "public"."flyway_schema_history" ... Successfully applied 1 migration to schema "public", now at version v1 (execution time 00:00.169s) Started LeoSatelliteApplication in 6.994 seconds # 第二次启动(已迁移库,幂等复验) Schema "public" is up to date. No migration necessary. ``` 库内核对结论:`flyway_schema_history` 记录 V1 成功;10 张业务表 + 历史表全部就位;种子账号 admin / operator 可正常登录;验证后临时库与进程已清理干净。 ![flyway验证.png](https://pic.code-nav.cn/post_picture/1944355748262088705/j6QXTE1G7CaxRR8H.webp) ## 三、D3:前端质量门禁——86 个错误清零 ### 3.1 存量盘点 `eslint.config.js`(ESLint 9 flat config,继承 `@vue/eslint-config-typescript` + `eslint-plugin-vue` 推荐集)落地后,全量扫描暴露了平台的历史欠账:**86 errors + 1240 warnings**。 | 类别 | 典型问题 | 说明 | | ----------------- | ------------------------------ | ---------------------- | | `no-explicit-any` | 请求层双泛型、类型定义裸用 any | 占比最高,集中在类型层 | | `no-unused-vars` | 未使用的导入与变量 | 多次迭代的沉积 | | 其他 | 隐式 any、空 catch 参数等 | 零散分布 | 修复原则先立规矩:**不关闭任何争议规则、不使用一处 `eslint-disable`**——门禁的意义在于真实,以"禁规则"掩盖问题等于自欺。 ### 3.2 两个典型修复范式 **范式一:axios 泛型误用 → 类型化门面。** 原来的调用长这样: ```ts // 旧:第二个泛型被误当作"返回类型",与拦截器解包后的实际负载脱节 const res = await request.get<any, R<PageResult<Satellite>>>(url, { params }) ``` 问题根源:axios 的 `get<T, R>` 中 `R` 本应是"响应体类型",而项目的响应拦截器已经解包出 `data` 负载——**类型系统与实际运行时错位**,调用方只能看到一堆 `any`。 修复方案:封装类型化门面 `ApiClient`,让泛型直接表达"解包后的负载类型": ```ts export interface ApiClient { get<T>(url: string, config?: AxiosRequestConfig): Promise<T> post<T>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T> // ... } const request: ApiClient = { get: <T>(url: string, config?: AxiosRequestConfig) => service.get<T, T>(url, config), // ... } ``` 一次改造,**56 处 `any` 全部消除**,调用方还获得了完整的类型推断。 **范式二:v-model 联合类型断言。** 动态表单场景中,`v-model` 绑定到 `Record<string, string | number | boolean>` 的字段时,组件要求的窄类型无法自动收窄。解法不是 `as any`,而是按字段类型分支断言: ```html <el-input v-if="f.type === 'string'" v-model="cfg[f.key] as string" /> <el-input-number v-else-if="f.type === 'number'" v-model="cfg[f.key] as number" /> <el-switch v-else v-model="cfg[f.key] as boolean" /> ``` Vue 3 编译器原生支持 v-model 中的 TS 断言语法(内部先剥离 TS 节点再生成赋值),类型检查零损耗。 ### 3.3 结果 ```text npm run lint → 0 error 0 warning vue-tsc --noEmit → 0 error ``` ![lint全绿.png](https://pic.code-nav.cn/post_picture/1944355748262088705/oHAyZtUBIJqYHWuA.webp) ## 四、D4:密钥外置——仓库零明文 ### 4.1 三层配置体系 敏感配置(JWT 密钥、数据库/Redis 密码)从配置文件中彻底移除,改为三层体系,一份代码同时满足"本地开箱即用"与"生产强制注入": ```mermaid flowchart TB CODE["application.yml(占位符声明)<br/>${DB_PASSWORD} · ${JWT_SECRET} · ${REDIS_PASSWORD:}"] CODE --> DEV["本地开发<br/>application-local.yml 兜底<br/>零配置启动"] CODE --> PROD["容器 / 生产<br/>docker-compose + .env 注入<br/>缺参即启动失败(Fail-Fast)"] ``` | 层 | 文件 | 职责 | | ---------- | ------------------------------------- | ------------------------------------------------------ | | 声明层 | `application.yml` | 敏感项全部占位符化,仓库不出现任何真实值 | | 开发兜底层 | `application-local.yml` | 本地开箱即用的 dev-only 默认值,明确标注"生产必须替换" | | 容器注入层 | `docker-compose.yml` + `.env.example` | `${VAR:-开发默认}` 注入 + "生产必改"注释模板 | 两个值得强调的设计细节: 1. **`spring.datasource.password: ${DB_PASSWORD}` 不带默认值**——强制注入,漏配即启动失败。Fail-Fast 远优于静默跑在一个弱密码上;而 Redis 密码可空,用 `${REDIS_PASSWORD:}` 表达"允许为空"的语义。 2. **环境变量优先级天然高于 profile 文件**(Spring 的 relaxed binding)——本地开发不设任何环境变量也能跑,生产通过 compose 注入强随机值后自动覆盖兜底,一套代码两种形态。 ### 4.2 扫描验证 修改完成后做多模式全仓扫描:原 JWT 密钥串 **0 残留**、yml 中无明文密码赋值、无 PEM 私钥、Java 代码无硬编码。唯一保留的 `admin/admin123` 是 README 公开的演示账号(登录页有提示),不属于敏感泄露。 ![密钥扫描.png](https://pic.code-nav.cn/post_picture/1944355748262088705/BKzS9X6iat8XWw7z.webp) ## 五、D5:DoD 验收——数字说话 | 验收项 | 命令 / 方法 | 结果 | | ------------ | ---------------------- | ----------------------------------------------------------------- | | 后端构建 | `mvn clean package` | **BUILD SUCCESS**(14.5s,55.8MB 可执行 jar) | | 前端 lint | `npm run lint` | **0 error 0 warning** | | 前端类型检查 | `vue-tsc --noEmit` | **0 error** | | 密钥扫描 | 多模式正则全仓扫描 | **0 命中** | | 空库迁移 | 临时库 + 应用启动 | 自动建 10 表 + 种子;二次启动幂等 | | 登录链路 | `POST /api/auth/login` | 200 + JWT(token / refreshToken 完整返回) | | 产物核对 | jar 内资源检查 | `db/migration/V1__baseline.sql`、`application-local.yml` 均在包内 | 登录与运行态验证——种子账号 admin 登录成功,平台核心功能在迁移后的空库上正常工作: ![登录.png](https://pic.code-nav.cn/post_picture/1944355748262088705/MEj75Nws1PB099bC.webp) M0 出口清单除"`docker compose` 一键拉起"(本机暂无 Docker,留待环境就绪后补验)外,全部达成。偏差与验证记录已同步写入实施计划的完成记录,保证过程可复查。 ## 六、踩坑笔记(可直接抄作业) 1. **种子密码 hash 必须实测**。operator 账号的 BCrypt hash 疑似来自某文档示例,校验根本不匹配——"看起来对"不等于"能登录"。教训:种子数据里的每个 hash 都要跑一遍校验脚本再入库。 2. **lint 绿 ≠ 类型绿**。本次 lint 清零后,`vue-tsc` 仍报出类型化门面的参数隐式 any——对象字面量中的泛型箭头函数不会从接口定义获得参数推断,必须显式标注。ESLint 与类型检查是两把尺子,缺一不可。 3. **ESLint 9 flat config 移除了 `--ext`**。旧脚本 `eslint src --ext .ts,.vue` 直接报错,flat 时代改用 `eslint .`,由配置中的 `files` 匹配接管。 4. **幂等是基线脚本的底线**。所有建表走 `IF NOT EXISTS`、种子走 `ON CONFLICT DO NOTHING`——脚本既能被 Flyway 编排,也能被人工重放,两种用法都安全。 5. **占位符有无默认值是两种安全语义**。`${DB_PASSWORD}` 表示"必须注入",`${REDIS_PASSWORD:}` 表示"允许为空",生产敏感项一律前者 + 本地兜底放进 profile 文件。 ## 七、下周预告:M1 开局——测试体系从 0 到 1 M0 把地基修平,M1 开始搭工程化骨架(D6 起): - **后端测试体系**:JUnit5 + Mockito 单测、Testcontainers 集成测试(真实 PostgreSQL 16 镜像)、JaCoCo 覆盖率门禁; - **前端测试**:Vitest 组件测试 + Playwright E2E 冒烟(登录 → 仪表盘 → 卫星列表 → 遥测页); - **安全加固**:WebSocket 握手鉴权(STOMP ChannelInterceptor 校验 JWT)、按钮级 RBAC、审计日志 AOP; - **CI/CD**:Gitee Go 流水线串联 lint → 单测 + 覆盖率 → 镜像构建,任一红即阻断发布。 ## 八、结语 M0 这一周最值得"截图"的,不是任何一个页面,而是三行绿色输出:`BUILD SUCCESS`、`0 error 0 warning`、`No migration necessary`。 功能看演示,工程看门禁。从"功能齐全"到"工程可靠",跨越的不是代码量,而是纪律:数据库变更可版本化回放、配置零明文、质量门禁真实生效、每一项验收都有日志可查。第一周只是一小步,但方向已经立住。 > 📌 觉得这篇实战记录有价值?**点赞 + 在看 + 转发**,让更多航天与软件工程师看到! > 💬 留言聊聊:你们团队的数据库迁移是怎么管的?有没有被"文档与真实库不一致"坑过? *本文关键词:卫星平台 2.0 | 基线修复 | Flyway | 数据库迁移 | ESLint 9 | 密钥外置 | 工程化实战 | Spring Boot | Vue 3 | PostgreSQL *

停止记账焦虑,我只看这一个数字 【今安有余(MyWallet)】 小程序上线了!

![今安有余产品图](https://pic.code-nav.cn/post_picture/1720248103275196418/QUTEyImFsbbDYiqO.webp) # 产品定位 **今安有余**是一款帮用户记账、存钱、还债的轻量财务助手,围绕 **“记账 → 分钱 → 存钱 → 还债 → 调整”** 形成持续闭环,让用户今天过得安心,未来留有余地。 产品每天回答用户三个问题: 1. **今天还能安心花多少钱?** 2. **下一笔收入应该怎么分配?** 3. **按当前节奏,什么时候能存够应急金、还清债务?** --- ## 核心公式 > **今日安心可花 = 剩余可支配资金 ÷ 距下次“打钱日”剩余天数** **对学生党的翻译:** 爸妈打的生活费,刨掉食堂饭钱、话费、要还的花呗,剩下的除以月底前的天数——每天能放心花多少,打开就看到。 **一句话价值:** 不用记一笔账,也能知道今天能不能喝奶茶。 --- ## 使用场景 ### 场景 1:今日安心可花(每日核心场景) 阿杰早上打开小程序,首页直接显示“今天安心可花 86 元”。该金额已经扣除本月剩余固定账单、最低还款、应急金任务和必要生活预留。他不需要理解复杂预算,也能立即决定今天的消费边界。 ### 场景 2:快速记账(高频) 阿杰买了杯咖啡,打开小程序点“+”,选分类“餐饮”,输入 28 元,2 秒完成。当晚他看统计页发现今天餐饮超支了。 ### 场景 3:管理负债(中频) 阿杰有花呗欠款 3200 元,他在“负债”里新建了还款计划,设置每月 10 日还款 1000 元。临近还款日,小程序推送提醒,避免逾期。 <img src="https://pic.code-nav.cn/post_picture/1720248103275196418/JPo62xBTvyJSfxPT.webp" alt="微信图片_20260910115751_181_7" width="600" style="max-width: 100%; height: auto;" />

我让 GPT-6 做了一池锦鲤

大家好,我是不会喷火的小火龙。 GPT-6 Astra 一出来,官方文档里反复讲的就是一件事:端到端复杂任务执行。说白了就是,你给一个复杂需求,模型从头做到尾,中途还能接受你的反馈继续改。 作为一个每月 Token 开销不低的实战党,我对这种宣传向来是"先做再说"。这次我决定用一个真实项目来验证:让 GPT-6 在 Codex 环境里,从一份详细需求开始,完整交付一个互动式 3D 锦鲤池。 这篇文章会从公开资料出发,经过需求交付和功能验收,再到我不满意之后的返工过程,用可观察的行为和实际改动来评估 GPT-6 的能力边界。所有截图来自真实项目页面,所有数据来自开发验收记录。 ![01-revised-pond-day.jpg](https://pic.code-nav.cn/post_picture/1612112775822180354/STKfw50CLzRYuYZl.webp) *改模后的锦鲤池当前版本。静态截图能看全景和体型,但不能证明交互和性能。* ## 一、先看公开资料:GPT-6 到底在强调什么 动手之前,我先把相关的公开资料过了一遍。 [官方模型文档](https://developers.openai.com/api/docs/models/gpt-6-astra)把 Astra 定位在复杂推理、编码、电脑操作、研究和文档创建。页面标了 1,050,000 token 上下文和 128,000 token 最大输出。当然,这些是产品规格,不是我在自己项目里测出来的数字。 [使用指南](https://developers.openai.com/api/docs/guides/latest-model)着重讲了两个能力:跨代码和浏览器的多步骤执行,以及工作进行中接受新要求并调整方向。这两点跟我想观察的问题刚好对得上,我把它们记下来当观察项。 OpenAI 开发者博客上还有一篇[用 Astra 做浏览器游戏](https://developers.openai.com/blog/how-to-build-games-with-astra)的实践文章,作者 Thomas Ricouard 用 Codex 开发了一个完整的浏览器游戏,过程涉及目标设定、反复测试、截图检查和视觉返工,人依然负责最终审查外观和手感。这是我目前看到的跟锦鲤池最接近的官方案例。需要注意的是,这是厂商员工的实作,不能当独立第三方评测。 外部评测方面,[TrueStandard 的首周评测](https://truestandard.ai/blog/gpt-6-astra-review)可以了解外界反应,但它的性质要注意:作者明确写了自己没有跑基准测试,内容主要是公开演示和资料的整理汇总。拿来当独立实验引用就不合适了。 看完资料,我给自己列了四个观察点:实现完整性、交互因果关系、返修能力、验收边界。至于百万上下文窗口、异步工具调用这些,在这个项目里用不到的我就不硬塞了。 ## 二、为什么选锦鲤池:它会同时暴露好几种问题 选锦鲤池不是随意的决定。这个项目的需求本身就够复杂:鱼群要在水里游动,触水要有涟漪反馈,投喂食物后鱼要游过来吃,昼夜循环要联动灯光和音效,手机竖屏也得能正常操作。而且所有 3D 模型、鱼身花纹、水面效果、环境音效全部要由代码程序化生成,一个外部贴图文件都不用。 我提交给 Codex 的是一份详细的规格文件,写清了鱼群数量(桌面 12 条、手机 8 条)、六种花色、水面动画、投喂机制、昼夜切换、声音控制、画质设置。这里要特别说明,**这不是一句"帮我做个锦鲤池"就完事的任务**。 这个项目的好处在于,它同时考验图形渲染、行为逻辑、界面布局和工程协调。鱼得会游,还得长得像锦鲤。投喂得有响应,鱼不能隔着半个池塘瞬移过来。昼夜切换得好看,灯光变了鱼的颜色也要跟着变。这些子系统单独做不难,让它们一起正确工作才是真正的考验。 ## 三、第一版已经能玩了,我先看鱼到底有没有吃到食物 第一版交付后,项目在浏览器里跑起来了。庭院、水面、鱼群、投喂按钮、昼夜切换、声音控制,功能入口都在。 我没有看到"哇好漂亮"的截图就直接验收。我最关心的是交互逻辑有没有串起来,所以直接从投喂开始测。 点击投喂按钮,9 粒食物撒到水面。鱼群从不同方向靠过来,游到食物附近后吃掉一粒、消失一粒。 ![02-initial-pond-day.png](https://pic.code-nav.cn/post_picture/1612112775822180354/ZNYLv0fxlIFLNqan.webp) *第一版的锦鲤池全景。庭院和水面已成型,鱼在游动,但鱼体和鳍面的细节还没达到预期。* 它验证的是一条完整的交互因果链:用户点击 → 食物出现在水面 → 鱼从游荡状态切换到觅食 → 鱼朝食物游过去 → 到达一定距离后食物被消耗移除 → 鱼短暂减速然后恢复游荡。每一步都涉及状态管理和事件驱动,哪一步断了画面上都能看出来。 除了投喂,初版还跑了十分钟长程模拟(36,000 步),验证鱼群没有越界、速度没有数值溢出。惊扰测试确认了触水后鱼会加速散开,6 秒内平复。还有防瞬移保护:就算浏览器切后台挂了 50 秒再回来,单帧位移也被限制在 0.1 单位以内,鱼不会开屏飞出去。初版 6 项行为测试全部通过。 手机端方面,桌面浏览器模拟的 390×844 视口下,锦鲤减少到 8 条,没有横向溢出,按钮和文字正常显示。不过,这是桌面浏览器模拟视口,不是真机测试,帧率数据也是桌面的,不能说"手机上跑 120 帧"。 ![05-initial-mobile.png](https://pic.code-nav.cn/post_picture/1612112775822180354/OwcgOTUbtY7fq4BQ.webp) 到这一步我的判断是:GPT-6 通过 Codex 确实做出了一个有状态、有因果的可运行作品。行为测试能通过,工程管道是通的。 可是,这些测试回答的都是行为问题。审美问题,一项也没有覆盖。 ## 四、然后我说了一句:锦鲤的建模不对 功能检查做完,我放大画面仔细看了看鱼。 然后我跟 Codex 说了一句:**"锦鲤的建模不对,你去谷歌上调研一下就知道了,我喜欢那种写实风格但又比较精致的。请你修改。"** 为什么不满意?第一版的鱼体轮廓太均匀,从头到尾差不多粗细,少了锦鲤特有的肩宽尾窄的体型。鱼鳍是扁平的片状,没有扇面的透明质感。花纹和鳞片也偏粗糙,整体更像卡通鱼。 我的需求文件里写的是"偏写实、精致"的风格。6 项行为测试全部通过,投喂逻辑完美运转,可我一看画面就知道这不是我想要的锦鲤。 这个落差挺有意思的。传统软件里测试通过就基本可以交付,但做图形项目不一样。"鱼行为正确"和"鱼看起来像锦鲤"是两层完全不同的验收标准,后者目前没有什么自动化的手段。 ![01-revised-pond-day.jpg](https://pic.code-nav.cn/post_picture/1612112775822180354/YV1yem5GM4y63jhb.webp) *改模后的全景。与上图初版对比,体型和花纹变化可见。两张图是不同动画时刻的截图,鱼群位置会变化,不能作为逐像素对比。* 另外要交代一个事实:Codex 在执行调研时去谷歌搜了锦鲤图片,但图片搜索页超时了,养殖场的正文返回了 403。实际可用的参考主要是我提供的截图附图,不能写成"完整研读了专业解剖资料"。也没有把网上的图片直接用作贴图素材。 ## 五、这次返工,改到了鱼身结构和贴图方向 收到反馈后,Codex 开始重建鱼的模型。改的东西比我预想的多。 **先说体型。** 原来的鱼体接近均匀筒形,现在换成了 11 个控制点的三次 Hermite 样条曲线。从鱼嘴到鱼尾,截面宽度先从极窄增长到肩峰(半宽 0.308),再连续收窄到尾柄极细处(半宽 0.078)。肩宽约为尾柄的 4 倍,这就有了锦鲤那种"前宽后窄、肩膀最壮"的特征体型。代码还在背脊线额外加了一道隆起,塑造出脊背的厚度感。 **再说鱼鳍。** 从扁平三角片改成了带径向细分的扇面网格,每片鱼鳍 48 条射线、12 层环带,共 637 个顶点。生成时还给扇面注入了一道微弧,消除了纸片般的平板感。改完一共 6 片鱼鳍:一对胸鳍、一对腹鳍、背鳍、以及带分叉的双叶尾鳍。鱼还加了侧置的嵌入式眼球、口唇弧线和两根从嘴角撇出的触须。 **然后是鳞片和花纹。** 鳞片画在 2048×1024 的离屏 Canvas 上。鱼头前 20% 的区域保持光滑不画鳞片,模拟鳃盖和吻端的质感。身体部分用交错排列的弧线绘制覆瓦状鳞片(砖墙式的半步交错),同时在凹凸贴图上对应位置画深灰描边,让鳞片在光照下有微浮雕的立体感。六种花色各有独立的配色逻辑,比如红白(Kohaku)是白底加几块有机形状的红斑,边缘用 28 个极坐标采样点加多频谐波扰动生成,不是死板的椭圆。丹顶(Tancho)则是全身纯白、头顶正中一颗圆润的红印。材质用了 clearcoat 层模拟鱼体表皮的湿润光泽。 ![03-revised-koi-closeup.jpg](https://pic.code-nav.cn/post_picture/1612112775822180354/ViWziWEUB6bF89lr.webp) *改模后六种花色的近景。这个页面使用独立照明并去掉了水面遮挡,专门看鱼身细节,不是正式的池塘画面。* **最后说一个有意思的 bug:花纹贴反了。** 改完模型后我发现,本来应该画在背部的花纹跑到了肚子上。查下来是 Three.js 默认贴图行为导致的。鱼身的 UV 映射里,纵坐标 0.25 对应的是鱼的背脊线,0.75 对应鱼腹。Canvas 画花纹时也把斑块画在 y=0.25 的位置。但 Three.js 默认 `texture.flipY = true`,会把 Canvas 上下翻转再传给 GPU,于是 0.25 就变成了 0.75,背部花纹就跑到腹部去了。修复就一行: ```typescript map.flipY = false; ``` 颜色贴图和凹凸贴图都要设。这个修复只在本项目的 UV 映射方式下成立,不能直接当通用建议。 ![04-revised-pond-night.jpg](https://pic.code-nav.cn/post_picture/1612112775822180354/PJsqhm66fqMCM8IM.webp) *夜间状态,灯光和色调联动。静态截图不能证明切换过程的流畅度。* 改模后重新跑了构建(通过)、lint(通过)和测试(9 项全部通过,比初版多了几何校验)。新增测试验了什么?肩部宽度大于头部、肩宽是尾柄细处的 3 倍以上、沿全长密集采样 1000 个截面点无畸变跳变、背脊顶点的法线朝上且 UV 纵坐标精确等于 0.25(这条直接证明了几何和皮肤贴图的对齐)、6 片鱼鳍各 637 个顶点全部为有效浮点数。 测试通过说明几何和贴图在技术层面是对的。但"看起来像不像真正的锦鲤"?这是程序化生成加艺术化处理的模型,跟照片级写实还有距离。 ## 六、如何评价 GPT-6,以及如何测下一款模型 用这个项目的实际经历,我按四个方面来评价。 **工程完成度**:给的是一份包含鱼群、水面、投喂、昼夜、音频、响应式布局等子系统的详细需求,交回来的是一个在浏览器里能跑的完整项目,构建和 lint 都通过。对这个复杂度的任务来说,能一次交付可运行的工程,表现是好的。 **交互逻辑**:投喂的全链路验证(9 粒食物从撒下到被吃完)证明状态管理和事件驱动是通的。鱼群觅食、边界回避、惊扰恢复、防瞬移保护也都有行为测试覆盖,6 项初版测试全部通过。 **返修能力**:收到"建模不对"这个定性反馈后,模型没有只调几个参数敷衍了事,而是重建了体型曲线(11 控制点样条)、鱼鳍结构(扇面细分 637 顶点)、鳞片花纹(覆瓦交错加有机斑块),还找到并修正了贴图方向的 bug。改动产生了明确的视觉差异,测试也从 6 项增加到 9 项。这说明代理能把审美反馈转化成具体的代码修改。 **验收边界**:代理自己做的验收集中在行为和工程层面,没有办法自动判断"鱼看起来像不像锦鲤"。这一层验收需要人来做。 做个总结:在 Codex 工具环境下,GPT-6 能串起一个复杂交互项目的实现、检查和返修,这在我这个项目里是成立的。功能检查完成后,视觉和体验层面的验收仍然需要人来判断和拍板。 如果你也想测一款 AI 编程工具的实际水平,我的建议是:选一个你自己熟悉的项目,记录输入和每次人工干预,把测试数字和视觉感受分开评价,最后把结论限定在你的实验条件内。这比看排行榜上的分数靠谱得多。

兄弟们推荐IDEA 什么版本

大家都在用什么版本的IDEA

【自荐】PriTime: 一个可自托管的多端待办任务清单、时间管理应用

**PriTime 是一款可完全自托管的多端待办任务管理应用。任务、清单、标签、四象限、日历、番茄钟、习惯打卡、共享清单、AI 助手一应俱全,支持 Docker 一键部署,数据 100% 存在你自己的服务器或 NAS 上,并提供 JSON/Excel 全量导出,随时可走。** ![image.png](https://pic.code-nav.cn/post_picture/2054762602298363906/CugBMy6j2RIZVj22.webp) ## PriTime 是什么? PriTime 是一个多端待办任务管理应用,由三部分组成: * **Web 端**:Vue 3 + `Vite`解码 单页应用,浏览器打开即用 * **服务端 API**:Ruby on Rails 8 + PostgreSQL,标准 JSON API * **桌面端**:macOS 原生 SwiftUI 客户端(零第三方依赖) 多端共享同一套 REST API,登录同一账号即可同步。此外还有面向飞牛 fnOS 的 fpk 应用包,NAS 桌面双击图标就能打开。 ## 功能清单:一个不缺 | 能力 | 说明 | | ------------ | ------------------------------------------------------------------------- | | 任务管理 | 快速创建、子任务拆解、Markdown 描述、附件、拖拽排序 | | 组织方式 | 清单(自定义图标/颜色)+ 彩色标签,双维度分类 | | 任务属性 | 四级优先级、截止时间、提醒(准点/提前 5 分钟到 1 天)、9 种重复规则 | | 重复规则亮点 | 支持\*\*法定节假日 / 法定工作日(含调休补班)\*\*重复,国内用户刚需 | | 四象限视图 | 经典艾森豪威尔矩阵,按重要/紧急自动分象限 | | 日历视图 | 月历展示任务,可订阅节假日、传统节日、二十四节气、**未来 7 天天气** | | 下雨提醒 | 天气源开启后,降雨概率达标自动创建「带伞」提醒任务 | | 课程表视图 | 学生与固定日程人群的周期性事务管理 | | 专注模式 | 番茄钟计时,可绑定任务记录投入 | | 习惯打卡 | 每日打卡、连续天数激励 | | 纪念日 | 重要日期倒计时 | | 统计 | 完成率、完成趋势、清单/标签分布图表 | | 全局搜索 | `Ctrl/⌘ + K` 快速搜索标题与描述 | | 共享清单 | 邮箱邀请成员,多人协同维护一份待办,角色权限管理 | | AI 助手 | 自然语言创建任务(DeepSeek),自动解析时间/优先级/清单/标签 | | MCP 接口 | Claude Desktop 等 AI 客户端可直接调用 `create_task` 创建任务 | | Web Push | 浏览器通知 + 通知中心,逾期醒目提示 | | 模块管理 | 日历、四象限、专注等模块可自由开关,界面不打扰 | | 个性化 | 多套主题色 + 免费可商用字体,设置云端同步 | | 数据导出 | JSON 全量备份(可迁移/导入)+ Excel 查看,数据永远握在自己手里 | ## 三种使用姿势 ### 1. Docker 一键自托管(推荐) 一个 `docker-compose.yml`,Web + API + PostgreSQL 一次拉起 `docker compose up -d`,浏览器打开 `http://localhost:8080` 即可开始使用。后端容器启动时自动建库迁移,无需手工操作。 ### 2. 飞牛 fnOS 一键安装 打包好的 `pritime.fpk` 在应用中心手动安装即可,Web 与 API 合并为单容器 + 独立数据库容器,数据持久化在包目录,卸载重装数据不丢。NAS 桌面点击图标直达,全程同源、无 CORS 烦恼。 ### 3. 免登录本地模式(不想装服务器?) Web 端登录页提供「免登录 · 本地模式」:数据直接落在浏览器 IndexedDB,无需任何后端,完整业务逻辑在本地复刻执行。macOS 客户端同样提供本地模式,数据存储在系统级 SQLite(GRDB)。两种模式与服务器模式共用同一套导出/导入格式,以后想上自托管,导出 JSON 再导入即可无缝迁移。 ## 为什么选 PriTime 而不是 SaaS 待办工具? 1. **数据主权**:任务数据存你自己的服务器/NAS,不经过任何第三方,退出随时全量导出。 2. **无订阅费**:没有会员、没有广告、没有功能墙,深度使用零成本。 3. **本地化细节**:法定节假日/调休重复、二十四节气日历、中文天气与下雨提醒,这些是很多国外工具做不到位的地方。 4. **AI 能力可选**:不配置 Key 就是一个纯净的任务工具;配置 DeepSeek Key 后获得自然语言建任务能力,开发者还能通过 MCP 接入自己的 AI 工作流。 5. **轻量**:单容器即可跑起来,一台最低配 VPS 或老 NAS 就够。 ## 适合谁用? * 拥有 NAS / 家庭服务器,想找一款装在 NAS 上的任务管理应用的玩家 * 在意隐私,不愿把工作、生活待办交给云端 SaaS 的个人用户 * 需要「今天 / 未来 7 天 / 四象限 / 日历」多维视图的效率工具爱好者 * 学生党:课程表 + 重复任务 + 习惯打卡的组合很对口 * 开发者:REST API + MCP 接口,可以自由扩展和接入 AI 客户端 官网地址: [PriTime 官网](https://www.pritime.com/) [https://www.pritime.com/](https://www.pritime.com/)

告别 Agent 研发失控:vibe-workflow 实战指南

## 本节重点 用 Cursor、Claude Code 或 Antigravity 写代码时,很多同学都有过类似的体会:让 Agent 写个独立的辅助脚本或单文件 demo,通常很顺手;但如果把它放进一个现有的多文件项目里做多轮迭代,往往很容易失控。比如顺手改掉没让它动的基础库、改错一个地方后进入反复修补的死循环,或者换个对话窗口就把之前的设计细节忘光。 这篇文章介绍我开发的开源 Agent Skill —— vibe-workflow,以及它在微信小程序 moneyRecord(清新记账)中的实际用法。 本文主要包含四部分内容: - 分析 Coding Agent 在多文件项目中失控的常见原因; - vibe-workflow 的状态机与四条核心约束; - 以 moneyRecord 小程序 v0.2.0(月度预算与每日走势图)为例,看需求冻结、垂直切片到自动化验证的完整流程; - 在自己的项目中接入 vibe-workflow 的配置方法。 前置条件:有基本的 Git 使用经验,日常用过至少一款 AI 编程工具。 ## 一、为什么 Coding Agent 容易把项目改崩? 在多轮需求开发中,Agent 常见的问题主要有四类: ### 1. 范围膨胀(Scope Creep) 让 Agent 把某个保存按钮改成异步提交,打开 Git Diff 却发现它顺带重构了全局请求封装,甚至把原本做好的异常处理删掉了。给 Agent 编码权限,很容易被模型理解为可以随意调整业务和架构范围。 ### 2. 反复修补 遇到报错或单测失败时,Agent 的第一反应往往是就地加补丁:第 10 行报空就加一层判断,第 25 行受影响又补一个容错。几轮交互下来,Token 耗费不少,底层设计越来越乱,最初的问题依然没解决。 ### 3. 上下文随会话丢失 聊天窗口的上下文有限,一旦会话被压缩或者新开对话,模型就失去了之前的上下文。哪怕重新粘贴 Prompt,它也很难准确还原上一轮为什么这么设计、哪些模块已经测通。 ### 4. 虚假完成 模型经常在回复里宣称“所有功能均已实现并通过测试”,但实际运行或者跑单测时往往直接报错。没有真实的命令输出做佐证,模型的口头确认并不能作为交付依据。 这些问题的根源,通常不在于模型单点写代码的能力,而在于开发过程缺少生命周期管理和工程约束。如果不能把确定性的流程规范和模型自身的生成能力结合起来,Agent 的多轮产出就很难稳定。 ## 二、vibe-workflow 的机制与核心约束 vibe-workflow 是一个生命周期编排器(Orchestrator)。它用一套状态机把需求澄清、规格编写、架构设计、分步实现与测试验证串联起来,约束 Agent 在每一步的动作边界。 ```text REQUIREMENTS_FROZEN (需求冻结) ↓ SPECIFIED (行为规格) ↓ DESIGNED (架构设计) ↓ PLANNED (实施计划) ↓ BUILDING (垂直切片实现) ↓ VERIFYING (证据验收) ↓ READY_TO_SHIP (就绪发布) ↓ RELEASED (正式归档) ``` 在这个流程中,有四条核心规则: ### 1. 需求必须先冻结,实现细节可委派 项目或版本在写代码前,必须满足: ```text Requirement Status == FROZEN Open Questions == None Current Release ID exists Acceptance Goals are testable ``` 只要还有未确定的需求疑问,或者状态未标记为 FROZEN,Agent 就必须停下来,不能直接生成业务代码。产品的边界由人决定,具体实现细节才由 Agent 负责。 ### 2. 仓库是唯一记忆,聊天只是临时通道 不把设计方案和任务进度留在聊天记录里,而是统一保存在代码仓库的 `docs/vibe/` 目录下。 新开会话或切换窗口时,Agent 只需要读取 `docs/vibe/PROJECT.md` 和 `docs/vibe/PROGRESS.md`,就能获取当前状态,不需要依赖人工手动同步聊天上下文。 ### 3. 普通修改自主推进,关键事项走决策门禁 私有函数命名、小文件重构、本地单测等日常编码由 Agent 自行决定。但如果涉及产品范围调整、公共接口兼容性变动、数据库结构迁移、安全策略以及最终发布,Agent 必须停下来给出方案,等待人工明确确认。 ### 4. 没有新鲜的验证证据,不得声称完成 任务完成的判断标准只有一条:终端实际执行的测试命令或检查输出。必须有当前轮次跑通的测试日志,且覆盖既定的验收目标,才能把状态流转到完成。 此外还有一项熔断规则:如果 Agent 就同一报错连续修补 3 次仍未解决,或者改好一处导致其他两处出现新错误,必须停止打补丁,记录当前断点,重新审视架构或方案后再继续。 ## 三、实战:微信记账小程序 moneyRecord 以正在开发的微信原生记账小程序 `moneyRecord` 为例。在 v0.1.0 跑通基础记账与分类后,我们通过 vibe-workflow 推进 v0.2.0 的月度预算与收支趋势分析功能。 ### 1. 需求冻结与目标定义 (`PROJECT_BRIEF.md`) 在 `docs/vibe/releases/v0.2.0/PROJECT_BRIEF.md` 中,我们把本期范围和排除项写清楚,并将状态置为 FROZEN: ```markdown ## Requirement Control - Requirement Status: FROZEN - Current Release: v0.2.0 - Approved By: User ## In Scope (v0.2.0) - [x] 月度预算管理: 支持设置、修改或关闭月度预算限额;本地持久化。 - [x] 首页预算进度展示: 首页汇总卡片展示进度条、剩余预算、已用百分比。 - [x] 超支提醒机制: 预算超支时进度条呈现珊瑚红并标注“超支 ¥XXX”。 - [x] 每日收支趋势图表: 统计页新增基于 Canvas 2D 的每日收支趋势图。 ## Out of Scope - 分类独立子预算 - 年报与跨年度对比 - 多账户管理 ## Acceptance Goals | Goal ID | 可观察目标 | 验证方式 | |---|---|---| | GOAL-201 | 用户可成功设置月度预算,首页即时展示剩余预算与已用进度条 | 查看首页卡片渲染与数据 | | GOAL-202 | 当月支出未超预算时进度条为清新绿色;超支时变红并计算差额 | 录入超预算数据检查状态机 | | GOAL-203 | 统计页准确绘制当月每日收支趋势图表,柱状高度与金额匹配 | 自动化单测计算趋势聚合数据 | | GOAL-204 | 切换统计月份时,趋势图与每日数据自动同步更新 | 切换历史月份核对 | ## Open Questions - None ``` 明确了 Out of Scope 之后,Agent 就不会擅自去写多账户或分类子预算相关的逻辑。列出 GOAL-201 到 204,也让后续验收有了具体的比对标准。 ### 2. 行为规格与设计先行 (`SPEC.md` 与 `TECH_DESIGN.md`) 编码前先定义关键状态和计算规则。比如针对预算监控,在规格中先写明状态机: ```javascript const BUDGET_STATUS = { HEALTHY: 'HEALTHY', // 已用 < 80% (绿色) WARNING: 'WARNING', // 80% <= 已用 <= 100% (橙色) OVER_BUDGET: 'OVER_BUDGET'// 已用 > 100% (红色,计算超支差额) }; ``` 同时在架构设计中规定:UI 层不直接处理聚合,按日汇总的数据逻辑全部收敛到 `utils/recordService.js`,图表渲染使用微信原生的 Canvas 2D 接口。 ### 3. 垂直切片拆解 (`IMPLEMENTATION_PLAN.md`) 不一次性修改所有模块,而是把任务拆成 4 个垂直切片: - Slice 2.1: 预算存储与每日数据聚合服务(`storage.js`, `recordService.js`, `date.js`)。 - Slice 2.2: 预算设置界面与首页卡片联动(`pages/settings/*`, `pages/index/*`)。 - Slice 2.3: 统计页趋势分析与 Canvas 2D 图表渲染(`pages/stats/*`)。 - Slice 2.4: 自动化单测编写与集成验证。 每做完一个切片,Agent 都在 `docs/vibe/PROGRESS.md` 中打钩更新,这样无论中途被打断还是换窗口,接手时都能看到当前进度: ```markdown - [x] Slice 2.1: 预算底层服务与日趋势聚合 (storage.js, recordService.js, date.js) - [x] Slice 2.2: 预算管理界面与超支监控 (settings/*, index/*, record/*) - [x] Slice 2.3: 统计页收支趋势分析与 Canvas 2D 图表 (stats/*) - [x] Slice 2.4: 自动化测试与 v0.2.0 验证 (tests/test_v2.js, VERIFICATION.md, TECH_DESIGN.md) ``` ### 4. 验证与证据记录 (`VERIFICATION.md`) 写完功能后,在终端执行测试: ```bash node tests/test_core.js && node tests/test_v2.js ``` 输出真实的测试结果: ```text --- 开始测试 Slice 1 核心模块 --- ✓ utils/calc.js 测试通过 ✓ utils/date.js 测试通过 ✓ utils/icons.js 测试通过 ✓ utils/categoryService.js 测试通过 ✓ utils/recordService.js 核心领域逻辑测试全部通过! ======================================== 🎉 自动化测试 100% 通过! --- 开始测试 v0.2.0 预算与趋势分析模块 --- ✓ dateUtil.getDaysInMonth 测试通过 ✓ storage.js 预算存取测试通过 ✓ recordService.getBudgetStatus 状态机与超支计算测试通过 ✓ recordService.getMonthDailyTrend 每日趋势聚合测试通过 ================================================ 🎉 v0.2.0 自动化测试 100% 全部通过! ``` 把这些输出记录到 `docs/vibe/releases/v0.2.0/VERIFICATION.md`,确认 4 个 Acceptance Goal 都通过后,状态才正式更新为 `READY_TO_SHIP`。 ![image.png](https://pic.code-nav.cn/post_picture/1612112775822180354/InZLnNvxRSnxwWGS.webp) ## 四、在现有项目中接入 vibe-workflow 将这套流程加入现有项目通常只需要三个步骤: ### 1. 在根目录配置 `AGENTS.md` 在项目根目录创建 `AGENTS.md`,让 Agent 进入工作区时先阅读基础规则: ```markdown # Agent Instructions ## Workflow & Governance 本项目遵循 `vibe-workflow` 软件生命周期管理规范。 ### 核心规则 1. **Constitution**: - 工程开始前必须冻结需求(Requirement Status == FROZEN, Open Questions == None)。 - What to build is frozen. How to build it is delegated. - 不得静默改变产品范围;产品变化必须经过明确的人类决策。 - Repository is memory. Chat is conversation. - 没有 fresh verification evidence,不得声称完成。 2. **事实源**: - 项目总览与索引: `docs/vibe/PROJECT.md` - 当前执行进度: `docs/vibe/PROGRESS.md` - 当前 Release 需求基线: `docs/vibe/releases/<release-id>/PROJECT_BRIEF.md` - 当前架构事实: `docs/vibe/TECH_DESIGN.md` ``` ### 2. 建立 `docs/vibe/` 目录与基础文档 在 `docs/vibe/` 目录下放置两个核心文件: - `PROJECT.md`:记录项目定位、当前版本与测试命令: ```markdown # Project - Project Name: 你的项目名 - Current Release: v0.1.0 - Quality Profile: Standard - Supported Commands: npm test / npm run dev ``` - `PROGRESS.md`:记录当前执行切片与任务状态: ```markdown # Progress - Current Release: v0.1.0 - Current Workflow State: REQUIREMENTS_FROZEN - Operational Status: ACTIVE - Current Slice: None - Next Task: 编写 SPEC.md 行为规范 ``` ### 3. 日常开发指令 配置完成后,日常给 Agent 发指令时就可以按流程推进: - 开新需求时:“按照 vibe-workflow 规范,为我们规划 v0.3.0 的需求基线 `PROJECT_BRIEF.md`,列出需要我确认的问题。” - 新窗口继续工作时:“先读 `docs/vibe/PROJECT.md` 和 `docs/vibe/PROGRESS.md`,确认当前进度后继续执行下一个切片。” 这样可以让 Agent 始终围绕既定的切片和测试目标推进,减少无谓的来回试错。 ## 五、总结与仓库地址 使用 AI 辅助编程,工具的生成速度很快,但如果缺少约束,规模稍大就会带来返工成本。vibe-workflow 的出发点,就是通过需求冻结、仓库持久化记录、垂直切片和测试证据链,把开发过程固定在可控的轨道里。 如果你在开发中也遇到过 Agent 随意改代码或遗忘上下文的问题,欢迎尝试这个工作流。 已在 GitHub 开源: 👉 **https://github.com/sz-xiaohuolong/vibe-workflow** 觉得对你有帮助的话,欢迎去 GitHub 点个 Star 支持一下。也欢迎提交 issue 或 PR,一起交流 Agent 工程化落地的经验。

怎么感觉编程导航全是java后端啊, 压力一下就上来了

下载 APP