文档中所有的数据交互涉及编码统一使用 UTF-8,url 里的所有参数值请做 urlencode 编码, 响应类型为 application/json;charset=UTF-8。接口通讯协议支持 HTTP 和 HTTPS,请求方式支持 POST/GET,建议用 HTTPS 协议和 POST 方式发 送请求。
根据不同的安全等级采用不同的接口访问权限校验机制:
uToken: E5E0A2593A3AE4C038081D5F113CEC78 timestamp: 2019-03-31 21:39:34 Request Body: {"wh":"仓库1","aaa":"bbb","skuname":"货品X"} 字符串(uToken + body(以字段名按asc码表的顺序进行排序生成的字符串)+ timestamp) 排序后的body字符串:aaabbbskuname货品Xwh仓库1 签名前的字符串:E5E0A2593A3AE4C038081D5F113CEC78aaabbbskuname货品Xwh仓库12019-03-31 21:39:34 签名:MD5(E5E0A2593A3AE4C038081D5F113CEC78aaabbbskuname货品Xwh仓库12019-03-31 21:39:34) = A0653C36C426143156462D0B6FCAFD76
基于jQuery发起AJAX请求
jQuery.getJSON(url, params, function(data) { }); // GET请求 jQuery.post(url, params, function(result) { }); // POST请求 jQuery.ajax({ url : url, type : "GET|POST|DELETE", data : {}, success: function(result) { } });
基于tssJS发起AJAX请求
tssJS.ajax({ url : url, method : "GET|POST|DELETE", params : { }, ondata : function() { } }); tssJS.get(url, params, function(data) { }); tssJS.post(url, params, function(result) { }); tssJS.JSONP.getJSON(url, params, function(data) { });
JAVA 远程调用,借助httpClient包
String url = "http://www.boubei.com/tss/data/json/5"; PostMethod postMethod = new PostMethod(url); postMethod.setParameter("uName", "XXX"); postMethod.setParameter("timestamp ", "2018-12-22 09:18:11"); // 时间戳timestamp格式:yyyy-MM-dd hh:mi:ss postMethod.setParameter("uSign ", "7fa59411844a5db3970b8ae81b3532cc"); // uSign 参考上面签名方式, postMethod.setParameter("paramX ", "..."); HttpClient httpClient = new HttpClient(); int statusCode = httpClient.executeMethod(postMethod); if(statusCode == 200) { String result = postMethod.getResponseBodyAsString(); ...... // 返回结果 }
微信小程序访问TSS 接口(TSS可轻松为小程序提供后台服务)
wx.request({ url: "https://www.boubei.com/tss/data/json/5", method: "POST", header: { Cookie: wx.getStorageSync('cookie') }, data: {"uName": "13588888888", "uToken": "XXXXXXXXXXXX", "param1": "2018-09-26"}, success: res => { }, fail: res => { }, complete: res => { } })
JSONP远程调用报表数据服务接口,跨域调用 (只有数据服务支持,数据表接口等不支持JSONP调用)
tssJS.JSONP.getJSON( "http://www.boubei.com/tss/data/jsonp/5", {'param1': 'hello jsonp!', "uName": "13588888888", "uSign": "7fa59411844a5db3970b8ae81b3532cc"}, function(result) { console.log(result.length); } );
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{precode} | String | 是 | 取号器前缀,如:SO、XXyyMMddxxxx | XX-xxxx |
{count} | int | 是 | 取号个数,一次可取1到100000个不等的号 |
jQuery.post('/tss/tss/SO-xxxx/1', function( sns ) { callback( sns ); } ); // 返回结果sns为数组
<img src="http://ebi.boubei.com/tss/img/api/ck/1234">
<img src="http://ebi.boubei.com/tss/img/api/bar/10249025592?size=1.2">
<img src="http://ebi.boubei.com/tss/img/api/qrbar/1?msg=http://wx.boubei.com?id=2">
<img src="https://ebi.boubei.com/tss/wx/api/acode2?appId=wx5255074da90a4dca&page=pages/homepage/index">
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{report} | String | 是 | 可以是 : reportId | reportCode | reportName |
分页参数 | 数字 | 否 | 示例: {page:1, pagesize|rows:100} |
查询条件参数 | 自定义 | 自定义 | param1, param2, ..... paramN | paramCode |
缓存策略参数 | String | 否 | noCache='true'(不缓存) | uCache='true'(按【用户 + 参数】缓存) | 默认按【参数 + 用户所在域】缓存 |
引用session值 | String | 自定义 | 用户登录后,用户相关的账号、组织、角色、域等信息存放在session中,如需引用,可以通过${key}方式去引用,比如:param2 = ${userGroup},更多可以引用的session值参考: Freemarker中可以使用的全局变量 |
var params = {"param1": "2017-06-01", "param2": "2017-06-30"}; jQuery.getJSON('/tss/data/json/769', params, function(data) { console.log(data); } ); 注0:769为报表服务的ID,data 为报表的查询结果,数组格式 注1:当请求参数里带有页码page参数时(即分页查询),返回结果为一个对象,格式如:{"total": 3242, "rows": List< Map< String, Object > >} 注2:要求用户先登录系统且用户对报表有浏览权限才能调用6、调试SQL解析结果:http://localhost:9000/tss/data/json/xxx?debugSQL=true
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
自定义 | 自定义 | 自定义 | 各个报表服务自行定义参数 |
String | 否 | 导出数据后直接以电子邮件发送 |
http://www.boudata.com/tss/data/export/42/1/10000?paramX=XXX&email=boubei@163.com
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{record} | String | 是 | record可以是:数据表的ID | Name | Table |
查询参数 | 自定义 | 自定义 | 数据表定义的所有字段,以及创建人、创建时间、修改人、修改时间,支持按区间查询(适合日期时间、数字类字段,格式:[fromVal, toVal])和 in查询(多个条件有英文逗号分隔) |
非空查询 | null | 支持查询null或not null的记录,参数示例 'f1': 'is null', 'f2': 'is not null' | |
精确查询 strictQuery |
布尔 | 否 |
查询参数及匹配方式:strictQuery="true" 精确查询,否则为模糊查询;系统默认 strictQuery="false" 如需某个字段始终要精确查询(比如一些状态类字段:正常、不正常),可以在字段定义里加属性,'strictQuery': 'true' |
分页参数 | 数字 | 否 | 示例: {page:1, pagesize|rows:100}, 默认pagesize = 1000 |
fields | String | 否 |
指定字段,查询结果只返回指定的字段,格式如:f1 as code, f2 as name 。导出数据表时也可以通过fields来完成数据表头自定义。 注:系统会对fields进行防SQL注入检查,如果fields比较复杂,比如带子查询等,可以把fields定义在自定义SQL里(避开SQL注入检查),自定义SQL编码命名为"macro_"打头,使用时传递 fields = macro_xxx |
groupby | String | 否 | 汇总维度字段 |
sortField | String | 否 | 对结果集按此字段进行排序,多个字段排序用逗号, 例如:money desc, day asc |
sortType | String | 否 | desc | asc| onlynull | notnull,分别对应降序、升序、只取空值、只取非空 |
引用session值 | String | 自定义 | 用户登录后,用户相关的账号、组织、角色、域等信息存放在session中,如需引用,可以通过${key}方式去引用,比如:org = ${userGroup},更多可以引用的session值参考: Freemarker中可以使用的全局变量 |
var params = {"code": "XX", "createtime": "[2017-06-01, 2017-06-30]"}; jQuery.getJSON('/tss/xdata/json/769', params, function(data) { console.log(data); } ); // 769为数据表的ID 注1:查询数据按用户所拥有的权限进行过滤,如只有录入权限的用户,只能查询自己录入的数据;拥有浏览权限的用户可以查询所有数据。 所有参数值不得含有SQL关键字,后台会进行防SQL注入检查。 fields可以是个子查询,通过 macro_xxx 调用SQLDef里的定义脚本。6、权限控制:此接口按调用者被授予的角色、所属的组织结构等严格过滤数据.
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{record} | String | 是 | record可以是:数据表的ID | Name | Table |
id | int | 是 | 记录ID值 |
jQuery.getJSON('/tss/xdata/769/12', {}, function(data) { console.log(data); } ); // 12为数据行的ID6、权限控制:查询用户需要对此记录有编辑或浏览权限,否则看不到该记录,系统将报"权限不足"的异常。
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{record} | String | 是 | record可以是:数据表的ID | Name | Table |
字段 | 数据表定义 | 是 | 数据表里定义的字段,key:value |
_after_ | String | 否 | 可定义新增后续操作, eg: _after_ = '[{ \"sqlCode\": \"s24\", \"data\": {} }]', 其中s24在数据表【SQL自定义表】里定义,更多参考MultiSQLExcutor |
var params = {‘code’: ‘A1’, ‘name’: ‘Jack’, ……}; jQuery.post('/tss/xdata/769', params, function(info) { callback(info.result); } );6、权限控制:用户需要对当前录入表有录入权限,否则系统将报"权限不足"的异常。
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{record} | String | 是 | record可以是:数据表的ID | Name | Table |
id | int | 是 | 记录ID值 |
字段 | 数据表定义 | 是 | 数据表定义的字段(一个以上,creator、updator、version等除外),参数里包含的字段将被修改,没有包含的不做修改。 |
_after_ | String | 否 | 可定义修改后续操作, eg: _after_ = '[{ \"sqlCode\": \"s24\", \"data\": {} }]', 其中s24在数据表【SQL自定义表】里定义,更多参考MultiSQLExcutor |
jQuery.post('/tss/xdata/769/12', params, function(info) { console.log(info.result) } );6、权限控制:用户需要对当前录入表有维护权限或当前记录的创建人,否则系统将报"权限不足"的异常。
参数名 | 类型 | 必填 | 描述 |
---|---|---|---|
{record} | String | 是 | record可以是:数据表的ID | Name | Table |
id | int | 是 | 记录ID值 |
jQuery.ajax({ url : '/tss/xdata/769/12', type : "DELETE", success: function(result) { } }); 支持逻辑删除,可以在以下两个地方配置: 1、系统参数 LOGIC_DEL=true 则对本站所有录入表都生效,全部执行逻辑删除; 2、录入表备注 LOGIC_DEL:=true 此录入表只执行逻辑删除; 另外还提供了数据表批量删除接口: DELETE /tss/xdata/batch/{record} 参数 {"ids": "1,2,3,4,5"}, 根据参数ids(逗号分隔)批量删除数据6、权限控制:用户需要对被删除记录有删除权限(通常能编辑即能删除),否则系统将报"权限不足"的异常。
var url = encodeURI("/tss/xdata/export/769?" + queryString); tssJS("#downloadFrame").attr( "src", url); // 通过设置导出地址到一个隐藏的iframe,来执行导出
POST /tss/xdata/batch/{record} 批量更新选中记录行的某个字段值(一次只能更新一个字段),用在批量审批等场景 示例: $.post("/tss/xdata/batch/13", {'ids':'1,2,3,4', 'field': 'brand', 'value': '农夫'} , function(data) {}); POST /tss/xdata/cud/json/{record} JSON批量保存数据表的记录集,新增、修改、删除All in one (注:此方法没有强事务一致性,值支持换行) 示例: tssJS.post("/tss/xdata/cud/json/{recordId}", {"json": "[{...}, {...}, ...]"}, function(result) { } ); POST /tss/xdata/cud/{record} CSV批量保存数据表的记录集,新增、修改、删除All in one (注:此方法没有强事务一致性,值不支持换行) 示例: tssJS.post("/tss/xdata/cud/{recordId}", {"csv": "......"}, function(result) { } ); 参数: csv(逗号分隔,每一行的逗号个数应严格一致),如下: id,f1,f2,f3 ,30.1,test3,2017-05-03 // 无ID,新增 1,11.1,test-u,2016-05-01 // 有ID,修改 2,,, // 只有ID,删除权限控制:需要操作者有相应的权限,每一行都会严格进行权限检测。
除了针对数据表单行操作以外,如果希望一次操作多张表的多条数据记录,可以用自定义接口来实现。
1、请求地址:/tss/api/dml/multi1、在SQL自定义表(SQLDef,dm_sql_def)里定义以下四个SQL语句: s1: insert into tbl_jx(name,score,day,createtime,creator,version) values ('${name}', ${score}, '${day}', '${day}', 'Admin', 0) s2: select IFNULL(max(id), 1) as maxid from tbl_jx s3: update tbl_jx t set t.score = ${score} where t.id = ${maxid} s4: delete from tbl_jx where id = ${maxid} - 1 2、在页面通过AJAX发起以下请求: var json = []; json.push({ "sqlCode": "s1", data: {"name": "JK", "score": 59, "day": "2017-01-01"} }); json.push({ "sqlCode": "s1", data: {"name": "Jon", "score": 58, "day": "2017-01-02"} }); json.push({ "sqlCode": "s2", data: {} }); json.push({ "sqlCode": "s3", data: {"score": 100} }); json.push({ "sqlCode": "s4", data: {} }); var params = {}; params.ds = "connectionpool"; params.json = JSON.stringify(json); tssJS.post("/tss/api/dml/multi", params, function(result) { console.log(result); } ); 返回结果: {result: "Success", maxid: 2, step1: 1, step2: 1, step4: 1, step5: 0}
POST /tss/auth/file/upload?afterUploadClass=com.boubei.tss.dm.record.file.CreateAttach&recordId={record}&itemId=xxx 上传附件 POST /tss/remote/upload?afterUploadClass=com.boubei.tss.dm.record.file.CreateAttach&recordId={record}&itemId=xxx 小程序等上传 GET /tss/xdata/attach/json/{record}/{itemId} 数据表某行数据附件清单 GET /tss/xdata/attach/download/{id} 下载指定附件 DELETE /tss/xdata/attach/{id} 删除指定附件的记录 注1:操作附件前提是操作人对附件所属的数据表数据记录有相应的浏览或编辑权限。 更详细的附件操作参考:modules/dm/recorder_upload.html,任何数据表自定义页面都可以集成附件上传功能。需要引入下面资源文件,及一段脚本 < link rel="stylesheet" href="../tools/tssJS/css/reset.css"> < link rel="stylesheet" href="../tools/tssJS/css/tool.css"> < link rel="stylesheet" href="../tools/tssJS/css/message.css"> < script src="../tools/tssJS/tssJS.all.js"> var tableId = -101; var globalValiable = {"tableId": tableId} function uploadX(itemId) { globalValiable.itemId = itemId; var title = "上传员工的证件照"; tssJS.openIframePanel("if1", title, 710, 255, "../modules/dm/recorder_upload.html", true); }权限控制:读取或删除附件记录需要操作者对附件所属的数据记录有查询或维护权限。
GET /tss/param/json/simple/{code} [parma.value] GET /tss/param/json/combo/{code} List<[param.id, param.text, param.value]> GET /tss/param/json/combo/{code}?KV=true List<{"text": param.text, "value": param.value}> GET /tss/param/json/tree/{code} List<[param.id, param.parentId, param.text, param.value]> function getParam(key, callback) { tssJS.getJSON("/tss/param/json/simple/" + key, function(val) { callback && val && callback(val); }, 'GET'); }
GET /tss/auth/service/roles --> List< [role.id, role.name] > 获取当前用户有查看权限的角色,用于前台生成角色下拉列表 GET /tss/auth/service/rusers/{roleId} --> List< User > 获取拥有指定角色的用户列表 GET /tss/auth/service/gusers/{groupId} --> List< User > 获取指定用户组下的用户列表 GET /tss/auth/user/userHas 用户个人、组织、角色信息, 返回一个如下数组 userHas[0] = List< [groupId, groupName] > 用户所处的组织信息,数组格式,从高到低 userHas[1] = List< roleId > 用户拥有的角色ID列表,数组格式 userHas[2] = userId; 用户ID userHas[3] = Environment.getUserCode(); -- 用户账号 userHas[4] = Environment.getUserName(); -- 用户姓名 userHas[5] = List< groupId >; 用户所属辅助组ID列表,数组格式 userHas[6] = Environment.isFirstTimeLogon(); userHas[11] = List< String> 用户拥有的角色名称列表,数组格式 userHas[12] = Domain 用户所属域 POST /tss/auth/message 参数:title, content, receiverIds,发送站内消息 POST /tss/auth/message/email 参数:title, content, receivers,发送普通文本邮件 POST /tss/auth/message/email2 参数:title, content, receivers,发送HTML格式邮件 其中参数receivers,支持 email/登陆账号/角色(可指定域xx@role@domain)/用户组/辅助组,如:lovejava@163.com,BD0001,12@tssRole@domain,2@tssGroup function email(receivers, title, content) { $.post("/tss/auth/message/email2", {"receivers": receivers, "title": title, "content": content}); } function sendMessage(receivers, title, content) { $. post ("/tss/auth/message", {"receivers": receivers, "title": title, "content": content}); }
供Ajax调用(来自ArticleAction): GET /tss/auth/article/list/xml/{channelId}/{page}/{pageSize}/{needPic} 获取文章(包含附件)列表 GET /tss/auth/article/channels/{channelIds}/{page}/{pageSize} 根据栏目ids,获取这些栏目下的所有文章列表 GET /tss/auth/article/channelDeeply/{channelId}/{page}/{pageSize} 取指定栏目以及其所有子栏目的所有文章列表 GET /tss/auth/article/journal/{channelId}/{year}/{month} 根据栏目和日期来获取文章列表,用于期刊类需求 GET /tss/auth/article/channelTree/{channelId} 获取栏目树,用以显示"当前位置"等地方 GET /tss/auth/article/xml/{articleId} 获得已发布文章生成的xml信息 POST /tss/auth/article/import/{channelId} 参数:articleXml 第三方文章数据导入 POST /tss/auth/article/search 参数:searchStr 全文检索 POST /tss/auth/article/{articleId}/comment 参数:comment 新增一条评论 GET /tss/auth/article/{articleId}/comment 查看文章评论列表 DELETE /tss/auth/article/{articleId}/comment/{index} 删除一条评论 GET /tss/download?id=文章ID&seqNo=附件序号 文件附件查看下载
GET /tss/auth/navigator/json/{id} List< MenuDTO > GET /tss/auth/navigator/xml/{id} 动态Portlet使用 Portal支持通过Freemarker模板引擎和AJAX两种形式访问栏目内容等接口服务。 一、 动态portlet和 ajax portlet 的区别 ➢ Ajax portlet是生成网页发送到客户端后,再由客户端发送AJAX请求后台接口服务获具体数据,然后解析显示。不支持网页静态发布。 ➢ 动态portlet是通过Freemarker引擎解析portlet中的宏代码,直接调用java方法获取相应数据,再生成网页。支持网页静态发布。 二、参考 classes/freemarker/common.ftl < #macro showMenu menuId> < #assign data = menuService.getMenuXML(menuId) /> < #assign doc = manager.translateValue(data) /> < #assign menu = doc.Menu /> < TABLE height=33 width="90%" align=center>< TBODY>< TR> < #list menu.MenuItem as item> < TD class=mainTd id=td_${item.@id}> < SPAN class=menuSpan id=manegeMenu_${item.@id}> < a href='${item.@url}'>${item.@name}< /a> < /SPAN> < /TD> < /#list> < /TR>< /TBODY>< /TABLE> < /#macro> 创建一个portlet: < div id=${id} > < @common.showMenu menuId=26 < /div> 注:引用common.ftl中定义的任何变量或者方法都需要加上前缀common,如:common.showMenu。 Request Parameters取到的都是String型,所以自定义的 macro 方法参数最好都为String