在供应链中,大客户会给上游供应商提供一些web系统,用于接收打印新的订单、入库单等。
通常,供应商需要用客户提供的账号密码登陆这些系统,下载订单,再录入到自己的ERP系统中。
本文介绍一种自动登陆抓取WEB订单的解决方案。
先让我们来探索一下这个客户的web订单打印系统。
首先,用chrome浏览器访问客户web系统登陆页面,按F12
打开开发工具。
接下来,输入账号密码登陆,登陆后,查询一下订单,然后逐个查看右侧列表的历史请求。
我们可以发现浏览器首先把账号密码POST到Login.aspx,进行登陆。
然后下载了一大堆静态资源(css/js/png等等),这些可以跳过不看,最后发现一个api数据请求CRUDhandler.ashx,这个POST请求的请求表单包含一系列参数。
点击Preview
标签,展开返回的json,可以发现原来数据都在这个rows数组里,包含了大量订单信息。
好了,到这里我们大概明白了这个web系统的原理:先post账号密码到Login.aspx获取cookie,再post供应商号等到CRUDHandler.ashx获取订单信息。
以NX为例,首先在外部接口中注册一下这个网站及下面的接口。
其中Login.aspx这个登陆接口主要传入账号密码(txtusername,txtpassword),传出随便填一个文本字段,比如test(实际没传出,但后面提数时必填,所以随便弄一个)
另一个CRUDHandler.ashx数据接口有一堆传入参数,一个不落都设置好。
传出表结构也有一堆字段,这些字段根据实际真实订单一一对应填好备注,便于识别使用。
在订单导入模板中加两个提数,设置通过API提取
第一个叫q登陆
,使用登陆接口,传入绑定字段填入账号密码,返回字段随便找个绑定test,不然不给保存ORZ……
第二个叫q数据
,使用数据接口,传入绑定字段填入浏览器请求中使用的内容,返回的rows表结构填充给本模板明细表。
最后做个抓订单
按钮,执行这两个提数公式。
改进前:我们需要登陆客户的网站,设置查询参数,点击查询按钮查询订单列表,挑选新订单,导出订单,再录入到自己的ERP系统。
改进后:直接登陆自己的ERP系统,一键自动登陆+抓取+存入。
使用chrome分析客户web系统的请求过程。
使用api提数模拟登陆请求和数据请求。
使用按钮执行api提数。
2019-08-15
上一章讲了详情页面的自定义,这一章继续讲列表页面,更简单哦
将原生的列表改成直接显示商品图片的列表,改改css,还可以做淘宝的卡片列表哦。
在NX安装目录/web/esap/下建立一个html文件,例如goods.html
,作为商品表
的列表页面。
goods.html文件代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<title>商品查询</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">
<a v-for="item,key in data1" :href="'http://外部IP或域名/#!/myReport/1/133/' + item.RecordID + '/0/null'" class="weui-media-box weui-media-box_appmsg">
<div class="weui-media-box__hd">
<img class="weui-media-box__thumb" :src="'http://esap:9090/p/' + item.图片" alt="图片" />
</div>
<div class="weui-media-box__bd">
<p>{{ item.品名 }}</p>
<p>{{ item.规格 }}</p>
</div>
</a>
<a href="javascript:;" class="weui-btn weui-btn_mini weui-btn_primary">增加</a>
<a href="javascript:history.go(-1);" class="weui-btn weui-btn_mini weui-btn_primary">返回</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: {}
},
created: function() {
axios.get('http://esap:9090/api2/goods?id='+getUrlKey('id')) // 需要预先在esap/sql/api2下定义goods模板
.then(r => {
this.data1=r.data.data[0]
})
.catch(e => { console.log(e) })
}
})
</script>
</body>
</html>
说明:
'http://外部IP或域名/#!/myReport/1/133/' + item.RecordID + '/0/null'
是拼接详情页面的url,可以从原生详情页面的url修改,133是模板号
'http://esap:9090/p/' + item.图片
是拼接商品图片URL,属于esap-api
本案使用esap的数据api,当然,你也可以使用NX自带的api。
在上一篇的esap/sql/api2/xs.get文件追加定义goods
模板如下:
{{define "goods"}}
select * from 商品表
{{end}}
在设计器中设置商品表模板属性-外部界面-【列表页面】,URL设为:esap/xsdd.html?id={RecordID}
通过上述3步,就实现了列表页面自定义,报表详情页面仍然使用原生页面。
回顾一下上一篇的详情页面自定义变化:
再看看列表页面自定义后的变化:
使用vue + axios + weui编写h5页面。
使用esap-api获取数据,其中图片api为:http://esap服务器:9090/p/picId
设置外部界面中的自定义URL。
PS: 慧表NX外部界面需正式版特殊授权,试用版无此选项,特此提醒。
2019-08-02
搭载esap4.0的ex-app来袭,自定义界面,快速定制你的APP
ex-app大量采用nxapp+自定义UI,本案采用表格展现销售订单明细数据,替换了原生详情页面的流式布局,查询时更简洁,更直观。
在NX安装目录/web/目录下建立一个目录,例如esap
,里面建立一个html文件,例如xsdd
,作为销售订单
的详情页面。
xsdd.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>
<th>单位</th>
</tr>
<tr v-for="item2,key2 in data2">
<td style="padding:6px">{{ item2.品号 }}</td>
<td>{{ item2.品名 }}</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('http://esap:9090/api2/xsdd?id='+getUrlKey('id')) // 需要在esap/sql/api2下定义xsdd模板
.then(r => {
this.data1=r.data.data[0][0]
this.data2=r.data.data[1]
})
.catch(e => { console.log(e) })
}
})
</script>
</body>
</html>
本案使用esap的数据api,当然,你也可以使用NX自带的api。
在esap/sql/api2/目录下建立xs.get文件
里面定义销售订单详情查询模板xsdd
:
{{define "xsdd"}}
select 单号,日期,往来,往来号,制单 from 订单表 where recordid={{.id}}
select 品号,品名,规格,数量,单位 from 订单D where recordid={{.id}}
{{end}}
这里有两个语句,都是用URL中的id参数匹配recordid,一个查主表订单表
,一个查明细订单D
,选择部分字段用于展示。
在设计器中设置销售订单模板属性-外部界面-【报表页面】,URL设为:esap/xsdd.html?id={RecordID}
通过上述3步,就实现了详情页面自定义。
从原生的流式布局:
变为表格布局:
使用vue+axios编写h5页面。
使用esap-api获取数据。
设置外部界面中的自定义URL,同理,列表也可以自定义,例如列表改成卡片式。
PS: 慧表NX外部界面需正式版特殊授权,试用版无此选项,特此提醒。
2019-08-01
esap4.0的更新通常会伴随发布一个nxt示例库,导入这个库后,稍作修改就可以同时为多个应用进行服务,像一个八爪章鱼一样,这就是ESAP最佳实践经验之一的章鱼模式
登陆admin,在设置-数据库中开启其他应用库,例如:pws
,esapp1
等等。
把提醒模板单独导出导入到其他应用,在计划任务中设置相应的提醒,任务ID
第一段设为该库的数据源名
。
自定义提醒同理,额外添加后缀。
修改查询,数据源填入其他库源名,模板函数后面也可以加入。
这样,查询结果,例如身份证信息就会存入其他数据库,而不是nxt库了。
记得先在其他库建立或导入模板用于承接数据。
自定义API的sql模板位于esap/sql/api2/,多库时,只要在请求URL上加个db参数即可。
例如:请求http://esap:9090/api2/action?id=1
,会默认用esap
库执行。
而请求http://esap:9090/api2/action?id=1&db=pws
,就会用pws
库执行。
始终使用nxt库作为主库。
通过不同的配置,去操作其他应用库(NX/ES/金蝶/用友等)。
本文示例应用ESAP4.0.8+支持。
2019-07-19
esap4.0的机器人已经非常强大,而不满足于此的童鞋们又提出是否能直接在工作台也体验AI识别的快感。
本文以NX为例就这个问题展示如果打造原生体验的识别方案。
工作台建立表单插入或复制粘贴图片后,就可以开始点按钮立即识别。
把查询模板简化一下,只需要输入需要的字段即可。
示例中,建立sql/api2/bdai.post文件,里面建立下列AI识别sql模板
{{define "aiidcard"}}
{{with $data := post ("bdai" | token | printf "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=%v") (.praw | body | base64 | map "detect_direction" "true" "id_card_side" "front" "image")}}
select '{{.words_result.公民身份号码.words}}' 号码
,'{{.words_result.姓名.words}}' 姓名
,'{{.words_result.性别.words}}' 性别
,'{{.words_result.民族.words}}' 民族
,'{{.words_result.出生.words}}' 出生
,'{{.words_result.住址.words}}' 住址
{{end}}
{{end}}
{{define "aiidcardback"}}
{{with $data := post ("bdai" | token | printf "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=%v") (.praw | body | base64 | map "detect_direction" "true" "id_card_side" "back" "image")}}
select 签发机关= '{{.words_result.签发机关.words}}'
,签发日='{{.words_result.签发日期.words}}'
,失效日='{{.words_result.失效日期.words}}'
{{end}}
{{end}}
{{define "aidriving"}}
{{with $data := post ("bdai" | token | printf "https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license?access_token=%v") (.praw | body | base64 | map "detect_direction" "true" "accuracy" "high" "image")}}
select '{{.words_result.证号.words}}' 证号
,'{{.words_result.姓名.words}}' 姓名
,'{{.words_result.准驾车型.words}}' 准驾车型
,'{{.words_result.住址.words}}' 住址
,'{{.words_result.有效期限.words}}' 有效期限
{{end}}
{{end}}
{{define "aivehicle"}}
{{with $data := post ("bdai" | token | printf "https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license?access_token=%v") (.praw | body | base64 | map "detect_direction" "true" "image")}}
select '{{.words_result.车辆识别代号.words}}' 车辆识别代号
,'{{.words_result.所有人.words}}' 所有人
,'{{.words_result.号牌号码.words}}' 号牌号码
,'{{.words_result.住址.words}}' 住址
,'{{.words_result.注册日期.words}}' 注册日期
,'{{.words_result.品牌型号.words}}' 品牌型号
{{end}}
{{end}}
{{define "aiplate"}}
{{with $data := post ("bdai" | token | printf "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate?access_token=%v") (.praw | body | base64 | map "detect_direction" "true" "image")}}
select '{{.words_result.number}}' 车牌
,'{{.words_result.color}}' 颜色
{{end}}
{{end}}
{{define "aiocr"}}
{{with $data := post ("bdai" | token | printf "https://aip.baidubce.com/rest/2.0/ocr/v1/webimage?access_token=%v") (.praw | body | base64 | map "detect_direction" "true" "image")}}
select '{{range $v := .words_result}}{{$v.words}},{{end}}' 文字
{{end}}
{{end}}
在NX-设计区-外部接口中一一注册这些接口
接口传入,统一为praw,即图片
传出需要先建一个表结构,字段与上面的sql模板输出对应
然后传出这个表结构即可
采用API提数,传入本表图片字段,传出表一一对应填入本表。
身份证正反面同时识别
使用ESAP定义查询API
使用NX的API提数
本文示例应用ESAP4.0.8+支持。
2019-07-18