一、引言
菜单角标(Badge)是企业级应用中常见但容易被低估的小功能:它要求在多用户、多节点、多业务并发的场景下,对每一位用户、每一个菜单实时呈现待办数量。看似一个红点,背后却串联起Redis 发布订阅、SignalR 实时推送、配置开关、后台服务条件注册、文档同步与日志规范化等多个工程层面。本文记录我在 IMS.JMOM 项目中使用 Qoder 完成这一功能从 0 到 1、再从功能到工程化重构的全过程心得。
二、需求背景与技术方案
2.1 业务诉求
在“其他入库”等业务模块产生待处理任务时,对应菜单实时显示数量。
用户跨多节点登录时,角标数据全局一致,不丢推送。
角标信息属于运行时状态,不落库,重启可重建。
可通过配置开关一键关闭,避免对未启用 Redis 的部署造成影响。
2.2 关键设计
存储:Redis Hash,Key 为 User:Badge:{userId},Field 为菜单 ID,Value 为数量。
通道:Redis 发布订阅频道承载“增量 / 覆盖 / 清除”三类 OpType 消息。
推送:RedisBadgeSubscribeHost 后台服务订阅频道,命中本节点在线用户后,通过 SignalR Hub<IMenuBadgeHub>.RefreshBadge() 向前端广播。
全局化:ClearAllBadge 改为 HashGetAll + 逐字段 HashDeleteAsync,避免销毁 Hash 结构。
开关:appsettings 增加启用项,未启用时跳过后台服务注册与发布订阅链路。
三、Qoder 在开发过程中的具体作用
3.1 高质量的语义检索,让“破冰”变得轻松
在面对一个不熟悉的单体仓库时,最大的成本是“找”。Qoder 的语义搜索能直接回答“现有 SignalR Hub 是怎么注册的”“缓存服务在哪里抽象”“后台服务是如何托管的”这类高层问题,让我可以在十几分钟内拼出完整的架构画像,再基于既有约定去设计 IMenuBadgeHub、BadgeService、RedisBadgeSubscribeHost 这些新组件,避免重复造轮子。
3.2 工具并行调用,把“调研 + 实现”压缩在同一个心流里
Qoder 支持在一次回合中并行执行多个搜索/读取/编辑操作。在做菜单角标功能时,我经常一次性发起 grep_code 找所有 Console.WriteLine、search_codebase 找现有日志样例、read_file 读关键 Service 文件,再统一进行 search_replace。这种“并行查、集中改”的节奏,把日志规范化(5 个文件 25 处统一替换为 ILogger 的结构化日志)这种重复劳动从“看着都累”变成“一气呵成”。
3.3 上下文记忆,让“今天接昨天”毫无负担
菜单角标功能不是一次写完的:先实现单业务场景,再扩展到 WMS 单据按 BillType 分组初始化,再做全局化重构、清除链路统一走发布订阅、再到配置开关化。Qoder 把每一步的关键决策、涉及文件、技术债务沉淀为可检索记忆,下一次开口就能延续上下文,不必反复粘贴目录树。
3.4 自然语言驱动重构,让规范真正落地
把“反模式”改成“规范”往往是最容易被搁置的事情。借助 Qoder,我用一句“把 BadgeService 等 5 个文件的 Console.WriteLine 全部替换为 ILogger 结构化日志,并按错误/警告/信息分级”,就把过去要写一篇手册的工作完成了:它会自动补 using、改造构造函数、生成模板字符串参数化日志,最后还能比对风格是否与 SysAppController 一致。
3.5 文档同步:让代码和说明书不再各说各话
ClearAllBadge 改造之后,《Redis 发布订阅推送方案》《菜单角标功能-使用说明》都需要更新。Qoder 能在一次任务里识别出所有受影响章节(架构图、流程、数据结构、消息体、API、前端集成),顺手把 SignalR Hub 接口与 Hub<IMenuBadgeHub> 的关系也讲清楚,避免“代码改了,文档没改”的经典坑。
四、印象深刻的两个细节
4.1 ICache 抽象不能直接做发布订阅
项目里早有一层 ICache 缓存抽象,最初我想直接复用它做 Pub/Sub。Qoder 在阅读现有实现后明确指出:ICache 仅暴露读写接口,没有订阅 API,必须新建 RedisService 直接持有ConnectionMultiplexer 才能调用 ISubscriber。这个判断帮我避开了一次错误的抽象渗透,也让 RedisBadgeSubscribeHost 拥有了干净的依赖结构。
4.2 配置开关与后台服务条件注册
在做开关化时,我希望未启用菜单角标的部署里完全不要起后台订阅服务。Qoder 提议用条件 AddHostedService 注册 + 在 BadgePublishService 入口做开关短路,二者结合让“关掉就当没有”这件事变得彻底——既不占线程,也不会因为缺 Redis 配置而启动失败。
五、心得体会
把 Qoder 当“架构同事”而不是“代码补全”:先和它对齐方案再下手,比让它“顺嘴写一段”有价值得多。
“一次说清、一次到位”:把约束(不落库、可开关、文档同步、日志规范)一次性讲明,Qoder 的产出更接近可合并的 PR。
信任它的检索能力,少给提示,多给目标:它在大型仓库里跨模块定位的效率往往比我手敲 grep 高。
保留人类的最终判断:模型给出的方案是“候选”,是否引入新依赖、是否破坏既有抽象,仍由我决定。
把记忆当资产:每完成一个里程碑就让它记下来,下一次做相邻功能时,启动成本几乎为零。
六、结语
菜单角标功能从一个红点演变为全局化、可开关、可观测、文档完备的工程化模块,这一过程离不开精工智能内部 AI 辅助开发工具的全程协作。它并未越俎代庖去做架构决策,却将我从繁复的代码检索、文档撰写、日志比对中解脱出来,让我能集中精力深耕 WMS、MES、APS 及 智能物流 系统的业务逻辑设计与架构优化。这正是精工智能软件开发日常的缩影——系统不止于上线诞生,更在于持续维护与反复迭代。日复一日,我们通过一次次看似细微的调整,让软件功能更贴合车间现场;年复一年,我们通过一次次扎实的版本演进,让数字化工厂的底座愈发稳固。AI 辅助开发的意义,从不是替代人的思考,而是让我们成为更专注、更深入业务本质的开发者,从而让精工智能的每一套系统,都在时间的打磨中沉淀出真正的生命力。










































































































