ESAP4.0功能前瞻
我要在现场能快速记录单据,包括发票,银行回单等,直接拍照上传,最好能自动识别发票号
等关键信息。
因为AI识别发票需要大量使用AccessToken,所以我们要从esap官网下载tokenserver组件服务,
下载解压后,使用notepad++等工具修改tc.yml,配置oauth2.0的id和key,Demo使用村长的百度AI,端口port用默认的19999
接下来进入admin配置令牌服务器,示例安装在本机,所以填入http://127.0.0.1:19999
首先,制作一个【发票Demo】
模板,里面包含5个关键信息字段:买卖双方,发票号,日期,发票图
。
接下来,在企业微信的应用中增加一个【采发票】菜单,ID=cfp
,类型为:拍照或相册菜单
在esap查询中建立一组查询,有2个查询,其中第一个查询由菜单(ID=cfp)发起,模式=2,表示新建表单模式,设置下一步
,由于前面使用的是拍照或相册菜单,这里模板返回空。
实际填报效果如下,在点击【采发票】菜单后,直接传图即可。
工作台也生成了相应表单,客户需求搞定了。
4.x版简化为
token
配置tokenserver后生效,获取tokenserver中对应app的access_token,
Demo中的片断{ { ... gettoken "bdai" ... } }
最终会解析成 { { ... 百度AI的access_token ... } }
其他示例:{ { ... gettoken "app1" ... } }
4.x版简化为
map
makemap用来构建post请求的body,参数必须为偶数个数,例如{ {makemap "name" "村长" "num" 18988889999} }
会被解析为
一个body对象:{name: "村长", num: 18988889999}
getbody
在4.x版简化为body
base64函数故名思意,将一组字节编码为base64,通常用getbody(url)来获取微信图片的字节。
使用base64编码图片字节是百度AI的要求。
4.x版简化为
get
,get(url)
原型:ApiGet(method, url, body)
该函数是一个http请求函数,method可以为get或post,函数返回json对象。
示例中,我们把用户发来的图片url(.praw)转化为字节并进行了base64编码,
然后post到了百度AI接口:https://aip.baidubce.com/rest/2.0/ocr/v1/vat_invoice,
最终得到的数据赋值给了$data变量,在后续的sql中就可以直接使用变量中的值了。
更多变量值参考百度AI文档:https://ai.baidu.com/docs#/OCR-API/5099e085
主要应用Tokenserver配合ESAP获取AI所需的AccessToken,使用apiget等高级自定义工具函数联合查询。
本文示例应用ESAP3.0.32+支持,本文涉及的JU/NX数据库备份可在聚慧禅院中下载。
2019-03-20
本文展示一种基于es/ju/nx的全新的填报方式。
客户1:我想通过微信对话式的录入单据。
客户2:我想通过微信把照片上传到已有的表单中。
客户3:我不想打字,只想点点点,扫扫扫,拍拍拍……
首先,制作一个【交互Demo】
模板,里面包含4个字段:品名(文字),安全库存(数字),图片1和图片2(图形)。
接下来,在企业微信的应用中增加一个【建商品】菜单,ID=jsp
在esap查询中建立一组查询,这里有5个查询,其中第一个查询由菜单(ID=jsp)发起,模式=2,表示新建表单模式,设置下一步
,后续查询将依次执行。
实际填报效果如下,在点击【建商品】菜单后,依次填写或传图即可。
同时,工作台也生成了相应表单,客户1的应用场景搞定了。
这次,仍然用【交互Demo】
模板做示例,手工建立两个表单,保时捷
和兰博基尼
,没有传图片。
接下来,在企业微信的应用中增加一个【扫品名】菜单,ID=spm
在esap查询中再建立一组查询,这里有3个查询,其中第一个查询由菜单(ID=spm)发起,设置下一步
,后续查询将依次执行。
做一个兰博基尼
文字二维码用于扫描,实际中可能是订单号之类的唯一ID:
实际填报效果如下,在点击【扫品名】菜单后,依次传图即可。
工作台相应表单也自动补齐了,客户2和客户3的应用场景一起搞定了。
这是一个ESAP高级自定义sql函数,原型是DownloadPic(picUrl, tableName, fieldName, rcid, picNo)
Demo中的{ {if addpic .praw "交互Demo" "图片1" .rcid $pic} }
意思是从.praw
下载图片到交互Demo
表的图片1
字段,praw
参数类似于P
参数,主要用于微信图片URL获取
这是一个ESAP高级自定义sql函数,原型是GetTableValue(dbs, table, cond, ret, value)
sql模板中的{ {$rcid := (gettablevalue "nxt" "交互Demo" "品名" "recordid" .pf0)} }
实际是执行了一个sql:
select recordid from nxt..交互Demo where 品名=.pf0
,.pf0是第一次按钮扫描的值,也就是兰博基尼
,代入后就是:
select recordid from nxt..交互Demo where 品名='兰博基尼'
,结果赋值给$rcid变量,用于后续数据处理。
主要应用了连续查询,并使用了支持JU/NX/ES的ESAP高级自定义函数。
本文示例应用ESAP3.0.31+支持,本文涉及的JU/NX/ES数据库备份可在ESAP达摩院中下载。
PS:JUAP模式下,需要通过admin控制台重新打JU补丁。
2019-03-19
本文展示一种基于ju/nx的全新的工作流替代方案。
工作流是一个老生常谈的话题,虽然村长不推荐使用,但是偶尔用一下也无妨。
工作流的本质是多人协同按照顺序维护一条数据记录,接下来我们基于ju/nx的映射模板特性,即多模板可以显示和维护同一条数据,来构造一种全新的协同填报方式。
首先,制作一个【工序总览】
模板,这里面涉及3个工序,每个工序完成后,下一个工序在工作台才能看到数据并修改补填自己工序的数据,直到3个工序全部走完。
作为总览台账模板,该模板我们不做其他设置,关闭新建、修改权限,仅保留管理员的删除权限。
接下来,制作【工序1】
的填报模板,字段全部映射
到总览模板的表,另外增加一个暂存
临时字段。
在状态
字段上设置一个EXCEL公式:=IF((C7>0)*(G1=0),2,1)
,公式的意思就是如果填报了实际产量(C7),就流转到工序2(状态2),但如果勾选了暂存(G1),就仍然保存在本工位。
增加一条新建消息提醒
表间公式,选择【工序2】
模板,关联条件为订单号,消息内容为机器2有新的工序任务
,用来提醒工序2流程人员进行办理。
最后我们要设置一下加载表达式,当状态=1时可见。
这样【工序1】模板就基本完成了。
相类似的,再制做一下【工序2】模板,字段依旧全部映射。
在状态
字段上设置一个EXCEL公式:=IF((C9>0)*(H1=0),3,IF((C9=0)*(H1=1),1,2))
,公式的意思有两层:
1.如果填报了实际产量(C9),就流转到工序3(状态3),但如果勾选了暂存(H1),就仍然保存在本工位。
2.如果没有填报产量(C9=0),可以通过勾选退回(H1=1)到前一步流程(状态1)。
【工序2】要增加两条新建消息提醒
的表间公式,一条向下到【工序3】
模板
另一条向上回到【工序1】
【工序2】模板的加载表达式为状态=2时可见。
如法炮制,制作【工序3】模板,这里不再赘述,只是提醒公式向下返回到【工序总览】。
新建工序1,填入实际数,可以看到状态到2了。
如果勾选暂存,状态会回到1。
不勾暂存,保存一下,桌面右下角立即出现提示
通过点击消息前的小图标可以直接办理
工序2任务,太棒了。
在办理工序2时,可以填入数量,状态变成3。
也可以不填,勾退回,状态变成1。
保存后,可以看到消息中出现退回提醒,点击可重新办理【工序1】形成完美闭环。
主要综合应用了映射模板、回写新建提醒、和权限控制(模板权限、字段权限、加载表达式等)
本文旨在拓展映射技术的应用思维,本文涉及的数据库备份可在聚慧禅院中下载。
2019-03-07
本文源自村长多年的ERP架构经验!
在正式谈系统架构思想之前,我们先回顾一下自己的第一套ES类系统设计是什么样的?
ES官方教程第一篇是订单,所以大部分玩家第一个模板可能是销售订单
,定义了销售订单_主表
,销售订单_明细
。
然后呢?可能是销售出库单
,定义了销售出库单_主表
,销售出库单_明细
。
好了,接下来大概率是采购订单
,定义了采购订单_主表
,采购订单_明细
。
不出意外的话,后面跟着采购入库单
,定义了采购入库单_主表
,采购入库单_明细
。
深入一点的还会有生产订单
,定义了生产订单_主表
,生产订单_明细
。
与之匹配的是生产入库单
,定义了生产入库单_主表
,生产入库单_明细
,
以及生产领料单
,定义了生产领料单_主表
,生产领料单_明细
。
好了,一个进销存系统主体模板基本完成。
这是典型的先模板,再开表
的架构模式。
举例一个经典问题是库存计算,通常为了回避回写带来的不确定性,中小系统可以采用视图计算库存,年结来切割数据。
视图代码示例如下:
select 品号,库存=sum(入)-sum(出) from (
select 品号,入=数量,出=0 from 采购入库单_明细
union all
select 品号,入=数量,出=0 from 生产入库单_明细
union all
select 品号,入=0,出=数量 from 销售出库单_明细
union all
select 品号,入=0,出=数量 from 生产领料单_明细
) io group by 品号
这种架构最大的问题就是一旦增加了模板,或模板增加了字段,或增加了统计维度,就要改视图代码。
例如公司又新开发了注塑车间和包装车间的相关个性单据,可能代码要改成下面这样:
select 品号,库存=sum(入)-sum(出) from (
select 品号,入=数量,出=0 from 采购入库单_明细
union all
select 品号,入=数量,出=0 from 生产入库单_明细
union all
select 品号,入=数量,出=0 from 注塑入库单_明细
union all
select 品号,入=数量,出=0 from 包装入库单_明细
union all
select 品号,入=0,出=数量 from 销售出库单_明细
union all
select 品号,入=0,出=数量 from 生产领料单_明细
) io group by 品号
又例如公司开始对批次有管理要求,我们不但要把所有收发单据模板改一遍,加上批号
字段,还要改sql:
select 品号,批号,库存=sum(入)-sum(出) from (
select 品号,批号,入=数量,出=0 from 采购入库单_明细
union all
select 品号,批号,入=数量,出=0 from 生产入库单_明细
union all
select 品号,批号,入=数量,出=0 from 注塑入库单_明细
union all
select 品号,批号,入=数量,出=0 from 包装入库单_明细
union all
select 品号,批号,入=0,出=数量 from 销售出库单_明细
union all
select 品号,批号,入=0,出=数量 from 生产领料单_明细
) io group by 品号,批号
不但如此,我们还要修改相关列表规范,增加字段,修改相关引用模板,增加填充字段。任何一个新需求,都几乎要把整个系统全部翻修一遍。
如果有一天公司做大了,收购了一堆公司,那简直要改得筋疲力尽,两眼发黑…
如果我们换一种思路,从数据库角度出发去开发模板,即先开表,再模板
模式,一切会变得不同。
先开表,把可能需要的字段都预先定义好,保证未来数据表本身变动最少。
例如设计收发表,把需要的和可能需要的字段都塞进去。
然后定义:收发主表
,收发明细
。
接下来,只要是出入库单类模板,都映射
到这两个表,根据需要取舍字段,不一定要全部一一映射。
这样,无论我们怎么增加新的相类似模板,视图代码永远是:
select 品号,批次,库存=sum(收)-sum(发) from 收发明细 group by 品号,批次
事实上,全球著名的SAP也是把订单都视为订单
对象,所有销售,采购,生产等订单都继承自这个对象。
因此,我们可以把订单表也做后台统一,唯一的区别就是类型=销售/采购/生产
这样做的好处是,只需要一个视图就可以完成所有订单收发查询了。
很明显,映射在提数和回写方面都能节省大量设计维护工作量。
映射的本质是多模板共用一套数据表,形成多头蛇
效果,无论通过哪个模板填报都能把数据存到一起。
反过来,映射也可以把数据库已有的数据以不同的方式展示给用户,也就是SAP中的用户视图
,所谓用户视图并不是SQL视图,而是根据权限等要求,系统对不同的用户展示不同的数据。
例如,商品表中通常含有单价,通常这些敏感信息我们不希望仓管看见,但仓管又必须能查询其他商品信息。
EXCEL类平台要解决权限不同,用户视图不同一般有三种方案:
1.使用模板本身的字段权限设置,不同用户隐藏不同的字段。缺点是:图片
,附件
不受约束。
2.另外建一个纯查询模板,提数显示需要的信息。缺点是:工作台没法用。
3.使用映射模板,这是在JU/NX中才可用的方案,ES不行,ES的映射模板在工作台不能相互显示数据。
第三种方案具体的操作方法选择原商品表,右键-复制新增,修改新增的模板名称,将数据表映射到原商品表,删除不要的单价,附件等字段,设置权限仅仓管可见,原模板设置仓管不可见。
这种方案使仓管可以在工作台看到商品表,但又完全没有其他不相干的字段,本身也不需要设置提数公式,是最简洁有效的方案。
无单价模板效果示例:
小贴士:一般的,使用映射表后,建立列表等规范时,选择原始模板表,可以避免数据规范因业务变动删模板失效。
本文旨在拓展映射技术的应用思维,本文涉及的数据库备份可在聚慧禅院中下载。
最后,村长祝愿大家在新的一年里工作顺利,心想事成,爱生活,爱宝贝^_^。
2019-03-06
本文手把手教你玩转ESAP自定义web查询,给你的数据装上翅膀!
客户通过微信(或企业微信)扫描订单上的二维码,即可看查看web版订单页面,获得进度信息。
首先用vue画出这个web模板,文件路径为esap根目录/static/app2/index.html
。
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>ESAP订单查询</title>
<link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/1.1.3/weui.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<div class="weui-cells__title">主表</div>
<div v-for="item,key in data1" class="weui-cells" style="margin-top:0">
<div class="weui-cell">
<div class="weui-cell__bd">
<p>{ { key } }</p>
</div>
<div class="weui-cell__ft">{ { item } }</div>
</div>
</div>
<div class="weui-cells__title">明细</div>
<table border="1" style="border-collapse: collapse;color: #444;border-color:#c7c7c7" width="100%">
<tr style="background-color:#f0faff">
<th style="padding:6px">产品</th>
<th>数量</th>
<th>单价</th>
<th>金额</th>
</tr>
<tr v-for="item2,key2 in data2">
<td style="padding:6px"></td>
<td>{ { item2.数量 } }</td>
<td>{ { item2.单价 } }</td>
<td>{ { item2.金额 } }</td>
</tr>
</table>
<a href="javascript:;" class="weui-btn weui-btn_mini weui-btn_primary">增加</a>
<a href="javascript:;" class="weui-btn weui-btn_mini weui-btn_primary">保存</a>
<a href="javascript:;" class="weui-btn weui-btn_mini weui-btn_primary">返回</a>
<a href="javascript:;" class="weui-btn weui-btn_primary">生成Excel格式打印</a>
</div>
<script>
let getUrlKey = function(name){
return decodeURIComponent((new RegExp('[?|&]'+name+'='+'([^&;]+?)(&|#|;|$)').exec(location.href)||[,""])[1].replace(/\+/g,'%20'))||null;
};
var app = new Vue({
el: '#app',
data: {
data1: {},
data2:[]
},
created: function() {
axios.get('/api2/demo?id='+getUrlKey('id')) // 需要预先在esap/sql/api2下定义demo模板
.then(r => { this.data1=r.data.data[0][0];this.data2=r.data.data[1] })
.catch(e => { console.log(e) })
}
})
</script>
</body>
</html>
在esap/sql/api2目录下新建一个test.get文件,里面定义demo模板
{{define "demo"}}
select 编号,日期,客户,总数量,总金额,物流进度 from demo where 编号=:id
select * from demod where 编号=:id
{{end}}
扫描二维码其实就是执行了这个查询,代入编号后的查询结果如图:
村长直接绑定了一个专属应用,其实也可以绑定菜单ID,注意原文URL填/static/app2?id={ {.p0} }
,也就是web模板路径+查询参数
大功告成,可以去生成几个二维码扫描测试了!
本案综合应用了esap的数据api
,web-server
,微信查询
。
本案涉及的文件已打包点击下载,欢迎下载玩耍。