# SatWeb旧版本(20210510及以前)

SatWeb框架将H5和传统的CS程序融合,主体是纯H5页面,运行在浏览器中,CS程序可以由PB,Delphi,C#,VB等语言开发,通过提供的组件,将CS运行在html5框架的tab中。解决了传统CS开发界面不美观,升级困难等问题。方便快速将现有的CS程序Web化,避免程序WEB化时全部重新开发,一次投入过大。后续客户可以根据自己的需要借助框架把CS功能逐渐全Web化。 借助SatRDA提供的强大的插件功能,可以很容易实现跨平台的前端和后台的开发。

# 下载地址:

群文件下载 SatRDA_V20210510

  • QQ群:345559891
  • Delphi开发群:374683171

# 界面预览

web webloading webmessage

# 开始使用

  1. 下载最新版本并解压

  2. 进入server目录,双击satserver.exe运行

  3. 打开浏览器,输入 http://127.0.0.1:5555/webui (opens new window), 可以看到效果

# SatWeb配置

  1. 通过SatRDA后台配置 配置SatRDA插件

  2. 点击插件管理,可以看到webuierp两个插件 其中webui插件是SatWeb的H5界面,类型是h5,提供浏览器看到的全部html5界面。其中Dir为web/webui表示文件为plugins/web/webui, webui把框架html5全部打包成了一个文件。
    其中erp为框架提供webapi,这里类型是js插件,用js实现了webapi,也可以使用pb,delphi等实现。js实现webapi的好处是可以跨平台,支持linux运行。
    更详细了解js和h5插件可以参考satrda插件

# 自定义框架显示菜单

示例中框架的菜单如下:
menu

该菜单是根据plugins/erp/test.js文件中写的webapi返回的,

function satrda_service(url,ctx,r,w) {			
	console.log("satrda_service:" + url)
	satrda.Router.serveHttp(url,ctx,r,w)
}

(function() {
	let app = {
		captchaImage(ctx,r,w) {
			let captcha = satrda.Captcha;
			let data = captcha.create({type:"string",height:40,width:120})
			w.write(data);
		},
		login(ctx,r,w) {
			let data = r.jsonBody;
			//校验成功
			if (satrda.Captcha.verify(data.uuid,data.code.toLowerCase())) {
				w.write({code:0,token:"123456",msg:"操作成功"})
			} else {
				w.write({code:500,msg:"校验失败"})
			}
			
		},
		getInfo(ctx,r,w) {
			let data = {"msg":"操作成功","code":200,"permissions":["*:*:*"],"roles":["admin"],"user":{"searchValue":null,"createBy":"admin","createTime":"2018-03-16 11:33:00","updateBy":null,"updateTime":null,"remark":"管理员","dataScope":null,"params":{},"userId":1,"deptId":103,"userName":"admin","nickName":"satrda","email":"satrda@163.com","phonenumber":"15888888888","sex":"1","avatar":"","password":"$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2","salt":null,"status":"0","delFlag":"0","loginIp":"127.0.0.1","loginDate":"2018-03-16T11:33:00.000+0800","dept":{"searchValue":null,"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"dataScope":null,"params":{},"deptId":103,"parentId":101,"ancestors":null,"deptName":"研发部门","orderNum":"1","leader":"admin","phone":null,"email":null,"status":"0","delFlag":null,"parentName":null,"children":[]},"roles":[{"searchValue":null,"createBy":null,"createTime":null,"updateBy":null,"updateTime":null,"remark":null,"dataScope":"1","params":{},"roleId":1,"roleName":"管理员","roleKey":"admin","roleSort":"1","status":"0","delFlag":null,"flag":false,"menuIds":null,"deptIds":null,"admin":true}],"roleIds":null,"postIds":null,"admin":true}};
			w.write(data);
		},
		getRouters(ctx,r,w) {

			let data = {"msg":"操作成功","code":200,"data":[{"name":"Demo","path":"/demo","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"Demo","icon":"tool"},"children":[{"name":"Driver","path":"driver","hidden":false,"component":"cschild","meta":{"title":"数据驱动","icon":"build"}},{"name":"Http","path":"http","hidden":false,"component":"cschild","meta":{"title":"HTTP","icon":"code"}},{"name":"Push","path":"push","hidden":false,"component":"cschild","meta":{"title":"即时推送","icon":"swagger"}},{"name":"Crypt","path":"crypt","hidden":false,"component":"cschild","meta":{"title":"常用算法","icon":"swagger"}},{"name":"Json","path":"json","hidden":false,"component":"cschild","meta":{"title":"Json","icon":"swagger"}}]},{"name":"CS","path":"/cs","hidden":false,"redirect":"noRedirect","component":"Layout","alwaysShow":true,"meta":{"title":"cs窗口","icon":"tool"},"children":[{"name":"Win1","path":"win1","hidden":false,"component":"cschild","meta":{"title":"窗口1","icon":"build"}},{"name":"Win2","path":"win2","hidden":false,"component":"cschild","meta":{"title":"窗口2","icon":"code"}},{"name":"Win3","path":"win3","hidden":false,"component":"cschild","meta":{"title":"窗口3","icon":"swagger"}}]}]}
			w.write(data);
		},
		logout(ctx,r,w) {
			let data = {msg:"操作成功",code:200};
			w.write(data);
		}
	}
	
	satrda.Router.all("/erp",app);

})();

其中satrda.Router.all("/erp",app);表示将/erp开头的api注册到app对象中,注册后app中的方法会映射为webapi。如getRouters方法的webapi地址为/erp/getRouters,该方法提供了自定义的框架菜单,可以看到实现非常简单,修改json为自己程序的菜单。也可以通过取数据库内容动态生成,js插件的更多示例可以参考示例的js/test.js。插件也支持断点调试,具体参考SatRDA用户手册。
app对象中还有一些方法,captchaImage 提供了验证码功能,login提供了用户登录验证。
这里为了代码清晰,菜单json压缩成了一行,建议修改菜单时,先把getRouters中的菜单json进行格式化,格式化后如下:

{
	"msg": "操作成功",
	"code": 200,
	"data": [{
			"name": "Demo",
			"path": "/demo",
			"hidden": false,
			"redirect": "noRedirect",
			"component": "Layout",
			"alwaysShow": true,
			"meta": {
				"title": "Demo",
				"icon": "tool"
			},
			"children": [{
					"name": "Driver",
					"path": "driver",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "数据驱动",
						"icon": "build"
					}
				}, {
					"name": "Http",
					"path": "http",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "HTTP",
						"icon": "code"
					}
				}, {
					"name": "Push",
					"path": "push",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "即时推送",
						"icon": "swagger"
					}
				}, {
					"name": "Crypt",
					"path": "crypt",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "常用算法",
						"icon": "swagger"
					}
				}, {
					"name": "Json",
					"path": "json",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "Json",
						"icon": "swagger"
					}
				}
			]
		}, {
			"name": "CS",
			"path": "/cs",
			"hidden": false,
			"redirect": "noRedirect",
			"component": "Layout",
			"alwaysShow": true,
			"meta": {
				"title": "cs窗口",
				"icon": "tool"
			},
			"children": [{
					"name": "Win1",
					"path": "win1",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "窗口1",
						"icon": "build"
					}
				}, {
					"name": "Win2",
					"path": "win2",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "窗口2",
						"icon": "code"
					}
				}, {
					"name": "Win3",
					"path": "win3",
					"hidden": false,
					"component": "cschild",
					"meta": {
						"title": "窗口3",
						"icon": "swagger"
					}
				}
			]
		}
	]
}

可以按照这个格式修改或添加自己的菜单,修改完成后,把这个json复制回getRouters函数,重新运行satserver即可以看到效果

# CS程序修改

CS程序可以通过发消息与satweb框架交互,satweb打开关闭窗口时,会发送消息给CS程序,CS程序需要调用框架的loading和messagebox等也可以给satweb发消息。

# PB示例代码

  1. 主窗口定义实例变量
n_win_service n_win

2.主窗口open加上代码

n_win.of_init(handle(this))
//修改为网页上显示的id值,可以调试时附加到浏览器
n_api.il_web = 723334
//如果在浏览器打开,此函数会把窗口附加到浏览器
n_api.of_webapp_attach(handle(this), false)

  1. 窗口other事件
long ll_msg
ulong ll_data
string ls_cmd

ll_msg = message.number
//得到浏览器发送回来的数据,可以自己根据返回的字符参数,确定要执行的操作。
if ll_msg = 74 then
	ll_data = n_api.SatWebApp_GetData(lparam)
	ls_cmd = n_api.of_utf8tostring(ll_data)
	
	event ue_webcmd(ls_cmd)
end if
  1. 定义ue_webcmd事件
//接收网页发过来的命令
string ls_params[]
string ls_key
ulong ll_hwnd
ls_params = n_api.of_split( as_cmd, ";")
if ls_params[1] = "open" then
	ls_key = ls_params[2]
	ll_hwnd = long(ls_params[3])
	choose case ls_key
		case "/demo/driver"
			n_win.of_openchild(ls_key, "w_child", ll_hwnd)
		case "/demo/http"
			n_win.of_openchild(ls_key, "w_http", ll_hwnd)
		case "/demo/push"
			n_win.of_openchild(ls_key, "w_push", ll_hwnd)
		case "/demo/crypt"
			n_win.of_openchild(ls_key, "w_crypt", ll_hwnd)
		case "/demo/json"
			n_win.of_openchild(ls_key, "w_json", ll_hwnd)
		case else
			n_win.of_openchild(ls_key, "w_child", ll_hwnd)
	end choose
	
elseif ls_params[1] = "close" then
	n_win.of_closechild(ls_params[2])
elseif ls_params[1] = "hide" then
	n_win.of_hideChild()
elseif ls_params[1] = "location-host" then 
	n_api.il_host = ls_params[2]
elseif ls_params[1] = "user" then
	ls_key = ls_params[2]
end if

可以在该事件中打开自己的窗口。更多内容参考具体的示例

# CS程序调试

在实际的开发过程中,调试程序是最常用的功能。satweb框架允许CS程序在ide调试过程中加载到框架,方便开发人员实时看到效果。调试步骤:

  1. 在浏览器输入 http://127.0.0.1:5555/webui?debug=true 显示如下: debug
  2. pb程序在窗口open事件中修改n_api.il_web为网页id值,运行程序,即可
//修改为网页上显示的id值,可以调试时附加到浏览器
n_api.il_web = 593820

# 编译发布

记住将n_api.il_web改为-1,不用调试模式。将程序编译为exe,然后通过上传工具,上传到应用名为test的应用中。上传工具使用可以参考自动升级