" + row.text + "";
145 | html += "
";
148 | }else {
149 | html += ""
152 | }
153 | return html;
154 | }
155 |
156 | getLayoutRoadMenu = function(tab){
157 | var html = "";
158 | for(i,t in tab){
159 | html += "
" + t[1] + "";
160 | if(i < #tab) html += "
";
161 | }
162 | return html;
163 | }
164 |
--------------------------------------------------------------------------------
/lib/carl/sql.aardio:
--------------------------------------------------------------------------------
1 |
2 | namespace carl.sql
3 |
4 | namespace ms{
5 | string = ..string;
6 | table = ..table;
7 |
8 | getInsertSql = function(tabname,tab){
9 | var t = {};
10 | table.push(t,"insert into " + tabname + "(");
11 | for k,v in table.eachName(tab){
12 | if(type(v) == type.string || type(v) == type.number || type(v) == type.boolean){
13 | table.push(t,k,",");
14 | }
15 | }
16 | t[#t] = "";
17 | table.push(t,")values(");
18 | for k,v in table.eachName(tab){
19 | if(type(v) == type.string){
20 | v = string.str(v);
21 | if(string.lower(v) == "getdate()" || v === "NULL" || (string.startWith(v,"@") && !string.find(string.right(v,#v-1),"\A"))){
22 | table.push(t,v,",");
23 | }
24 | else {
25 | table.push(t,"'",string.replace(v,"'","''"),"'",",");
26 | }
27 | }
28 | elseif(type(v) == type.number){
29 | table.push(t,v,",");
30 | }
31 | elseif(type(v) == type.boolean){
32 | table.push(t,v?1:0,",");
33 | }
34 | }
35 | t[#t] = "";
36 | table.push(t,")")
37 | return string.join(t);
38 | };
39 |
40 | getUpdateSql = function(tabname,tab,where){
41 | var t = {};
42 | table.push(t,"update " + tabname + " set ");
43 | for k,v in table.eachName(tab){
44 | if(type(v) == type.string){
45 | v = string.str(v);
46 | if(string.lower(v) == "getdate()" || v === "NULL"){
47 | table.push(t,k,"=",v,",")
48 | }
49 | else {
50 | table.push(t,k,"=");
51 | table.push(t,"'",string.replace(v,"'","''"),"'",",")
52 | }
53 | }
54 | elseif(type(v) == type.number){
55 | table.push(t,k,"=",v,",");
56 | }
57 | elseif(type(v) == type.boolean){
58 | table.push(t,k,"=",v?1:0,",");
59 | }
60 | }
61 | t[#t] = "";
62 | table.push(t," where ",where);
63 | return string.join(t);
64 | };
65 |
66 | getPageSql=function(sql, currentPage, pageSize, orderRowName,countName="rowCount",rowName="rowId"){
67 | if( !#orderRowName ) return sql;
68 | currentPage = tonumber(currentPage) : 1;
69 | pageSize = tonumber(pageSize) : 30;
70 | var curr = currentPage < 1 ? 1 : currentPage;
71 | var startRowNum = (curr - 1) * pageSize + 1;
72 | var endRowNum = startRowNum + pageSize - 1;
73 | var mysql = "SELECT *,(SELECT COUNT(*) FROM( " + sql + " )AS h) AS '" + countName + "' FROM (SELECT *,ROW_NUMBER() OVER ";
74 | mysql +="(ORDER BY " + orderRowName + ") AS '" + rowName + "' FROM ( " + sql + ")AS c) a ";
75 | mysql +="WHERE a." + rowName + " BETWEEN " + startRowNum + " AND " + endRowNum;
76 | return mysql;
77 | };
78 | }
79 |
80 | namespace my{
81 | string = ..string;
82 | table = ..table;
83 |
84 | getInsertSql = function(tabname,tab){
85 | var t = {};
86 | table.push(t,"insert into " + tabname + "(");
87 | for k,v in table.eachName(tab){
88 | if(type(v) == type.string || type(v) == type.number || type(v) == type.boolean){
89 | table.push(t,k,",");
90 | }
91 | }
92 | t[#t] = "";
93 | table.push(t,")values(");
94 | for k,v in table.eachName(tab){
95 | if(type(v) == type.string){
96 | v = string.str(v);
97 | v = string.replace(v,"@\","\\");
98 | if(string.lower(v) == "now()" || v === "NULL"){
99 | table.push(t,v,",");
100 | }else {
101 | table.push(t,"'",string.replace(v,"'","''"),"'",",");
102 | }
103 | }
104 | elseif(type(v) == type.number){
105 | table.push(t,v,",");
106 | }
107 | elseif(type(v) == type.boolean){
108 | table.push(t,v?1:0,",");
109 | }
110 | }
111 | t[#t] = "";
112 | table.push(t,")")
113 | return string.join(t);
114 | };
115 |
116 | getUpdateSql = function(tabname,tab,where){
117 | var t = {};
118 | table.push(t,"update " + tabname + " set ");
119 | for k,v in table.eachName(tab){
120 | if(type(v) == type.string){
121 | v = string.str(v);
122 | v = string.replace(v,"@\","\\");
123 | if(string.lower(v) == "now()" || v === "NULL"){
124 | table.push(t,k,"=",v,",")
125 | }
126 | else {
127 | table.push(t,k,"=");
128 | table.push(t,"'",string.replace(v,"'","''"),"'",",")
129 | }
130 | }
131 | elseif(type(v) == type.number){
132 | table.push(t,k,"=",v,",");
133 | }
134 | elseif(type(v) == type.boolean){
135 | table.push(t,k,"=",v?1:0,",");
136 | }
137 | }
138 | t[#t] = "";
139 | table.push(t," where ",where);
140 | return string.join(t);
141 | };
142 |
143 | getPageSql=function(sql, currentPage, pageSize, orderRowName,countName="rowCount"){
144 | if( !#orderRowName ) return sql;
145 | currentPage = tonumber(currentPage) : 1;
146 | pageSize = tonumber(pageSize) : 30;
147 | var curr = currentPage < 1 ? 1 : currentPage;
148 | var startRowNum = (curr - 1) * pageSize;
149 | var mysql = "SELECT *,(SELECT COUNT(*) FROM( " + sql + " )h) AS '" + countName + "' FROM( " + sql + ")c";
150 | mysql += " ORDER BY " + orderRowName;
151 | mysql += " LIMIT " + startRowNum + "," + pageSize;
152 | return mysql;
153 | };
154 | }
--------------------------------------------------------------------------------
/lib/carl/ctrl/comboboxex.aardio:
--------------------------------------------------------------------------------
1 | //comboboxex 下拉多选框
2 | namespace carl.ctrl.comboboxex{}
3 |
4 | import win.ui.tracker;
5 | import win.ui.ctrl.metaProperty;
6 | import carl.ctrl.treeviewex;
7 |
8 | namespace win.ui.ctrl;
9 |
10 | class comboboxex{
11 | ctor(parent,tParam){
12 |
13 | this = ..win.form(right=100;bottom=25;border="none";exmode="none";mode="child";parent=parent;tParam=tParam)
14 | this.add(
15 | btn={cls="button";text="u";left=82;top=1;right=100;bottom=25;dr=1;dt=1;font=LOGFONT(name='Marlett';charset=2;weight=500);tabstop=1;z=2};
16 | edit={cls="edit";left=1;top=1;right=82;bottom=25;autohscroll=false;autovscroll=false;dl=1;dr=1;dt=1;edge=1;hidesel=1;readonly=1;z=1}
17 | )
18 |
19 | this.btn.oncommand = function(id,event){
20 | this.hideForm();
21 | }
22 | var winform = ..win.form(right=100;bottom=100;border="none";exmode="none";parent=this);
23 | winform.add(treeview={cls="treeview";left=0;top=0;right=100;bottom=100;ah=1;asel=false;aw=1;bgcolor=16777215;chkBox=1;db=1;dl=1;dr=1;dt=1;edge=1;hscroll=1;singleExpand=false;vscroll=1;z=1});
24 | this.tvEx = ..win.ui.ctrl.treeviewex(winform.treeview);
25 | this.startFirst = false;
26 |
27 | this.onDestroy = function(){
28 | winform.close();
29 | }
30 |
31 | var fromPoint = ::User32.api("WindowFromPoint", "int(int x, int y)");
32 |
33 | ..win.ui.tracker(this.btn).onMouseLeave = function(wParam,lParam){
34 | while(true){
35 | var hwnd = fromPoint(..win.getMessagePos());
36 | if(hwnd != winform.treeview.hwnd && hwnd != this.edit.hwnd){
37 | if(this.isShow) this.hideForm();
38 | break ;
39 | }
40 | ..win.delay(200)
41 | }
42 | }
43 | };
44 |
45 | onCreate = function(){
46 | this.tvEx.exCheckBoxesChanged = function(hItem, checked){//选中事件
47 | var tab = this.tvEx.getItemData(hItem);
48 | if(tab) tab.checked = checked;
49 |
50 | var t = {};
51 | this.tvEx.enum(
52 | function(hItem,parent){
53 | var tab = this.tvEx.getItemData(hItem);
54 | var child = false;
55 | for h in this.tvEx.each(hItem){
56 | child = true;
57 | break ;
58 | }
59 | if(tab && tab.checked && !child) table.push(t,tab.text)
60 | }
61 | )
62 | this.edit.text = string.join(t,";");
63 | this.text = this.edit.text;
64 | }
65 | this.tvEx.onnotify = function(id,code,ptr) {
66 | /*响应通知*/
67 | return this.tvEx.exOnnotify(id,code,ptr);
68 | };
69 | this.edit.text = this.text;
70 | }
71 |
72 | hideForm = function(){
73 | var show = this.btn.text=="u" ? true : false;
74 | this.btn.text = this.btn.text=="u" ? "t" : "u";
75 | var x,y,cx,cy = ..win.getPos(this.hwnd,true);
76 | winform.setPos(x,y+cy-2,cx,200);
77 | winform.show(show);
78 | if(show && !this.startFirst){
79 | ..win.delay(200);
80 | this.setChecked();
81 | this.startFirst = true;
82 | }
83 | this.isShow = show;
84 | }
85 |
86 | insertItem = function(...){
87 | this.tvEx.insertItem(...);
88 | this.tvEx.exExpandAll();
89 | this.edit.text = this.text;
90 | this.setChecked();
91 | this.tvEx.ensureVisible(this.tvEx.getFirst())
92 | }
93 |
94 | setChecked = function(){
95 | var tabchecked = string.split(this.text,";");
96 | this.tvEx.enum(
97 | function(hItem,parent){
98 | var tab = this.tvEx.getItemData(hItem);
99 | if(tab){
100 | if(table.find(tabchecked,tab.text)){
101 | tab.checked = true;
102 | this.tvEx.setChecked(hItem,true)
103 | }else {
104 | tab.checked = false;
105 | this.tvEx.setChecked(hItem,false)
106 | }
107 | }
108 | }
109 | )
110 | }
111 |
112 | getChecked = function(key){
113 | var t = {};
114 | this.tvEx.enum(
115 | function(hItem,parent){
116 | var tab = this.tvEx.getItemData(hItem);
117 | if(tab && tab.checked){
118 | var tc = table.clone(tab);
119 | for(i=1;#tc;1) table.remove(tc);
120 | if(key){
121 | table.push(t,tc[key])
122 | }else {
123 | table.push(t,tc)
124 | }
125 | }
126 | }
127 | )
128 | return t;
129 | }
130 |
131 | getKey = function(key){
132 | var t = {};
133 | this.tvEx.enum(
134 | function(hItem,parent){
135 | var tab = this.tvEx.getItemData(hItem);
136 | if(tab){
137 | var tc = table.clone(tab);
138 | for(i=1;#tc;1) table.remove(tc);
139 | if(key){
140 | table.push(t,tc[key])
141 | }else {
142 | table.push(t,tc)
143 | }
144 | }
145 | }
146 | )
147 | return t;
148 | }
149 |
150 |
151 | }
152 |
153 | namespace comboboxex{
154 | string = ..string;
155 | table = ..table;
156 | }
157 |
158 | /*intellisense()
159 | win.ui.ctrl.comboboxex = 下拉多选控件
160 | win.ui.ctrl.comboboxex() = 下拉多选控件
161 | ?win.ui.ctrl.comboboxex = !comboboxex.
162 | !comboboxex.insertItem(table对像) = table对象,用法与treeview.insertItem一样,
163 | !comboboxex.getChecked() = 返回所有选中项table对像
164 | !comboboxex.getChecked(key) = 返回所有选中项key值table对像
165 | !comboboxex.getKey() = 返回全部项table对像
166 | !comboboxex.getKey(key) = 返回全部项key值table对像
167 | end intellisense*/
168 |
--------------------------------------------------------------------------------
/aardio-rpc/main.aardio:
--------------------------------------------------------------------------------
1 |
2 | if( !request ){
3 |
4 | /*
5 | 创建一个兼容FastCGI接口的简单Web服务器,如果已经在Web服务器环境下这段可以省略。
6 | */
7 | import fsys.log;
8 | import wsock.tcp.simpleHttpServer;
9 | import process;
10 | import console;
11 |
12 | global.onError = function( err,over ){
13 | if(!over){
14 | import debug;
15 | var stack = debug.traceback(,"调用栈",3);
16 | err = ..string.concat(err,'\n',stack);
17 | }
18 | fsys.log.print( err );
19 | }
20 |
21 | var server = wsock.tcp.simpleHttpServer("127.0.0.1",/*8081*/);
22 | console.setTitle("aardio rpc服务器已启动 " + server.getUrl() );
23 | process.execute( server.getUrl() )
24 |
25 | server.run(
26 | function(response,request){
27 | response.loadcode( request.path ); //参数可以省略
28 | }
29 | );
30 |
31 | return;
32 | }
33 |
34 | ?>
35 |
36 |
37 |
38 |
39 |
40 |
aardio rpc
41 |
42 |
43 |
查看RPC服务运行情况
44 |
aardio rpc技术支持论坛
45 |
46 | 文件说明:
47 | \rpc.aardio RPC服务端首页
48 | \config.aardio 配置文件
49 | \functions.aardio 自定义函数
50 | \sqlhelper.aardio 数据库操作类
51 |
52 | IDE环境测试步骤
53 | 1.在aardio10 打开本工程直接按F5运行
54 | 2.运行以下例子
55 |
56 | 正式服务端架设步骤
57 | 1.在aardio10 新建工程,选择FastCGI服务端,并在main.aardio文件中加载以下4个库
58 |
import carl.rpc.server;
59 |
import carl.mssql;
60 |
import carl.mysql;
61 |
import carl.oracle;
62 | 然后发布成aardio-cgi.exe程序
63 | 2.架设IIS网站,并添加模块映射,指定aardio-cgi.exe
64 | 3.发布本工程aardio-rpc,IIS网站目录指向发布后的Publish文件夹
65 | 4.运行以下例子
66 |
67 | 客户端运用例子:
68 |
import console
69 | import carl.rpc.client;
70 |
71 | console.open()
72 |
73 | var serverUrl = "http://= request.host?>/rpc.aardio";//rpc服务端地址
74 |
75 | /*
76 | RSA公钥,留空不加密,
77 | 需要配置服务端 /config.aardio 文件
78 | */
79 | var rsaPublicKey = /*
80 | BgIAAACkAABSU0ExAAQAAAEAAQDve7UdKeI35NfLa8JkE4YQsxwKNCeE/OwAsqwd
81 | iVv/g4I0Lay5DupUhM8j8DHPePg6TFiDQ2APSaSRx5hiA/lrDlfX2UBltJV+Hzl8
82 | lxhj/wChQl8+7A9I6IvcyjqCzwZMRllVj5cOUFouxJJV/PqemQf5n+vQJ90V2B6F
83 | kCnjxg==
84 | */
85 |
86 | var rpcClient = carl.rpc.client(serverUrl, rsaPublicKey);
87 |
88 | var serverTime,err = rpcClient.getServerTime();
89 | console.log("服务端getServerTime返回值",serverTime,err);
90 |
91 | console.log("服务端funTest返回值",rpcClient.funTest("参数1",{a=3},true,false));
92 |
93 | console.log("服务端函数不存在",rpcClient.abcd());
94 |
95 | var tab,err = rpcClient.getTable("select * from UserInfo")//执行SQL,返回结果集
96 | if(!tab) console.log("SQL执行失败",err);
97 |
98 | for(i=1;#tab;1){
99 | var row = tab[ i ]
100 | console.log(i,table.tostring(row))
101 | }
102 | /*
103 | 服务端默认已封装4个常用数据库函数:
104 | rpcClient.exec() //执行SQL无返回值
105 | rpcClient.getTable() //执行SQL返回结果集
106 | rpcClient.getTables() //执行多个SQL返回结果集
107 | rpcClient.transaction();//事务执行
108 | rpcClient.storedProcedures();//执行储存过程
109 | 用法请查看库 carl.mysql或carl.mssql 两个库
110 | */
111 | rpcClient.close();
112 |
113 | console.pause(true)
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/aardio-erp/lib/ws/System/SystemMenu.aardio:
--------------------------------------------------------------------------------
1 |
2 | namespace ws.System.SystemMenu
3 |
4 | import ws;
5 | import ws.sql;
6 | import ws.System;
7 |
8 | string = ..string;
9 | table = ..table;
10 |
11 | var webservice = ws.System;
12 | var tablename = "SystemMenu"
13 |
14 | insert = function(t){
15 | var sql = ws.sql.getInsertSql(tablename, t);
16 | var ok,err = webservice.exec(sql)
17 | return ok,err;
18 | }
19 |
20 | update = function(tab,Id){
21 | var sql = ws.sql.getUpdateSql(tablename, tab, "MenuId = '" + Id + "'");
22 | var ok,err = webservice.exec(sql)
23 | return ok,err;
24 | }
25 |
26 | getMenuName = function(MenuId){
27 | var sql = "SELECT MenuName FROM " + tablename + " where MenuId='" + MenuId + "'";
28 | var tab,err = webservice.getTable(sql);
29 | if(!tab || !#tab) return null,err;
30 | return tab[1]["MenuName"];
31 | }
32 |
33 | //返回树形菜单
34 | getMenuList = function(MenuIdStr,sqlExp){
35 | var tlist,tmenuId = {"一级菜单"},{["一级菜单"] = "0"};
36 | var sql = "SELECT MenuId,MenuName,MenuIdStr,SortIdStr FROM " + tablename + " %s order by SortIdStr";
37 | var where = "";
38 | if(MenuIdStr){
39 | if(sqlExp == "like"){
40 | where = "where MenuIdStr like '%" + MenuIdStr + "%'";
41 | }
42 | elseif(sqlExp == "not like") {
43 | where = "where MenuIdStr not like '%" + MenuIdStr + "%'";
44 | }
45 | elseif(sqlExp == "=") {
46 | tlist,tmenuId = {},{};
47 | where = "where MenuIdStr='" + MenuIdStr + "'";
48 | }
49 | elseif(sqlExp == "!=") {
50 | where = "where MenuIdStr!='" + MenuIdStr + "'";
51 | }
52 | }
53 | sql = string.format(sql, where);
54 | var tab,err = webservice.getTable(sql);
55 | for(i=1;#tab;1){
56 | var t = tab[i];
57 | var MenuName = formatMenuIdStr(t.MenuIdStr,t.MenuName);
58 | table.push(tlist,MenuName);
59 | tmenuId[MenuName] = t.MenuId;
60 | }
61 | return tlist,tmenuId,tab;
62 | }
63 |
64 | //返回完整菜单ID串
65 | getMenuIdStr = function(MenuId, NowMenuId){
66 | MenuId = tostring(MenuId);
67 | var MenuIdStr = ",";
68 | if(MenuId != "0"){
69 | var sql = "SELECT MenuIdStr FROM " + tablename + " where MenuId='" + MenuId + "'";
70 | var tab,err = webservice.getTable(sql);
71 | if(!tab) return null,err;
72 | if(!#tab) return null,"无效菜单";
73 | MenuIdStr = tab[1]["MenuIdStr"];
74 | }
75 | if(NowMenuId) MenuIdStr += tostring(NowMenuId) ++ ",";
76 | return MenuIdStr;
77 | }
78 |
79 | //返回排序ID串
80 | getSortIdStr = function(MenuId,SortId){
81 | MenuId = tostring(MenuId);
82 | if(MenuId == "0") return SortId;
83 | var sql = "SELECT SortIdStr FROM " + tablename + " where MenuId='" + MenuId + "'";
84 | var tab,err = webservice.getTable(sql);
85 | if(!tab) return null,err;
86 | if(!#tab) return null,"无效菜单";
87 | return tab[1]["SortIdStr"] ++ "," ++ SortId;
88 | }
89 |
90 | //格式化完整菜单
91 | formatMenuIdStr = function(MenuIdStr,MenuName){
92 | MenuIdStr = string.trim(MenuIdStr,",")
93 | var t = string.split(MenuIdStr,",");
94 | var MenuId = t[#t];
95 | var str = "";
96 | for(i=1;#t-1;1){
97 | str = str ++ " ";
98 | }
99 | if(!MenuName){ MenuName = getMenuName(MenuId) : ""};
100 | str += (str=="") ? MenuName : ("|—" ++ MenuName);
101 | return str;
102 | }
103 |
104 | //格式化同级排序
105 | formatSortIdStr = function(SortIdStr){
106 | var t = string.split(SortIdStr,",");
107 | var str = "";
108 | for(i,SortId in t){
109 | if(i<#t) str = (str ++ " ");
110 | }
111 | var SortId = t[#t];
112 | str = (str=="") ? (str ++ SortId) : (str ++ "|—" ++ SortId);
113 | return str;
114 | }
115 |
116 | getMenuData = function(MenuIds){
117 | var sql = "SELECT MenuId,ParentId,MenuName,MenuPath,ImagePath FROM " + tablename + " %s order by SortIdStr";
118 | var where = "where 1=1 and IsUse='1'";
119 | if(#MenuIds){
120 | where += " and MenuId in(" + MenuIds + ")";
121 | }
122 | sql = string.format(sql, where);
123 | var tab,err = webservice.getTable(sql);
124 | if(!tab) return null,err;
125 | return tab;
126 | }
127 |
128 | //返回 窗口菜单,树形菜单 table对像
129 | getFormAndTreeMenuTable = function(MenuIds, FunctionName){
130 | var tab,err = getMenuData(MenuIds);
131 | if(!tab) return null,err;
132 | var each;
133 | each = function(row){
134 | var tchild = {};
135 | var tchildTree = {};
136 | var n = 0;
137 | for(i=1;#tab;1){
138 | var t = tab[i];
139 | if(t.ParentId == row.MenuId){
140 | if(n>0) table.push(tchild,{});
141 | var t1,t2 = each(t);
142 | table.push(tchild, t1);
143 | table.push(tchildTree, t2);
144 | n++;
145 | }
146 | }
147 |
148 | var t = {row.MenuName};
149 | if(#tchild){
150 | table.push(t,tchild);
151 | }else {
152 | table.push(t, function(id){
153 | if(FunctionName)
154 | FunctionName(row.MenuPath, row.MenuName);//窗口菜单执行函数
155 | }
156 | )
157 | }
158 |
159 | var tTree = {text=row.MenuName; MenuId=row.MenuId; MenuPath=row.MenuPath; ImagePath=row.ImagePath};
160 | if(#tchildTree){
161 | table.push(tTree,tchildTree);
162 | }
163 | return t,tTree;
164 | }
165 |
166 | var tMeun = {};//窗口菜单
167 | var tTree = {};//树形菜单
168 | for(i=1;#tab;1){
169 | var row = tab[i];
170 | if(row.ParentId == 0){//一级菜单
171 | var t1,t2 = each(row);
172 | table.push(tMeun, t1);
173 | table.push(tTree, t2);
174 | }
175 | }
176 | return tMeun,tTree;
177 | }
178 |
179 | getMenuIdsTable = function(){
180 | var sql = "SELECT MenuId FROM " + tablename;
181 | var tab,err = webservice.getTable(sql);
182 | if(!tab) return null,err;
183 | var t = {}
184 | for(i=1;#tab;1){
185 | var row = tab[i];
186 | table.push(t,row.MenuId)
187 | }
188 | return t;
189 | }
190 |
--------------------------------------------------------------------------------
/lib/carl/ctrl/toolbar.aardio:
--------------------------------------------------------------------------------
1 | //toolbar 工具条控件
2 | namespace carl.ctrl.toolbar{}
3 |
4 | import win.imageList;
5 | import win.ui.toolbar;
6 | import win.ui.ctrl.metaProperty;
7 |
8 | namespace win.ui.ctrl;
9 | class toolbar {
10 | ctor(parent,tParam){
11 | this = ..win.form(text="aardio form";right=995;bottom=23;border="none";exmode="none";mode="child";parent=parent;tParam=tParam)
12 | this.add();
13 | this.toolbar = ..win.ui.toolbar(this);
14 | this.toolbar.create( style = 0x1000/*_TBSTYLE_LIST*/); // 创建工具条
15 | this.toolbar.showLabel = true; //在按钮上显示文字
16 | this.toolbar.imageList = ..win.imageList( 16, 16 ).add($"~/lib/carl/ctrl/.res/toolbar.gif",0xFFFFFF/*透明色*/) ;
17 | this.toolbar.add();
18 | }
19 |
20 | buttons = function(){
21 | return this.toolbar.buttons;
22 | }
23 |
24 | hidebar = function( name, s){//隐藏true,显示false
25 | var buttons = this.buttons();
26 | for(i=1;#buttons;1){
27 | var bt = this.toolbar.getButton(i);
28 | var btl = this.toolbar.getButton(i+1);
29 | if(bt.text == name){
30 | ::SendMessageInt(this.toolbar.hwnd, 0x0400 + 4/*_TB_HIDEBUTTON*/, bt.id, s ? 1 : 0)
31 | if(btl && !#btl.text) ::SendMessageInt(this.toolbar.hwnd, 0x0400 + 4/*_TB_HIDEBUTTON*/, btl.id, s ? 1 : 0)
32 | }
33 | }
34 | }
35 |
36 | enabled = function(name, s = true){//禁用false,启用true
37 | var buttons = this.buttons();
38 | for(i=1;#buttons;1){
39 | var bt = this.toolbar.getButton(i);
40 | if(bt.text == name && bt.enabled != s){
41 | bt.enabled = s;
42 | }
43 | }
44 | }
45 |
46 | add = function(...){
47 | return this.toolbar.add(...);
48 | }
49 |
50 | createButton = function(name,func,num, ...){
51 | var t = {...};
52 | var funcom = function(id){
53 | if(type(func) != type.function) return ;
54 | var btnEvent = this.toolbar.getButtonById(id);
55 | btnEvent.disabled = true;
56 | var r,r1 = func( ..table.unpackArgs(t) );
57 | if( r1 !== false) btnEvent.disabled = false;
58 | }
59 | var tbb = this.toolbar.add(name, funcom, num);
60 | this.toolbar.add()
61 | return tbb;
62 | }
63 |
64 | btnAdd = function(func, name = "新增", ...){
65 | return this.createButton( name, func, 1, ...)
66 | }
67 | btnEdit = function(func, name = "修改", ...){
68 | return this.createButton( name, func, 2, ...);
69 | }
70 | btnDelete = function(func, name = "删除", ...){
71 | return this.createButton( name, func, 3, ...);
72 | }
73 | btnSave = function(func, name = "保存", ...){
74 | return this.createButton( name, func, 4, ...);
75 | }
76 | btnSearch = function(func, name = "查询", ...){
77 | return this.createButton( name, func, 5, ...);
78 | }
79 | btnClose = function(func, name = "关闭", ...){
80 | return this.createButton( name, func, 6, ...);
81 | }
82 | btnRefresh = function(func, name = "刷新", ...){
83 | this.createButton( name, func, 7, ...);
84 | }
85 | btnCancel = function(func, name = "取消", ...){
86 | this.createButton( name, func, 8, ...);
87 | }
88 | btnSetting = function(func, name = "设置", ...){
89 | return this.createButton( name, func, 9, ...);
90 | }
91 | btnStart = function(func, name = "开始", ...){
92 | return this.createButton( name, func, 10, ...);
93 | }
94 | btnPrint = function(func, name = "打印", ...){
95 | return this.createButton( name, func, 11, ...);
96 | }
97 | btnStop = function(func, name = "暂停", ...){
98 | return this.createButton( name, func, 12, ...);
99 | }
100 | btnOpenFolder = function(func, name = "打开文件夹", ...){
101 | return this.createButton( name, func, 13, ...);
102 | }
103 | btnCloseFolder = function(func, name = "关闭文件夹", ...){
104 | return this.createButton( name, func, 14, ...);
105 | }
106 | btnUp = function(func, name = "上移", ...){
107 | return this.createButton( name, func, 15, ...);
108 | }
109 | btnDown = function(func, name = "下移", ...){
110 | return this.createButton( name, func, 16, ...);
111 | }
112 | btnConfirm = function(func, name = "确定", ...){
113 | return this.createButton( name, func, 17, ...);
114 | }
115 | btnRight = function(func, name = "向右", ...){
116 | return this.createButton( name, func, 18, ...);
117 | }
118 | btnLeft = function(func, name = "向左", ...){
119 | return this.createButton( name, func, 19, ...);
120 | }
121 | }
122 |
123 | /*intellisense()
124 | win.ui.ctrl.toolbar = 工具条控件
125 | ?win.ui.ctrl.toolbar = !toolbar.
126 | !toolbar.toolbar = !toolbar.
127 | !toolbar.add(标题,回调函数,图像索引,可选指定命令ID) = @.add(\n "文字", \n function (id) {\n\n },1\n)
128 | !toolbar.add() = 添加一个分隔条
129 | !toolbar.hidebar("按钮名称",true) = 隐藏true,显示false
130 | !toolbar.enabled("按钮名称",true) = 禁用false,启用true
131 | !toolbar.createButton("按钮名称","func函数","图标索引","func函数参数") = 创建按钮,func函数执行过程中按钮将自动禁用,执行结束启用,如果func函数,返回值第二个参数为false,将禁用按钮
132 | !toolbar.btnAdd(func, "新增") = 新增按钮
133 | !toolbar.btnEdit(func,"修改") = 修改按钮
134 | !toolbar.btnDelete(func, "删除") = 删除按钮
135 | !toolbar.btnSave(.(func, "保存") = 保存按钮
136 | !toolbar.btnSearch(func, "查询") = 查询按钮
137 | !toolbar.btnClose(func, "关闭") = 关闭按钮
138 | !toolbar.btnRefresh(func, "刷新") = 刷新按钮
139 | !toolbar.btnCancel(func, "取消") = 取消按钮
140 | !toolbar.btnSetting(func, "设置") = 设置按钮
141 | !toolbar.btnStart(func, "开始") = 开始按钮
142 | !toolbar.btnPrint(func, "打印") = 打印按钮
143 | !toolbar.btnStop(func, "暂停") = 暂停按钮
144 | !toolbar.btnOpenFolder(func, "打开文件夹") = 打开文件夹按钮
145 | !toolbar.btnCloseFolder(func, "关闭文件夹") = 关闭文件夹按钮
146 | !toolbar.btnUp(func, "上移") = 上移
147 | !toolbar.btnDown(func, "下移") = 下移
148 | !toolbar.btnConfirm(func, "确定") = 确定
149 | !toolbar.btnRight(func, "向右") = 向右
150 | !toolbar.btnLeft(func, "向左") = 向左
151 | end intellisense*/
152 |
--------------------------------------------------------------------------------
/lib/carl/processcmd.aardio:
--------------------------------------------------------------------------------
1 | //processcmd 进程通信
2 | import win;
3 | import win.guid;
4 | import process;
5 | import process.command;
6 | import thread.table;
7 |
8 | namespace carl
9 |
10 | processcmd = class {
11 | ctor( guid, ... ){
12 | var cmdline = _CMDLINE;
13 | var owerPid = ..process.getId();
14 | if( !guid ){
15 | guid = ..win.guid.create();
16 | guid = string.upper( tostring(guid) );
17 | }
18 | if( #cmdline ){
19 | if(cmdline[1] == '{'# ) {
20 | var r,t = call(eval,,cmdline);
21 | if(!r) return null,"错误命令行参数: " ++ cmdline;
22 | guid = t.guid;
23 | this.parentPid = t.parentPid;//父进程ID
24 | }else {
25 | return null,"不是有效参数";
26 | }
27 | }
28 | if(!_STUDIO_INVOKED){
29 | var mutex,err = ..process.command.join(guid);//加入进程群组
30 | if(!mutex) return null,err;
31 | }
32 | this.pids = ..thread.table("table" + guid);
33 | this.guid = guid;
34 | this.serverCmd = ..process.command( ... );//注册进程命令对象
35 |
36 | if( !..thread.get(guid) ) {
37 | ..thread.set(guid, true)
38 |
39 | this.serverCmd.receive = function( t ) { //接收命令
40 | if( (t.toPid && t.toPid != owerPid) || (!t.toPid && !this.parentPid) )
41 | return ;
42 | if( type.table == type(t.msg) ){
43 | if( this.parentPid ){
44 | if( type(this.receiveChild) != type.function )
45 | error("请先定义receiveChild消息处理函数",2);
46 | return this.receiveChild(t.fromPid, table.unpackArgs(t.msg));
47 | }else {
48 | if( type(this.receiveParent) != type.function )
49 | error("请先定义receiveParent消息处理函数",2);
50 | return this.receiveParent(t.fromPid, table.unpackArgs(t.msg));
51 | }
52 | }
53 | }
54 |
55 | this.serverCmd.quit = function( fromPid ) {
56 | if( fromPid == owerPid || (!fromPid && this.parentPid))
57 | win.quitMessage(0);
58 | }
59 | }
60 | };
61 |
62 | sendto = function( toPid, types, ... ) {
63 | var t = {};
64 | t.fromPid = owerPid;
65 | t.toPid = toPid;
66 | t.msg = {...};
67 | if( types == "send" ){
68 | return ..process.command.send("receive",t);
69 | }
70 | elseif( types == "post" ){
71 | return ..process.command.post("receive",t);
72 | }
73 | elseif( types == "quit" ){
74 | ..process.command.post("quit",toPid);
75 | }
76 | }
77 |
78 | send = function( toPid, ...) {
79 | return this.sendto( toPid, "send",...)
80 | }
81 |
82 | post = function( toPid, ...) {
83 | return this.sendto( toPid, "post", ... )
84 | }
85 |
86 | create = function( exepath,sec=1000 ) {
87 | if( _STUDIO_INVOKED ) error("请先发布,才能创建子进程");
88 | exepath := ..io._exepath;
89 | var t = {}
90 | t.guid = guid;
91 | t.parentPid = owerPid;
92 | var pro,err = ..process(exepath, table.tostring(t));//命令参数 cmd
93 | if(!pro) return null,err;
94 | this.pids.push(pro.id);
95 | delay(sec)
96 | return pro.id;
97 | }
98 |
99 | quit = function( toPid ) {
100 | this.sendto( toPid, "quit" );
101 | this.removePid(toPid);
102 | }
103 |
104 | kill = function( toPid ) {
105 | try{
106 | var p;
107 | if( toPid ){
108 | p = ..process(toPid);
109 | if(p) p.terminate();
110 | }else {
111 | for( i,pid in this.pids.each() ){
112 | p = ..process(toPid);
113 | if(p) p.terminate();
114 | }
115 | }
116 | this.removePid(toPid);
117 | }
118 | }
119 |
120 | waitClose = function(pid,f,...){
121 | var bool;
122 | while(true){
123 | bool = false;
124 | if(pid){
125 | if( ..process.getPath(pid) ) bool = true;
126 | }
127 | else {
128 | for( i,pid in this.pids.each() ){
129 | if(..process.getPath(pid)){
130 | bool = true;
131 | break ;
132 | }
133 | }
134 | }
135 | if(f){
136 | if(f(...) === false) break ;
137 | }
138 | if(!bool) this.removePid(pid);
139 | if(!bool || !delay(1000)) break ;
140 | }
141 | }
142 |
143 | removePid = function(pid){
144 | for(i=1;this.pids.len();1){
145 | if(!pid){
146 | this.pids.remove();
147 | }
148 | elseif(pid == this.pids[i]) {
149 | this.pids.remove(i);
150 | break ;
151 | }
152 | }
153 | }
154 |
155 | }
156 |
157 | namespace processcmd{
158 | table = ..table;
159 | string = ..string;
160 | delay = ..win[["ui"]] ? ..win[["delay"]] : sleep;
161 | }
162 |
163 | /**intellisense()
164 | carl.processcmd = 进程通信库
165 | carl.processcmd() = 创建进程通信对像,第一次创建,参数:进程群组Guid,可忽略,创建成功后,可以用 对像.guid 读取
166 | carl.processcmd(guid) = 创建进程通信对像,参数:进程群组Guid不可忽略,可传入第一次创建的guid
167 | ?carl.processcmd = !cmd.
168 | !cmd.create() = 创建本身做为子进程,成功返回子进程ID,失败返回null,错误信息;
169 | !cmd.create(.(子进程路径)) = 创建子进程,参数:子进程路径,成功返回子进程ID,失败返回:null,错误信息;
170 | !cmd.send(.(进程ID,消息内容)) = 阻塞调用跨进程命令,参数一:可指定进程ID,忽略则向所有子进程发消息,\n可获取处理该命令的回调函数返回值,\n用于父进程与子进程之间通信,或子进程与子进程之间通信
171 | !cmd.post(.(进程ID,消息内容)) = 非阻塞调用跨进程命令,参数一:可指定进程ID,忽略则向所有子进程发消息,\n无返回值,\n用于父进程与子进程之间通信,或子进程与子进程之间通信
172 | !cmd.receiveParent = @.receiveParent = function( fromPid,... ) {
173 | /*如果当前进程是父进程,此函数用于接收来至其他进程发的消息,回调参数:发送方进程ID,不定个数参数*/
174 | __/*进程里第一次最先定义此函数的地方有效,其他地方无效*/
175 | }
176 | !cmd.receiveChild = @.receiveChild = function( fromPid,... ) {
177 | /*如果当前进程是子进程,此函数用于接收来至其他进程发的消息,回调参数:发送方进程ID,不定个数参数*/
178 | __/*进程里第一次最先定义此函数的地方有效,其他地方无效*/
179 | }
180 | !cmd.quit(.(进程ID)) = 退出一个子进程,发送win.quitMessage()退出消息
181 | !cmd.quit() = 退出所有子进程,发送win.quitMessage()退出消息
182 | !cmd.kill(.(进程ID)) = 强制杀死子进程
183 | !cmd.kill() = 强制杀死所有子进程
184 | !cmd.serverCmd = 进程命令对象
185 | !cmd.parentPid = 父进程ID,如果值为null,说明当前进程是父进程
186 | !cmd.guid = 进程群组Guid
187 | !cmd.pids = 所有子进程ID表table对像
188 | !cmd.waitClose() = 等待所有子进程退出
189 | !cmd.waitClose(pid) = 等待指定子进程退出,参数子进程ID
190 | end intellisense**/
191 |
--------------------------------------------------------------------------------
/aardio-erp/lib/web/layoutEx.aardio:
--------------------------------------------------------------------------------
1 |
2 | import win;
3 | import web.layout;
4 | import web.layout.behavior.windowCommand;
5 | import web.layout.behavior.titleMenu;
6 | import web.layout.behavior.msgbox;
7 | import web.layout.debug;
8 | import win.ui.shadow;
9 |
10 | namespace web{
11 |
12 | layoutEx = class {
13 | ctor( winform,url,menu = true ){
14 | this = ..web.layout( winform );
15 | ..win.ui.shadow(winform); //添加阴影边框
16 | if( _STUDIO_INVOKED ){
17 | this.attachEventHandler( ..web.layout.debug );
18 | }
19 | this.go(url);
20 | this.wait();
21 | if(winform.max === false) this.querySelector( "[command='window-max']").command = "";//禁用双击标题最大化
22 | if(!menu) this.getEle("windowmenu").style.display = "none";
23 | var ele = this.getEle("mainTitle");
24 | if(ele) ele.innerText = winform.text;
25 | };
26 |
27 | msgbox = function(str,title,style){
28 | return msgbox(str,title,style,winform);
29 | }
30 | msgboxTest = function(str,title){
31 | return msgboxTest(str,title,winform)
32 | }
33 | msgboxErr = function(str,title){
34 | return msgboxErr(str,title,winform)
35 | }
36 |
37 | ["select"] = function(eleName,v,sel=true){
38 | var opt,child,value,text;
39 | var ele = this.getEle(eleName);
40 | if( string.cmp(ele.tagName,"select") ) return ;
41 | if(ele){
42 | if(type(v)==type.number and v < ele.length){
43 | opt = ele.options[i];
44 | }else{
45 | v = sel ? string.lower(v) : v;
46 | for(i=0;ele.length-1;1){
47 | child = ele.options[i];
48 | if( !child ) continue ;
49 | value = sel ? string.lower(child.value) : value;
50 | text = sel ? string.lower(child.text) : text;
51 | if(value == v or text == v){
52 | opt = child;
53 | break ;
54 | }
55 | }
56 | }
57 | }
58 | if( opt ){
59 | opt.selected = true;
60 | if( ele.onchange ) ele.fireEvent("onchange");
61 | }
62 | return opt;
63 | }
64 |
65 | setEle = function(eleName,val,name){
66 | var ele = this.getEle(eleName);
67 | if(!ele) return null,"未找到节点";
68 |
69 | if( type(val) == type.table ){
70 | for(k,v in val)
71 | this.setEle(eleName,v,k,frame);
72 | }
73 | elseif(name){
74 | ele[name] = val;
75 | }
76 | elseif( string.cmp(ele.tagName,"textArea") == 0 ){
77 | ele.innerHTML = val;
78 | }
79 | elseif( !string.cmp(ele.tagName,"input") ){
80 | select(ele.type) {
81 | case "radio","checkbox" {
82 | ele.state.checked = val;
83 | };
84 | else {
85 | ele.value = val;
86 | };
87 | };
88 | };
89 | elseif( string.cmp(ele.tagName,"select") == 0 ){
90 | this.select( eleName,val );
91 | }
92 | return ele;
93 | };
94 |
95 | getEleValue = function(eleName){
96 | var ele = this.getEle(eleName);
97 | if(!ele) return null,"未找到节点";
98 | if( string.cmp(ele.tagName,"textArea") == 0 ){
99 | return ele.innerHTML;
100 | }
101 | elseif( !string.cmp(ele.tagName,"input") ){
102 | select(ele.type) {
103 | case "radio","checkbox" {
104 | return ele.state.checked;
105 | };
106 | else {
107 | return ele.value;
108 | };
109 | };
110 | };
111 | elseif( string.cmp(ele.tagName,"select") == 0 ){
112 | return this.$1("option:checked").getAttribute("value");
113 | }
114 | }
115 |
116 | bindConfig = function(cfgFile){
117 | if( type(cfgFile.save) != "function" )
118 | error("无效配置文件",2);
119 | for(name,value in cfgFile){
120 | var ele = this.getEle(name);
121 | if(!ele) continue ;
122 | this.setEle(name,value);
123 | }
124 | cfgFile.beforeSave = function(){
125 | if( winform._hasBeenDestroyed ){return;}
126 | var tag = {"input";"select";"textArea"}
127 | for(k,tagName in tag){
128 | var eles = this.$(tagName);
129 | for(i=1;#eles;1){
130 | var name = eles[i].id : eles[i].name;
131 | if(!name) continue ;
132 | cfgFile[name] = this.getEleValue(name)
133 | }
134 | }
135 | };
136 | winform.onClose = function(){
137 | cfgFile.beforeSave();
138 | };
139 | };
140 | }
141 |
142 | namespace layoutEx{
143 | string = ..string;
144 | table = ..table;
145 |
146 | msgbox = function(str,title,style,form){
147 | return loadcode($"\lib\web\layout\msgbox.aardio")(form,str,title,style);
148 | }
149 | msgboxTest = function(str,title,form){
150 | return msgbox(str,title,0x1 | 0x20 /*_MB_OKCANCEL|_MB_ICONQUESTION*/,form ) == 1;
151 | }
152 | msgboxErr = function(str,title,form){
153 | return msgbox( str,title,0x10/*_MB_ICONHAND*/,form );
154 | }
155 | }
156 | }
157 |
158 | if(_reWinMsgbox) return ;
159 | var msgbox = win.msgbox;
160 | win.msgbox = function(...){//重写win.msgbox函数,影响全局
161 | var text,title,style,hwndOwner = ...;
162 | if(!hwndOwner) hwndOwner = win.getForeground();
163 | var form = win.form.getForm(hwndOwner);
164 | if(form){
165 | return web.layoutEx.msgbox(text,title,style,form);
166 | }else {
167 | return msgbox(...);
168 | }
169 | }
170 | _reWinMsgbox = true;
171 |
172 | /**intellisense()
173 | web.layoutEx = HTMLayout扩展库
174 | web.layoutEx( __/*winform对象*/,__/*url路径*/ ) = 创建HTMLayout窗体
175 | ?web.layoutEx = !weblayout.
176 | !weblayout.msgbox(.("文本","标题",样式) = 弹出对话框\n除参数一以外,所有参数可选
177 | !weblayout.msgboxErr(.("文本","标题") = 弹出错误对话框
178 | !weblayout.msgboxTest(.("文本","标题") = 返回布尔值表示用户是否按了“确定”按钮。\n标题参数可选
179 | !weblayout.setEle(eleName,value) = 设置节点值
180 | !weblayout.getEleValue(eleName) = 读取节点值
181 | !weblayout.bindConfig(config配置文件) = @??.bindConfig(config.winform);//自动保存表单
182 | end intellisense**/
183 |
--------------------------------------------------------------------------------
/lib/carl/http.aardio:
--------------------------------------------------------------------------------
1 | //http网络库
2 | namespace carl.http
3 |
4 | string = ..string
5 | math = ..math;
6 | thread = ..thread;
7 | raw = ..raw;
8 | table = ..table;
9 |
10 | delay = ..win[["ui"]] ? ..win[["delay"]] : sleep;
11 |
12 | agent ="Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36";
13 |
14 | var func = function(tab,mode = "http"){
15 | import inet.http;
16 | import inet.whttp;
17 |
18 | var http,t;
19 | if(mode == "http"){
20 | http = inet.http(tab["agent"]);
21 | if(tab["flags"]) http.disableCache(); //http.flags = 0x80000000/*_INTERNET_FLAG_RELOAD强制文件从服务器下载不是缓存*/ | 0x4000000/*_INTERNET_FLAG_DONT_CACHE*不缓存数据*/
22 | }else {
23 | http = inet.whttp(tab["agent"],tab["proxy"]);
24 | }
25 | if(tab["postdata"]){
26 | t = {http.post(tab["url"], tab["postdata"], tab["header"], tab["refurl"])};
27 | }else {
28 | t = {http.get(tab["url"], tab["header"], tab["refurl"])};
29 | }
30 | http.close();
31 | http = null;
32 | thread.set("d_t_" ++ tostring(thread.getId()),t);
33 | }
34 |
35 | var functcp = function(tab){
36 | import wsock.tcp.client;
37 | import thread.table;
38 | import inet.url;
39 | import string.list;
40 |
41 | var funchunked;
42 | funchunked = function(html, rhtml=""){
43 | var len,html = string.match(html,"(\w+)" ++ '\r\n' ++ "(.*)");
44 | if(len == "0" || !len) return rhtml;
45 | len = tonumber(len, 16);
46 | rhtml += string.left(html, len);
47 | html = string.sub(html,len+1,#html)
48 | return funchunked(html, rhtml);
49 | }
50 |
51 | var turl = inet.url.split(tab["url"])
52 | if(turl.path == "") turl.path = "/";
53 | var getUrl = turl.extraInfoLen ? turl.path ++ turl.extraInfo : turl.path;
54 | var postdata = tab["postdata"];
55 | var method = postdata ? "POST" : "GET";
56 | var sendData = method ++ " " ++ getUrl ++ ' HTTP/1.1\r\n';
57 |
58 | var tsend = string.list(tab["header"]:"",'\r\n',":");
59 | tsend["Host"] = turl.host;
60 | tsend["Connection"] := "close";
61 | tsend["User-Agent"] := tab["agent"];
62 | tsend["Cache-Control"] := "max-age=0";
63 | tsend["Accept"] := "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain,image/png,*/*;";
64 | tsend["Accept-Language"] := "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3;";
65 | tsend["Accept-Charset"] := "GBK,utf-8";
66 | if(tab["refurl"]) tsend["Referer"] := tab["refurl"];
67 | if(method == "POST") tsend["Content-Type"] := (postdata[1]=='{'# or postdata[1]=='['#) ? "application/json; charset=utf-8" : "application/x-www-form-urlencoded";
68 | sendData += tsend._tostring() ++ '\r\n\r\n';
69 | if(method == "POST") sendData += postdata ++ '\r\n\r\n';
70 |
71 | var tre,t = {},{};
72 | var html;
73 | try{
74 | var tcp = wsock.tcp.client();
75 | tcp.connect(turl.host, turl.port);
76 | tcp.write( sendData );
77 | for(str,size in tcp.eachRead()){
78 | table.push(t,str);
79 | }
80 | tcp.close();
81 | tcp = null;
82 | html = string.join(t);
83 | }
84 | catch(e){
85 | tre[2] = e;
86 | }
87 | if(#html){
88 | var status = string.match(html,"(.*?)" ++ '\r\n');
89 | var header = string.match(html, '\r\n' ++ "(.*?)" ++ '\r\n\r\n');
90 | html = string.match(html,'\r\n\r\n' ++ "(.*)");
91 | var code = string.match(status,"HTTP\s*\/1\.1\s*(\d+)");
92 | if(code == "200"){
93 | if(string.find(header,"Transfer\-Encoding\:\s*chunked")){
94 | var rhtml = funchunked(html);
95 | if(#rhtml) html = rhtml;
96 | }
97 | tre[1] = html;
98 | }
99 | else {
100 | tre[2] = html;
101 | tre[3] = tonumber(code);
102 | }
103 | tre[4] = header;
104 | }
105 | html = null;
106 | thread.set("d_t_" ++ tostring(thread.getId()),tre);
107 | }
108 |
109 | var funcommand = function(url, mode, ...){
110 | var tab = {};
111 | if(type(url) == type.string){
112 | tab["url"] = url;
113 | tab["postdata"], tab["header"], tab["refurl"] = ...;
114 | }
115 | elseif(type(url) == type.table){
116 | tab = url;
117 | }
118 | else {
119 | return null,"参数错误";
120 | }
121 | tab["agent"] := agent;
122 | var handle,tid;
123 | if(mode == "tcp"){
124 | handle,tid = thread.create(functcp, tab);
125 | }else {
126 | handle,tid = thread.create(func, tab, mode);
127 | }
128 | var name = "d_t_" ++ tostring(tid);
129 | thread.set(name, null);
130 | var t;
131 | var timeout = (tab["timeout"] : 90) * 10;//秒
132 | for(i=1;timeout;1){
133 | delay(100);
134 | t = thread.get(name);
135 | if(t) break;
136 | if(i == timeout && handle) thread.terminate( handle );
137 | }
138 | if( handle ) raw.closehandle( handle );
139 | handle = null;
140 | thread.set(name, null);
141 | if(t){
142 | return table.unpackArgs(t);
143 | }else {
144 | return null,"Request Timeout";
145 | }
146 | }
147 |
148 | down = function(url, ...){
149 | return funcommand(url,"http",...);
150 | }
151 |
152 | downwhttp = function(url, ...){
153 | return funcommand(url, "whttp", ...);
154 | }
155 |
156 | downtcp = function(url, ...){
157 | return funcommand(url, "tcp", ...);
158 | }
159 |
160 | /**intellisense()
161 | carl.http.down(url,postdata,header,refurl) = inet.http库,返回 html,err,code
162 | carl.http.down = @.down(\n{\n url = "";\n postdata = null;\n header = null;\n refurl = null;\n agent = null;\n timeout = 90;\n flags=false;\n}\n)//参数:table对像 inet.http库,返回 html,err,code
163 | carl.http.downwhttp(url,postdata,header,refurl) = inet.whttp库,返回 html,err,code
164 | carl.http.downwhttp = @.downwhttp(\n{\n url = "";\n postdata = null;\n header = null;\n refurl = null;\n agent = null;\n timeout = 90;\n}\n)//参数:table对像 inet.whttp库,返回 html,err,code
165 | carl.http.downtcp(url,postdata,header,refurl) = 通过wsock.tcp.client,返回 html,err,code,header,不支持https
166 | carl.http.downtcp = @.downtcp(\n{\n url = "";\n postdata = null;\n header = null;\n refurl = null;\n agent = null;\n timeout = 90;\n}\n)//参数:table对像 wsock.tcp.client库,返回 html,err,code,header,不支持https
167 | end intellisense**/
168 |
--------------------------------------------------------------------------------
/lib/carl/update.aardio:
--------------------------------------------------------------------------------
1 | //update自动更新
2 |
3 | namespace carl;
4 |
5 | update = class {
6 | ctor(updateUrl, downUrl, mainExe, winform, cmdmsg ){
7 | this.updateUrl = updateUrl;
8 | this.downUrl = downUrl;
9 | this.winform = winform;
10 | this.cmdmsg = cmdmsg;
11 | this.updateExe = string.replace(mainExe,"\.","_u.");//更新程序名称
12 | this.updateExeOld = string.replace(mainExe,"\.","_update.");//更新程序名称
13 | this.mainExe = mainExe; //主程序名称
14 | this.updateDir = io._exedir; //更新的程序目录
15 | this.exeDir = this.updateDir; //主程序路径
16 | };
17 |
18 | //获取最新版本号
19 | getNewVer = function(){
20 | var http = inet.http()
21 | html = http.get(this.updateUrl):"";
22 | http.close();
23 | var ver,log = string.match(html,"ver=\[(.*?)\].*?log=\[(.*?)\]");
24 | return ver,log;
25 | };
26 |
27 | //检查是否要更新
28 | checkUpdate = function(ver,up=false){
29 | var bool = false;
30 | if(this.cmdmsg == "-update"){//开始下载更新
31 | process.kill(this.mainExe)
32 | var downBox = inet.downBox(,"程序升级")
33 | downBox.endProc = function(ret,fileSize,err){
34 | if(ret){
35 | downBox.close()
36 | if(this.winform){this.winform.close();}
37 | io.remove(this.exeDir + this.mainExe + ".dowload")
38 | win.delay(100)
39 | process(this.exeDir + this.mainExe)
40 | if(this.winform){this.winform.close();}
41 | return ;
42 | }
43 | }
44 | downBox.download(this.downUrl,this.exeDir + this.mainExe);
45 | }else {
46 | var newVer,logtxt = this.getNewVer();//最新版本号
47 | if(newVer){
48 | newVernum = string.replace(newVer,"\.","");
49 | ver = string.replace(ver,"\.","");
50 | if(tonumber(newVernum)>tonumber(ver)){ //有新版本
51 | bool = true;
52 | var str = "有新的版本[" + newVer + "]是否现在更新?" + '\n' + logtxt;
53 | if(!up){
54 | ok = win.msgboxTest(str,"更新")
55 | }else {
56 | ok = true;
57 | win.msgbox(str,"更新");
58 | }
59 | if(ok){
60 | fsys.createDir(this.updateDir)
61 | process.kill(this.updateExe)
62 | win.delay(100)
63 | io.remove(this.updateDir + this.updateExe);//删除更新文件
64 | sleep(500);
65 | var updateExePath = fsys.joinpath(this.updateDir,"\" + this.updateExe);
66 | fsys.copy(io._exepath,updateExePath);//复制到临时目录
67 | sleep(500);
68 | if(io.exist(updateExePath)){
69 | process(updateExePath,"-update");//命令参数 cmd
70 | }else {
71 | ok = win.msgboxTest("无法启动更新程序,是否手动下载最新版?","错误");
72 | if(ok){
73 | win.msgbox("下载后请手动覆盖" + this.mainExe + "即可","提示")
74 | process.execute(this.downUrl);
75 | }
76 | }
77 | if(this.winform){this.winform.close();}
78 | return true;
79 | }
80 | }
81 | }
82 | process.kill(this.updateExe)
83 | win.delay(100)
84 | //io.remove(this.updateDir + this.updateExe);//删除更新文件
85 | io.remove(this.updateDir + this.updateExeOld);
86 | io.remove(this.exeDir + this.mainExe + ".dowload")
87 | io.remove(this.exeDir + this.mainExe + ".dow!oad")
88 | return bool,newVer;
89 | }
90 | }
91 | }
92 |
93 | namespace update{
94 | import win;
95 | import fsys;
96 | import process;
97 | import inet.downBox;
98 | import inet.http;
99 |
100 | string = ..string;
101 | table = ..table;
102 | io = ..io;
103 | time = ..time;
104 |
105 | var projectDir = "\";
106 | if( _STUDIO_INVOKED ){
107 | import ide;
108 | projectDir = ide.getProjectDir();
109 | }
110 |
111 | //获取当前版本号
112 | getVersion = function(res = "res"){
113 | if( !_STUDIO_INVOKED ){
114 | return string.load("\" ++ res ++ "\version.txt");
115 | }
116 | var file = res ++ "\version.txt";
117 |
118 | var version = string.load(projectDir ++ file):""
119 | if(version == ""){
120 | version = "1.0.02";
121 | string.save(projectDir + file, version);
122 | }
123 | return calVersion(version,-1),file;
124 | };
125 |
126 | //计算版本号增加或减少
127 | calVersion = function(version,n=1){
128 | version = string.replace(version,"\.","");
129 | version = tostring((tonumber(version)) + n);//版本号加n,下次发布用
130 | major,minor,build = string.sub(version,-#Ver,-4),string.sub(version,-3,-3),string.sub(version,-2,-1);
131 | version = major + "." + minor + "." + build;
132 | return version;
133 | }
134 |
135 | saveNextVersion = function(res = "res"){
136 | if(_STUDIO_INVOKED){
137 | var version,file = getVersion(res);//版本号
138 | version = calVersion(version,2);//下个版本
139 | string.save(projectDir + file, version)
140 | }
141 | };
142 |
143 | updateWeb = function(exeName,res = "res",update = "Publish\update\"){
144 | if(_STUDIO_INVOKED){
145 | var updateDir = projectDir ++ update;
146 | fsys.createDir(updateDir)
147 | var html = "ver=[%s]" + '\r\n' + "log=[" + '\r\n' + "%s" + '\r\n' + "]" + '\r\n';
148 | var version = getVersion(res);
149 | version = calVersion(version,1);//当前个版本
150 | var t = time();
151 | t.format="%Y-%m-%d";
152 | var log = tostring(t) + "更新日志:"
153 | var updatefile = updateDir + "index.html";
154 | var logtxt = string.load(updatefile):"";
155 | html = string.format(html,version, log)
156 | string.save(updatefile,html + logtxt);
157 |
158 | var updateExe = updateDir + exeName + ".exe";
159 | io.remove(updateExe)
160 |
161 | var upxExe = projectDir + "Publish\" + exeName + ".upx.exe";
162 | var mainExe = projectDir + "Publish\" + exeName + ".exe";
163 | if(io.exist(upxExe)){
164 | fsys.copy(upxExe,updateExe);
165 | }else {
166 | fsys.copy(mainExe,updateExe);
167 | }
168 | }
169 | }
170 |
171 | }
172 |
173 |
174 | /**intellisense()
175 | carl.update = 自动更新库
176 | ?carl.update = !update.
177 | carl.update(updateUrl, downUrl, mainExe, winform, _CMDLINE ) = 版本url,程序下载url,主程序名,主窗体,启动参数
178 | update.checkUpdate(_) = 参数版本号
179 | carl.update.getVersion() = 获取当前程序版本
180 | carl.update.saveNextVersion() = 保存下一次版本号,请在updateWeb()后执行,本函数尽限ide环境中使用
181 | carl.update.updateWeb() = 发布网站上的更新内容,请在saveNextVersion()之前执行,本函数尽限ide环境中使用
182 | end intellisense**/
183 |
--------------------------------------------------------------------------------
/aardio-erp/res/System/MenuAddEdit.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | /*DSG{{*/
3 | var winform = win.form(text="AAuto Form";right=284;bottom=262;border="dialog frame";exmode="none";max=false;mode="popup";parent=...)
4 | winform.add(
5 | cboIsUse={cls="combobox";left=214;top=161;right=269;bottom=185;edge=1;hscroll=1;items={"启用";"禁用"};mode="dropdownlist";tabstop=1;vscroll=1;z=18};
6 | cboParentId={cls="combobox";left=71;top=38;right=269;bottom=62;edge=1;hscroll=1;items={};mode="dropdownlist";tabstop=1;vscroll=1;z=11};
7 | groupbox={cls="groupbox";left=4;top=21;right=280;bottom=257;edge=1;z=1};
8 | static={cls="static";text="菜单名称";left=14;top=75;right=68;bottom=93;transparent=1;z=3};
9 | static2={cls="static";text="菜单路径";left=14;top=107;right=68;bottom=125;transparent=1;z=4};
10 | static3={cls="static";text="异动人";left=14;top=199;right=58;bottom=217;transparent=1;z=5};
11 | static4={cls="static";text="异动时间";left=14;top=231;right=68;bottom=249;transparent=1;z=6};
12 | static5={cls="static";text="上级菜单";left=15;top=42;right=69;bottom=60;transparent=1;z=7};
13 | static6={cls="static";text="同级排序";left=14;top=167;right=68;bottom=185;transparent=1;z=10};
14 | static7={cls="static";text="图标路径";left=14;top=137;right=68;bottom=155;transparent=1;z=15};
15 | static8={cls="static";text="状态";left=183;top=165;right=212;bottom=183;transparent=1;z=17};
16 | toolbar={cls="toolbar";text="工具条";left=0;top=-2;right=283;bottom=25;center=1;dl=1;dr=1;dt=1;edge=1;transparent=1;z=2};
17 | txtImagePath={cls="edit";left=71;top=129;right=269;bottom=155;autohscroll=false;autovscroll=false;edge=1;hidesel=1;tabstop=1;z=16};
18 | txtMenuName={cls="edit";left=71;top=68;right=269;bottom=94;autohscroll=false;autovscroll=false;edge=1;hidesel=1;tabstop=1;z=12};
19 | txtMenuPath={cls="edit";left=71;top=99;right=269;bottom=125;autohscroll=false;autovscroll=false;edge=1;hidesel=1;tabstop=1;z=13};
20 | txtSortIdStr={cls="edit";text="01";left=71;top=160;right=176;bottom=186;autohscroll=false;autovscroll=false;edge=1;hidesel=1;num=1;tabstop=1;z=14};
21 | txttrdate={cls="edit";left=71;top=223;right=269;bottom=249;autohscroll=false;autovscroll=false;edge=1;hidesel=1;readonly=1;z=9};
22 | txttruser={cls="edit";left=71;top=191;right=269;bottom=217;autohscroll=false;autovscroll=false;edge=1;hidesel=1;readonly=1;z=8}
23 | )
24 | /*}}*/
25 |
26 | var tlist,tmenuId;
27 |
28 | winform.btnSave = function(){
29 | var SortId = (tonumber(winform.txtSortIdStr.text,10));
30 | if(SortId > 99){
31 | winform.msgbox("排序号范围: 0-99","提示")
32 | return false;
33 | }
34 | winform.txtSortIdStr.text = string.format("%02i", SortId)
35 | var t = conn.getwinform(winform)
36 | if( !#t["MenuName"] ){
37 | winform.msgbox("菜单名称不能为空!","提示")
38 | return false;
39 | }
40 | t.IsUse = (t.IsUse="启用") ? "1" : "0";
41 | var MenuId;
42 | if(winform.parent.page.index){
43 | MenuId = winform.parent.trow.MenuId;
44 | }
45 | t.ParentId = tmenuId[t.ParentId];//父级ID
46 | MenuId = winform.parent.Edit ? MenuId : null;
47 | t.MenuIdStr = ws.System.SystemMenu.getMenuIdStr(t.ParentId, MenuId);//完整菜单ID串 (,0,1,)
48 | if(!#t.MenuIdStr){
49 | winform.msgbox("无效上级菜单","提示")
50 | return false;
51 | }
52 | t.SortIdStr = ws.System.SystemMenu.getSortIdStr(t.ParentId,t.SortIdStr);
53 | var ok,err;
54 | if(winform.parent.Edit){//修改
55 | var lastMenuIdStr = winform.parent.trow.MenuIdStr;
56 | var lastSortIdStr = winform.parent.trow.SortIdStr;
57 | var lastIsUse = winform.parent.trow.IsUse;
58 | if(lastMenuIdStr == t.MenuIdStr && lastSortIdStr == t.SortIdStr && lastIsUse == t.IsUse){
59 | ok,err= ws.System.SystemMenu.update(t, MenuId);
60 | }
61 | else {//上级菜单有变,需更新相应的下级菜单
62 | var tsql = {};
63 | table.push(tsql,ws.sql.getUpdateSql("SystemMenu", t, "MenuId = '" ++ MenuId ++ "'"));
64 | var t1,t2,tab = ws.System.SystemMenu.getMenuList(lastMenuIdStr,"like");//菜单
65 | for(i=1;#tab;1){
66 | var tup = tab[i];//MenuId,MenuName,MenuIdStr,SortIdStr
67 | var tchild = {};
68 | if(lastMenuIdStr != t.MenuIdStr){
69 | tchild.MenuIdStr = string.replace(tup.MenuIdStr,"^" ++ lastMenuIdStr,t.MenuIdStr,1);
70 | }
71 | if(lastSortIdStr != t.SortIdStr){
72 | tchild.SortIdStr = string.replace(tup.SortIdStr,"^" ++ lastSortIdStr,t.SortIdStr,1);
73 | }
74 | tchild.IsUse = t.IsUse;
75 | table.push(tsql,ws.sql.getUpdateSql("SystemMenu", tchild, "MenuId = '" ++ tup.MenuId ++ "'"));
76 | }
77 | ok,err= ws.System.transaction(tsql);
78 | }
79 | }
80 | else {//新增
81 | t["MenuId"] = ws.System.sp_getPrimaryKey("SystemMenu");
82 | t.MenuIdStr += tostring(t["MenuId"]) ++ ",";//完整菜单ID串 (,0,1,5,)
83 | ok,err= ws.System.SystemMenu.insert(t);
84 | }
85 | if(ok){
86 | winform.msgbox("保存成功","提示")
87 | winform.close();
88 | winform.parent.page.search();
89 | }else {
90 | winform.msgbox("保存失败," ++ (err:""),"提示")
91 | }
92 | }
93 |
94 | winform.load = function(){
95 | win.delay(10);
96 | winform.cboIsUse.selIndex = 1;
97 | var MenuIdStr,sqlExp;
98 | if(winform.parent.Edit){
99 | MenuIdStr = winform.parent.trow.MenuIdStr;
100 | sqlExp = "not like";
101 | }elseif(winform.parent.page.index){
102 | MenuIdStr = winform.parent.trow.MenuIdStr;
103 | //sqlExp = "=";
104 | }
105 | tlist,tmenuId = ws.System.SystemMenu.getMenuList(MenuIdStr,sqlExp);//菜单
106 | winform.cboParentId.items = tlist;
107 | winform.cboParentId.selIndex = 1;
108 | if(winform.parent.Edit){//修改
109 | conn.setwinform(winform, winform.parent.trow);
110 | winform.txtSortIdStr.text = string.match(winform.parent.trow.SortIdStrShow,"(\d+)");
111 | var ParentId = winform.parent.trow.ParentId;
112 | if(ParentId != "0"){
113 | var ParentIdStr,err = ws.System.SystemMenu.getMenuIdStr(ParentId);//上级菜单ID串
114 | if(!ParentIdStr){
115 | winform.msgbox(err:"","提示");
116 | winform.close();
117 | }
118 | winform.cboParentId.selText = ws.System.SystemMenu.formatMenuIdStr(ParentIdStr);
119 | }
120 | }else {
121 | if(winform.parent.page.index){//新增子菜单
122 | var MenuIdStrShow = winform.parent.trow.MenuIdStrShow;
123 | winform.cboParentId.selText = MenuIdStrShow;
124 | }
125 | }
126 | winform.txttrdate.text = ws.getServerTime();
127 | winform.txttruser.text = tabLoginInfo["NickName"];
128 | }
129 |
130 | winform.toolbar.btnSave(winform.btnSave,"保存")
131 | winform.text = (winform.parent.Edit ? "修改" : "新增") ++ "系统菜单";
132 | winform.show();
133 | winform.load();
134 | win.loopMessage();
135 | return winform;
136 |
--------------------------------------------------------------------------------
/aardio-erp/res/Demo/Report.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | /*DSG{{*/
3 | var winform = win.form(text="loading...";right=600;bottom=400;parent=...)
4 | winform.add(
5 | cboReportType={cls="combobox";left=534;top=28;right=589;bottom=48;dl=1;dt=1;edge=1;items={"日报";"周报";"月报"};mode="dropdownlist";tabstop=1;z=8};
6 | cboShop={cls="comboboxex";text="请选择门店";left=3;top=27;right=212;bottom=51;autosize=1;center=1;dl=1;dt=1;edge=1;tabstop=1;transparent=1;z=1};
7 | page={cls="page";text="整页控件";left=0;top=54;right=600;bottom=400;autosize=1;center=1;clip=1;db=1;dl=1;dr=1;dt=1;edge=1;transparent=1;z=6};
8 | static={cls="static";text="统计起始订单日期";left=218;top=32;right=323;bottom=48;dl=1;dt=1;transparent=1;z=7};
9 | static7={cls="static";text="-";left=422;top=31;right=435;bottom=45;dl=1;dt=1;transparent=1;z=4};
10 | toolbar={cls="toolbar";text="工具条";left=0;top=-2;right=600;bottom=25;center=1;dl=1;dr=1;dt=1;edge=1;transparent=1;z=2};
11 | txtOrderDate1={cls="datetimepick";left=321;top=28;right=416;bottom=49;dl=1;dt=1;edge=1;z=5};
12 | txtOrderDate2={cls="datetimepick";left=435;top=28;right=530;bottom=49;dl=1;dt=1;edge=1;z=3}
13 | )
14 | /*}}*/
15 |
16 | winform.listview = winform.page.listview();
17 | winform.lvEx = winform.page.listviewEx();
18 | winform.listview.onnotify = function(id,code,ptr){
19 | return winform.lvEx.openonnotify(id,code,ptr)//默认菜单,排序
20 | }
21 | winform.page.isPage = false;
22 | winform.page.table = {
23 | {key = "rowId";name = "序号";len = 50};
24 | {key = "dateSpan";name = "报表类型(点我排序)";len = 150};
25 | {key = "ShopType";name = "平台";len = 80};
26 | {key = "ShopName";name = "门店";len = 150};
27 | {key = "OrderCount";name = "订单总数(全部)";len = 120};
28 | {key = "OrderSuccesCount";name = "订单总数(已付款)";len = 120};
29 | {key = "TotalAmount";name = "总销售额";len = 80};
30 | {key = "BuyOrderCount";name = "已拍单数";len = 80};
31 | {key = "BuyTotalAmount";name = "已拍销售额";len = 80};
32 | {key = "notBuyOrderCount";name = "未拍单数";len = 80};
33 | {key = "notBuyTotalAmount";name = "未拍销售额";len = 80};
34 | {key = "TotalProfit";name = "已拍毛利润";len = 80};
35 | {key = "ProfitRate";name = "毛利润率";len = 80};
36 | {key = "EveryPrice";name = "客单价";len = 80};
37 | {key = "startDate";name = "开始日期";len = 130};
38 | {key = "endDate";name = "结束日期";len = 130};
39 | }
40 |
41 | winform.page.where = function(){
42 | var t = winform.cboShop.getChecked("ShopId");
43 | if(!#t){
44 | t = winform.cboShop.getKey("ShopId");//所有门店
45 | }
46 | if(!#t){
47 | winform.msgbox("您没有门店权限,请联系部门管理员!","提示")
48 | return false;
49 | }
50 | var shopIds = string.join(t,",");
51 | var types = winform.cboReportType.selText;
52 | var reportType;
53 | if( types == "日报"){
54 | reportType = "2"
55 | }
56 | elseif( types == "周报"){
57 | reportType = "0"
58 | }
59 | elseif( types == "月报"){
60 | reportType = "1"
61 | }
62 | return reportType,shopIds;
63 | }
64 |
65 | winform.page.getTable = function(){
66 | var reportType,shopIds = winform.page.where();
67 | if(!reportType) return false;
68 | var tab,err = {};
69 | var date1 = winform.txtOrderDate1.time;
70 | var date2 = winform.txtOrderDate2.time;
71 | if(reportType == "0"){//周报
72 | date1.addday(1-date1.dayofweek)
73 | date2.addday(7-date2.dayofweek)
74 | dt = date2.diffday(date1);
75 | dt = dt>=7 ? (tonumber(dt/7,10)) : 0;//相差周数
76 | }
77 | else if(reportType == "1") {//月报
78 | dt = date2.diffmonth(date1);
79 | }
80 | else {//日报
81 | dt = date2.diffday(date1);
82 | }
83 | date1.format="%Y-%m-%d";
84 | for(i=0;dt;1){
85 | var t,err = ws.Order.sp_WeeklyMonthShopReport(tostring(date1),reportType,shopIds);
86 | table.push(tab,table.unpack(t))
87 | if(reportType == "0"){
88 | date1.addday(7);
89 | }
90 | else if(reportType == "1") {
91 | date1.addmonth(1);
92 | }
93 | else {
94 | date1.addday(1);
95 | }
96 | win.delay(100)
97 | }
98 | return tab,err;
99 | }
100 |
101 | var rep = function(str,paten){
102 | var num = string.match(str,"(\d+)" ++ paten);
103 | if(num){
104 | num = tonumber(num,10)
105 | num = string.format("%02i", num)
106 | str = string.replace(str,"\d+(" + paten + ")",num ++ "\1")
107 | }
108 | return str;
109 | }
110 |
111 | winform.lvEx.setCellBefore = function(value, key, row, col){
112 | if( key == "ProfitRate"){
113 | value = tostring(value) ++ "%";
114 | }
115 | elseif(key == "dateSpan"){
116 | var t = {"日";"周";"月"}
117 | for(k,v in t){
118 | value = rep(value,v)
119 | }
120 | }
121 | if(string.find(value,"汇总")){
122 | for( i=1;winform.listview.columnCount;1 ){
123 | winform.lvEx.setTextColor(row,i,gdi.RGB(255,0,0))//红色
124 | }
125 | }
126 | return value;
127 | }
128 |
129 | winform.lvEx.showDataBefore = function(){
130 | var tempate = carl.report.template(winform.lvEx.DataTable);//报表
131 | tempate.row = {"OrderCount";"OrderSuccesCount";"TotalAmount";"BuyOrderCount";"BuyTotalAmount";"notBuyOrderCount";"notBuyTotalAmount";"TotalProfit"};
132 | tempate.rowCmd = "sum";
133 | tempate.col = {//列
134 | ProfitRate="math.round([TotalProfit]*100/([BuyTotalAmount]:1), 2)";//毛利率
135 | EveryPrice="math.round([BuyTotalAmount]/([BuyOrderCount]:1), 2)";//客单价
136 | };
137 | tempate.rowDefault = {"rowId";"startDate";"endDate"};
138 | tempate.rowKey = "dateSpan";
139 | tempate.rowKeyValue = "汇总 [dateSpan]:";
140 | tempate.run();
141 | }
142 |
143 | winform.btnDao = function(){
144 | if(not winform.page.start()){return false; }
145 | var tdao = {}
146 | for(k,t in winform.page.table){
147 | if(k>1) table.push(tdao,t.key)
148 | }
149 | var tnow = time();
150 | tnow.format="%Y%m%d %H%M%S";
151 | var filename = tostring(tnow)
152 | var ok,err = winform.lvEx.exportToExcel(tdao, filename);//文件名称
153 | if(ok){
154 | pathname = ok;
155 | if(winform.msgboxTest("导出成功。是否打开?","提示")){
156 | process.execute(pathname);
157 | }
158 | }elseif(err) {
159 | winform.msgbox("导出失败," + err,"提示")
160 | }
161 | }
162 |
163 | winform.btnSearch = function(){
164 | winform.page.search();
165 | }
166 |
167 | winform.load = function(){
168 | winform.cboShop.insertItem({{text="全部";table.clone(tabSystemTreeShop)}});
169 | winform.cboReportType.selIndex = 3;
170 | winform.txtOrderDate1.time = time().addday(1-time().day)
171 | winform.page.load();
172 | }
173 |
174 | winform.toolbar.btnSearch(winform.btnSearch, "查看报表")
175 | winform.toolbar.btnOpenFolder(winform.btnDao, "导出")
176 |
177 | winform.show()
178 | //win.loopMessage();
179 | return winform;
180 |
--------------------------------------------------------------------------------
/lib/carl/ctrl/pagectrl.aardio:
--------------------------------------------------------------------------------
1 | //pagectrl 分页控件
2 | namespace carl.ctrl.pagectrl{}
3 |
4 | import util.metaProperty;
5 | namespace win.ui.ctrl;
6 | class pagectrl {
7 | ctor(parent,tParam){
8 | /*DSG{{*/
9 | this = win.form(text="aardio form";right=706;bottom=22;border="none";exmode="none";mode="child";parent=parent;tParam=tParam)
10 | this.add(
11 | btnPageEnd={cls="static";text="尾页";left=583;top=6;right=613;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=13};
12 | btnPageNext={cls="static";text="下一页";left=534;top=6;right=573;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=14};
13 | btnPagePrev={cls="static";text="上一页";left=484;top=6;right=524;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=11};
14 | btnPageStart={cls="static";text="首页";left=447;top=6;right=474;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=10};
15 | btnRefresh={cls="static";text="刷新";left=410;top=6;right=437;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=18};
16 | btnReverse={cls="static";text="反选";left=46;top=6;right=75;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=17};
17 | btnSearch={cls="static";text="跳转";left=677;top=6;right=705;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=12};
18 | btnSelect={cls="static";text="全选";left=8;top=6;right=37;bottom=21;color=16711680;dl=1;dt=1;notify=1;transparent=1;z=16};
19 | static={cls="static";text="/";left=114;top=6;right=129;bottom=21;dl=1;dt=1;transparent=1;z=1};
20 | static2={cls="static";text="共";left=172;top=6;right=191;bottom=21;dl=1;dt=1;transparent=1;z=4};
21 | static3={cls="static";text="条记录";left=262;top=6;right=305;bottom=21;dl=1;dt=1;transparent=1;z=6};
22 | static4={cls="static";text="每页";left=307;top=6;right=335;bottom=21;dl=1;dt=1;transparent=1;z=7};
23 | static5={cls="static";text="条";left=389;top=6;right=407;bottom=21;dl=1;dt=1;transparent=1;z=9};
24 | txtNowPage={cls="static";text="1";left=75;top=6;right=109;bottom=21;align="right";color=255;dl=1;dt=1;transparent=1;z=2};
25 | txtPageNum={cls="edit";text="1";left=622;top=2;right=669;bottom=22;autohscroll=false;autovscroll=false;dl=1;dt=1;edge=1;hidesel=1;num=1;z=15};
26 | txtPageSize={cls="edit";text="50";left=335;top=2;right=382;bottom=22;autohscroll=false;autovscroll=false;dl=1;dt=1;edge=1;hidesel=1;num=1;z=8};
27 | txtTotalCount={cls="static";text="1000000";left=193;top=6;right=253;bottom=19;align="center";color=255;dl=1;dt=1;transparent=1;z=5};
28 | txtTotalPage={cls="static";text="1";left=126;top=6;right=166;bottom=21;color=255;dl=1;dt=1;transparent=1;z=3}
29 | )
30 | /*}}*/
31 |
32 | ..table.mix(this@, _metaProperty);
33 | }
34 |
35 | onCreate = function(){//创建窗口后触发此函数
36 | for(name,ctrl in this.eachControl() ){
37 | if( ..string.startWith(name,"btn") ){
38 | ctrl.wndproc = function(hwnd,message,wParam,lParam){
39 | if(message = 0x200/*_WM_MOUSEMOVE*/ or message = 0x202/*_WM_LBUTTONUP*/)
40 | win.cur.setCur(hwndmouse);//鼠标形状变成手状
41 | }
42 | ctrl.oncommand = function(id,event){
43 | if( event ) return ;
44 | ctrl.disabled = true;
45 | this.btnCommand( name )
46 | ctrl.disabled = false;
47 | }
48 | }
49 | }
50 | }
51 |
52 | btnCommand = function( name ){
53 | var nowpage = tonumber(this.txtNowPage.text);
54 | var totalpage = tonumber(this.txtTotalPage.text);
55 | var page = this.txtPageNum.text;
56 | select(name) {
57 | case "btnSelect" {//全选
58 | if( !this.listview ){
59 | this.msgboxErr("请先绑定listview控件","错误");
60 | return ;
61 | }
62 | for(i=1;this.listview.count;1) this.listview.setChecked(i);
63 | if(this.selected) this.selected();
64 | }
65 | case "btnReverse" {//反选
66 | if( !this.listview ) return;
67 | for(i=1;this.listview.count;1) this.listview.setChecked(i,!this.listview.getChecked(i))
68 | if(this.selected) this.selected();
69 | }
70 | case "btnRefresh" {//刷新
71 | this.showFunc();
72 | }
73 | case "btnPageStart" {//首页
74 | this.txtNowPage.text = 1;
75 | this.showFunc();
76 | }
77 | case "btnPagePrev" {//上一页
78 | if( nowpage > 1 ){
79 | this.txtNowPage.text = nowpage - 1;
80 | this.showFunc();
81 | }
82 | }
83 | case "btnPageNext" {//下一页
84 | if( nowpage < totalpage ){
85 | this.txtNowPage.text = nowpage + 1;
86 | this.showFunc();
87 | }
88 | }
89 | case "btnPageEnd" {//尾页
90 | this.txtNowPage.text = totalpage;
91 | this.showFunc();
92 | }
93 | case "btnSearch" {//跳转
94 | if( #page ){
95 | this.txtNowPage.text = page;
96 | this.showFunc();
97 | }
98 | }
99 | }
100 | }
101 |
102 | listview = function(listview){
103 | this.listview = listview;
104 | }
105 |
106 | showFunc = function(){
107 | if( !this["showPage"] ){
108 | this.msgboxErr("请选绑定showPage显示函数","错误")
109 | return ;
110 | }
111 | this.showPage();
112 | var page = tonumber(this.txtPageSize.text) : 30;
113 | this.txtPageSize.text = page;
114 | var totalCount = tonumber(this.txtTotalCount.text) : 0;
115 | this.txtTotalPage.text = ..math.ceil( totalCount/page );//总页数
116 | }
117 |
118 | load = function(){
119 | this.btnPageStart.oncommand()
120 | }
121 | }
122 |
123 | namespace pagectrl {
124 | import win.cur;
125 | hwndmouse = win.cur.load(32649/*_IDC_HAND*/)//鼠标形状变成手状句柄
126 |
127 | _metaProperty = ..util.metaProperty(
128 |
129 | pageSize = {//每页记录数
130 | _get = function(){
131 | return owner.txtPageSize.text;
132 | }
133 | _set = function( v ){
134 | owner.txtPageSize.text = v;
135 | }
136 | };
137 |
138 | nowPage = {//当前页数
139 | _get = function(){
140 | return owner.txtNowPage.text;
141 | }
142 | _set = function( v ){
143 | owner.txtNowPage.text = v;
144 | }
145 | };
146 |
147 | totalCount = {//总记录
148 | _get = function(){
149 | return owner.txtTotalCount.text;
150 | }
151 | _set = function( v ){
152 | owner.txtTotalCount.text = v;
153 | }
154 | };
155 | )
156 | }
157 |
158 | /*intellisense()
159 | win.ui.ctrl.pagectrl = 分页控件
160 | win.ui.ctrl.pagectrl() = 分页控件
161 | ?win.ui.ctrl.pagectrl = !pagectrl.
162 | !pagectrl.pageSize = 获取或设置 每页显示记录数
163 | !pagectrl.nowPage = 获取或设置 当前页数
164 | !pagectrl.totalCount = 获取或设置 总记录
165 | !pagectrl.load() = 加载第一页
166 | !pagectrl.selected() = @.selected = function(){\n __\n}//点全选或反选后,回调函数
167 | !pagectrl.listview(.(listview控件) = 绑定listview控件
168 | end intellisense*/
169 |
--------------------------------------------------------------------------------
/aardio-erp/res/System/LimitMenu.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | /*DSG{{*/
3 | var winform = win.form(text="loading...";right=600;bottom=401;border="dialog frame";parent=...)
4 | winform.add(
5 | cbIsAdmin={cls="checkbox";text="设为部门管理员";left=169;top=47;right=276;bottom=65;dt=1;z=8};
6 | gbMenu={cls="groupbox";text="我可分配的系统菜单";left=162;top=76;right=412;bottom=400;aw=1;db=1;dt=1;edge=1;z=2};
7 | groupbox={cls="groupbox";text="我可分配的用户列表";left=1;top=27;right=160;bottom=400;aw=1;db=1;dl=1;dt=1;edge=1;z=3};
8 | groupbox3={cls="groupbox";text="我可分配的菜单按钮";left=414;top=76;right=599;bottom=400;aw=1;db=1;dr=1;dt=1;edge=1;z=5};
9 | groupbox4={cls="groupbox";text="设置";left=162;top=27;right=599;bottom=74;aw=1;dr=1;dt=1;edge=1;z=1};
10 | msg={cls="static";text="说明:打勾后,可对本部门及下级子部门员工进行菜单权限分配,尽限于分配本身享有的权限!";left=276;top=48;right=591;bottom=68;aw=1;color=16711680;dr=1;dt=1;nWrap=1;transparent=1;z=9};
11 | toolbar={cls="toolbar";text="工具条";left=0;top=-2;right=600;bottom=25;center=1;dl=1;dr=1;dt=1;edge=1;transparent=1;z=4};
12 | tvButton={cls="treeview";left=416;top=93;right=597;bottom=398;asel=false;aw=1;bgcolor=15793151;chkBox=1;db=1;dt=1;edge=1;fullRow=1;hscroll=1;singleExpand=false;vscroll=1;z=6};
13 | tvMenu={cls="treeview";left=164;top=93;right=410;bottom=398;asel=false;aw=1;bgcolor=15793151;chkBox=1;db=1;dt=1;edge=1;fullRow=1;hscroll=1;singleExpand=false;vscroll=1;z=10};
14 | tvUser={cls="treeview";left=3;top=45;right=158;bottom=398;asel=false;aw=1;bgcolor=15793151;db=1;dl=1;dt=1;edge=1;fullRow=1;hscroll=1;singleExpand=false;vscroll=1;z=7}
15 | )
16 | /*}}*/
17 |
18 | var tvMenu,tvUser;
19 | var tabUserInfo,tabUserMenu,tabMyMenuId = {},{},{};
20 | var myIsAdmin = (tabLoginInfo["LoginName"] == "admin" || tabLoginInfo["IsAdmin"] == "1");
21 |
22 | tvUser = win.ui.ctrl.treeviewex(winform.tvUser);
23 | tvUser.onnotify = function(id,code,ptr) {
24 | /*响应通知*/
25 | return tvUser.exOnnotify(id,code,ptr);
26 | };
27 | tvUser.exMouseClick = function(hItem){//单击事件
28 | var tab = tvUser.getItemData(hItem);
29 | if(!tab) return ;
30 | var SystemUserId = tab.SystemUserId;
31 | if(!SystemUserId) return ;
32 | SystemUserId = tostring(SystemUserId);
33 | var tabtvMenu = tvMenu.getItemData(tvMenu.getFirst());
34 | if(tabtvMenu.SystemUserId == SystemUserId) return ;
35 |
36 | var t = tabUserInfo[SystemUserId];
37 | if(!t) t = ws.System.SystemUser.getUserInfo(SystemUserId);
38 | if(!t) return ;
39 | tabUserInfo[SystemUserId] = t;
40 |
41 | var tMenuId = tabUserMenu[SystemUserId];
42 | if(!tMenuId) tMenuId = ws.System.SystemUserToMenu.getUserMenuIds(SystemUserId);//加载已分配的菜单权限
43 | if(!tMenuId) return ;
44 | tabUserMenu[SystemUserId] = tMenuId;
45 | tabtvMenu.SystemUserId = SystemUserId;
46 | tvMenu.setItemText(tvMenu.getFirst(),tab.text)
47 |
48 | winform.cbIsAdmin.checked = t["IsAdmin"] == "1" ? true : false;
49 | tvMenu.enum(
50 | function(hItem,parent){
51 | var t = tvMenu.getItemData(hItem);
52 | var bool = table.find(tMenuId,t.MenuId) ? true : false;
53 | tvMenu.setChecked(hItem,bool)
54 | t.checked = bool;
55 | }
56 | )
57 | }
58 |
59 | tvMenu = win.ui.ctrl.treeviewex(winform.tvMenu);
60 | tvMenu.onnotify = function(id,code,ptr) {
61 | /*响应通知*/
62 | return tvMenu.exOnnotify(id,code,ptr);
63 | };
64 | tvMenu.exCheckBoxesChanged = function(hItem, checked){//选中事件
65 | var tab = tvMenu.getItemData(hItem);
66 | if(tab) tab.checked = checked;
67 | }
68 | tvMenu.exMouseClick = function(hItem){//单击事件
69 | //显示菜单按钮权限
70 | }
71 |
72 | winform.loadUser = function(){
73 | var tabtree = {text="全部"};
74 | if(myIsAdmin){
75 | var tabUser = ws.System.SystemUser.getLimitUserList();
76 | if(tabUser){
77 | for(i=1;#tabUser;1){
78 | var row = tabUser[i]
79 | row.text = "[" + row.LoginName + "] " + row.NickName;
80 | }
81 | table.push(tabtree,tabUser)
82 | }
83 | }
84 | tvUser.insertItem(tabtree);
85 | tvUser.exExpandAll();
86 | }
87 |
88 | winform.loadMenu = function(){
89 | var tab = {text="全部"}
90 | if(myIsAdmin){
91 | table.push(tab,table.clone(tabSystemTreeMenu))
92 | }
93 | tvMenu.insertItem(tab);//系统菜单
94 | tvMenu.exExpandAll();
95 | }
96 |
97 | winform.load = function(){
98 | winform.loadUser();
99 | winform.loadMenu();
100 | if(tabLoginInfo["LoginName"] == "admin"){//获取自己的权限
101 | tabMyMenuId = ws.System.SystemMenu.getMenuIdsTable();
102 | }else {
103 | tabMyMenuId = ws.System.SystemUserToMenu.getUserMenuIds(tabLoginInfo["SystemUserId"]);
104 | }
105 | if(!myIsAdmin) winform.msgbox("您不是部门管理员,不能分配权限","提示");
106 | }
107 |
108 | winform.btnSave = function(){
109 | var t = tvMenu.getItemData(tvMenu.getFirst());
110 | var SystemUserId = t.SystemUserId;
111 | if(!SystemUserId){
112 | winform.msgbox("请指定用户!","提示")
113 | return false;
114 | }
115 | var addNum,delNum = 0,0;
116 | var trdate = ws.getServerTime();
117 | var truser = tabLoginInfo["NickName"];
118 | var tabMenu,tsql= {},{};
119 | tvMenu.enum(
120 | function(hItem,parent){
121 | var tab = tvMenu.getItemData(hItem);
122 | if(tab and tab.checked) table.push(tabMenu,tab.MenuId)
123 | }
124 | )
125 | var tabMenuOld = tabUserMenu[SystemUserId];//原先的菜单权限
126 | for(i,MenuId in tabMenu){
127 | var t = {};
128 | t.SystemUserId = SystemUserId;
129 | t.MenuId = MenuId;
130 | t.trdate = trdate;
131 | t.truser = truser;
132 | if(!table.find(tabMenuOld,MenuId)){//新增菜单权限
133 | var sql = ws.System.SystemUserToMenu.getInsertSql(t);
134 | table.push(tsql, sql);
135 | addNum++;
136 | }
137 | }
138 | for(i,MenuId in tabMenuOld){
139 | if(!table.find(tabMenu, MenuId) && table.find(tabMyMenuId,MenuId)){//删除菜单权限
140 | var sql = ws.System.SystemUserToMenu.getDeleteSql(SystemUserId, MenuId);
141 | table.push(tsql, sql);
142 | delNum++;
143 | }
144 | }
145 |
146 | var isAdmin = winform.cbIsAdmin.checked ? "1" : "0";
147 | var tinfo = tabUserInfo[SystemUserId];
148 |
149 | if(tinfo["IsAdmin"] != isAdmin){
150 | t = {}
151 | t.isAdmin = isAdmin;
152 | table.push(tsql,ws.sql.getUpdateSql("SystemUser", t, "SystemUserId='" + SystemUserId + "'"));//部门管理员
153 | }
154 | if(!#tsql){
155 | winform.msgbox("权限无变化!","提示");
156 | return false;
157 | }
158 | var msg = "菜单权限 新增:" ++ addNum ++ ",删除:" ++ delNum;
159 | msg += "
是否保存?";
160 | if(!winform.msgboxTest(msg,"询问")){
161 | return false;
162 | }
163 | var ok,err = ws.System.transaction(tsql)
164 | if(ok){
165 | tabUserInfo[SystemUserId] = ws.System.SystemUser.getUserInfo(SystemUserId);
166 | tabUserMenu[SystemUserId] = ws.System.SystemUserToMenu.getUserMenuIds(SystemUserId);
167 | winform.msgbox("保存成功","提示")
168 | }else {
169 | winform.msgbox("保存失败," ++ (err:""),"提示")
170 | }
171 | }
172 |
173 | winform.toolbar.btnSave(winform.btnSave, "保存权限")
174 |
175 | winform.show()
176 | //win.loopMessage();
177 | return winform;
178 |
--------------------------------------------------------------------------------
/lib/carl/mssql.aardio:
--------------------------------------------------------------------------------
1 | //mssql 数据库
2 | namespace carl
3 |
4 | mssql = class {
5 | ctor( server,database,uid,pwd ){
6 | var conn,err;
7 | try{
8 | conn,err = sqlServer( ["Data Source"] = server;["Database"] = database;["User ID"] = uid;["Password"] = pwd; )
9 | }
10 | catch(e){
11 | err = e;
12 | }
13 | if( conn ){
14 | this.conn = conn;
15 | }else {
16 | return null,err;
17 | }
18 | };
19 |
20 | regetTable = function(sql,...){//重写原库getTable函数
21 | var rs,err = this.conn.openRecordSet(sql,,,...);
22 | if(!rs) return null,err;
23 |
24 | var fields = {};
25 | for( i=1;rs.Fields.Count ){
26 | fields[i] = rs.Fields(i-1).Name;
27 | }
28 |
29 | var trim = string.trimright;
30 | var result = { fields = fields };
31 | var v;
32 | while(!rs.eof){
33 | var row = {};
34 | for(i,name in fields){
35 | v = rs( i-1 ).value;
36 | if( type( v ) == "string" ) v = trim(v);
37 | elseif(..time.istime(v)){//增加时间判断
38 | v.format="%Y-%m-%d %H:%M:%S";
39 | v = tostring(v);
40 | }
41 | if(#name) row[name] = v;
42 | else row[i] = v;
43 | }
44 | table.push( result,row );
45 | rs.movenext();
46 | }
47 | rs.close();
48 | return result;
49 | }
50 |
51 | exec = function(sql,...){//执行SQL或存储过程,无返回值
52 | var tab = {...};
53 | var ok,err;
54 | try{
55 | if( this.conn )
56 | ok,err = this.conn.exec(sql,table.unpack(tab));
57 | }
58 | catch(e){
59 | err = e;
60 | }
61 | return ok,err;
62 | }
63 |
64 | getTable = function(sql,...){//执行SQL,返回table记录集
65 | var tab = {...};
66 | var t,err;
67 | try{
68 | if( this.conn )
69 | t,err = this.regetTable(sql,table.unpack(tab));
70 | }
71 | catch(e){
72 | err = e;
73 | }
74 | if( type(t) != type.table ) t = null;
75 | return t,err;
76 | }
77 |
78 | getTableFirst = function(sql,...){//执行SQL,返回第一条记录
79 | var row,result,err,rs;
80 | var tp = {...}
81 | try{
82 | if( this.conn ){
83 | rs,err = this.conn.openRecordSet(sql,,,table.unpack(tp));
84 | if(!rs) return;
85 |
86 | var fields = {};
87 | for( i=1;rs.Fields.Count ){
88 | fields[i] = rs.Fields(i-1).Name;
89 | }
90 | var trim = string.trimright;
91 | row = {};
92 | if(!rs.eof){
93 | var v;
94 | for(i,name in fields){
95 | v = rs( i-1 ).value;
96 | if( type( v ) == "string" ) v = trim(v);
97 | elseif(..time.istime(v)){//增加时间判断
98 | v.format="%Y-%m-%d %H:%M:%S";
99 | v = tostring(v);
100 | }
101 | if(#name) row[name] = v;
102 | else row[i] = v;
103 | }
104 | }
105 | rs.close();
106 | }
107 | }
108 | catch(e){
109 | err = e;
110 | }
111 | if( type(row) != type.table ) row = null;
112 | return row,err;
113 | }
114 |
115 | transaction = function( tsql, ... ){//事务执行
116 | if(!#tsql) return null,"无事务SQL语句";
117 | var sql =/*
118 | SET NOCOUNT ON;
119 | BEGIN TRY
120 | BEGIN TRAN
121 | {sql}
122 | select 1 as Result
123 | COMMIT TRAN
124 | END TRY
125 | BEGIN CATCH
126 | ROLLBACK TRAN
127 | select -1 as Result,('事务失败,'+ ERROR_MESSAGE()) as Msg
128 | END CATCH
129 | */
130 | var str = (type.table == type(tsql)) ? string.join(tsql,'\r\n') : tsql;
131 | if( ... ) str = sqlServer.formatSqlParameters(str, ...);
132 | sql = string.replace(sql,"@{sql}", str);
133 | var tab,err = this.getTable(sql);
134 | if(!tab) return null,err;
135 | if(tab[1]["Result"] == 1) return true;
136 | return null,tab[1]["Msg"];
137 | }
138 |
139 | storedProcedures = function(name, ...){//执行存储过程,存储过程名称,参数(只能字符型)
140 | var t = {...};
141 | var re,err;
142 | try{
143 | this.spname(name);
144 | for(i=1;#t;1){
145 | this.spinput("@t" + tostring(i), t[i]);//输入参数
146 | }
147 | re,err = this.spexec();//执行,返回table
148 | }
149 | catch(e){
150 | err = e;
151 | }
152 | return re,err;
153 | }
154 |
155 | spname = function(name){//存储过程
156 | this.conn.cmd = com.CreateObject("ADODB.Command")
157 | this.conn.cmd.ActiveConnection = this.conn.connection;
158 | this.conn.cmd.CommandType = 4;
159 | this.conn.cmd.prepared = true;
160 | this.conn.cmd.CommandText = name;//存储过程函数名称
161 | }
162 |
163 | getRsTable = function(rs){
164 | var fields = {};
165 | for( i=1;rs.Fields.Count ){
166 | var name = rs.Fields(i-1).Name;
167 | fields[i] = #name ? name : i;
168 | }
169 | var trim = string.trimright;
170 | var result = { fields = fields };
171 | var v;
172 | while(!rs.eof){
173 | var row = {};
174 | for(i,name in fields){
175 | if(type.number == type(name)){
176 | v = rs( name-1 ).value;
177 | }else {
178 | v = rs( name ).value;
179 | }
180 | if( type( v ) == "string" ) v = trim(v);
181 | elseif(..time.istime(v)){//增加时间判断
182 | v.format="%Y-%m-%d %H:%M:%S";
183 | v = tostring(v);
184 | }
185 | name = tostring(name);
186 | row[name] = v;
187 | }
188 | table.push( result,row );
189 | rs.movenext();
190 | }
191 | return result;
192 | }
193 |
194 | //存储过程传入参数,需按顺序
195 | spinput = function(keyname,value,types = 0xC8/*_adVarChar*/){
196 | var size;
197 | if( types == 0xC8/*_adVarChar*/){
198 | value = tostring(value);
199 | size = #value+2;
200 | }
201 | this.conn.cmd.Parameters.Append(this.conn.cmd.CreateParameter(keyname,types,1/*_adParamInput*/,size,value));
202 | }
203 |
204 | //执行存储过程有返回记录集
205 | spexec = function(){
206 | var rs = this.conn.cmd.Execute();
207 | while(rs && !rs.State){
208 | rs = rs.NextRecordset();
209 | }
210 | if(!rs) return ;
211 | return this.getRsTable(rs);
212 | }
213 |
214 | close = function(){
215 | if( this.conn )
216 | this.conn.close();
217 | }
218 |
219 | }
220 |
221 | namespace mssql{
222 | import sqlServer;
223 | import com;
224 |
225 | table = ..table;
226 | string = ..string;
227 | }
228 |
229 | /**intellisense()
230 | carl.mssql = mssql数据库
231 | carl.mssql( server,database,uid,pwd ) = 创建mssql数据库连接
232 | carl.mssql() = !mssql.
233 | !mssql.conn = 数据库连接句柄
234 | !mssql.getTable(sql) = 返回查询结果集table对像\n每个元素代表一行,每行由N个键值对列组成,键fields为列名结果集
235 | !mssql.getTableFirst(sql) = 执行SQL,返回第一条记录,空记录返回空table对像
236 | !mssql.exec(sql) = 执行sql,成功返回ture,失败返回null,err
237 | !mssql.transaction(tab) = 事务执行多个sql语句,参数table对像或sql语句,成功返回ture,失败返回null,err,说明:全部执行成功,或全部失败
238 | !mssql.storedProcedures(name) = 执行存储过程,参数1:存储过程名称,参数2以后,是传存储过程函数参数(参数只能是字符型)
239 | !mssql.close() = 关闭连接
240 | end intellisense**/
241 |
--------------------------------------------------------------------------------