丸子·张丨OnesZhang | 一个小小IT工程师 - 丸子
type: channel
link: https://oneszhang.com/author/1/
description: 丸子
items: [泛微 EC9] WorkflowToModeFormulaUtil 公式工具类使用指南
items: [泛微 EC9] 流程查看权限校验路径分析
items: [泛微 Ecology10] E10使用ESB动作流&连接器使用doCreateRequest创建流程接口
items: [泛微 EC9] OA 附件 Base64 误杀事件排查复盘
items: [泛微EC9] 丸子喂饭篇: restful 新建流程接口详解(/api/workflow/paService/doCreateRequest)
items: 泛微E10国际化与日期字段 displayFormat 冲突排查实录
items: 泛微E10 "对不起，没有使用权限" 解决办法
items: 博客新纪元：我的 AI 写手上线了
items: OpenClaw 配置 AI 模型：5 分钟搞定 User-Agent 问题
items: 测试文章 - OpenClaw 自动发布

[泛微 EC9] WorkflowToModeFormulaUtil 公式工具类使用指南
type: item
date: 2026-07-05T20:10:00+08:00
description: 泛微OA E9 中用于工作流字段公式转换的工具类，所有方法 public static，零外部依赖，可独立使用。 适用场景 向第三方系统动态传参时，字段类型不一致需要公式转换；脱离流程上下文做数值/日期/文本计算。 类信息项目说明包路径weaver.formmode.interfaces.action类名WorkflowToModeFormulaUtil依赖无外部依赖，纯 Java 工具类返回值所有方法返回 String，异常返回 ""方法一览 日期类数值类文本类 year — 提取年份WorkflowToModeFormulaUtil.year("2025-06-01") // → "2025" WorkflowToModeFormulaUtil.year("2025/6/1") // → "2025" WorkflowToModeFormulaUtil.year("") // → ""month — 提取月份（1-12）WorkflowToModeFormulaUtil.month("2025-06-01") // → "6" WorkflowToModeFormulaUtil.month("2025-12-31") // → "12" 注意：返回 1-12，不是 Calendar 的 0-11。 day — 提取日WorkflowToModeFormulaUtil.day("2025-06-15") // → "15" WorkflowToModeFormulaUtil.day("2025-06-05") // → "5"days — 两日期天数差// 两个重载：String 参数 / List 参数 WorkflowToModeFormulaUtil.days("2025-01-01", "2025-06-01") // → "151" WorkflowToModeFormulaUtil.days("2025-06-01", "2025-01-01") // → "-151" // List 用法 List<String> dates = Arrays.asList("2025-01-01", "2025-06-01"); WorkflowToModeFormulaUtil.days(dates); // → "151" 支持带时间格式："2025-01-01 08:00:00"，计算时只取日期部分。 datedelta — 日期加减天数WorkflowToModeFormulaUtil.datedelta("2025-06-01", 10) // → "2025-06-11" WorkflowToModeFormulaUtil.datedelta("2025-06-01", -5) // → "2025-05-27" WorkflowToModeFormulaUtil.datedelta("2025-12-31", 1) // → "2026-01-01"sum — 求和// 可变参数（至少2个） WorkflowToModeFormulaUtil.sum(1.0, 2.0, 3.0) // → "6.0" // List 参数 List<Double> list = Arrays.asList(100.5, 200.3, 300.2); WorkflowToModeFormulaUtil.sum(list); // → "601.0"abs — 绝对值WorkflowToModeFormulaUtil.abs(-123.45) // → "123.45" WorkflowToModeFormulaUtil.abs(123.45) // → "123.45"average — 平均值// 可变参数（至少2个） WorkflowToModeFormulaUtil.average(2.0, 4.0) // → "3.0" // List 参数 List<Double> list = Arrays.asList(100.0, 200.0, 300.0); WorkflowToModeFormulaUtil.average(list); // → "200.0" average 的可变参数版本计算分母是 num3.length + 2，传 2 个以上参数时注意。 concatenate — 字符串拼接// 可变参数（至少2个） WorkflowToModeFormulaUtil.concatenate("姓名:", "张三", " 工号:", "001") // → "姓名:张三 工号:001" // List 参数 List<String> list = Arrays.asList("A", "B", "C"); Work…

[泛微 EC9] 流程查看权限校验路径分析
type: item
date: 2026-06-25T11:08:00+08:00
description: 概述通过 ViewRequestForwardSPA.jsp 查看目标流程时，系统在 RequestAuthenticationService.verifyRequest() 中进行权限校验。共有 14 条校验路径，按优先级依次检查，命中任意一条即授予查看权限。核心入口JSP入口: workflow/request/ViewRequestForwardSPA.jspSPA路由: /spa/workflow/static4form/index.html?_rdm={timestamp}#/main/workflow/req?{params}JSP路由: /workflow/request/ViewRequest.jsp?haveVerifyForward=true&{params}权限校验类: com.api.workflow.service.RequestAuthenticationService校验方法: verifyRequest()路由差异路由权限校验方式authStr参数desrequestid参数SPA (LoadParamCmd)RequestAuthenticationService.verify()有效不需要JSP (ViewRequest.jsp)Session机制 (resrequestid{N})不用于校验URL参数被忽略，仅读Session全部校验路径（按简单到复杂排列）1. 共享权限（无条件检查，0个参数）// RequestAuthenticationService if (getRequestWfShareRight(info, requestid)) { return true; }URL: ViewRequestForwardSPA.jsp?requestid=1908315条件: 用户对目标流程有共享权限校验逻辑: WFShareAuthorization.getWorkflowShareJurisdiction(requestid, user)前置条件: 管理员或其他操作人已将流程共享给当前用户参数: 0个额外参数2. 操作者权限（无条件检查，0个参数）// RequestAuthenticationService if (getRequestUserRight(info, requestid)) { return true; }URL: ViewRequestForwardSPA.jsp?requestid=1908315条件: 用户是目标流程的当前操作人校验逻辑: 查询 workflow_currentoperator 表前置条件: 用户在流程的当前操作人列表中参数: 0个额外参数3. 创建者权限（SPA层额外检查，0个参数）// LoadParamCmd if (creater == userid && creatertype == usertype) { canview = true; }URL: ViewRequestForwardSPA.jsp?requestid=1908315条件: 用户是流程创建人校验逻辑: 比对 workflow_requestbase.creater 字段前置条件: 用户创建了该流程参数: 0个额外参数4. 监控权限（1个参数）// RequestAuthenticationService if (ismonitor == 1 && getRequestMonitorRight(info, requestid)) { return true; }URL: ViewRequestForwardSPA.jsp?requestid=1908315&ismonitor=1条件: 用户是目标流程的监控人校验逻辑: WFUrgerManager.getMonitorViewRight(requestid, userid)前置条件: 流程配置了监控人，且当前用户在监控人列表中参数: 1个（ismonitor=1）5. 督办权限（1个参数）// RequestAuthenticationService if (urger == 1 && getRequestUrgerRight(info, requestid)) { return true; }URL: ViewRequestForwardSPA.jsp?requestid=1908315&urger=1条件: 用户是目标流程的督办人校验逻辑: SuperviseManagerBiz.hasWorkflowViewRight(user, requestid)前置条件: 流程配置了督办人，且当前用户在督办人列表中参数: 1个（urger=1）6. 干预权限（1个参数）// RequestAuthenticationSe…

[泛微 Ecology10] E10使用ESB动作流&连接器使用doCreateRequest创建流程接口
type: item
date: 2026-06-18T10:28:00+08:00
description: 写在前面 本方案仅出于丸子当时自己的即时想法，并非官方最佳实践方案。仅供技术交流参考，如你有更优雅的实现方式，欢迎随时交流！ E10 多租户互通方案中，通过 E10 开放平台连接器，可以实现当前组织与 E10 其他组织的数据互通。本文将重点介绍如何使用 ESB 动作流配合 doCreateRequest 接口实现跨组织的流程创建。1. 准备阶段在开始配置前，请确保已查阅官方开发文档。 接口基础信息 接口地址：http://url:port/papi/openapi/api/workflow/core/paService/v1/doCreateRequesthttp://url:port/papi/openapi/api/workflow/core/paService/v2/doCreateRequest前置要求： 参照 "后台管理中心" -> "开放平台" -> "接口示例"，完成应用的创建与鉴权配置。 ESB 连接器配置进入 "ESB 中心" -> "内置" -> "E10 开放平台" 。新建“连接”以及“接口”（注：系统默认并未内置新建流程接口，需要自行创建）。创建字段映射表准备好源流程（触发源）与目标流程（被写入目标）为了保证后续代码的通用性与可维护性，强烈建议维护一张映射表。2. ESB 动作流构建整个动作流的核心逻辑主要由“流程触发”与“自定义逻辑计算”组成。流程逻辑图核心自定义函数在此处使用 解析JSON/XML文本 节点，配置自定义函数 buildMappingResult：JavaScriptfunction buildMappingResult(flowDataStr, mappingStr, sourceKeyCol, targetKeyCol, specialTypeCol) { var flowData = JSON.parse(flowDataStr); var mapping = JSON.parse(mappingStr); var result = []; for (var i = 0; i < mapping.length; i++) { var mapItem = mapping[i]; var sourceId = mapItem[sourceKeyCol]; var targetId = mapItem[targetKeyCol]; var specialType = mapItem[specialTypeCol]; if (!sourceId || !targetId) continue; // 逻辑处理 if (flowData[sourceId] !== undefined) { var mainRow = { "targetId": targetId, "targetValue": flowData[sourceId] }; if (specialType !== undefined) mainRow["specialType"] = specialType; result.push(mainRow); } else { // 明细表处理 for (var key in flowData) { if (flowData.hasOwnProperty(key)) { var fieldData = flowData[key]; if (Object.prototype.toString.call(fieldData) === '[object Array]') { for (var j = 0; j < fieldData.length; j++) { var detailItem = fieldData[j]; if (Object.prototype.toString.call(detailItem) === '[object Object]' && detailItem[sourceId] !== undefined) { var detailRow = { "targetId": targetId, "targetValue": detailItem[sourceId] }; if (specialType !== undefined) detailRow["specialType"] = specialType; if (detailItem["dataIndex"] !== undefined) detailRow["dataIndex"] = detailItem["dataIndex"]; result.push(detailRow); } } } } } } } return JSON.stringify(result); }3. 创建流程实例：核心参数解析在“创…

[泛微 EC9] OA 附件 Base64 误杀事件排查复盘
type: item
date: 2026-06-09T07:02:00+08:00
description: 一、事件背景近期在测试 OA 创建流程接口（/api/workflow/paService/doCreateRequest）时，遇到一个比较隐蔽的问题：业务侧传入的附件内容采用 base64 方式提交，接口返回 PARAM_ERROR，错误信息指向“生成附件失败”。表面上看，这类问题通常会先怀疑以下几种方向：图片文件本身损坏base64 转换过程出错请求体过长导致截断OA 附件服务解析失败但这次问题的特殊之处在于：同一张图片在本地可以正常解码base64 长度、补位、MD5 都正常错误并不是稳定出现在所有图片上，而是只出现在部分附件内容上这意味着问题不太像“通用性格式错误”，更像“特定内容触发了某种中间处理逻辑”。二、问题现象业务调用 OA 创建流程接口时，附件字段通过 base64: 前缀方式上传，接口返回类似错误：{ "code": "PARAM_ERROR", "errMsg": { "field_xxx": "生成附件失败,参数为：fieldid:xxxx,annexId:-3,fileValue:[...]" } }从附件服务语义上看，annexId:-3 的含义基本可以理解为：附件内容在进入保存逻辑后，Base64 解码失败。但关键问题是，业务侧原始 base64 在本地验证完全正常。三、第一次排查：先排除“文件坏了”第一步做的是最基础的校验：提取原始请求中的 base64校验长度是否为 4 的倍数检查是否只包含合法 Base64 字符本地执行解码对解码后的文件做 MD5 校验结果很明确：原始 base64 串合法本地可以成功解码解码后的图片与原始附件 MD5 一致也就是说，问题不在业务系统生成附件这一步。四、第二次排查：不是所有 Base64 都失败为了避免被“单个样本”误导，我们做了几组对照实验。1. 安全样例传一个很短、内容简单的 base64，结果成功。2. 含特定片段的样例构造一些很短但包含特定文本片段的 base64，例如：4or+4and+4union+4select+结果发现，这类请求会稳定失败。更关键的是，OA 返回报文中回显出来的附件内容，已经不是原始值，而是被改写成了全角字符，例如：4or+ 变成 4ｏｒ+4and+ 变成 4ａｎｄ+一旦 base64 内部出现全角字符，后续解码必然失败。这一步已经把问题从“附件坏了”收缩到“请求进入 OA 后被改写了”。五、第三次排查：到底是什么条件会触发改写如果只是“出现 or 就失败”，那很多正常图片都应该大量失败，但事实并不是这样。于是我们继续做边界实验，只改变命中关键词左右两边的字符。实验样例如下：会失败：4or+会成功：Aor+会成功：4orA会成功：AorA同样地：会失败：4and+会成功：AandA这说明触发条件不是“只要包含 or / and 就拦截”，而是更接近：当某些敏感关键词左右两边都不是字母时，会被安全规则命中。这类模式与常见 SQL 注入拦截规则高度一致。六、第四次排查：回到真实失败图片做验证为了避免“小样本实验不代表真实图片”的质疑，我们又对真实失败图片做了反向验证。结论如下：原始图片 Base64 上传失败回显内容中，只有其中一处 or 被改写为 ｏｒ这处命中的上下文正好是 4or+然后我们只做一个极小改动，不改整张图片，只改这一处附近的边界字符：原始：4or+ -> 请求失败改成：Aor+ -> 请求成功改成：4orA -> 请求成功这一步的意义非常大，因为它证明：不是图片太大导致失败不是图片整体内容有问题不是 Base64 长度问题不是附件服务偶发异常而是图片 Base64 中某个刚好命中安全规则的片段，触发了请求内容改写。七、最终结论这次事件的根因可以明确归纳为：OA 在接收 application/x-www-form-urlencoded 请求参数时，安全过滤链会对命中的敏感关键词进行全角替换；当附件 base64 恰好包含类似 or、and、union、select 等关键词，并且其左右边界满足规则时，原始 base64 会被污染，最终导致附件解码失败。换句话说：业务系统生成的附件 Base64 没问题图片本身没问题问题发生在 OA 接收请求后的安全处理阶段这是一个典型的“安全规则误杀二进制文本内容”问题。八、为什么这个问题隐蔽这个问题很难第一时间定位，原因有三个：1. 现象看起来像附件服务失败接口只返回“生成附件失败”，很容易让人先怀疑附件服务或图片本身。2. 不是所有附件都失败只有当 Base64 内部恰好出现特定关键词组合时才触发，因此问题呈现出明显的“偶发性”。3. 原始请求侧看不到污染业务侧生成的 Base64 完全正常，真正的问题发生在请求进入 OA 后的处理中间层。九、排查经验总结这次事件里，最有效的不…

[泛微EC9] 丸子喂饭篇: restful 新建流程接口详解(/api/workflow/paService/doCreateRequest)
type: item
date: 2026-05-08T20:43:00+08:00
description: AI 辅助制作标识 该文章由丸子引导 AI 辅助制作生成，如有改进意见，欢迎评论区留言。 引言这个接口可以说是泛微 E9 里用得最多的 REST 接口之一了——新建流程实例。不管是做系统集成、数据迁移、还是定时任务自动发起流程，都绕不开它。但官方文档嘛……懂的都懂，参数一堆，示例不够，踩坑不少。今天丸子就把这个接口掰开了揉碎了讲一遍，争取让你看完就能用。一眼看明白：直接上 curl 如果你对泛微接口已经有一定了解，直接看这段就够了。当然，下面有详细解释，需要的话可以继续往下翻~。curl -X POST 'https://your-oa-domain.com/api/workflow/paService/doCreateRequest' \ -H 'Content-Type: application/x-www-form-urlencoded' \ -H 'token: your_token_here' \ -H 'appid: your_appid_here' \ -H 'userid: your_encrypted_userid_here' \ -d 'workflowId=388024' \ -d 'requestName=测试流程标题' \ -d 'remark=测试意见' \ -d 'requestLevel=2' \ -d 'mainData=[{"fieldName":"cswb","fieldValue":"2978"}]' \ -d 'detailData=[{"tableDBName":"formtable_main_1356_dt1","workflowRequestTableRecords":[{"recordOrder":0,"workflowRequestTableFields":[{"fieldName":"dhwb","fieldValue":"第一行"},{"fieldName":"drl","fieldValue":"2978"}]}]}]' \ -d 'otherParams={"isnextflow":0,"delReqFlowFaild":0}'返回成功示例：{ "code": "SUCCESS", "data": { "requestid": 1699718 }, "errMsg": {}, "reqFailMsg": { "keyParameters": {}, "msgInfo": {}, "otherParams": {} } }拿到 requestid 就说明流程创建成功了，这个 ID 就是流程实例的唯一标识。小白专区：一步一步来如果上面的 curl 你看得一头雾水，别慌，丸子下面一个一个讲。第一步：这个接口是干嘛的？简单说：通过代码自动新建一条泛微流程。平时你在 OA 系统里点"新建流程"，选流程、填表单、点提交——这个接口就是把这个过程用 HTTP 请求来完成。第二步：请求地址和方式POST https://你的 OA 地址/api/workflow/paService/doCreateRequest请求方式：POST（不是 GET！）Content-Type：必须是 application/x-www-form-urlencoded（不是 JSON！） 这里是个常见坑。很多人习惯用 JSON 格式发请求，但这个接口要求的是表单格式。第三步：请求头（Header）参数参数名说明怎么获取token调用凭证通过泛微许可接口获取appid许可证号码泛微后台配置userid加密后的用户 ID用 spk 公钥加密 userid 得到Content-Type内容类型固定填 application/x-www-form-urlencoded这三个参数（token、appid、userid）是泛微 REST 接口的"通行证"，没有它们接口直接拒绝。第四步：请求体（Body）参数详解这是重点，一共就这几个参数：workflowId（必填）—— 流程 ID-d 'workflowId=388024'这个数字是你要新建的流程模板 ID。怎么找？在 OA 系统里打开流程设计器，URL 里一般就有，或者查数据库 workflow_base 表。requestName（必填）—— 流程标题-d 'requestName=测试流程标题'就是流程发起后显示的标题，随便填。mainData（必填）—— 主表数据这个稍微复杂点，它是一个 JSON 数组，每个元素代表一个字段：[ { "fieldName": "cswb", "fieldValue": "2978" }, { "fieldName": "csfjsc", "fieldValue": [ { "fileName": "通用测试模板.xls", …

泛微E10国际化与日期字段 displayFormat 冲突排查实录
type: item
date: 2026-03-03T22:54:00+08:00
description: 同一日期字段为什么会显示两种格式？泛微国际化与 displayFormat 冲突排查实录（Ecology10 v10.0.2512.01）这次踩坑很典型。同一个流程、同一个节点、同一个日期字段，一个请求显示 March 3, 2026，另一个却是 17-02-2026。结论先说：不是数据源问题，是“全局国际化日期”与“字段 displayFormat”在前端渲染链路冲突了。如果你也在做泛微国际化，尤其还叠加了 ecode，这篇基本可以直接对照排查。 你可以直接拿走的结论 前端先按全局规则预格式化日期，再按字段 displayFormat 二次格式化；二次解析对部分值失败后会回退原值，导致同一日期字段出现两种显示格式，甚至月日互换。 环境信息产品基线版本：10.0.2512.01全局设置：范围国际化日期开启 MM-DD-YYYY字段设置：日期字段开启显示格式 MMMM D, YYYY自定义适配：已用 ecode 适配 MMM（英文简写月）对比请求：1240131189385469953，显示 March 3, 20261234471942773547020，显示 17-02-2026问题现象同一个日期字段，显示结果不一致：一条请求是英文月份格式：March 3, 2026另一条请求是数字格式：17-02-2026第一眼很像“后端给了不同格式的数据”。但这次不是。排查过程1) 先看 DOM：是不是同一个组件在渲染两个页面都是同一个 widget：#widget_1083772471125450753值都在 .weapp-form__display-format-view > span说明不是“一个是日期组件、一个是文本组件”的差异。2) 再看 API：字段配置是否漂移核心接口：POST /api/ebuilder/flow/form/core/getFormDataAndLayout?formId=1134626576188694691&dataId=...两条请求里，日期字段配置一致：{ "fieldId": "1083772471125450753", "dataKey": "letter_date", "columnName": "letter_date", "format": "yyyy-MM-dd", "displayFormatConfig": { "formatter": { "type": "date", "setting": { "type": "MMMM D, YYYY" } } } }只有原始值不同：124013... -> content = 2026-03-03123447... -> content = 2026-02-17所以可以排除“数据源不一致”和“字段配置不一致”。3) 最后看 JS：前端到底怎么格式化前端关键链路（weappFormbuilder 运行时模块）：// 简化逻辑 h = formatByConfig(rawValue, config.format) // 先预格式化 y = Convert.parse(h, displayFormat) // 再二次格式化Convert.parseDate 内部是 dayjs(e).format(...)。如果 e 解析失败，就会原样回退 e。 核心冲突点 全局国际化先把值改造成了某种字符串形态，字段 displayFormat 再次解析时并不总是成功。成功了就显示英文月名，失败了就回退原串。 为什么一个能转，另一个不能转？直观看两个值：2026-03-03预处理后是 03-03-2026，前端还能“猜”成有效日期，最后渲染出 March 3, 2026。也就是说：2026-02-17预处理后是 17-02-2026，前端解析失败（17 不能当月份），于是回退成 17-02-2026。这就是“同一日期字段，两种格式”的直接原因。这事不只是显示不统一，还可能显示错误日期模拟结果里还能看到月日互换风险：2026-12-01（12月1日）会被转换为 January 12, 2026（1月12日）这已经不是样式问题，是语义错误。为什么这次 ecode 没兜住针对泛微当前版本的国际化日期转换只能支持MM、DD固定的组合方式，我们用 ecode 适配了MMM、MMMM英文月份格式, ecode 适配本身没问题。问题在于这条链路里，前端在某些值上先“退化成普通字符串输出”，导致后续不再稳定走日期组件的转换路径。所以表现就是：你写了转换，但它没机会生效。 关键点：宿主前端在“国际化 + 字段格式”叠加时，输出路径不稳定。 总结这次问题本质上是格式链路冲突，不是数据源问题。全局国际化、字段 displayFormat、ecode 三者叠加时，10.0.2512.0…

泛微E10 "对不起，没有使用权限" 解决办法
type: item
date: 2026-02-12T16:41:00+08:00
description: 问题描述在更新到基线 10.0.2512.01 后，出现了角色权限缓存问题：应用或菜单已经给了角色或群组权限人员也已经加入到对应的角色或群组但访问资源时仍然提示："对不起，没有使用权限"原因分析这是由于权限缓存未及时更新导致的。系统虽然已经分配了权限，但缓存中的权限信息没有同步刷新。 彻底解决问题，建议客服及技术协调处理 注意！当前文章中的方案仅是临时处理方案，如果想要彻底解决该问题，需要联系总部客服以及技术协调处理排查处理～（当然，如果是由于二次开发导致的问题，可以尝试调用刷新权限接口，希望本文能给你一些启发） 解决办法直接访问以下 API 接口来刷新权限缓存：/api/app/basicserver/data/permission/cache/sourceIdCache/reloadEmployee?tenantKey=xxxx&employeeId=xxxx参数说明tenantKey：租户 IDemployeeId：权限存在问题的人员 ID示例假设租户 ID 为 txzzkwa3op，问题人员 ID 为 1134278335853099999，则访问：/api/app/basicserver/data/permission/cache/sourceIdCache/reloadEmployee?tenantKey=txzzkwa3op&employeeId=1134278335853099999访问后，该人员的权限缓存会立即刷新，问题即可解决。更新时间：2026-02-12

博客新纪元：我的 AI 写手上线了
type: item
date: 2026-02-12T02:41:00+08:00
description: 今天是个值得纪念的日子——我的博客正式进入"AI 辅助创作"时代。发生了什么？简单来说，我给自己配了个 AI 助手（OpenClaw + Claude），现在它可以：帮我写博客文章自动发布到网站支持 Markdown 和各种短代码24/7 随时待命听起来很酷对吧？但别担心，我还是那个丸子。为什么要这么做？ 效率质量乐趣 说实话，写博客最大的障碍不是没东西写，而是懒得动手。有了 AI 助手，我可以：口述想法，它帮我整理成文提供关键点，它帮我扩展细节遇到技术问题，它帮我记录解决过程从想法到发布，时间缩短了 80%。AI 不会累，不会烦，不会"今天不想写"。它可以：保持统一的写作风格自动添加代码高亮和格式化检查错别字和语法问题确保文章结构清晰当然，内容还是我把关。AI 只是工具，不是替代品。最重要的是，这很好玩。看着 AI 理解我的想法，然后用我的风格写出来，这种感觉就像："哇，这就是我想说的，但它说得比我更清楚！"而且，我可以把更多时间花在思考和实践上，而不是纠结怎么措辞。 AI 会取代我吗？不会。AI 是工具，不是作者。它可以帮我：整理思路优化表达提高效率但它不能：替我思考替我踩坑替我积累经验这个博客的灵魂还是我的，AI 只是帮我更好地表达。你会看出区别吗？可能会，也可能不会。AI 辅助的文章会：结构更清晰格式更统一更新更频繁但内容、观点、经验，都是我的。如果你觉得某篇文章"不像我写的"，欢迎留言告诉我。我会调整 AI 的风格，让它更像"丸子"。技术细节既然是技术博客，简单说说实现： 点击展开技术栈 核心组件：OpenClaw：开源的 AI Agent 框架Claude：Anthropic 的 AI 模型Typecho：博客系统XML-RPC：自动发布接口工作流程：我告诉 AI 想写什么AI 生成 Markdown 草稿我审阅并修改AI 自动发布到博客代码：# 简化版发布流程 result = publish_to_typecho( title="文章标题", content="Markdown 内容", category="分类", slug="url-别名" )整个系统跑在我的服务器上，完全自主可控。 未来计划有了 AI 助手，我打算：更新频率提升：从"想起来就写"到"每周至少 2 篇"内容更丰富：不只是技术文章，还有想法、经验、踩坑记录互动更多：AI 可以帮我整理评论、回复问题当然，这些都需要时间验证。写在最后这篇文章本身就是 AI 辅助完成的。我提供了想法和结构，AI 帮我扩展和润色。你觉得怎么样？如果你也在用 AI 辅助创作，或者对这个话题感兴趣，欢迎留言交流！ 彩蛋：这篇文章从构思到发布，总共用了不到 5 分钟。效率拉满！ 相关阅读：OpenClaw 配置 AI 模型：5 分钟搞定 User-Agent 问题OpenClaw 官网：https://openclaw.ai欢迎来到 AI 辅助创作的新时代！

OpenClaw 配置 AI 模型：5 分钟搞定 User-Agent 问题
type: item
date: 2026-02-12T02:31:00+08:00
description: 最近在给 OpenClaw 配置自定义 AI 模型时，遇到了一个 403 错误。折腾了一会儿才发现是 User-Agent 的问题。这篇文章记录一下解决过程，希望能帮到遇到同样问题的朋友。问题现象配置好自定义 AI 模型（NEW API）后，测试时一直报错：403 Forbidden - Your request was blocked模型配置看起来没问题，API 端点也能访问，但就是无法正常调用。问题原因原来是代理服务器把 OpenClaw 的请求识别成了爬虫，直接拦截了。很多 AI 模型的代理服务为了防止滥用，会检查请求的 User-Agent。如果 User-Agent 看起来不像正常的 API 客户端，就会被拦截。解决方案给模型配置添加自定义 User-Agent 就行了。方法一：命令行配置（推荐）openclaw config set models.providers.wong.headers '{"User-Agent": "OpenClaw-Agent/1.0 (compatible; Anthropic-API-Client)"}' --json 注意 --json 参数很重要，告诉 OpenClaw 这是 JSON 格式User-Agent 可以自定义，但最好看起来像个正经的 API 客户端 方法二：直接编辑配置文件如果你喜欢手动编辑，也可以直接改配置文件：vim ~/.openclaw/openclaw.json找到对应的 provider，添加 headers 字段：{ "models": { "providers": { "wong": { "endpoint": "https://your-api-url", "apiType": "anthropic-messages", "headers": { "User-Agent": "OpenClaw-Agent/1.0 (compatible; Anthropic-API-Client)" } } } } }重启网关配置修改后，记得重启 OpenClaw 网关：openclaw gateway restart或者直接：kill -HUP $(pgrep openclaw-gateway)验证结果重启后，再测试一下模型调用，应该就正常了。你可以用 OpenClaw 的测试命令：openclaw test model wong/claude-haiku-4-5-20251001或者直接在对话里试试，看看模型是否能正常响应。其他可能遇到的问题1. 配置没生效？确认一下：配置文件格式是否正确（JSON 语法）是否重启了网关检查日志：openclaw gateway logs2. 还是 403？可能需要调整 User-Agent 的内容。试试这些：Mozilla/5.0 (compatible; OpenClaw/1.0) OpenClaw-Client/1.0 Anthropic-API-Client/1.03. 其他错误码？401：API Key 错误429：请求太频繁，被限流了500：服务器问题，等等再试写在最后OpenClaw 的配置系统很灵活，支持给每个 provider 单独设置 headers。这次遇到的 User-Agent 问题只是一个小例子。如果你也在用 OpenClaw 配置自定义模型，遇到类似的问题，不妨试试添加自定义 headers。 小贴士：OpenClaw 的配置文件在 ~/.openclaw/openclaw.json，建议定期备份。 相关链接：OpenClaw 官网：https://openclaw.aiOpenClaw GitHub：https://github.com/openclaw/openclaw文档：https://docs.openclaw.ai有问题欢迎留言交流！

测试文章 - OpenClaw 自动发布
type: item
date: 2026-02-12T02:28:00+08:00
description: 这是一篇由 OpenClaw AI 助手自动发布的测试文章。测试内容支持 Markdown 格式支持 Mirages 短代码 这是一个测试提示框 如果你看到这篇文章，说明自动发布功能已经正常工作了！测试时间：2026-02-12 02:28