JIRA插件开发实战:CSV批量导入创建Issue的完整实现
简介专为JIRA定制的一款批量建单插件允许普通用户借助CSV文件一次创建多个问题免去逐条手动录入的繁琐。所有问题均基于当前用户权限创建并严格校验必填字段与业务约束相比官方导入器更贴合实际配置要求适合需要高频提交工单的团队或JIRA二次开发者。压缩包共93个文件以32个Java源码为主体辅以14个CSV示例数据、11个VM页面模板、6个JS与6个XML配置文件另有PSD设计源图与CSS样式整体约11.99MB。目前已有725人学习下载内容包含完整Maven工程结构、测试资源及marketing素材可直接编译部署或作为插件开发范本。通过阅读源码与CSV样例可快速掌握JIRA问题字段配置、校验逻辑及REST/API集成思路为批量导入场景提供可复用的落地参考。1. 这个插件解决的是什么场景权限收紧后的批量建单如果你的团队在用 JIRA 管迭代你会很快遇到一个矛盾管理员有批量导入问题的权限但真正每天要提单、维护需求池的往往是普通开发、测试和产品运营。这些普通用户没有 JIRA 管理后台的 bulk 操作入口也没法用 Excel 一次性导入几十条 issue。于是最常见的情况是——大家把需求写在共享表格里管理员收到表格后再一条条手打进 JIRA费时间不说误粘贴、漏行、字段填错简直是家常便饭。这个插件要做的就是把「收集表格」和「落地 issue」打通启动插件后普通用户可以在 JIRA 的项目页面里直接上传一个 CSV 文件配置文件按约定放好系统批量读取、逐行校验、自动创建 issue并且把每条导入的结果写回一张记录表。它的适用对象很明确就是那些没有管理员后台权限、但需要批量建单的一线业务同学而项目里涉及到的 JIRA API 调用、CSV 解析、异常回滚和结果回执也是你在做一个完整的 JIRA 插件集成时绕不开的骨架代码。下文按「项目结构 - API 调用 - CSV 解析 - 避坑 - 改造」的顺序把这个插件从头拆到尾。2. 插件架构与项目结构一个普通 JIRA 插件的完整骨架2.1 与 JIRA 的集成方式JIRA 插件通常有两种形态一种是跑在 JIRA 服务端内部的 Java 插件使用 Atlassian SDK 开发打成 jar 上传安装另一种是通过 REST API 外部调用的独立服务。这个项目属于前者它以 OSGi bundle 的方式部署到 JIRA 中运行时调用的是 JIRA 内部的 Java API 和 Active Objects 数据库表而不是走 HTTP 去请求自己的接口。这么选的直接好处是用户权限可以直接复用 JIRA 的User与ProjectPermission体系不需要自己再做一套登录和授权另外插件能直接从当前登录用户上下文里拿到ApplicationUser对象CSV 里的 reporter 配置也可以和真实用户做比对校验。插件在一个工程里拆成了三个职责模块.java源码层、atlassian-plugin.xml注册层、js前端入口层和数据库迁移文件层。源码里最核心的接口是BulkCreateService它接收一个 CSV 文件流、一个项目 Key 和当前用户返回一个包含成功数、失败数和每条错误原因的结果对象。前端部分是用 JIRA 的 Web Panel 或 Servlet 提供上传入口点击上传后文件流被提交到后台 Servlet再由BulkCreateService调度解析器和 issue 创建器。2.2 目录结构与模块职责拆开工程目录看每个包负责的事情非常清楚src/main/java/ com/example/bulkcreate/ servlet/ UploadServlet.java // 接收前端上传的 CSV 文件 service/ BulkCreateService.java // 协调解析与创建返回结果集 IssueCreateService.java // 单条 issue 创建封装 JIRA API csv/ CsvParser.java // 解析 CSV生成行对象 CsvRow.java // 单行数据的字段模型 model/ BulkCreateResult.java // 结果汇总模型 ImportError.java // 单条失败原因模型 src/main/resources/ atlassian-plugin.xml // 插件描述符注册 servlet/AP/权限 js/ bulk-create.js // 前端逻辑文件选择、上传、结果展示 css/ bulk-create.css db/ create-records-table.xml // Active Objects 建表迁移文件从结构上可以看到这个插件没有把代码堆在一个类里而是把「上传入口」「解析器」「业务服务」拆开。这样做的目的很直接如果你以后想增加 Excel 格式导入只需要在service层加一个ExcelParser再在BulkCreateService里做一个格式判断前端和 issue 创建逻辑都不用动。同样如果你想把导入历史存进 JIRA 的数据库以便复查可以直接沿用BulkCreateRecord这个 Active Objects 实体。2.3 插件描述符 atlassian-plugin.xmlatlassian-plugin.xml是 JIRA 插件能否被识别和授权的前提。关键配置有两块一是定义了前端资源web-resource二是把UploadServlet注册成了可访问的 URL同时还声明了权限验证方式。这里贴出核心部分atlassian-plugin keycom.example.bulkcreate nameBulk Create Issues plugin-info descriptionCSV batch create issues for JIRA/description vendor-nameExample/vendor-name version1.0.0/version /plugin-info servlet keyupload-servlet nameUpload Servlet url-pattern/bulk-create/upload/url-pattern descriptionHandle CSV upload/description /servlet web-resource keybulk-create-resources resource typedownload namebulk-create.js location/js/bulk-create.js/ resource typedownload namebulk-create.css location/css/bulk-create.css/ contextjira.project/context /web-resource /atlassian-pluginweb-resource里的context决定前端资源出现在哪个页面jira.project表示只出现在项目页面这样用户进入具体项目后可以直接看到「批量导入」入口。servlet的url-pattern必须写完整路径建议带插件自己的前缀避免和别的插件冲突。servlet默认没有做额外登录校验因为它跑在 JIRA 域内JIRA 自身的 session 会先过滤掉未登录请求但插件内部仍然要查一遍当前用户对目标项目的建单权限这部分逻辑在IssueCreateService里完成。3. 核心模块拆解一次 CSV 导入从上传到 issue 落库的完整链路3.1 前端触发上传文件并提交到 Servlet前端的入口是一个简单的表单。用户在项目页面点击「批量导入」后bulk-create.js读取选中的 CSV 文件用 FormData 把文件流直接 POST 给/bulk-create/upload并在请求参数里带上目标projectKey。这里没有用 AJAX 轮询或分片上传因为 CSV 文件一般不会很大几 MB 以内一次提交基本不会有超时问题。const uploadCsv (file, projectKey) { const formData new FormData(); formData.append(file, file); formData.append(projectKey, projectKey); fetch(/rest/bulk-create/1.0/upload, { method: POST, body: formData }) .then(res res.json()) .then(result renderResult(result)) .catch(err alert(上传失败${err.message})); };这个接口路径里的/rest/前缀不是 JIRA REST API而是插件自己注册的 servlet 别名路径实际路由由插件 key 和 url-pattern 拼接决定。projectKey由页面隐含字段带入写死在前端并不安全所以后端会再次校验当前用户是否具备该项目的CREATE_ISSUES权限。如果校验失败返回 JSON 里的successCount为 0但错误列表会给出权限不足的提示。3.2 后端解析CsvParser 把文本行映射成字段对象CSV 解析是这个项目里最容易翻车、也最值得逐行讲的部分。项目里的CsvParser并没有引入 OpenCSV 这类第三方库而是直接用 BufferedReader 按行读取再用逗号切分。这么做的一个实际考虑是插件运行在 JIRA 的 OSGi 容器中引入额外依赖需要处理包导入声明稍不注意就会出现ClassNotFoundException。自写一个短解析器可控性更高。public ListCsvRow parse(InputStream inputStream) throws IOException { ListCsvRow rows new ArrayList(); BufferedReader reader new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8)); String headerLine reader.readLine(); if (headerLine null) { throw new IllegalArgumentException(CSV 文件为空); } String[] headers headerLine.split(,, -1); String line; int lineNumber 1; while ((line reader.readLine()) ! null) { lineNumber; if (line.trim().isEmpty()) { continue; } String[] values splitCsvLine(line, headers.length); rows.add(new CsvRow(headers, values, lineNumber)); } return rows; }splitCsvLine的处理逻辑要考虑带引号的字段。例如描述里有逗号像新增用户头像, 并增加缓存如果简单按逗号 split 就会错位。项目中采用了一个小状态机遇到双引号时开启「引号内模式」引号内的逗号不切分遇到下一个引号再退出。这能覆盖大多数从 Excel 导出的 CSV 场景。但如果单元格内容包含换行这种逻辑处理不了——规范做法是告知用户先处理掉单元格内的换行符避免解析错行。CsvParser返回的是ListCsvRow每个CsvRow内部持有的是headers和values两个数组以及原始行号。原始行号非常重要后面创建失败时错误信息里能准确告诉用户「第 12 行创建失败」而不是让人去数文件。3.3 单条 issue 创建调用 JIRA Java API 封装创建 issue 的核心在IssueCreateService。这段代码用的是 JIRA 7.x 之后的IssueService接口。有人会问为什么不直接用IssueManager因为IssueService会做权限校验和数据校验直接使用IssueManager相当于绕过了业务规则校验导致创建出来的 issue 可能缺少必填字段或者严重越权。项目中明确使用IssueService这一点对插件这种场景来说是必须的——它要承接普通用户的输入必须走完整校验链。public IssueService.CreateValidationResult createIssue(String projectKey, String summary, String description, String reporter, String priority, ApplicationUser currentUser) { IssueInputParameters params issueService.newIssueInputParameters(); params.setProjectId(projectKey) .setIssueTypeId(10002) .setSummary(summary) .setReporterId(reporter) .setDescription(description) .setPriorityId(priority); CreateValidationResult validationResult issueService.validateCreate(currentUser, params); if (validationResult.isValid()) { issueService.create(currentUser, validationResult); } return validationResult; }setIssueTypeId(10002)里的10002是当前 JIRA 实例中某个 issue 类型的 ID。不同实例里 ID 不同所以项目在配置里把这个值做成了可配置项由插件管理员在后台设定。setReporterId中的 reporter 是从 CSV 传过来的用户名这里有个隐藏风险——如果 CSV 中的 reporter 不是 JIRA 里的有效用户validateCreate会直接校验失败。很多初次使用插件的用户会在这卡住看到一条「用户不存在」的错误。解决办法是在解析阶段就查一次UserUtil发现无效用户直接标记而不是到创建阶段才报。validateCreate返回的CreateValidationResult里带有逐字段的错误信息项目会把validationResult.getErrors()收集起来转成ImportError塞进结果集。这样即使用户一次导入了 200 行每一行的失败原因是「负责人不存在」「摘要为空」「优先级非法」都能在回执里分门别类地看到不至于 200 行里失败 30 行时一脸懵。3.4 批量调度逐条创建 收集错误不中断整体导入BulkCreateService是整个插件的编排者。它的循环逻辑中有一个设计选择值得单独说遇到失败行是立即中断还是继续这个项目的答案是「继续」。因为批量导入的典型场景是一次性处理上百条需求如果第 3 行失败就中断后面 97 条会被阻塞改完 CSV 后又要重新上传整个文件体验极差。相反逐条创建、逐条收集错误最后一次性返回结果用户只需要对照错误列表修改对应行然后重新上传出错的部分。public BulkCreateResult bulkCreate(InputStream csvStream, String projectKey, ApplicationUser user) { ListCsvRow rows csvParser.parse(csvStream); BulkCreateResult result new BulkCreateResult(); if (rows.isEmpty()) { result.addError(文件没有有效数据行); return result; } for (CsvRow row : rows) { try { IssueService.CreateValidationResult validationResult issueCreateService.createIssue( projectKey, row.get(summary), row.get(description), row.get(reporter), row.get(priority), user ); if (validationResult.isValid()) { result.incrementSuccess(); } else { MapString, String errors validationResult.getErrors(); result.addError(new ImportError(row.getLineNumber(), errors.toString())); } } catch (Exception e) { result.addError(new ImportError(row.getLineNumber(), e.getMessage())); } } return result; }外层 try-catch 包住单行创建作用是隔离单行异常。即使validateCreate本身因为意外情况抛异常也不会拖垮后续行。有一点要注意这个循环是单线程顺序执行的200 行的耗时大约在几十秒级别。如果将来要支持上千行建议改成线程池分批提交但必须注意 JIRA 的IssueService实现并不是所有版本都线程安全贸然并发可能引入数据一致性问题。4. CSV 格式约定与字段映射导入规则怎么定解析器才不会翻车4.1 第一行必须是表头这个项目约定 CSV 第一行为表头行支持的中文字段名有摘要、描述、负责人、优先级、组件也可以使用英文summary、description、reporter、priority、components。CsvParser把第一行读入headers数组之后用户写配置时可以直接说「把 Excel 的第一行改成这个表头」而不需要理解什么字段映射概念。必须提醒一点CSV 文件的编码必须是 UTF-8。如果用户从 Windows 版 Excel 直接「另存为 CSV」默认生成的是 ANSI 编码用 UTF-8 读取时中文会变成乱码导致创建的 issue 标题出现一堆「测试」之类的内容。项目里对文件编码做了检测在读取前判断 BOM 头遇到非 UTF-8 就直接返回提示而不是用错误数据创建一堆乱码 issue。4.2 支持的自定义映射配置除了使用固定表头之外项目还留了一个进阶能力在插件后台配置一个字段映射 JSON把 CSV 的任意列名映射到 JIRA 的字段 ID。这个设计是为了兼容用户已有的 Excel 模板——每个团队的现成表格列名各不相同有的是「问题描述」有的是「需求明细」如果不支持自定义映射强迫所有人改表头推广阻力会非常大。配置片段如下{ summary: 标题, description: 详细描述, reporter: 提出人, priority: 紧急程度 }解析时CsvRow.get(summary)会先去查映射配置如果配置里把summary指向了真实列名标题就从对应列取值。实现上就是用配置 Map 把表头统一成规范字段名再让IssueCreateService只认规范字段名。这样职责隔离得很清楚解析器只负责「把任意列名变成规范字段」创建服务只关心「从规范字段取值并传给 JIRA API」。4.3 必填字段校验前置CSV 的行内容五花八门空行、多余空格、全角逗号都可能出现。项目在解析后立刻做一次基础体检而不是把脏数据送到 JIRA 那里由 validate 统一报错。基础体检输出几种典型错误摘要列为空、负责人带有前后空格、优先级不存在。这里有一个小技巧private String clean(String value) { if (value null) { return ; } return value.trim().replace(\uFEFF, ); }\uFEFF是 BOM 字符在很多从 Excel 导出的 CSV 中第一行第一个字段前面会带着这个隐藏字符。如果不清理第一行创建的 issue 标题前面会多出一个不可见字符JIRA 上看不出来但搜索时就是匹配不到。加上replace(\uFEFF, )之后这个问题被彻底解决。我从维护类似插件的血泪经验里总结出这条凡是用户上传的文件永远先清 BOM、清首尾空格、统一换行符再做业务校验。5. 常见问题与避坑记录插件装好、文件传对了依然可能翻车的几个地方5.1 上传文件 404Servlet 路径和 alassian-plugin.xml 不一致现象前端页面能正常打开但点击上传后请求返回 404Network 面板里看到请求地址是/bulk-create/upload后台日志也不见打印任何内容。原因atlassian-plugin.xml中url-pattern/bulk-create/upload/url-pattern注册的路径在运行时会被加上插件上下文前缀实际可访问路径通常是/rest/bulk-create/1.0/upload这种形式但具体前缀取决于插件 key 和rest还是servlet的声明方式。如果前端fetch的路径和后端实际注册路径不一致请求自然到不了 Servlet。解决在插件启动后先在浏览器里访问http://jira-address/rest/bulk-create/1.0/upload确认能否返回 405 或错误 JSON确认路径后再把前端fetch的地址和后端url-pattern改成一致。建议直接把url-pattern固定为/bulk-create/upload省得每次记上下文。5.2 Active Objects 表没有自动创建现象插件日志报net.java.ao.ActiveObjectsException: Table bulk_create_record not found。原因这个插件在记录导入历史时依赖 Active Objects而 AO 表需要专门的迁移文件在插件启动时执行建表。如果你直接把create-records-table.xml放在db目录但atlassian-plugin.xml里没有声明对应的ao配置表就不会创建。解决在插件描述符里补上 Active Objects 配置保证迁移文件在插件安装后被自动执行。配置示例ao keyao-module entitycom.example.bulkcreate.model.BulkCreateRecord/entity /ao5.3 CSV 第一行字段被吞掉现象CSV 一共 101 行数据导入后只创建了 100 条 issue第一条始终不见。原因第一行的表头如果带 BOM并且解析器在readLine()时直接把 BOM 当成了表头内容的一部分就会出现第一行的列名错位——比如summary变成了\uFEFFsummary后续row.get(summary)匹配不到列名返回 null但该行不会报错而是被跳过。解决在save文件时检测并剥离 BOM同时配置 UTF-8 无 BOM 格式输出如果用户已上传带 BOM 文件解析器里也做一次判断。上文clean()方法里的replace(\uFEFF, )就是干这个用的。5.4 多行描述导致错行现象CSV 里某条描述文本包含换行导入后原本 3 条 issue 变成了 5 条后面所有数据错位。原因CSV 规范中包含换行的字段必须用双引号包裹大多数导出工具也会这么做但用户手工复制粘贴时很容易漏掉引号。解析器按行读取碰到「裸换行」就自动拆成两行于是后面的列全部错位。解决在解析器里增加一个状态判断——如果当前行在引号未闭合状态下结束继续读下一行并拼接直到引号闭合。这能兼容大多数带引号的换行数据。对于没有引号包裹的裸换行直接报行号提示用户修改。也可以借鉴成熟 CSV 库的实现把解析器重写得更稳健。5.5 负责人是显示名而不是用户名现象CSV 里「负责人」写的是「张三」而不是zhangsan创建时提示用户不存在。原因JIRA 内部存储和 API 识别用户的唯一标识是用户名或accountIdCSV 里写的是显示名。validateCreate的setReporterId只认用户名。解决在解析后增加一个用户映射步骤——用UserUtil按显示名模糊查找用户找到后替换成用户名找不到就把这一行标记为失败并提示「负责人张三未匹配到 JIRA 用户」。在插件后台再做一层「CSV 显示名 - JIRA 用户名」的映射维护效果会更好。6. 二次开发给插件加上「只导入新增行」和「导入前预览」能力如果你要基于这个项目做二次开发建议先改两个地方一是把「预览」能力加进来二是把「增量导入」做进去。这两个是最实用的改造点因为现阶段插件是「上传即执行」用户只有在结果回执里才知道哪些行失败整个流程是黑匣子。6.1 改造一导入前预览在BulkCreateService里加一个preview(InputStream, projectKey)方法它只做解析、字段校验和用户校验不调用issueService.create。返回一个预检结果列表前端把它渲染成一个表格用户看到哪行有问题当场改完再上传而不是上传后才知道翻车。实现上只需要把bulkCreate里的createIssue调用换成validateOnly并在IssueCreateService里加一个空实现的createIssue(..., boolean validateOnly)。public boolean isValidateOnly() { return false; }这样改还有一个好处插件未来接 JIRA Automation 或 CI 做扫表导入时可以先跑 preview 确认数据质量再执行真正导入。6.2 改造二增量导入增量导入的判断依据是「摘要 项目 Key 创建人」唯一索引。在导入前查一次 JIRA 的IssueService或直接 SQL 查jiraissue表插件内部有 db 访问能力把现有 issue 的摘要拉出来做成一个 Set解析 CSV 时如果某行摘要已经存在就跳过并标记为重复。SetString existingSummaries loadExistingSummaries(projectKey); rows.stream() .filter(row - !existingSummaries.contains(row.get(summary))) .forEach(row - createIssue(projectKey, row));注意 JQL 查询量不能太大一次性查出项目全部 issue 几百条还好几千条建议分页拉取。增量导入能避免用户每隔几天重新上传一次全量 CSV 时的重复建单问题。6.3 改造三结果落库成 AO 表项目里虽然有BulkCreateRecord实体但默认没把每次导入历史写进表里。建议把每次上传的文件名、项目 Key、成功数、失败数、耗时和操作人记录进 Active Objects 表。这样后续既能排查历史问题也能做团队导入量统计还能避免用户重复上传同一文件而不自知。写 AO 表时要注意事务边界逐条 issue 创建过程中每个issueService.create是独立事务不能让一条失败回滚之前已创建成功的 50 条所以结果落库必须在整体循环结束后执行。6.4 验证方式与收尾二次开发完成后最慢但可靠的验证方法是搭一个本地 JIRA用 SDK 的atlas-run或者 Docker 镜像安装插件然后准备三份 CSV全量正确、部分错误、包含重复行分别跑测试。重点观察结果回执里的行号和错误信息是否准确定位到了 CSV 的原始行。跑完这些场景插件的健壮性基本能顶住一线用户的实际使用。我早年做类似导入工具时吃过「没有预览直接跑批」的亏——一次导入造成了上百条脏数据后来维护数据花了一个周末。从那以后我每次给这类工具加新功能前都强制自己先跑一遍「全量 - 部分错误 - 全错误」三种测试文件确认回执信息没有歧义才敢放给用户。希望这篇解析能帮你在接手团队内部工具类插件时少踩几个类似的坑。本文还有配套的精品资源点击获取

相关新闻

单辅助源校正阵列误差:MUSIC谱峰偏移修复与DOA估计实战

单辅助源校正阵列误差:MUSIC谱峰偏移修复与DOA估计实战

简介:面向阵列信号处理与波达方向估计领域的学习者和研究人员,压缩包围绕单辅助源校正阵列误差给出了一套可运行的MATLAB实现和毕设参考程序。该主题聚焦阵列误差对波达方向估计精度的显著影响,核心思路是引入一个位置与特性已知的辅助源&…

2026/10/18 9:30:30 阅读更多 →
工业机器人结构设计实战:从关节构型到系统调试

工业机器人结构设计实战:从关节构型到系统调试

1. 结构设计全局观:先想清楚机器人是什么,再谈画图工业机器人结构设计,听起来是个非常高门槛的领域,但这些年因为3D打印、开源控制系统和轻量型机器人套件的普及,很多创客、自动化设备公司和高校实验室都开始自己造机械…

2026/10/18 9:30:30 阅读更多 →
FPGA驱动高速DAC的确定性时序设计与工程落地

FPGA驱动高速DAC的确定性时序设计与工程落地

简介:本资源面向FPGA开发初学者与数字模拟混合系统设计工程师,提供DAC902~908系列高精度数模转换芯片的完整技术支撑与Cyclone IV E平台可落地驱动方案。内容涵盖官方Datasheet、模块化Verilog驱动源码、FPGA测试例程、原理图及详细使用说明书&#xff0…

2026/10/18 9:30:30 阅读更多 →

最新新闻

AI日报内容策划与运营:从信息筛选到价值传递的完整指南

AI日报内容策划与运营:从信息筛选到价值传递的完整指南

1. 当“日报”变成一种产品:AI日报的定位与内容框架“AI 日报”这四个字看起来简单,但真正动手做过内容产品的人都知道,日报类内容是最难做的品类之一。它不像深度长文可以靠一个核心观点撑起全文,也不像教程可以靠步骤的完整性获…

2026/10/18 12:33:28 阅读更多 →
VB.NET实现非均匀B样条曲线:算法解析与交互绘制工具

VB.NET实现非均匀B样条曲线:算法解析与交互绘制工具

简介:基于VB.NET实现的非均匀B样条(NURBS)曲线示例工程,面向计算机图形学与CAD建模方向的开发者,解决自定义曲线生成与控制点编辑问题。源码覆盖控制点、权重、Knot向量定义,以及曲线求值、节点插入和逆算等…

2026/10/18 12:33:28 阅读更多 →
PHP生成Excel:基于PhpSpreadsheet封装库实现xlsx导出详解

PHP生成Excel:基于PhpSpreadsheet封装库实现xlsx导出详解

简介:这是一份面向PHP初学者的Excel导出示例源码包,演示了通过PHPExcel或PhpSpreadsheet类库在服务端生成Excel文件的基础流程。资源解压后共2个文件,包括一个demo.php主程序和一个jpg图片文件,整个rar压缩包约30KB。demo.php中包…

2026/10/18 12:33:28 阅读更多 →
Python OpenCV实现金属锈蚀量化检测与HSV颜色空间分析

Python OpenCV实现金属锈蚀量化检测与HSV颜色空间分析

简介:这是一份面向材料科学实验人员与计算机视觉初学者的金属表面锈蚀检测实践代码包,基于Python实现轻量级图像处理算法,解决金属腐蚀程度量化评估难题。项目采用颜色空间分析技术对固定视角拍摄的金属样本图像进行锈斑区域分割与像素级统计…

2026/10/18 12:33:28 阅读更多 →
基于React+TypeScript+SVG的图表设计器架构设计与实现

基于React+TypeScript+SVG的图表设计器架构设计与实现

最近在推进一个跨平台系统的图形化展示需求,手头这套内部代号diagram-design的图表设计器项目,从第一行代码到核心链路跑通,前后折腾了接近两个月。中间踩过的坑、推翻过的方案,比我上一个纯后台项目加起来都多。这个项目没有用多…

2026/10/18 12:33:28 阅读更多 →
LangChain核心模块实战:从模型封装到RAG链路构建

LangChain核心模块实战:从模型封装到RAG链路构建

在接触LangChain之前,我一度觉得这类框架不过是把各家大模型API包了一层皮,没什么深度可言。直到某次在公司做内部工具,需要把十几个零散的模型调用、知识库检索、多轮对话服务整合到一个统一入口,硬生生用裸API堆了快两千行胶水代…

2026/10/18 12:32:27 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →