Skip to content

TomCzHen/jiandaoyun_push_tool

Repository files navigation

简道云推送工具

  • 解决什么问题?

在无法对现有应用进行二次开发的前提下,通过数据库队列功能,实现推送表单数据到简道云。

  • 下载下来就能直接实现推送?

不能。

程序只是读取数据库内置消息队列后推送到简道云,队列消息的生成、写入需要通过数据库编程实现(存储过程、触发器)。数据库队列功能依赖数据库版本、安装选项、访问用户权限、是否开启等限制。

系统需求

配置数据库

因为开启数据库队列功能操作存在很多限制,程序无法保证自动完成配置操作,请参考对应文档以及官方文档进行配置。

部署

注意:请先参考配置数据库说明,安装好需要的数据库驱动

  1. 安装 Python 3.6 并使用 pip install pipenv 命令安装 pipenv
  2. 下载或 clone 代码到本地
  3. 在项目根目录执行 pipenv install 安装依赖
  4. 复制 config.example.tomlconfig.toml,查看配置文件注释进行配置。

使用说明

通过 API 操作表单有以下限制:

  • 表单创建人固定为组织名称
  • 网页端支持的约束检查在 API 无效(例如:唯一、必填等)
  • 部分表单控件 API 不支持

守护进程运行

Windows 部署推荐使用 SQL Server 代理作业随代理启动,或者使用 NSSM - the Non-Sucking Service Manager 添加为系统服务运行。

python run.py --daemon

部门成员信息同步

使用系统计划任务定时运行。

python run.py --sync

运行成功后会将简道云成员、部门信息写入到配置文件对应的表名中。程序会自动创建对应表,每次更新都是全量更新。

运行逻辑

  1. 推送的表单数据按约定的格式,以队列消息方式插入数据库队列。
  2. 程序读取队列消息,调用简道云 API 获取需要的表单结构信息,将字段转换为简道云 API 需要的格式结构。

表单组件支持

控件名称 控件类型 数据类型
单行文本 text String
多行文本 textarea String
数字 number Number
日期时间 datetime String
单选按钮组 radiogroup String
复选框组 checkboxgroup Array
下拉框 combo String
下拉复选框 combocheck Array
成员单选 user Array
成员多选 usergroup Array
部门单选 dept Array
部门多选 deptgroup Array
子表单 subform Array

注意:不支持的控件类型数据会丢失,同名字段数据会丢失。

日期组件

API 仅接受标准 RFC3339 日期格式的 UTC 时间,大多数传统行业数据库应用肯定不是 UTC 时间,加上服务端、应用端时区问题。

简单来说,虽然可以在代码中实现日期转换,但是由于各种各样的原因(数据库时区设置错误、客户端时区/时间格式、数据库存储类型等等)。进行标准转换后的时间可能并不是预期的时间,因此,转换的处理交给数据库编程处理。

请自行查阅相关资料,将日期转换为对应格式字符串。

成员部门组件

API 只接收成员或部门的 id,需要使用同步通讯录功能,将成员部门信息同步到数据库,生成表单数据时自行匹配 id。如果 id 不存在,API 不会因此报错,即使该字段为必填也会留空。

队列消息格式

{
    "app_id":"app_id",
    "entry_id":"entry_id",
    "op":"create",
    "query_fields":[],
    "data":{},
    "is_start_workflow":false,
    "etag": "etag_string"
}
  • app_id entry_id

对应简道云的表单 app_identry_id

  • op

支持 create|update|delete,分别对应表单三种操作

  • query_fields

提交表单数据操作请求时,通过该字段先查询匹配条件的表单数据

  • data

表单数据

  • is_start_workflow

表示是否发起流程单,相关限制请查看简道云 API 文档,非必要键,默认为 false

  • etag

为了减少请求次数,会缓存表单结构数据。在字段名称、顺序发生变化时,程序会自动刷新结构数据缓存。

但如果删除表单字段后重新添加同名字段,对应简道云字段 id 发生变化,需要通过修改 etag 值,让程序更新表单组件缓存数据。

使用实例

注意:生成的字符串需要进行是否符合 JSON 格式校验,下面是一个消息例子:

{
    "app_id":"app_id",
    "entry_id":"entry_id",
    "data":{
        "单行文本":"单行文本测试数据",
        "多行文本":"单行文本测试数据",
        "数字":123.12,
        "日期时间":"2017-12-08T00:00:00.00Z",
        "单选按钮组": "单选选项",
        "成员单选":"user_id",
        "成员多选":[
            "user_id_1",
            "user_id_2"
        ],
        "部门单选":"dept_id",
        "部门多选":[
            "dept_id_1",
            "dept_id_2"
        ],
        "子表单":[
            {
                "单行文本":"子表单单行文本1",
                "数字":123.12
            },
            {
                "单行文本":"子表单单行文本2",
                "数字":123.12
            }
        ]
    },
    "op":"create",
    "query_fields":[
        "单行文本"
    ],
    "is_start_workflow":false,
    "etag": "20190107"
}

以实际例子说明,假设简道云表单设置字段有单行文本数字唯一字段三个字段,那么生成的队列消息内容如下:

{
    "app_id":"app_id",
    "entry_id":"entry_id",
    "data":{
        "唯一字段": "唯一值",
        "单行文本":"单行文本测试数据",
        "数字":123.12,
    },
    "op":"create",
    "query_fields":[
        "唯一字段"
    ],
    "is_start_workflow":false,
    "etag": "20190107"
}

程序根据 query_fields 中的字段,找到 data唯一字段 的值,然后转换为简道云 API 需要的 _widget_xxxxx 字段对应 ID。 查询符合条件的表单。再根据 opsafe_limie 的配置通过 API 操作表单。

基于以上运行逻辑,所以不能支持表单中存在多个同名字段。

何时生成

根据实际情况可以使用以下两种方法实现:

  1. 修改现有业务对应存储过程,在业务执行完毕,数据库事务提交前插入队列
  2. 在对应数据表使用 AFTER INSERT 或 AFTER UPDATE 触发器

一些提醒:

  1. 将生成消息封装为单独的函数或存储过程进行调用
  2. 子表单数据很多时,生成消息所需的时间会增加事务耗时
  3. 注意变量数据类型、数据库对象数据类型的最大长度,避免数据较大时产生异常或截断

如何生成

如果数据库不支持 JSON 类型以及相关函数,那么只能使用字符串拼接的方式生成。

  • Oracle

使用 format_message 函数可以减轻一些工作量

declare
  json_fmt_string     VARCHAR2(512) := '{"app_id":"%s","entry_id":"%s","op":"%s","query_fields":%s,"data":%s,"is_start_workflow":false}';
  json_string         VARCHAR2(2048);
  data_string         VARCHAR2(512) := '{"单行文本":"单行文本测试数据","数字":123.12,"日期时间":"2018-06-28"}';
  query_fields_string VARCHAR2(128) := '["单行文本"]';
begin
  json_string := utl_lms.format_message(json_fmt_string,'app_id','entry_id','create',query_fields_string,data_string);
  dbms_output.put_line(json_string);
end;
  • SQL Server

SQL Server 2012 或以上版本可以使用 FORMATMESSAGE 函数来实现,详细用法查看官方文档FORMATMESSAGE (Transact-SQL)

技术支持

Bug 、问题请提交 issue。其他方式只提供有偿技术支持。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages