IMXDR
type: channel
link: https://www.imxdr.com/
description: xdr's Blog!!!!
items: OA-金蝶API接口通用中间件说明文档 v2.0
items: Nginx判断UA标识，实现链接仅能在飞书内部打开，外部浏览器打开跳转至其他链接
items: 泛微E9审批矩阵动态调整解决方案
items: 记录一次利用DeepSeek生成泛微E9流程使用情况的展示页
items: 泛微E9查询某一时间段流程退回情况和退回意见
items: 飞书自建应用接入ChatGPT和飞书
items: 泛微OA表单提交/保存时发送POST请求
items: 金蝶单据撤销时，给相关人员发送飞书提醒功能实现
items: 金蝶多选基础资料列表无法显示的解决办法
items: Windows打开金蝶提示为了对电脑进行保护，已经阻止此应用

OA-金蝶API接口通用中间件说明文档 v2.0
type: item
date: 2026-01-04T08:49:00+08:00
description: 📋 文档信息项目说明文档名称泛微OA-金蝶API接口通用中间件说明文档版本v2.0创建日期2025年11月24日更新日期2025年12月20日作者徐东瑞当前功能API代理 + Token自动管理 + 前端框架 + 流程集成🎯 变更记录版本日期变更内容v1.02025-10-22初始版本，包含基础API代理功能v2.02025-11-24新增前端同步框架、流程集成、附件上传、权限控制等完整功能🎯 项目概述1.1 项目背景为解决泛微E9 OA系统与金蝶云星空旗舰版ERP系统之间的数据交互需求，开发一套完整的API代理中间件。该中间件不仅提供API代理功能，还包含前端同步框架、自动Token管理、附件上传、权限控制等完整解决方案，实现安全、稳定、高效的数据同步。1.2 已实现功能✅ **统一接入**：提供统一的API入口，简化前端调用✅ **Token管理**：自动管理金蝶API访问令牌，每小时自动刷新✅ **API代理**：完整的请求转发和响应处理机制✅ **附件上传**：支持文件流式上传到金蝶系统，避免内存溢出✅ **权限校验**：基于角色的细粒度访问控制✅ **前端框架**：可复用的JavaScript同步框架，支持步骤化执行，支持按条件执行步骤，支持延迟执行步骤✅ **流程集成**：与泛微E9流程表单无缝集成✅ **错误处理**：统一的错误解析和用户提示✅ **进度显示**：可视化同步进度提示🏗️ 系统架构2.1 整体架构图┌─────────────────────────────────────────────────────────────┐ │ 泛微E9 OA系统 │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 流程表单 │ │ Ecode后台 │ │ 定时任务 │ │ │ │ (前端代码块) │ │ (框架代码) │ │ (Token管理) │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ │ │ └────────────────┼────────────────┘ │ │ │ │ │ ┌───────────▼───────────┐ │ │ │ API代理中间件 │ │ │ │ KingdeeProxyServlet │ │ │ └───────────┬───────────┘ │ └──────────────────────────┼─────────────────────────────────┘ │ ┌──────────────────────────▼─────────────────────────────────┐ │ 金蝶云星空ERP │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ 业务API │ │ Token服务 │ │ 附件服务 │ │ │ │ /v2/... │ │ /oauth2/... │ │ /uploadFile │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────┘2.2 数据流向流程发起：用户在OA流程表单提交数据框架处理：前端KingdeeSync框架拦截提交事件步骤执行：按配置步骤依次调用金蝶API代理转发：中间件验证权限并转发请求金蝶处理：金蝶系统处理业务逻辑结果返回：响应逐层返回至前端界面进度提示：用户实时查看同步进度2.3 技术栈层级技术选型前端框架JavaScript ES5+、jQuery、Promise异步中间件Java Servlet、HttpURLConnection数据库SQL Server（泛微内置）JSON处理FastJSON、原生JSON文件处理流式传输、Zip解压、AES加密权限控制泛微角色体系、基于角色的访问控制📊 数据库设计3.1 数据表结构3.1.1 Token存储表 (uf\_kingdeeAPI)CREATE TABLE [uf_kingdeeAPI] ( [id] INT IDENTITY(1,1) PRIMARY KEY, [clientid] VARCHAR(50) NULL, -…

Nginx判断UA标识，实现链接仅能在飞书内部打开，外部浏览器打开跳转至其他链接
type: item
date: 2025-09-15T14:19:51+08:00
description: server { server_name ai.jinyi-food.com; listen 80; # 飞书User-Agent检测和重定向逻辑 set $feishu_redirect 0; if ($http_user_agent ~* (Lark|Feishu)) { set $feishu_redirect 1; } # 如果不是飞书访问，则重定向到百度 if ($feishu_redirect = 0) { return 302 https://www.baidu.com; } location / { proxy_pass http://192.168.5.100; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-Proto $scheme; } }

泛微E9审批矩阵动态调整解决方案
type: item
date: 2025-09-11T14:48:00+08:00
description: 方案背景在OA审批流程配置中，针对常见的“申请人→部门经理→副总”审批场景，通常采用部门矩阵功能进行配置，这种方法能够满足大部分业务流程的审批需求。然而，在某些特殊情况下，会出现特定角色无需参与审批流程的现象。例如：当董事长代管研发部时，研发部的部门矩阵中“副总”审批岗位指向了董事长。但在用车申请等特定流程中，只需审批至部门经理即可，无需董事长审批。目前针对此类情况的解决方案是在流程路径中设置条件跳转，以跳过特定审批人。但这种做法存在明显弊端：由于组织架构中部门与岗位调整较为频繁，而流程中的路径条件无法批量检索与统一维护，导致审批路径未能及时随组织变动更新。其直接结果是用户频繁反馈不应由其审批的流程被错误地推送过来，影响了审批效率与用户体验。配置示例：解决方案思路通过OA流程配置操作者的外部接口功能，结合SQL语句，查询矩阵表中对应的审批人，如果需要跳过审批，则返回一个没有人员对应的ID（如0），此时流程节点会找不到审批人，再利用流程异常自动流转至下一节点功能跳过该节点。不需要跳过审批则正常返回矩阵对应审批人。SQL语句SELECT CASE WHEN fgld = 3 THEN 0 ELSE fgld END AS fgld_result FROM Matrixtable_1 WHERE bm = $sqbm$ --Matrixtable_1对应OA中部门矩阵表 --fgld对应分管领导，3代表杨总的ID，0没有人员对应 --$sqbm$对应流程表单中需要取值的部门字段配置方法配置流程节点操作者配置流程异常处理最终效果正常审批跳过审批优点通用性强，可用于所有流程可拓展性强，可通过变通满足其他类似要求，举一反三减少流程维护频次降低流程错误几率

记录一次利用DeepSeek生成泛微E9流程使用情况的展示页
type: item
date: 2025-08-16T18:04:00+08:00
description: 前言泛微E9版本的后台对于流程使用分析功能上还是比较欠缺的，公司使用OA系统的时间也比较久了，有很多没有必要的流程还存在在系统重，如果单条筛选工作量巨大，之前就发现DS对泛微数据库的结构记录的比较准确，索性就让DS帮我完成这一工作，再进阶成网页形式展现出来，也方便日后再做流程统计的时候查看。效果图最终版SQL代码WITH CurrentFlows AS ( SELECT wb.id, wb.workflowname, wb.activeVersionID, wb.isvalid, -- 添加 isvalid 字段 wb.workflowtype, -- 添加 workflowtype 字段 MAX(wf.createdate) AS last_created FROM workflow_base wb JOIN workflow_requestbase wf ON wb.id = wf.workflowid WHERE wb.id = wb.activeVersionID OR wb.activeVersionID IS NULL GROUP BY wb.id, wb.workflowname, wb.activeVersionID, wb.isvalid, wb.workflowtype ), TotalCounts AS ( SELECT wb.workflowname, COUNT(*) AS total_submissions, SUM(CASE WHEN wf.createdate >= '2025-01-01' AND wf.createdate < '2026-01-01' THEN 1 ELSE 0 END) AS submissions_2025 FROM workflow_base wb JOIN workflow_requestbase wf ON wb.id = wf.workflowid GROUP BY wb.workflowname ) SELECT cf.id AS 流程类型ID, cf.workflowname AS 流程类型名称, cf.activeVersionID AS 活动版本ID, -- 映射 isvalid 字段 CASE cf.isvalid WHEN 0 THEN '无效' WHEN 1 THEN '有效' WHEN 2 THEN '测试' ELSE '未知状态' END AS 流程状态, -- 获取 workflowtype 的中文名称 wt.typename AS 路径类型, tc.total_submissions AS 历史总提交次数, tc.submissions_2025 AS [2025年提交次数], cf.last_created AS 最后创建时间 FROM CurrentFlows cf JOIN TotalCounts tc ON cf.workflowname = tc.workflowname -- 关联 workflow_type 表获取路径类型中文名 LEFT JOIN workflow_type wt ON cf.workflowtype = wt.id ORDER BY cf.last_created DESC;最终版PHP代码<?php // 数据库配置信息 $serverName = "数据IP,1433"; // 服务器地址（IP:端口） $databaseName = "数据表名"; // 数据库名称 $username = "数据库用户名"; // 登录用户名 $password = "数据库密码"; // 登录密码 // 连接选项 $connectionOptions = [ "Database" => $databaseName, // 目标数据库 "Uid" => $username, // 用户名 "PWD" => $password, // 密码 "CharacterSet" => "UTF-8" // 字符集 ]; // 尝试连接数据库 $conn = sqlsrv_connect($serverName, $connectionOptions); // 检查连接是否成功 if ($conn === false) { die(" ❌ 数据库连接失败！ " . print_r(sqlsrv_errors(SQLSRV_ERR_ALL), true) . " "); } // 定义用户提供的 SQL 查询 $query = " WITH CurrentFlows AS ( SELECT wb.id, wb.workflowname, wb.activeVersionID, wb.isvalid, wb.workflowtype…

泛微E9查询某一时间段流程退回情况和退回意见
type: item
date: 2025-08-16T17:43:00+08:00
description: 数据库代码：SELECT log.requestid AS 流程ID, log.workflowid AS 流程定义ID, workflow.workflowname AS 流程名称, log.nodeid AS 退回节点ID, from_node.nodename AS 退回节点名称, log.destnodeid AS 退回目标节点ID, to_node.nodename AS 目标节点名称, log.operator AS 操作人ID, res.lastname AS 操作人姓名, log.receivedPersons AS 接收人, log.operatedate AS 操作日期, log.operatetime AS 操作时间, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( CAST(log.remark AS NVARCHAR(MAX)), ' ', ''), ' ', ''), ' ', ''), ' ', ''), ' ', ''), ' ', '') AS 退回意见 FROM workflow_requestlog log JOIN workflow_nodebase from_node ON log.nodeid = from_node.id JOIN workflow_nodebase to_node ON log.destnodeid = to_node.id JOIN HrmResource res ON log.operator = res.id JOIN workflow_base workflow ON log.workflowid = workflow.id WHERE logtype = '0' -- 3表示退回操作 AND log.operatedate like '%2025%'执行效果：数据库字段定义：在workflow_requestlog表的logtype字段中，0代表批准操作，2代表提交操作，3代表退回操作，7代表转发操作，9代表批注操作。

飞书自建应用接入ChatGPT和飞书
type: item
date: 2024-03-11T18:29:00+08:00
description: GitHub项目地址：飞书 To ChatGpt飞书 To 文心一言支持功能：## 👻 机器人功能 🗣 语音交流：私人直接与机器人畅所欲言「Whisper」 🕵️ 图片推理: 借助大模型互动式对话图片「GPT4V」 💬 多话题对话：支持私人和群聊多话题讨论，高效连贯 🖼 文本成图：支持文本成图和以图搜图 「DALLE-3」 🛖 场景预设：内置丰富场景列表，一键切换AI角色 🎭 角色扮演：支持场景模式，增添讨论乐趣和创意 🤖 AI模式：内置4种AI模式，感受AI的智慧与创意 🔄 上下文保留：回复对话框即可继续同一话题讨论 ⏰ 自动结束：超时自动结束对话，支持清除讨论历史 📝 富文本卡片：支持富文本卡片回复，信息更丰富多彩 👍 交互式反馈：即时获取机器人处理结果 🎰 余额查询：即时获取token消耗情况 🔙 历史回档：轻松回档历史对话，继续话题讨论 🚧 🔒 管理员模式：内置管理员模式，使用更安全可靠 🚧 🌐 多token负载均衡：优化生产级别的高频调用场景 ↩️ 支持反向代理：为不同地区的用户提供更快、更稳定的访问体验 📚 与飞书文档互动：成为企业员工的超级助手 🚧 🎥 话题内容秒转PPT：让你的汇报从此变得更加简单 🚧 📊 表格分析：轻松导入飞书表格，提升数据分析效率 🚧 🍊 私有数据训练：利用公司产品信息对GPT二次训练，更好地满足客户个性化需求 🚧操作关键步骤：1.部署好Go语言环境、目前生产环境使用版本为go version go version go1.22.0 linux/amd642.config.yaml修改配置信息3.执行后台运行命令，避免宝塔关闭命令提示符窗口后服务停止运行#执行服务 nohup go run main.go #停止服务 ps -ef | grep cpolar kill -9 PID效果展示：

泛微OA表单提交/保存时发送POST请求
type: item
date: 2024-03-11T18:00:55+08:00
description: 代码如下：$().ready(function () { //WfForm.OPER_SAVE为保存操作，SUMBIT为提交操作，必须要有callback(); 否则将会中断操作 WfForm.registerCheckEvent(WfForm.OPER_SAVE, function (callback) { var url = "http://www.baidu.com"; //设置往form表单中添的元素，name=value的方式，设置一个json数组对象 var params = { "billid":WfForm.getFieldValue("field15631"), "sqr": $('div[data-fieldmark="field15632"] .ant-select-selection__choice__content a').text(), "fyftbm": $('div[data-fieldmark="field5994"] .ant-select-selection__choice__content a').text(), "cxsj":WfForm.getFieldValue("field15633"), "ccrs":WfForm.getFieldValue("field10980"), "ckxm":WfForm.getFieldValue("field10981"), "lxdh":WfForm.getFieldValue("field11378"), "yclx":$('div[data-fieldmark="field5997"] .ant-select-selection-selected-value').text(), "sfd":$('div[data-fieldmark="field11379"] .ant-select-selection-selected-value').text(), "mdd":WfForm.getFieldValue("field5996"), "yjycjssj":WfForm.getFieldValue("field15634"), "sjxm":$('div[data-fieldmark="field6004"] .ant-select-selection__choice__content a').text(), "sjdh":WfForm.getFieldValue("field10982"), "cph":WfForm.getFieldValue("field6003") } $.ajax({ url: url, // 目标资源 cache: false, //true 如果当前请求有缓存的话，直接使用缓存。如果该属性设置为 false，则每次都会向服务器请求 async: false, //默认是true，即为异步方式 data: params, dataType: "jsonp", // 服务器响应的数据类型 type: "POST", // 请求方式 success: function (data) { console.log(data) } }); }); callback(); });

金蝶单据撤销时，给相关人员发送飞书提醒功能实现
type: item
date: 2023-09-30T19:12:12+08:00
description: 前言金蝶云星空标准产品自带的消息推送功能无法在单据撤销时发送消息通知，只能在保存等其他操作触发消息通知，并且触发成功后，消息只能发送至金蝶客户端和云之家消息平台内，无法发送至办公沟通软件，恰好飞书有多种接口支持通过webhook的形式将消息发送给相关人员，可以对功能进行实现。操作步骤1.在金蝶BOS协同开发平台，打开单据，操作列表内找到相关操作，在服务插件内注册一个新的python插件，经复制代码。示例代码：# -*- coding: utf-8 -*- import clr import sys #添加对cloud插件开发的常用组件的引用 clr.AddReference('System') clr.AddReference('System.Data') clr.AddReference('Kingdee.BOS') clr.AddReference('Kingdee.BOS.Core') clr.AddReference('Kingdee.BOS.App') clr.AddReference('Kingdee.BOS.ServiceHelper') clr.AddReference('Newtonsoft.Json') #导入cloud基础库中的常用实体对象（分命名空间导入，不会递归导入） from Kingdee.BOS import * from Kingdee.BOS.Core import * from Kingdee.BOS.Core.Bill import * from Kingdee.BOS.Core.DynamicForm.PlugIn import * from Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel import * from System import * from System.Data import * from System.Net import * from System.Text import * from System.IO import * #from System.String import * from Kingdee.BOS.App.Data import * from System.Collections.Generic import List from Kingdee.BOS.ServiceHelper import * from Newtonsoft.Json.Linq import * sys.setdefaultencoding('utf-8') def OnPreparePropertys(e): e.FieldKeys.Add("FBillTypeID"); # e.FieldKeys.Add("FProviderContactId");#这里使用的是字段标识，后面从数据包取值用的是绑定实体属性 e.FieldKeys.Add("F_RNCV_Wly");#采购员基础资料 # e.FieldKeys.Add("PurchaseOrgId")#采购组织基础资料 # e.FieldKeys.Add("SupplierId")#供应商基础资料 def EndOperationTransaction(e): #这里获取单据数据包方式和前面一样 #print(e.DataEntitys); for billObj in e.DataEntitys: billId=billObj["Id"];#单据ID billNo=billObj["F_RNCV_BillNo"];#单据编号 wlyObj = billObj["F_RNCV_Wly"];#物流员基础资料 wly_name = ("{0}").format(wlyObj["Name"]);#采购员姓名 msgdata = '{\"billno\":\"'+billNo+'\",\"wly\":\"'+wly_name+'\",\"time\":\"'+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+'\"}' webRequest=HttpPost(msgdata,'飞书机器人webhook地址') def ValidateResult(responseText): s=('{0}').format(responseText); # if (s.find("response_error:")>=0): # failText = s.TrimStart("response_error:".ToCharArray()) + "发送消息失败，请自行联系相关人员，避免发货出现问题！"; # return failText; return …

金蝶多选基础资料列表无法显示的解决办法
type: item
date: 2023-09-15T13:16:11+08:00
description: 【应用场景】将多选基础资料字段的名称合并到文本字段。标准产品不支持在列表上对多选基础资料进行过滤和显示，如果想对多选基础资料数据进行过滤和显示，目前只能将多选基础资料冗余一份文本数据，然后对该份文本数据进行过滤和显示。【案例演示】采购订单，将多选基础资料字段的名称合并到文本字段。【实现步骤】登录BOSIDE，扩展采购订单，新增多选基础资料字段和文本字段。在基本信息上新增实体服务规则，保存元数据，开发完毕。前置条件：F\_Jac\_MulBase <> null and len(F\_Jac\_MulBase)>0为真计算公式：F\_Jac\_Text = ','.join(map(lambda x:x.Name.ToString(),F\_Jac\_MulBase.TargetObjects))F\_Jac\_Text1 = ','.join(map(lambda x:x.Number,F\_Jac\_MulBase.TargetObjects))为假计算公式：F\_Jac\_Text = ''F\_Jac\_Text1 = ''【功能验证】登录业务站点，打开采购订单新增界面，录入或删除多选基础资料后，编码和文本字段会自动更新数据。【参考资料】获取多选基础资料的内码：','.join(map(lambda x:x.Id,F\_Jac\_MulBase.TargetObjects))获取多选基础资料的编码：','.join(map(lambda x:x.Number,F\_Jac\_MulBase.TargetObjects))获取多选基础资料的名称：','.join(map(lambda x:x.Name.ToString(),F\_Jac\_MulBase.TargetObjects))

Windows打开金蝶提示为了对电脑进行保护，已经阻止此应用
type: item
date: 2023-08-23T09:43:38+08:00
description: 问题症状：解决办法：1.进入”控制面板“--”用户账户“--”用户账户“，选择”更改用户账户控制设置“，拉倒最后。2.按【win+R】快捷键打开运行，输入gpedit.msc，打开后依次进入”Windows设置“--”安全设置“--”本地策略“--”安全选项“，找到”用户账户控制：以管理员批准模式运行所有管理员“，双击将其设置为”已禁用“即可。如果家庭版提示找不到gpedit.msc没有策略组进行以下操作：a.桌面新建文本文档，将下面代码复制到文本文档中：@echo off pushd "%\~dp0" dir /b C:\\Windows\\servicing\\Packages\\Microsoft-Windows-GroupPolicy-ClientExtensions-Package\~3\*.mum >List.txt dir /b C:\\Windows\\servicing\\Packages\\Microsoft-Windows-GroupPolicy-ClientTools-Package\~3\*.mum >>List.txt for /f %%i in ('findstr /i . List.txt 2^>ul') do dism /online /norestart /add-package:"C:\\Windows\\servicing\\Packages\\%%i"pauseb.将文件后缀改为.batc.运行该批处理文件即可。如果运行时提示权限错误，需右键文件选择”以管理员身份运行“。完成后继续执行第二步操作。