Comp AI CRM 前端 URL 精简实战用 nuqs urlKeys 让分享链接更短更干净【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址: https://gitcode.com/gh_mirrors/crm48/crm本文基于仓库内.agents/skills/nuqs/references/advanced-url-keys.md技能文档讲解 TypeScript/Next.js 应用中使用nuqs的urlKeys选项把冗长的 URL 查询参数名映射为简短键如latitude→lat在不牺牲代码可读性的前提下获得更干净、更易分享、占用带宽更小的链接。读完你将掌握useQueryStates第二参数的urlKeys配置方法、与withDefault/withOptions等链式 API 的协作方式并能参照 Comp AI CRM 仓库apps/app中真实的 nuqs 使用模式落地到自己的列表页、记录面板与弹窗状态同步场景。为什么 URL 参数键也需要“精简”在 Agent 优先的 CRM 这类重度交互的 Web 应用中页面状态大量以 URL 查询参数的形式存在列表的搜索词、分页、排序方向、当前打开的记录面板、时间线 tab、关闭商机原因弹窗……这些状态共同构成一张“可分享的视图快照”。如果每个状态都使用完整的描述性参数名URL 会迅速变得冗长?latitude48.8566longitude2.3522zoomLevel12这类链接存在三个实际问题难以分享与阅读粘贴到邮件、Slack 或即时通讯工具中时一长串语义重复的键名让链接可读性大幅下降占用更多带宽与存储每一次pushState都会把整条 URL 写入浏览器历史日志、埋点与分析系统也会记录完整的查询串容易出现截断/复制错误长参数名放大了人工复制与传输时被截断或改写的风险。nuqs提供的urlKeys正是为这个场景设计的在代码里继续使用描述性变量名在 URL 中则序列化为简短的键名。urlKeys 是什么把“代码名”和“URL 键”解耦urlKeys是useQueryStates的第二个配置参数中的一项useQueryStates(parsers, { urlKeys: { latitude: lat, longitude: lng, zoomLevel: z } })它的语义非常清晰键对象左侧代码中使用的描述性参数名即parsers对象中的 key值对象右侧出现在 URL 中的实际查询参数键。urlKeys只负责键名的映射不改变值的序列化方式——值的编码/解码仍由对应的parseAs*parser 决定。因此你可以为parsers中的每一个 key 单独指定缩写也可以只缩写其中几个。从冗长到精简完整对比示例错误示范冗长的 URL 参数以下代码功能正确但会把完整的参数名暴露在 URL 中use client import { useQueryStates, parseAsFloat, parseAsInteger } from nuqs export default function MapView() { const [coords, setCoords] useQueryStates({ latitude: parseAsFloat.withDefault(0), longitude: parseAsFloat.withDefault(0), zoomLevel: parseAsInteger.withDefault(10) }) // URL: ?latitude48.8566longitude2.3522zoomLevel12 // Long, harder to share, uses more bandwidth return Map {...coords} / }正确示范使用 urlKeys 缩写use client import { useQueryStates, parseAsFloat, parseAsInteger } from nuqs export default function MapView() { const [coords, setCoords] useQueryStates( { latitude: parseAsFloat.withDefault(0), longitude: parseAsFloat.withDefault(0), zoomLevel: parseAsInteger.withDefault(10) }, { urlKeys: { latitude: lat, longitude: lng, zoomLevel: z } } ) // URL: ?lat48.8566lng2.3522z12 // Shorter, cleaner URLs // Code still uses descriptive names console.log(coords.latitude, coords.longitude, coords.zoomLevel) return Map {...coords} / }对比可见URL 由?latitude48.8566longitude2.3522zoomLevel12缩短为?lat48.8566lng2.3522z12组件代码仍然通过coords.latitude、coords.longitude、coords.zoomLevel访问数据可读性零损失setCoords更新状态时nuqs 会自动按urlKeys映射写出短键无需在业务代码中手工拼 URL。urlKeys 的行为细节与注意事项结合nuqs的 parser 体系仓库中大量使用的parseAsString、parseAsInteger、parseAsBoolean、parseAsJson、parseAsStringLiteral、parseAsArrayOf、parseAsNativeArrayOf等见 list-search-params.ts使用urlKeys时有几个要点值得注意1. 只改键名不改序列化urlKeys与 parser 的.withDefault()、.withOptions()相互独立、可以叠加。例如仓库中分页参数配置为page: parseAsInteger.withDefault(1).withOptions({ history: push })如果为它加上urlKeys: { page: p }URL 中会变成?p2而history: push的入栈行为、默认值1的省略逻辑都不受影响。2. 默认值不会出现在 URL 中parseAsInteger.withDefault(10)意味着当z的值为默认值10时URL 中不会出现z10链接可以进一步缩短。这解释了为什么示例中的“正确版本”只包含z12一个 zoom 参数。3. 使用null清除参数setCoords时传入null会从 URL 中移除对应键。这一点在仓库的 record-stack.ts 中有典型用法关闭记录面板时一次把record、tab、add、thread、fields、field等多个参数全部置null以清空整组状态。4. 键名映射是静态的需避免冲突urlKeys是编译期写死的映射表不是运行时动态计算。设计缩写时应确保彼此唯一如latitude→lat、longitude→lng并避免与页面中其他模块的查询参数键撞车——毕竟 URL 是全局命名空间。5. 改动是破坏性的把参数名从latitude改为lat后任何分享出去的旧链接?latitude48.8566将不再被解析。若你的页面已有对外分享的链接或收藏的 URL需要评估兼容性。6. 数组与对象参数同样适用urlKeys对parseAsArrayOf、parseAsNativeArrayOf、parseAsJson等复杂 parser 同样生效——它只重命名 URL 中的键值的编码格式如逗号分隔、JSON 字符串保持不变。与 Server 端 createLoader 的配合nuqs的一大优势是客户端状态与服务端渲染共享同一组 parser。仓库中的 list-search-params.ts 展示了这一模式return { config: { ...config, defaultSort, defaultDir, pageSize }, parsers, load: createLoader(parsers), toInput, defaultInput: () toInput(defaults), };其中parsers既被客户端 use-table-query.ts 的useQueryStates(parsers)使用也被服务端createLoader(parsers)用于在 RSC 中读取并校验查询参数。要点urlKeys应作为共享配置的一部分。由于 parser 集合含urlKeys映射同时驱动客户端渲染与服务端读取只要你在parsers定义处统一配置urlKeys或把urlKeys传入useQueryStates时保持两端一致服务端createLoader就能正确识别短键。在 Comp AI CRM 中searchParsers、record-stack的params、stage-change的closeReasonParams都是这种“集中定义、多处消费”的结构天然适合在定义处补充urlKeys。在 Comp AI CRM 仓库中的实际应用场景先说明事实在本次检索的仓库源码中暂未发现urlKeys的实际使用对urlKeys的全文搜索无匹配结果因此以下为基于官方 API 语义、结合仓库真实代码结构给出的优化示范并非仓库现状描述。仓库apps/app的 package.json 声明了nuqs: ^2.8.9并已在多个模块使用useQueryStates列表页搜索与分页list-search-params.ts 定义searchParsersq、page、fields、archivedlist-search.tsx 与 use-table-query.ts 消费它们记录面板栈record-stack.ts 用record/tab/add/thread/fields/field描述打开的记录、tab、表单与时间线并通过setParams(..., { history })控制 push/replace关闭商机原因弹窗stage-change.tsx 用closing、closingStage两个参数承载弹窗状态。以record-stack为例为 URL 键做一次“瘦身”的示意const params { record: parseAsArrayOf(parseAsString, ,).withDefault([]), tab: parseAsString, add: parseAsStringLiteral(RECORD_FORMS), thread: parseAsString, fields: parseAsStringLiteral(RECORD_KINDS), field: parseAsString, [TIMELINE_PARAM]: timelineTabParser, } // 在消费处使用 urlKeys 缩写 URL 键 useQueryStates(params, { urlKeys: { record: r, tab: t, add: a, thread: th, fields: f, field: fd, }, })改造后一个“打开某公司的记录并切到时间线”的链接可能从?recordcompany:acmetabtimeline缩短为?rcompany:acmettimeline而组件内recordKey(ref)、stack等逻辑完全无需改动。收益总结与适用边界建议使用urlKeys的场景参数名较长如latitude、zoomLevel、closingStage且 URL 会频繁被分享、复制、写入埋点或浏览器历史单页承载多组状态搜索 分页 筛选 面板键名叠加后 URL 明显超长期望对外输出的链接保持稳定简洁同时内部代码继续使用语义化命名。不必过度使用的场景参数名本身已经很短如q、id缩写收益趋近于零纯内部路由、不会对外分享、也没有历史记录长度压力的页面页面 URL 结构需要保持稳定以便缓存/埋点按模式匹配的场景——此时引入缩写反而增加维护成本。urlKeys的核心理念可以概括为一句话让 URL 面向分享者让变量名面向开发者。在 Comp AI CRM 这种以数据表格、记录面板和多状态弹窗为主界面的应用中它是提升链接可用性、降低带宽与历史记录开销的低成本手段——一次集中配置即可让所有通过useQueryStates读写 URL 的页面同时受益。【免费下载链接】crmComp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM.项目地址: https://gitcode.com/gh_mirrors/crm48/crm创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
【DvAdmin】MySQL数据每日备份 在管理网站时,定期备份网站文件和数据库至关重要,能够有效预防数据丢失,尤其是在遇到服务器故障或网络攻击的情况下。宝塔面板提供了简单易用的手动和自动备份功能,无需编写复杂脚本,即可实现对网站的全面保护。本文将介绍如何通过宝塔面板进行手动与自动备份,帮助管理员… · 2026/9/24 13:34:38
1GW 机房:Anthropic 降本 40% 的底气? 模型的价格写在官网上,随时能改;算力的价格写在租约里,一签就是好几年。9 月 23 日,Anthropic 把这两件事同时摆上了台面。
模型那一侧:Opus 5.5 已在亚马逊云、谷歌云和微软 Azure 上线,官方称它在大多数任务上性能接近 Claude Fable 5.1,运行成本比 Opus 5 低 40%,定… · 2026/9/24 13:34:38
Flask 扩展 Migrate 管理迁移数据库 使用 Flask 构建 Web 应用时,数据库模型经常处于持续变动之中。每次手动更新数据库结构不仅繁琐,还容易出错。为了解决这个问题,Flask-Migrate 扩展应运而生。它基于 Alembic 实现数据库迁移,结合 Flask-SQLAlchemy 使用,能够自动生成迁移脚本并执行变更,是开发过程中管理… · 2026/9/24 13:34:25
【企业智能体开发】实现任务规划与可控的工具调用 小林的投屏问题进入第二轮:她已经说明使用线缆,服务台查到了适用指引,却在尝试后仍看不到画面。此时如果 Agent 只会“调用下一个工具”,它可能重复检索同一篇资料,甚至在员工未确认时直接建单。真正的任务规划,是把目标拆成有前置条件、有完成证据、有退出路径的少量步骤… · 2026/9/24 14:02:12
【企业智能体开发】管理会话上下文与任务状态 小林已经把“线缆连接、A301、屏幕无信号”说清楚,也按指引试过了。她离开聊天窗口去检查设备,几分钟后回来输入:“还是不行。”如果 Agent 只记得最后四个字,就可能重新询问房间号;如果把整段聊天原样塞回模型,却没有明确的任务状态,也可能误以为已经创建了工单。
本篇… · 2026/9/24 14:02:05
【企业智能体开发】用结构化输出约束智能体决策 演示服务台时,小林说“A301 投屏没有画面”。模型给出一段看似热心的回答:“先问连接方式,查一下设备说明;若不行,就创建工单。”这段话适合人阅读,却不适合程序直接执行:它同时包含追问、查询和写入三个动作,而且没有说明什么时候获得员工确认。
企业 Agent 需要把“… · 2026/9/24 14:02:05
【企业智能体开发】建立测试集与回归评测流程 服务台试点一周后,团队准备更换模型,并改进投屏指引的切分方式。演示对话看起来更自然了,小林的问题却可能出现新错误:原来会先追问连接方式,现在直接推荐不适用步骤;原来会在建单前确认,现在把“帮我处理”误当成同意。没有固定的测试集,每一次“优化”都可能悄悄破坏… · 2026/9/24 14:02:05
【企业智能体开发】设计可替换的模型调用适配层 小林的投屏求助已经能在演示循环里走完“追问—查指引—回答”。试点时,团队却遇到一个常见变化:同一套服务台,有些请求需要较强的理解能力,有些只需完成简单分类;某个模型接口维护时,还需要切换到备用服务。如果业务代码里到处都是某家模型的请求字段、消息格式和错误码… · 2026/9/24 14:02:05
【企业智能体开发】用 Python 实现最小智能体执行循环 小林在会议室提交“投屏没有画面”之后,服务台先问连接方式;她回答“线缆连接”后,系统才查适用指引并给出建议。这不是一次模型调用就能完成的问答,而是一段根据中间结果改变下一步的任务。若只把全部历史对话反复塞给模型,程序仍然不知道何时该追问、何时能调用工具、何… · 2026/9/24 14:02:05
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44