├── .gitignore
├── README.md
├── TODO.txt
├── config
└── settings.table
├── default.aproj
├── dlg
├── goods_purchase.aardio
├── goods_purchase_history.aardio
├── goods_select.aardio
├── goods_sell.aardio
├── model_form.aardio
├── model_list.aardio
├── select_fields.aardio
└── settings.aardio
├── lib
├── config.aardio
└── sqlitemodel
│ ├── _.aardio
│ └── modelForm.aardio
├── main.aardio
└── res
├── models
├── company.sql.aardio
├── goods_category.sql.aardio
└── store.sql.aardio
└── toolbar.gif
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | media
3 | *.pyc
4 | *.pui
5 | *.prj
6 | *.db
7 | log/*.*
8 | temp
9 | Thumbs.db
10 | test*
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # sqlitemodel
2 |
3 | 给aardio封装了一个sqlite的增删改查的库
4 |
5 | item={
6 | id=5;
7 | name="fadf";
8 | code="fadf"
9 | }
10 |
11 |
12 | model.create(item) //创建一条数据
13 | model.get(item); //查询数据
14 | model.filter(item); //根据配置好的filter_fields过滤数据
15 | model.update(item); //根据id更新数据
16 | model.delete(item); //根据id删除数据
17 | model.search(item); //根据配置好的search_fields搜索数据
18 |
19 | 东西写了很久, 但是一直有各种错误
20 |
21 | 目标就是:
22 | 1. 增删改查少操心(console下可用)
23 | 2. 直接生成界面(增删改查的界面自动生成)
24 | 3. 和Excel互相批量导入导出
25 |
26 | 以上3个基本实现,还有待完善。
27 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | 插入数据故障
2 |
3 | 1. 数据库太忙被锁定,导致复式记账法失败(应该插入4条,结果只有3条)
--------------------------------------------------------------------------------
/config/settings.table:
--------------------------------------------------------------------------------
1 | {
2 | autoclose_model_form=0;
3 | rdConfirmDelete2=0;
4 | edit_dbpath="/data/biz.db";
5 | edit_Orgs='行政部;\r\n销售部;\r\n后勤部;';
6 | rdConfirmDelete1=1;
7 | dbpath="/data/biz.db";
8 | confirm_delete=true;
9 | edit_companyname="快乐的公司"
10 | }
--------------------------------------------------------------------------------
/default.aproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/dlg/goods_purchase.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import console;
3 | import time;
4 | import config;
5 | /*DSG{{*/
6 | var winform = win.form(text="采购单(入库)";right=982;bottom=458)
7 | winform.add(
8 | button={cls="button";text="选择商品";left=798;top=7;right=976;bottom=65;dr=1;dt=1;z=8};
9 | button2={cls="button";text="全部清空";left=892;top=99;right=976;bottom=130;dr=1;dt=1;z=9};
10 | button3={cls="button";text="删除选中";left=892;top=150;right=976;bottom=181;dr=1;dt=1;z=10};
11 | button5={cls="button";text="保存采购单";left=768;top=416;right=855;bottom=446;db=1;dr=1;z=14};
12 | edit_applier={cls="edit";left=462;top=38;right=592;bottom=60;dl=1;dt=1;edge=1;z=13};
13 | edit_from_store={cls="combobox";left=265;top=10;right=395;bottom=30;dl=1;dt=1;edge=1;items={};mode="dropdown";z=2};
14 | edit_org={cls="combobox";left=265;top=40;right=392;bottom=61;dl=1;dt=1;edge=1;items={};mode="dropdown";z=15};
15 | edit_ps_id={cls="edit";left=662;top=6;right=754;bottom=28;disabled=1;dl=1;dt=1;edge=1;readonly=1;z=18};
16 | edit_subject={cls="edit";left=265;top=67;right=674;bottom=90;dl=1;dt=1;edge=1;z=6};
17 | edit_to_store={cls="combobox";left=462;top=10;right=592;bottom=30;dl=1;dt=1;edge=1;items={};mode="dropdown";z=4};
18 | listview={cls="listview";left=206;top=99;right=878;bottom=397;db=1;dl=1;dr=1;dt=1;edge=1;fullRow=1;gridLines=1;vscroll=1;z=7};
19 | static={cls="static";text="供应商";left=205;top=9;right=260;bottom=29;dl=1;dt=1;transparent=1;z=1};
20 | static2={cls="static";text="仓库";left=401;top=12;right=452;bottom=33;dl=1;dt=1;transparent=1;z=3};
21 | static3={cls="static";text="备注";left=204;top=70;right=259;bottom=90;dl=1;dt=1;transparent=1;z=5};
22 | static4={cls="static";text="部门处室";left=204;top=41;right=259;bottom=61;dl=1;dt=1;transparent=1;z=11};
23 | static5={cls="static";text="申请人";left=401;top=40;right=452;bottom=60;dl=1;dt=1;transparent=1;z=12};
24 | static6={cls="static";text="采购单";left=606;top=9;right=657;bottom=29;dl=1;dt=1;transparent=1;z=17};
25 | treeview={cls="treeview";left=11;top=10;right=198;bottom=401;asel=false;bgcolor=16777215;dl=1;dt=1;edge=1;hscroll=1;vscroll=1;z=16}
26 | )
27 | /*}}*/
28 |
29 | //
30 | winform.user_define_fields= {}
31 |
32 | /*winform_reset_listview{{*/
33 | winform.reset_listview = function(model, items, fields, clear_data=true){
34 |
35 | if(#items == 0){
36 | winform.listview.clear();
37 | return
38 | }
39 |
40 | console.log("winform.listview.columnCount", winform.listview.columnCount)
41 |
42 | var display_fields;
43 |
44 | if(fields != null and type(fields) == "table" and #fields > 0 ){
45 | display_fields = fields;
46 | }else {
47 | display_fields = model.display_fields;
48 | }
49 |
50 | var n = winform.listview.columnCount;
51 | var unmatched = false;
52 | if(n != 0){
53 | //检测列标题是否匹配
54 | var captions = {};
55 | for(i=1;n;1){
56 | table.push(captions, winform.listview.getColumnText(i))
57 | }
58 |
59 | for(i=1;#display_fields;1){
60 | var k = display_fields[i]
61 | var caption = model.headers[k]
62 | if(caption==null){
63 | caption = k;
64 | }
65 | if(table.find(captions, caption) == null){
66 | console.log("列标题和user fields不匹配,不匹配的列为:", caption, table.tostring(captions))
67 | unmatched = true
68 | }
69 | }
70 | }
71 |
72 | //如果不匹配, 直接重新建立新的列标题
73 | if(unmatched or n == 0){
74 | //重新制作rebuild
75 | //unmatched, user_fields和现在的列标题不匹配
76 | //n==0, 是没有列标题, listview没有准备好,
77 | if(n==0){
78 | console.log("没有设置列标题,重新设置")
79 | }else {
80 | console.log("unmatched, user_fields和现在的列标题不匹配")
81 | }
82 |
83 |
84 | last_items = {} //列标题不匹配,数据也没用了。
85 | winform.listview.clear();
86 |
87 | for(i=1;n;1){
88 | winform.listview.delColumn(n+1-i);//从倒数开始删除, 以免删除前面的, 后面的索引都变了.
89 | }
90 |
91 | for(i=1;#display_fields;1){
92 | var k = display_fields[i]
93 | var caption = model.headers[k];
94 | if(caption==null){
95 | caption=k;
96 | }
97 | winform.listview.insertColumn(caption, 80, i);
98 | }
99 |
100 | n = winform.listview.columnCount;
101 | winform.listview.insertColumn("数量", 80, n+1);
102 | winform.listview.insertColumn("单价", 80, n+2);
103 | winform.listview.insertColumn("金额", 100, n+3);
104 |
105 | n = winform.listview.columnCount;
106 | if(n>=4){
107 | winform.listview.setColumn({cx=40},1)
108 | winform.listview.setColumn({cx=70},2)
109 | winform.listview.setColumn({cx=180},3)
110 | winform.listview.setColumn({cx=80},4)
111 | }
112 | }
113 |
114 | //如果清空listview
115 | if(clear_data){
116 | winform.listview.clear();
117 | }
118 |
119 | //加入新数据
120 | for(i=1;#items;1){
121 | var item = {}//每一行的数据
122 | for(j=1;#display_fields;1){
123 | field = display_fields[j];
124 | //if(k=="id"){
125 | // table.push(data, tostring(i))
126 | // continue
127 | //}
128 | var value = items[i][field];
129 | if(value != null){
130 | table.push(item, value)
131 | }else {
132 | table.push(item, "")
133 | }
134 | }
135 |
136 | //后面的3列数据,这里手动添加
137 | //table.push(item, items[i]["quantity"])//
138 | //table.push(item, items[i]["price"])
139 | //table.push(item, items[i]["amount"])
140 |
141 |
142 | var num = 1;//数量默认为1
143 | if(items[i]["quantity"] != null){
144 | num = items[i]["quantity"];
145 | }
146 |
147 | table.push(item, tostring(num));
148 |
149 | if(items[i]["price"] != null){
150 | table.push(item, tostring(items[i]["price"]));//单价
151 | table.push(item, tostring(num * items[i]["price"]));//金额
152 | }else {
153 | table.push(item, "0");//单价
154 | table.push(item, "0");//金额
155 | }
156 |
157 |
158 | winform.listview.addItem({
159 | text = item;
160 | });
161 | }
162 |
163 |
164 | }
165 | /*}}*/
166 |
167 |
168 | winform.reset_from = function(){
169 | winform.edit_ps_id.text = "";
170 | winform.edit_ps_id.disabled = true;
171 | winform.edit_applier.text = "";
172 | winform.edit_org.text = "";
173 | winform.edit_subject.text = "";
174 | winform.edit_to_store.text = "";
175 | winform.edit_from_store.text = "";
176 | winform.listview.clear();
177 | }
178 |
179 | winform.button.oncommand = function(id,event){
180 | var frmChild = winform.loadForm("\dlg\goods_select.aardio");
181 | var goods_ids = frmChild.doModal();
182 |
183 | //var sql = "select from ["+winform.+"]"
184 | var model = modGoods
185 | if(#goods_ids){
186 | var sql = string.format("select * from [%s] where id in (%s)", model.tablename, string.join(goods_ids,","))
187 | var items = model.getTable(sql);
188 |
189 | for(i=1;#items;1){
190 | items[i]["goods_id"] = items[i]["id"];
191 | items[i]["id"] = "";
192 | }
193 |
194 |
195 | /*
196 | var user_define_fields = model.display_fields
197 | table.removeByValue(user_define_fields, "created_at")
198 | table.removeByValue(user_define_fields, "updated_at")
199 | */
200 |
201 | var user_define_fields = {"id"; "goods_id";"name"; "unit"; "specs";}
202 | winform.reset_listview(model, items, user_define_fields, false)
203 | winform.user_define_fields = user_define_fields;
204 | }
205 | }
206 |
207 |
208 |
209 |
210 | winform.init = function(){
211 | //调用mainForm中的全局变量
212 | var suppliers = table.map(modStore.filter({["cate"]="供应商"}),function(v,k,result){
213 | if(type(k)== "number"){
214 | table.push(result, string.format("%s|%s", v.id, v.name))
215 | }
216 | })
217 |
218 | var stores = table.map(modStore.filter({["cate"]="仓库"}),function(v,k,result){
219 | if(type(k)== "number"){
220 | table.push(result, string.format("%s|%s", v.id, v.name))
221 | }
222 | })
223 |
224 |
225 | for(i=1;#suppliers;1){
226 | winform.edit_from_store.add(suppliers[i])
227 | }
228 |
229 | for(i=1;#stores;1){
230 | winform.edit_to_store.add(stores[i])
231 | }
232 |
233 |
234 | var edit_Orgs = config.settings.edit_Orgs;
235 |
236 | if(edit_Orgs != null){
237 | var items = string.split(edit_Orgs, "<;>")
238 | for(i=1;#items;1){
239 | winform.edit_org.add(string.trim(items[i]))
240 | }
241 |
242 | }
243 |
244 | var purchases = modPurchase.search();
245 | for(i=1;#purchases;1){
246 | winform.treeview.insertItem({text = purchases[i].name; ps_id = purchases[i].id})
247 | }
248 |
249 | }
250 |
251 | winform.edit_from_store.onEditChange = function(){
252 | var text = winform.edit_from_store.text;
253 | var items = table.filter( winform.edit_from_store.items, lambda(v) string.startWith(v,text) );
254 | if(string.trim(text) == ""){
255 | items = table.map(modStore.filter({["cate"]="供应商"}),function(v,k,result){
256 | if(type(k)== "number"){
257 | table.push(result, string.format("%s|%s", v.id, v.name))
258 | }
259 | })
260 | }
261 | winform.edit_from_store.autoComplete(items);
262 | }
263 |
264 | winform.edit_to_store.onEditChange = function(){
265 | var text = winform.edit_to_store.text;
266 | var items = table.filter( winform.edit_to_store.items, lambda(v) string.startWith(v,text) );
267 | if(string.trim(text) == ""){
268 | items = table.map(modStore.filter({["cate"]="仓库"}),function(v,k,result){
269 | if(type(k)== "number"){
270 | table.push(result, string.format("%s|%s", v.id, v.name))
271 | }
272 | })
273 | }
274 | winform.edit_to_store.autoComplete(items);
275 | }
276 |
277 | winform.button2.oncommand = function(id,event){
278 | winform.listview.clear();
279 | }
280 |
281 |
282 | winform.listview.onnotify = function(id,code,ptr){
283 | if(code = 0xFFFFFFFE/*_NM_CLICK*/ ){
284 | if(winform.listview.columnCount==0){
285 | return
286 | }
287 | var nm = winform.listview.getNotifyMessage(code,ptr);
288 | if( ! nm.iItem && nm.iSubItem ) return true;//不允许编辑项
289 |
290 | //一点击就出现编辑框, 不用先点一下, 再点一下
291 | //winform.listview.editLabel(nm.iItem, nm.iSubItem);
292 | //上面这一行只能编辑第一列, 第2列和后面的都不能编辑, 看了源码,不行
293 | var nCols = winform.listview.columnCount;
294 | if(nm.iSubItem")[1]);
413 |
414 | item["cate_id"] = 0;
415 | item["cate_name"] = "采购入库";
416 |
417 | item["trans_dir"] = "入库";
418 | item["trans_type"] = 1;
419 | item["trans_id"] = 0;
420 | item["balance"] = 0;
421 |
422 | console.log("准备保存的数据item");
423 | console.varDump(item)
424 | var from_id = modGoodsJournal.create(item);
425 |
426 | //对方那一条数据
427 | item["store_id"] = tonumber(string.split(pitem["from_store"], "<|>")[1]);
428 |
429 | item["cate_id"] = 0;
430 | item["cate_name"] = "销售出库";
431 |
432 | item["trans_dir"] = "出库";
433 | item["trans_type"] = 0;
434 | item["trans_id"] = 0;
435 | item["balance"] = 0;
436 | var to_id = modGoodsJournal.create(item); //double entry booking!!!
437 |
438 | var gtitem={}
439 | gtitem["goods_id"] = item["goods_id"];
440 | gtitem["name"]=item["name"];
441 | gtitem["quantity"]=item["quantity"];
442 | gtitem["amount"]=item["amount"];
443 |
444 | gtitem["from_store_id"]= tonumber(string.split(pitem["from_store"], "<|>")[1]);
445 | gtitem["from_store_name"]=string.split(pitem["from_store"], "<|>")[2];
446 | gtitem["from_journal_id"]=from_id;
447 |
448 | gtitem["to_store_id"]=tonumber(string.split(pitem["to_store"], "<|>")[1]);
449 | gtitem["to_store_name"]=string.split(pitem["to_store"], "<|>")[2];
450 | gtitem["to_journal_id"]=to_id;
451 |
452 |
453 |
454 |
455 | var gt_it = modGoodsTrans.create(gtitem); //创建转库的记录
456 |
457 | modGoodsPrice.create(item); //因为item中包含了modGoodsPrice需要的字段,所以不用改
458 |
459 | //计算库存
460 | var query = {}
461 |
462 | query["store_id"] = gtitem["from_store_id"]
463 | query["goods_id"] = item["goods_id"]
464 | query["trans_type"] = 1;
465 |
466 | var sql = "select sum(quantity) as sum_in from goods_journal
467 | where store_id=@store_id and goods_id =@goods_id and trans_type=@trans_type"
468 | var r = modGoodsJournal.exec(sql, query)
469 | console.log("入库数量:")
470 | console.varDump(r)
471 |
472 | var in_quantity = (r != null) ? r.sum_in : 0;
473 | console.log("in_quantity":tostring(in_quantity))
474 | console.varDump(in_quantity)
475 |
476 | sql = "select sum(quantity) as sum_out from goods_journal
477 | where store_id=@store_id and goods_id =@goods_id and trans_type=@trans_type"
478 | query["trans_type"] = 0;
479 | r = modGoodsJournal.exec(sql, query)
480 | var out_quantity = (r != null) ? r.sum_out : 0;
481 |
482 | sql="select sum(amount) as sum_in from goods_journal
483 | where store_id=@store_id and goods_id =@goods_id and trans_type=@trans_type"
484 | query["trans_type"] = 1;
485 | r = modGoodsJournal.exec(sql, query)
486 | var in_amount = (r != null) ? r.sum_in : 0;
487 |
488 | sql = "select sum(amount) as sum_out from goods_journal
489 | where store_id=@store_id and goods_id =@goods_id and trans_type=@trans_type"
490 | query["trans_type"] = 0;
491 | r = modGoodsJournal.exec(sql, query)
492 | var out_amount = (r != null) ? r.sum_out : 0;
493 |
494 | query["in_quantity"] = in_quantity;
495 | query["out_quantity"] = out_quantity;
496 | query["balance"] = in_quantity - out_quantity;
497 | query["amount"] = in_amount - out_amount;
498 | query["name"] = item["name"];
499 |
500 | modGoodsBalance.create(query)
501 |
502 |
503 |
504 | }
505 | winform.treeview.insertItem({text = pitem["name"];ps_id=ps_id})
506 | winform.reset_from();
507 | }else {
508 | console.log("----------------更新----------------------------------")
509 | ps_id = tonumber(ps_id)
510 | var tm = time.now();
511 | var pitem = {};
512 |
513 | pitem["name"] = tostring(tm, "采购单-%Y%m%d_%H%M%S", "chs");
514 | pitem["org"] = winform.edit_org.text;
515 | pitem["applier"] = winform.edit_applier.text;
516 | pitem["supplier"] = winform.edit_from_store.text;
517 | pitem["subject"] = winform.edit_subject.text;
518 | pitem["store"] = winform.edit_to_store.text;
519 | pitem["id"] = ps_id;
520 |
521 | var updated = modPurchase.update(pitem);
522 | console.log("modPurchase update", updated)
523 |
524 | required_fields = {
525 | "supplier";
526 | "store";
527 | "org";
528 | "applier";
529 | "name";
530 | }
531 |
532 | invalid = false;
533 | invalid_field = ""
534 | for(i=1;#required_fields;1){
535 | if(pitem[required_fields[i]] == null or pitem[required_fields[i]] == ""){
536 | invalid = true;
537 | invalid_field = required_fields[i];
538 | break;
539 | }
540 |
541 | }
542 |
543 | if(invalid){
544 | winform.msgbox(string.format("%s不能为空!", invalid_field));
545 | return ;
546 | }
547 |
548 |
549 | for(i=1;winform.listview.count;1){
550 | var item = {};
551 | //winform.user_define_fields
552 | for(j=1;#winform.user_define_fields;1){
553 | var field = winform.user_define_fields[j]
554 | item[field] = winform.listview.getItemText(i,table.find(winform.user_define_fields, field))
555 | console.log("field", field, item[field])
556 | }
557 | //item["goods_id"] = tonumber(item["id"]);
558 | //item["id"] = null;
559 |
560 | n = winform.listview.columnCount;
561 | item["quantity"] = winform.listview.getItemText(i,n-2)
562 | item["price"] = winform.listview.getItemText(i,n-1)
563 | item["amount"] = winform.listview.getItemText(i,n)
564 |
565 | item["price"] = tonumber(item["price"]);
566 | item["quantity"] = tonumber(item["quantity"]);
567 |
568 | item["amount"] = item["price"] * item["quantity"]
569 |
570 | item["ps_id"] = tonumber(ps_id);
571 |
572 | item["store_id"] = tonumber(string.split(pitem["store"], "<|>")[1]);
573 |
574 | item["cate_id"] = 0;
575 | item["cate_name"] = "采购入库";
576 |
577 | item["trans_dir"] = "入库";
578 | item["trans_type"] = 1;
579 | item["trans_id"] = 0;
580 | item["balance"] = 0;
581 |
582 | console.log("准备更新的数据item");
583 | console.varDump(item)
584 | if(item["id"]=="" or item["id"]== null){
585 | modGoodsJournal.create(item);
586 | modGoodsPrice.create(item); //只新建价格
587 | }else {
588 | modGoodsJournal.update(item);
589 | var priceitem = item;
590 | priceitem["id"] = null;
591 | modGoodsPrice.create(priceitem);//只新建价格
592 | }
593 | console.log("----------------------更新完毕-----------------------");
594 | }
595 | }
596 |
597 | }
598 |
599 | winform.delete_purchase = function(ps_id){
600 | var pitem = modPurchase.get({id=ps_id});
601 | var goods = modPurchaseGoods.filter({filter_field="purchase_id";keyword=ps_id});
602 | for(i=1;#goods;1){
603 | modPurchaseGoods.delete({id = goods[i].id})
604 | }
605 | modPurchase.delete({id=ps_id});
606 | }
607 |
608 |
609 | winform.treeview.onnotify = function(id,code,ptr){
610 | select(code) {
611 | case 0xFFFFFFFE/*_NM_CLICK*/ {
612 | var hi = winform.treeview.hitTest();
613 | if(hi){
614 | winform.listview.clear();
615 | var data = winform.treeview.getItemData(hi);
616 | var ps_id = data["ps_id"];
617 | if(ps_id){
618 | var pitem = modPurchase.get({id=ps_id});
619 | var items = modGoodsJournal.filter({["ps_id"]=ps_id;["trans_type"] = 1})
620 | console.log("pitem")
621 | console.varDump(pitem)
622 | console.log("goods[1]")
623 | console.varDump(items[1])
624 |
625 | winform.edit_org.text = pitem["org"];
626 | winform.edit_applier.text = pitem["applier"];
627 | winform.edit_subject.text = pitem["subject"];
628 | winform.edit_from_store.text = pitem["from_store"];
629 | winform.edit_to_store.text = pitem["to_store"];
630 | //取消winform.edit_ps_id禁用
631 | winform.edit_ps_id.disabled = false;
632 | winform.edit_ps_id.text = tostring(ps_id);
633 |
634 | winform.reset_listview(modGoods, items, winform.user_define_fields, false)
635 | }
636 |
637 | }else{
638 | winform.reset_from();
639 | }
640 |
641 |
642 |
643 |
644 | }
645 | case 0xFFFFFFFB/*_NM_RCLICK*/{
646 | //右键菜单
647 | var x,y = mouse.getPos();
648 | var hi = winform.treeview.hitTest();
649 |
650 | var iRow, iCol = winform.listview.hitTest(x,y,true);
651 | if(iRow){
652 | winform.listview.setSelected(iRow)
653 | winform.lastListviewSelected = iRow;
654 | }
655 |
656 | var menu = win.ui.popmenu(winform)
657 |
658 | menu.add("删除",
659 | function(){
660 | if(winform.msgboxTest("确认删除采购单吗?"++'\r\n\r\n'++"确认将会同时删除采购单中的商品记录")){
661 | var data = winform.treeview.getItemData(hi);
662 | var ps_id = data["ps_id"];
663 | if(ps_id){
664 | winform.delete_purchase(ps_id)
665 | winform.treeview.delItem(hi);
666 | winform.reset_from();
667 | }
668 | }
669 |
670 | }
671 | );
672 |
673 | menu.popup(x,y,true);
674 | }
675 | else {
676 | }
677 | }
678 | }
679 |
680 |
681 | winform.init();
682 | winform.show();
683 | win.loopMessage();
684 | return winform;
--------------------------------------------------------------------------------
/dlg/goods_purchase_history.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import win.ui.statusbar;
3 | import config;
4 | import console;
5 | import sqlitemodel.modelForm;
6 | /*DSG{{*/
7 | var winform = win.form(text="数据列表";right=948;bottom=601;border="dialog frame";mode="popup";parent=...)
8 | winform.add(
9 | btnGotoNPage={cls="button";text="转到第N页";left=650;top=353;right=724;bottom=374;db=1;dl=1;z=10};
10 | btnNext={cls="button";text="下一页";left=385;top=353;right=450;bottom=374;db=1;dl=1;z=8};
11 | btnPrev={cls="button";text="上一页";left=305;top=353;right=370;bottom=374;db=1;dl=1;z=7};
12 | button={cls="button";text="搜索";left=409;top=28;right=473;bottom=52;dl=1;dt=1;z=4};
13 | button2={cls="button";text="Button";left=740;top=352;right=811;bottom=374;db=1;dr=1;z=13};
14 | button3={cls="button";text="添加";left=52;top=28;right=127;bottom=51;z=15};
15 | button4={cls="button";text="批量导入";left=696;top=30;right=777;bottom=53;z=16};
16 | button6={cls="button";text="刷新";left=476;top=28;right=540;bottom=52;dl=1;dt=1;z=11};
17 | button7={cls="button";text="选择显示字段";left=551;top=28;right=648;bottom=52;dl=1;dt=1;z=12};
18 | comboCurrPage={cls="combobox";left=562;top=353;right=643;bottom=374;db=1;dl=1;edge=1;items={};mode="dropdown";z=9};
19 | comboItemsPerpage={cls="combobox";left=215;top=354;right=293;bottom=374;db=1;dl=1;edge=1;items={"10";"20";"50";"100"};mode="dropdown";z=5};
20 | edit={cls="edit";left=168;top=29;right=397;bottom=53;dl=1;dt=1;edge=1;z=14};
21 | listbox={cls="listbox";left=161;top=377;right=941;bottom=578;db=1;dl=1;dr=1;edge=1;hscroll=1;items={};vscroll=1;z=2};
22 | listview={cls="listview";left=162;top=56;right=934;bottom=346;db=1;dl=1;dr=1;dt=1;edge=1;font=LOGFONT(name='Consolas');fullRow=1;gridLines=1;hscroll=1;vscroll=1;z=3};
23 | static={cls="static";text="每页条数";left=160;top=354;right=211;bottom=369;db=1;dl=1;transparent=1;z=6};
24 | treeview={cls="treeview";left=5;top=56;right=156;bottom=578;asel=false;bgcolor=16777215;db=1;dl=1;dt=1;edge=1;vscroll=1;z=1}
25 | )
26 | /*}}*/
27 |
28 | ////
29 | //////////////////////////////
30 | ////全局变量
31 | winform.model = null;
32 | winform.lastListviewSelected = 0;
33 |
34 | is_form_valid = function(){
35 | if( #winform.edit_title.text
36 | && #winform.edit_account.text
37 | && #winform.edit_pass.text)
38 | {
39 | return true;
40 | }else {
41 | winform.msgboxErr("title,account and password is requried","Err")
42 | }
43 | return false;
44 | }
45 |
46 | initTreeview = function(model, tv){
47 |
48 | var filter_fields = model.filter_fields;
49 | if(#filter_fields>0){
50 | tv.clear();
51 | }
52 |
53 | var item = {text = "显示全部数据"}
54 | var hItem = tv.insertItem(item)
55 |
56 | for(i=1;#filter_fields;1){
57 | var item = {}
58 | /*{
59 | text = "按区划分";
60 | {
61 | { text = "芙蓉区" };
62 | { text = "天心区" };
63 | { text = "岳麓区" };
64 | { text = "开福区" };
65 | { text = "雨花区" };
66 | { text = "未分区" };
67 | }
68 | }*/
69 |
70 |
71 |
72 | var k = filter_fields[i]
73 | var caption = model.headers[k]
74 |
75 | console.varDump(model.headers)
76 | console.log("caption, k",caption, k)
77 |
78 | item["text"] = string.format("按%s过滤", caption);
79 | //query["filter_field"] = k
80 |
81 | var sql = string.format("select distinct %s from %s", k, model.tablename)
82 | var items = model.getTable(sql)
83 |
84 | var data = {}
85 | for(i=1;#items;1){
86 | table.push(data, {text = items[i][k]; filter_field = k})
87 | }
88 |
89 | table.push(item, data)
90 |
91 | var hItem = tv.insertItem(item)
92 |
93 | }
94 |
95 | tv.expandAll()
96 |
97 |
98 | }
99 |
100 | winform.button.oncommand = function(id,event){
101 |
102 | if(winform.model == null){
103 | winform.msgbox("窗口未设置model对象, 无法正确显示数据")
104 | }
105 |
106 | keyword = winform.edit.text;
107 | winform.load_data(keyword)
108 |
109 | }
110 |
111 |
112 |
113 | winform.load_data = function(keyword=""){
114 | var items={};
115 | var query = {};
116 | if(type(keyword)=="table"){
117 | query = keyword
118 | }elseif(type(keyword)=="string"){
119 | query["keyword"] = keyword;
120 | }
121 | query["QUERY_MODE"] = "SEARCH";
122 |
123 |
124 |
125 | CURR_QUERY = query; //记录到全局变量CURR_QUERY中
126 | //log(table.tostring(CURR_QUERY));
127 | items = winform.model.search(query);
128 |
129 | winform.resetlistview(items)
130 |
131 |
132 | }
133 |
134 |
135 |
136 | winform.resetlistview = function(items){
137 | winform.statusbar.setText("公司总数:" + #items);
138 |
139 |
140 | if(#items){
141 | winform.listview.clear();
142 | }else {
143 | winform.listview.clear();
144 | }
145 |
146 |
147 | //for(i=1;#items;1){
148 | // console.varDump(items[i])
149 | //}
150 |
151 |
152 | //如果获取了数据, 那么清空listview
153 | var n = winform.listview.columnCount;
154 | for(i=1;winform.listview.columnCount;1){
155 | winform.listview.delColumn(n+1-i);
156 | }
157 |
158 | var display_fields = winform.model.display_fields;
159 | for(i=1;#display_fields;1){
160 | var k = display_fields[i]
161 | var caption = winform.model.headers[k]
162 | winform.listview.insertColumn(caption, 140, i);
163 | }
164 |
165 | winform.listview.setColumn({cx=30},1)
166 | winform.listview.setColumn({cx=180},2)
167 | winform.listview.setColumn({cx=80},3)
168 |
169 |
170 |
171 | for(i=1;#items;1){
172 | //winform.listview.add(items[i]['title']);
173 | //console.log("query[i]")
174 | //console.varDump(items[i])
175 |
176 | var row ={}
177 | for(j=1;#display_fields;1){
178 | k = display_fields[j];
179 | //if(k=="id"){
180 | // table.push(data, tostring(i))
181 | // continue
182 | //}
183 | //console.log('k', k);
184 | if(items[i][k]!=null){
185 | table.push(row, items[i][k])
186 | }else {
187 | table.push(row, "")
188 | }
189 |
190 |
191 | }
192 | //
193 | //console.varDump(items[i])
194 | //
195 |
196 | winform.listview.addItem({
197 | text = row
198 | });
199 | }
200 |
201 | if(items["ITEMS_PERPAGE"]){
202 | winform.comboItemsPerpage.text = tostring(items["ITEMS_PERPAGE"])
203 | }
204 | if(items["PAGES"]){
205 | winform.comboCurrPage.clear();
206 | for(i=1;items["PAGES"];1){
207 | winform.comboCurrPage.add(tostring(i))
208 | }
209 | }
210 | if(items["CURR_PAGE"]!=null){
211 | winform.comboCurrPage.text = tostring(items["CURR_PAGE"]+1)
212 | }
213 | }
214 |
215 |
216 | winform.init = function(model){
217 |
218 | //winform.center()
219 | winform.model = model;
220 |
221 | var state = config.settings.autoclose_company_form;
222 | //
223 | //console.log(" config autoclose_company_form " ++ state)
224 | //
225 |
226 | if(state == null){
227 | state = false;
228 | config.saveAll()
229 | }
230 | //
231 | //console.log(" started " ++ state)
232 | //
233 | win.ui.statusbar( winform ).addItem("公司:", 100/*宽度*/)
234 |
235 | winform.statusbar.addItem("数据库:", 500);
236 |
237 | initTreeview(winform.model, winform.treeview)
238 |
239 | winform.load_data(winform.model)
240 | }
241 |
242 | winform.button7.oncommand = function(id,event){
243 |
244 | }
245 |
246 | winform.treeview.onnotify = function(id,code,ptr){
247 | if(code = 0xFFFFFFFE/*_NM_CLICK*/){
248 | //单击
249 | var x,y = mouse.getPos()
250 | var hItem,tvht = winform.treeview.hitTest(x,y,true);
251 |
252 | if(!hItem){
253 | return
254 | }
255 |
256 | winform.treeview.setSelected(hItem);
257 | winform.treeview.expandAll()
258 |
259 | var hitem = winform.treeview.getSelection()
260 | //winform.text = winform.treeview.getItemData(hitem);
261 | var data = winform.treeview.getItemData(hitem);
262 |
263 | var filter_field = data["filter_field"];
264 | //if(filter_field == null){
265 | // return
266 | //}
267 |
268 | var keyword = "";
269 |
270 | if(data == null or #data>0){
271 | //未选中节点, 或者选中节点有子节点(根节点)
272 | keyword = ""
273 | //return
274 | }else {
275 | //没有子节点的节点,如果是根节点, 那么也是在这里处理, 但是没有filter_field数据, 所以后面的filter
276 | // 会因为没有filter_field数据, 而返回全部数据, 忽略keyword
277 | keyword = data["text"];
278 | if(string.indexOf(keyword, "|")){
279 | keyword = string.split(keyword, "<|>")[1]
280 | }
281 | //winform.text = data["text"] ++ " 单位";
282 | }
283 |
284 | var query = {};
285 | query["filter_field"] = filter_field;
286 | query["keyword"] = keyword;
287 | var items_perpage = tonumber(winform.comboItemsPerpage.text);
288 | query["ITEMS_PERPAGE"] = items_perpage
289 | query["QUERY_MODE"] = "FILTER";
290 |
291 | CURR_QUERY = query;
292 | log(table.tostring(CURR_QUERY));
293 |
294 | var items = winform.model.filter(query)
295 |
296 | reset_listview(items)
297 |
298 | }
299 | }
300 |
301 |
302 | winform.item_detail = function(id){
303 | var mform = sqlitemodel.modelForm(winform.model, winform, id);
304 | mform.doModal(winform);
305 | winform.load_data(winform.model)
306 | }
307 |
308 | winform.delete_item = function(){
309 | var iRow = winform.listview.getSelection();
310 | console.log('irow',iRow)
311 |
312 | if(!iRow){
313 | return
314 | }
315 |
316 | var query = {}
317 | console.log(table.tostring(winform.model.display_fields))
318 | for(i=1;#winform.model.display_fields;1){
319 | k = winform.model.display_fields[i]
320 | query[k] = winform.listview.getItemText(iRow, i)
321 | }
322 |
323 | var confirmed = false; //默认不删除
324 | if(config.settings.confirm_delete){
325 | confirmed = winform.msgboxTest("确认删除吗?"); //看用户选择
326 | }else {
327 | confirmed = true; //无需确认
328 | }
329 |
330 | console.log("confirmed",confirmed, winform.model.tablename)
331 | if(confirmed){
332 | console.log(table.tostring(query))
333 | var deleted = winform.model.delete(query);
334 | //initTreeviewFilters(modCompany);
335 | if(deleted){
336 | winform.load_data();
337 | winform.msgbox("删除成功!")
338 | }else {
339 | winform.msgbox("删除失败!")
340 | }
341 |
342 |
343 | }
344 | }
345 |
346 |
347 |
348 | winform.listview.onnotify = function(id,code,ptr){
349 |
350 | select(code) {
351 |
352 | case 0xFFFFFFFD/*_NM_DBLCLK*/ {
353 | //双击编辑
354 | var x,y = mouse.getPos()
355 | var iRow, iCol = winform.listview.hitTest(x,y,true);
356 | if(iRow){
357 | winform.listview.setSelected(iRow)
358 | winform.lastListviewSelected = iRow;
359 | winform.item_detail(iRow)
360 | }
361 |
362 | }
363 | case 0xFFFFFFFB/*_NM_RCLICK*/ {
364 | //右键菜单
365 | var x,y = mouse.getPos()
366 | var iRow, iCol = winform.listview.hitTest(x,y,true);
367 | if(iRow){
368 | winform.listview.setSelected(iRow)
369 | winform.lastListviewSelected = iRow;
370 | }
371 |
372 | var menu = win.ui.popmenu(winform)
373 |
374 | menu.add("详细信息",
375 | function(){
376 | menu_company_detailinfo()
377 | }
378 | );
379 |
380 |
381 | var filter_fields = modCompany.filter_fields
382 |
383 | var filter_menus = {}
384 |
385 |
386 |
387 | for(i=1;#filter_fields;1){
388 | var item = {}
389 |
390 | var k = filter_fields[i]
391 | var caption = headers[k]
392 |
393 | table.push(item, string.format("更改选中项的%s为", caption))
394 | var sql = string.format("select distinct %s from %s", k, modCompany.tablename)
395 | var items = modCompany.getTable(sql)
396 |
397 | console.varDump(items)
398 |
399 | var data = {}
400 | for(i=1;#items;1){
401 | console.log("items[i][k]", items[i][k]);
402 | var x = {
403 | tostring(items[i][k]); //tostring() 避免 USTRING ERROR
404 | function(id){
405 | //winform.msgbox(tostring(items[i][k]))
406 | change_company_field(k,items[i][k]);
407 | }
408 | }
409 | console.log(" console.varDump(x)")
410 | console.varDump(x)
411 | table.push(data, x)
412 | }
413 |
414 | if(#data){
415 | console.log("console.varDump(data)")
416 | console.varDump(data)
417 | table.push(item, data)
418 | }else {
419 | continue;
420 | }
421 |
422 | console.log("continue;")
423 |
424 | console.varDump(item)
425 | table.push(filter_menus, item)
426 | }
427 |
428 | //console.varDump(filter_menus)
429 | if(#filter_menus){
430 | menu.addTable(
431 | //{filter_menus}
432 | filter_menus
433 | )
434 | }
435 |
436 | menu.add({});
437 |
438 | menu.add("全选",
439 | function(){
440 | for(i=1;winform.listview.count;1){
441 | winform.listview.setSelected(i)
442 | }
443 | }
444 | );
445 |
446 |
447 |
448 | menu.add("导出选中项数据",
449 | function(){
450 | var items = {}
451 | //console.log(winform.listview.columnCount)
452 | var ids = {}
453 | for(i=1;winform.listview.count;1){
454 |
455 | if(winform.listview.getSelected(i)){
456 | table.push(ids, winform.listview.getItemText(i,1)); //每一行的第1列就是id
457 | }
458 | }
459 | if(#ids){
460 | var TABLE_NAME = winform.model.tablename;
461 | var sql = "SELECT * FROM [" ++ TABLE_NAME ++ "] where id in (" + string.join(ids, ", ") + ")"
462 | items = winform.model.getTable(sql);
463 | export_model(winform.model, items);
464 | }
465 |
466 | }
467 | );
468 |
469 |
470 | menu.add({});
471 |
472 |
473 | menu.add("修改",
474 | function(){
475 | menu_edit_commpany()
476 | }
477 | );
478 | menu.add({});
479 |
480 | menu.add("删除",
481 | function(){
482 | console.log("删除")
483 | winform.delete_item()
484 | }
485 | );
486 | //menu.add("调换班级",
487 | /// function(){
488 | //
489 | // }
490 | //);
491 | menu.popup(x,y,true);
492 |
493 | }
494 | else {
495 | }
496 | }
497 | }
498 |
499 | winform.button3.oncommand = function(id,event){
500 | var mform = sqlitemodel.modelForm(winform.model, winform);
501 | mform.text = string.format("添加%s数据", winform.model.label )
502 | mform.doModal();
503 |
504 | winform.load_data(winform.model)
505 | }
506 |
507 | winform.button6.oncommand = function(id,event){
508 | winform.load_data()
509 | }
510 |
511 | //winform.init();
512 |
513 | winform.button4.oncommand = function(id,event){
514 | var filepath = fsys.dlg.open("Excel文件(*.xsl;*xlsx)|*.xsl;*xlsx","请选择Excel文件",,winform)
515 | if(filepath){
516 | import_model(winform.model, filepath);
517 | }
518 | }
519 |
520 | winform.enableDpiScaling();
521 | winform.show();
522 |
523 | win.loopMessage();
524 | return winform;
--------------------------------------------------------------------------------
/dlg/goods_select.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import math;
3 | import fsys.dlg;
4 | import config;
5 | import console;
6 | import sqlitemodel.modelForm;
7 | /*DSG{{*/
8 | var winform = win.form(text="选择商品";right=390;bottom=331)
9 | winform.add(
10 | button={cls="button";text="搜索";left=138;top=7;right=188;bottom=33;z=6};
11 | button5={cls="button";text="确定";left=275;top=292;right=374;bottom=324;z=2};
12 | button8={cls="button";text="新增商品";left=313;top=8;right=376;bottom=30;z=3};
13 | edit={cls="edit";left=52;top=8;right=117;bottom=32;edge=1;z=5};
14 | listview={cls="listview";left=12;top=42;right=379;bottom=284;edge=1;fullRow=1;gridLines=1;vscroll=1;z=4};
15 | static={cls="static";text="名称";left=13;top=10;right=65;bottom=29;transparent=1;z=1}
16 | )
17 | /*}}*/
18 |
19 | winform.button5.oncommand = function(id,event){
20 |
21 | var ids = {};
22 |
23 | for(i=1;winform.listview.count;1){
24 | if(winform.listview.getChecked(i)){
25 | table.push(ids, winform.listview.getItemText(i))
26 | }
27 |
28 | }
29 |
30 |
31 |
32 | winform.endModal(ids);
33 |
34 |
35 | }
36 |
37 | winform.onClose = function(){
38 | winform.button5.oncommand()
39 | }
40 |
41 |
42 |
43 | winform.init = function(){
44 |
45 |
46 | winform.listview.insertColumn("ID",50,1)
47 | winform.listview.insertColumn("名称",140,2)
48 | winform.listview.insertColumn("规格",100,3)
49 | winform.listview.setExtended(0x4/*_LVS_EX_CHECKBOXES*/);
50 |
51 | var goods = modGoods.search()
52 |
53 |
54 | for(i=1;#goods;1){
55 | var item = {goods[i].id; goods[i].name; goods[i].specs}
56 | winform.listview.addItem(item)
57 | }
58 |
59 | }
60 |
61 | winform.button8.oncommand = function(id,event){
62 | var goodsform = sqlitemodel.modelForm(modGoods, mainForm);
63 | goodsform.doModal(mainForm);
64 |
65 | var items = modGoods.search()
66 | if(#items>0){
67 | winform.listview.clear();
68 | for(i=1;#items;1){
69 | var item = {items[i].id; items[i].name; items[i].specs}
70 | winform.listview.addItem(item)
71 | }
72 | }
73 |
74 | }
75 |
76 | winform.listview.onnotify = function(id,code,ptr){
77 | select(code) {
78 | case 0xFFFFFFFE/*_NM_CLICK*/{
79 | var nm = winform.listview.getNotifyMessage(code,ptr)
80 | if( ! nm.iItem ) return ;
81 | winform.listview.setChecked(nm.iItem,!winform.listview.getChecked(nm.iItem) )
82 | }
83 | }
84 | }
85 |
86 | winform.button.oncommand = function(id,event){
87 | var items = modGoods.search(winform.edit.text)
88 | if(#items>0){
89 | winform.listview.clear();
90 | for(i=1;#items;1){
91 | var item = {items[i].id; items[i].name; items[i].specs}
92 | winform.listview.addItem(item)
93 | }
94 | }
95 | }
96 |
97 | winform.edit.oncommand = function(id,event){
98 | if(event== 0x300/*_EN_CHANGE*/){
99 | winform.button.oncommand();
100 | }
101 | }
102 |
103 | winform.init()
104 | winform.show();
105 | win.loopMessage();
106 | return winform;
--------------------------------------------------------------------------------
/dlg/goods_sell.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import console;
3 | import time;
4 | import config;
5 | /*DSG{{*/
6 | var winform = win.form(text="采购单(入库)";right=790;bottom=457)
7 | winform.add(
8 | button={cls="button";text="选择商品";left=507;top=5;right=685;bottom=63;dr=1;dt=1;z=8};
9 | button2={cls="button";text="全部清空";left=699;top=101;right=783;bottom=132;z=9};
10 | button3={cls="button";text="删除选中";left=699;top=152;right=783;bottom=183;z=10};
11 | button5={cls="button";text="生成采购单";left=575;top=418;right=662;bottom=448;z=14};
12 | comboOrg={cls="combobox";left=72;top=42;right=199;bottom=63;edge=1;items={};mode="dropdown";z=15};
13 | comboStore={cls="combobox";left=245;top=12;right=379;bottom=32;edge=1;items={};mode="dropdown";z=4};
14 | comboSupplier={cls="combobox";left=72;top=12;right=202;bottom=32;edge=1;items={};mode="dropdown";z=2};
15 | editApplier={cls="edit";left=269;top=40;right=399;bottom=62;edge=1;z=13};
16 | editNote={cls="edit";left=72;top=69;right=481;bottom=92;edge=1;z=6};
17 | listview={cls="listview";left=13;top=101;right=685;bottom=399;edge=1;fullRow=1;gridLines=1;vscroll=1;z=7};
18 | static={cls="static";text="供应商";left=12;top=11;right=67;bottom=31;transparent=1;z=1};
19 | static2={cls="static";text="仓库";left=208;top=11;right=237;bottom=32;transparent=1;z=3};
20 | static3={cls="static";text="备注";left=11;top=72;right=66;bottom=92;transparent=1;z=5};
21 | static4={cls="static";text="部门处室";left=11;top=43;right=66;bottom=63;transparent=1;z=11};
22 | static5={cls="static";text="申请人";left=208;top=42;right=259;bottom=62;transparent=1;z=12}
23 | )
24 | /*}}*/
25 |
26 | /*winform_reset_listview{{*/
27 | winform.reset_listview = function(model, items, fields){
28 |
29 | //如果获取了数据, 那么清空listview
30 | if(#items!=0){
31 | winform.listview.clear();
32 | }else {
33 | winform.listview.clear();
34 | return
35 | }
36 |
37 | var n = winform.listview.columnCount;
38 | for(i=1;n;1){
39 | winform.listview.delColumn(n+1-i);//从倒数开始删除, 以免删除前面的, 后面的索引都变了.
40 | }
41 |
42 | var display_fields;
43 |
44 | if(fields != null and type(fields) == "table" and #fields > 0 ){
45 | display_fields = fields;
46 | }else {
47 | display_fields = model.display_fields;
48 | }
49 |
50 | for(i=1;#display_fields;1){
51 | var k = display_fields[i]
52 | var caption = model.headers[k]
53 | winform.listview.insertColumn(caption, 140, i);
54 | }
55 |
56 | n = winform.listview.columnCount;
57 | winform.listview.insertColumn("采购数量", 140, n+1);
58 |
59 | n = winform.listview.columnCount;
60 | if(n>=3){
61 | winform.listview.setColumn({cx=30},1)
62 | winform.listview.setColumn({cx=180},2)
63 | winform.listview.setColumn({cx=80},3)
64 | }
65 |
66 | for(i=1;#items;1){
67 | var item = {}//每一行的数据
68 | for(j=1;#display_fields;1){
69 | k = display_fields[j];
70 | //if(k=="id"){
71 | // table.push(data, tostring(i))
72 | // continue
73 | //}
74 | //console.log('k', k);
75 | if(items[i][k]!=null){
76 | table.push(item, items[i][k])
77 | }else {
78 | table.push(item, "")
79 | }
80 | }
81 | table.push(item, "1");//采购数量默认为1
82 | //
83 | //console.varDump(items[i])
84 | //
85 |
86 | winform.listview.addItem({
87 | text = item
88 | });
89 | }
90 |
91 |
92 | }
93 | /*}}*/
94 |
95 | winform.button.oncommand = function(id,event){
96 | var frmChild = winform.loadForm("\dlg\goods_select.aardio");
97 | var goods_ids = frmChild.doModal();
98 |
99 | //var sql = "select from ["+winform.+"]"
100 | var model = modGoods
101 | if(#goods_ids){
102 | var sql = string.format("select * from [%s] where id in (%s)", model.tablename, string.join(goods_ids,","))
103 | var items = model.getTable(sql);
104 |
105 | /*
106 | var user_define_fields = model.display_fields
107 | table.removeByValue(user_define_fields, "created_at")
108 | table.removeByValue(user_define_fields, "updated_at")
109 | */
110 |
111 | var user_define_fields = {"id"; "name"; "specs"; "unit"}
112 | winform.reset_listview(model, items, user_define_fields)
113 | }
114 | }
115 |
116 |
117 |
118 |
119 | winform.init = function(){
120 | //调用mainForm中的全局变量
121 | var suppliers = table.map(modSupplier.search(),function(v,k,result){
122 | if(type(k)== "number"){
123 | table.push(result, string.format("%s|%s", v.id, v.name))
124 | }
125 | })
126 |
127 | var stores = table.map(modStore.search(),function(v,k,result){
128 | if(type(k)== "number"){
129 | table.push(result, string.format("%s|%s", v.id, v.name))
130 | }
131 | })
132 |
133 |
134 | for(i=1;#suppliers;1){
135 | winform.comboSupplier.add(suppliers[i])
136 | }
137 |
138 | for(i=1;#stores;1){
139 | winform.comboStore.add(stores[i])
140 | }
141 |
142 |
143 | var edit_Orgs = config.settings.edit_Orgs;
144 |
145 | if(edit_Orgs != null){
146 | var items = string.split(edit_Orgs, "<;>")
147 | for(i=1;#items;1){
148 | winform.comboOrg.add(string.trim(items[i]))
149 | }
150 |
151 | }
152 |
153 |
154 | }
155 |
156 | winform.comboSupplier.onEditChange = function(){
157 | var text = winform.comboSupplier.text;
158 | var items = table.filter( winform.comboSupplier.items, lambda(v) string.startWith(v,text) );
159 | winform.comboSupplier.autoComplete(items);
160 | }
161 |
162 | winform.comboStore.onEditChange = function(){
163 | var text = winform.comboStore.text;
164 | var items = table.filter( winform.comboStore.items, lambda(v) string.startWith(v,text) );
165 | winform.comboStore.autoComplete(items);
166 | }
167 |
168 | winform.button2.oncommand = function(id,event){
169 | winform.listview.clear();
170 | }
171 |
172 |
173 | winform.listview.onnotify = function(id,code,ptr){
174 | if(code = 0xFFFFFFFE/*_NM_CLICK*/ ){
175 |
176 | var nm = winform.listview.getNotifyMessage(code,ptr);
177 | if( ! nm.iItem && nm.iSubItem ) return true;//不允许编辑项
178 |
179 | //一点击就出现编辑框, 不用先点一下, 再点一下
180 | //winform.listview.editLabel(nm.iItem, nm.iSubItem);
181 | //上面这一行只能编辑第一列, 第2列和后面的都不能编辑, 看了源码,不行
182 | var nCols = winform.listview.columnCount;
183 | if(nm.iSubItem0){
66 | tv.clear();
67 | }
68 |
69 | var item = {text = "显示全部数据"}
70 | var hItem = tv.insertItem(item)
71 |
72 | for(i=1;#filter_fields;1){
73 | var item = {}
74 | /*{
75 | text = "上级菜单";
76 | {
77 | { text = "下级1" };
78 | { text = "下级2" };
79 | { text = "下级3" };
80 | { text = "下级4" };
81 | { text = "下级5" };
82 | { text = "其他" };
83 | }
84 | }*/
85 |
86 |
87 |
88 | var k = filter_fields[i]
89 | var caption = model.headers[k]
90 |
91 | console.varDump(model.headers)
92 | console.log("caption, k",caption, k)
93 |
94 | item["text"] = string.format("按%s过滤", caption);
95 | //query["filter_field"] = k
96 |
97 | var sql = string.format("select distinct %s from %s", k, model.tablename)
98 | var items = model.getTable(sql)
99 |
100 | var data = {}
101 | for(i=1;#items;1){
102 | table.push(data, {text = items[i][k]; filter_field = k})
103 | }
104 |
105 | table.push(item, data)
106 |
107 | var hItem = tv.insertItem(item)
108 |
109 | }
110 |
111 | tv.expandAll()
112 |
113 |
114 | }
115 |
116 | winform.button.oncommand = function(id,event){
117 |
118 | if(winform.model == null){
119 | winform.msgbox("窗口未设置model对象, 无法正确显示数据")
120 | }
121 |
122 | keyword = winform.edit.text;
123 | winform.load_data(keyword)
124 |
125 | }
126 |
127 |
128 |
129 | winform.load_data = function(keyword=""){
130 | var items={};
131 | var query = {};
132 | if(type(keyword)=="table"){
133 | query = keyword
134 | }elseif(type(keyword)=="string"){
135 | query["keyword"] = keyword;
136 | }
137 | query["QUERY_MODE"] = "SEARCH";
138 |
139 | winform.CURR_QUERY = query; //记录到全局变量CURR_QUERY中
140 | //log(table.tostring(CURR_QUERY));
141 | items = winform.model.search(query);
142 |
143 | winform.resetlistview(items)
144 |
145 |
146 | }
147 |
148 |
149 |
150 | winform.resetlistview = function(items){
151 | winform.statusbar.setText("公司总数:" + #items);
152 |
153 |
154 | if(#items){
155 | winform.listview.clear();
156 | }else {
157 | winform.listview.clear();
158 | }
159 |
160 |
161 | //for(i=1;#items;1){
162 | // console.varDump(items[i])
163 | //}
164 |
165 |
166 | //如果获取了数据, 那么清空listview
167 | var n = winform.listview.columnCount;
168 | for(i=1;winform.listview.columnCount;1){
169 | winform.listview.delColumn(n+1-i);
170 | }
171 |
172 | var display_fields = winform.model.display_fields;
173 | for(i=1;#display_fields;1){
174 | var k = display_fields[i]
175 | var caption = winform.model.headers[k]
176 | winform.listview.insertColumn(caption, 140, i);
177 | }
178 |
179 | winform.listview.setColumn({cx=40},1)
180 | winform.listview.setColumn({cx=180},2)
181 | winform.listview.setColumn({cx=80},3)
182 |
183 |
184 |
185 | for(i=1;#items;1){
186 | //winform.listview.add(items[i]['title']);
187 | //console.log("query[i]")
188 | //console.varDump(items[i])
189 |
190 | var row ={}
191 | for(j=1;#display_fields;1){
192 | k = display_fields[j];
193 | //if(k=="id"){
194 | // table.push(data, tostring(i))
195 | // continue
196 | //}
197 | //console.log('k', k);
198 | if(items[i][k]!=null){
199 | table.push(row, items[i][k])
200 | }else {
201 | table.push(row, "")
202 | }
203 |
204 |
205 | }
206 | //
207 | //console.varDump(items[i])
208 | //
209 |
210 | winform.listview.addItem({
211 | text = row
212 | });
213 | }
214 |
215 | if(items["ITEMS_PERPAGE"]){
216 | winform.comboItemsPerpage.text = tostring(items["ITEMS_PERPAGE"])
217 | }
218 | if(items["PAGES"]){
219 | winform.comboCurrPage.clear();
220 | for(i=1;items["PAGES"];1){
221 | winform.comboCurrPage.add(tostring(i))
222 | }
223 | }
224 | if(items["CURR_PAGE"]!=null){
225 | winform.comboCurrPage.text = tostring(items["CURR_PAGE"]+1)
226 | }
227 | }
228 |
229 |
230 | winform.init = function(model){
231 |
232 | //winform.center()
233 | winform.model = model;
234 |
235 | var state = config.settings.autoclose_company_form;
236 | //
237 | //console.log(" config autoclose_company_form " ++ state)
238 | //
239 |
240 | if(state == null){
241 | state = false;
242 | config.saveAll()
243 | }
244 | //
245 | //console.log(" started " ++ state)
246 | //
247 | win.ui.statusbar( winform ).addItem("公司:", 100/*宽度*/)
248 |
249 | winform.statusbar.addItem("数据库:", 500);
250 |
251 | initTreeview(winform.model, winform.treeview)
252 |
253 | winform.load_data(winform.edit.text);
254 | }
255 |
256 |
257 |
258 | winform.treeview.onnotify = function(id,code,ptr){
259 | if(code = 0xFFFFFFFE/*_NM_CLICK*/){
260 | //单击
261 | var x,y = mouse.getPos()
262 | var hItem,tvht = winform.treeview.hitTest(x,y,true);
263 |
264 | if(!hItem){
265 | return
266 | }
267 |
268 | winform.treeview.setSelected(hItem);
269 | winform.treeview.expandAll()
270 |
271 | var hitem = winform.treeview.getSelection()
272 | //winform.text = winform.treeview.getItemData(hitem);
273 | var data = winform.treeview.getItemData(hitem);
274 |
275 | var filter_field = data["filter_field"];
276 | //if(filter_field == null){
277 | // return
278 | //}
279 |
280 | var keyword = "";
281 |
282 | if(data == null or #data>0){
283 | //未选中节点, 或者选中节点有子节点(根节点)
284 | keyword = ""
285 | //return
286 | }else {
287 | //没有子节点的节点,如果是根节点, 那么也是在这里处理, 但是没有filter_field数据, 所以后面的filter
288 | // 会因为没有filter_field数据, 而返回全部数据, 忽略keyword
289 | keyword = data["text"];
290 | if(string.indexOf(keyword, "|")){
291 | keyword = string.split(keyword, "<|>")[1]
292 | }
293 | //winform.text = data["text"] ++ " 单位";
294 | }
295 |
296 | var query = {};
297 | query["filter_field"] = filter_field;
298 | query["keyword"] = keyword;
299 | var items_perpage = tonumber(winform.comboItemsPerpage.text);
300 | query["ITEMS_PERPAGE"] = items_perpage
301 | query["QUERY_MODE"] = "FILTER";
302 |
303 | CURR_QUERY = query;
304 | winform.log(table.tostring(CURR_QUERY));
305 |
306 | var items = winform.model.filter(query)
307 |
308 | winform.resetlistview(items);
309 |
310 | }
311 | }
312 |
313 |
314 | winform.item_detail = function(id){
315 |
316 | var mform = sqlitemodel.modelForm(winform.model, winform, id);
317 | mform.doModal(winform);
318 | winform.load_data(winform.edit.text);
319 | }
320 |
321 | winform.delete_items = function(ids){
322 |
323 | if(!ids){
324 | return ;
325 | }
326 |
327 | if(type(ids) != type.table){
328 | return ;
329 | }
330 |
331 | if(#ids==0){
332 | return ;
333 | }
334 |
335 | var confirmed = false; //默认不删除
336 | if(config.settings.confirm_delete){
337 | confirmed = winform.msgboxTest("确认删除吗?"); //看用户选择
338 | }else {
339 | confirmed = true; //无需确认
340 | }
341 |
342 | //console.log("confirmed",confirmed, winform.model.tablename)
343 | if(confirmed){
344 | var deletes = {}
345 | for(i=1;#ids;1){
346 | var query = {["id"]=ids[i]};
347 | //console.log(table.tostring(query))
348 | var deleted, _msg = winform.model.delete(query);
349 | table.push(deletes, {ids[i]; deleted});
350 | }
351 |
352 | var failed = false;
353 | for(i=1;#deletes;1){
354 | if(!deletes[i][2]){
355 | failed = true;
356 | winform.log(string.format("id(%s) 已经删除失败(%s)", deletes[i][1], tostring(deletes[i][2])))
357 | }else {
358 | winform.log(string.format("id(%s) 已经删除成功(%s)", deletes[i][1], tostring(deletes[i][2])))
359 | }
360 | }
361 |
362 | if(!failed){
363 | winform.load_data();
364 | winform.msgbox("删除成功!")
365 | }else {
366 | winform.msgbox("删除失败!")
367 | }
368 | }
369 | }
370 |
371 |
372 |
373 | winform.listview.onnotify = function(id,code,ptr){
374 |
375 | select(code) {
376 |
377 | case 0xFFFFFFFD/*_NM_DBLCLK*/ {
378 | //双击编辑
379 | var x,y = mouse.getPos()
380 | var iRow, iCol = winform.listview.hitTest(x,y,true);
381 | if(iRow){
382 | //console.log("选中行列", iRow, iCol)
383 | winform.listview.setSelected(iRow)
384 | winform.lastListviewSelected = iRow;
385 | var id = winform.listview.getItemText(iRow, 1);
386 | //console.log("----id", id)
387 | winform.item_detail(id);
388 | }
389 |
390 | }
391 | case 0xFFFFFFFB/*_NM_RCLICK*/ {
392 | //右键菜单
393 | var x,y = mouse.getPos()
394 | var iRow, iCol = winform.listview.hitTest(x,y,true);
395 | if(iRow){
396 | winform.listview.setSelected(iRow)
397 | winform.lastListviewSelected = iRow;
398 | }
399 |
400 | var menu = win.ui.popmenu(winform)
401 |
402 | menu.add("详细信息",
403 | function(){
404 | var iRow = winform.listview.getSelection(); //选中的行
405 | if(!iRow){
406 | winform.msgbox("请选中一项再操作");
407 | return
408 | }else {
409 | var id = winform.listview.getItemText(iRow, 1)
410 | winform.item_detail(id);
411 | }
412 | }
413 | );
414 |
415 |
416 | var filter_fields = winform.model.filter_fields
417 |
418 | var filter_menus = {}
419 |
420 |
421 |
422 | for(i=1;#filter_fields;1){
423 | var item = {}
424 |
425 | var k = filter_fields[i]
426 | var caption = headers[k]
427 | if(caption==null){
428 | continue
429 | }
430 |
431 | table.push(item, string.format("更改选中项的%s为", caption))
432 | var sql = string.format("select distinct %s from %s", k, winform.model.tablename)
433 | var items = winform.model.getTable(sql)
434 |
435 | //console.log("items")
436 | //console.varDump(items)
437 |
438 | var data = {}
439 | for(i=1;#items;1){
440 | //console.log("items[i][k]", items[i][k]);
441 | var x = {
442 | tostring(items[i][k]); //tostring() 避免 USTRING ERROR
443 | function(id){
444 | //winform.msgbox(tostring(items[i][k]))
445 | change_company_field(k,items[i][k]);
446 | }
447 | }
448 | //console.log(" console.varDump(x)")
449 | //console.varDump(x)
450 | table.push(data, x)
451 | }
452 |
453 | if(#data){
454 | //console.log("console.varDump(data)")
455 | //console.varDump(data)
456 | table.push(item, data)
457 | }else {
458 | continue;
459 | }
460 |
461 | //console.log("continue;")
462 |
463 | //console.varDump(item)
464 | table.push(filter_menus, item)
465 | }
466 |
467 | //console.varDump(filter_menus)
468 | if(#filter_menus){
469 | menu.addTable(
470 | //{filter_menus}
471 | filter_menus
472 | )
473 | }
474 |
475 | menu.add({});
476 |
477 | menu.add("全选",
478 | function(){
479 | for(i=1;winform.listview.count;1){
480 | winform.listview.setSelected(i)
481 | }
482 | }
483 | );
484 |
485 |
486 |
487 | menu.add("导出选中项数据",
488 | function(){
489 | var items = {}
490 | //console.log(winform.listview.columnCount)
491 | var ids = {}
492 | for(i=1;winform.listview.count;1){
493 | if(winform.listview.getSelected(i)){
494 | table.push(ids, winform.listview.getItemText(i,1)); //每一行的第1列就是id
495 | //var query = {}
496 | //console.log(table.tostring(winform.model.display_fields))
497 | //for(i=1;#winform.model.display_fields;1){
498 | // k = winform.model.display_fields[i]
499 | // query[k] = winform.listview.getItemText(iRow, i)
500 | //}
501 | }
502 | }
503 | if(#ids){
504 | var TABLE_NAME = winform.model.tablename;
505 | var sql = "SELECT * FROM [" ++ TABLE_NAME ++ "] where id in (" + string.join(ids, ", ") + ")"
506 | items = winform.model.getTable(sql);
507 | export_model(winform.model, items);
508 | }
509 |
510 | }
511 | );
512 |
513 |
514 | menu.add({});
515 |
516 |
517 | menu.add("修改",
518 | function(){
519 | var iRow, iCol = winform.listview.hitTest(x,y,true);
520 | if(iRow){
521 | //console.log("选中行列", iRow, iCol)
522 | winform.listview.setSelected(iRow)
523 | winform.lastListviewSelected = iRow;
524 | var id = winform.listview.getItemText(iRow, 1);
525 | winform.item_detail(id);
526 | }
527 | }
528 | );
529 | menu.add({});
530 |
531 | menu.add("删除选中项",
532 | function(){
533 | //console.log("删除选中项")
534 | var items = {}
535 | var ids = {}
536 | for(i=1;winform.listview.count;1){
537 | if(winform.listview.getSelected(i)){
538 | table.push(ids, winform.listview.getItemText(i,1)); //每一行的第1列就是id
539 | }
540 | }
541 | winform.delete_items(ids)
542 | }
543 | );
544 | //menu.add("调换班级",
545 | /// function(){
546 | //
547 | // }
548 | //);
549 | menu.popup(x,y,true);
550 |
551 | }
552 | else {
553 | }
554 | }
555 | }
556 |
557 | winform.button3.oncommand = function(id,event){
558 | var mform = sqlitemodel.modelForm(winform.model, winform);
559 | mform.text = string.format("添加%s数据", winform.model.label )
560 | mform.doModal();
561 |
562 | winform.load_data(winform.model)
563 | }
564 |
565 | winform.button6.oncommand = function(id,event){
566 | winform.load_data(winform.model)
567 | }
568 |
569 | //winform.init();
570 |
571 | winform.button4.oncommand = function(id,event){
572 | var filepath = fsys.dlg.open("Excel文件(*.xls;*xlsx)|*.xls;*xlsx","请选择Excel文件",,winform)
573 | if(filepath){
574 | import_model(winform.model, filepath);
575 | }
576 | }
577 |
578 | winform.btnPrev.oncommand = function(id,event){
579 | var curr_page = winform.comboCurrPage.text
580 | var prev_page = tonumber(curr_page) - 1;
581 | if(prev_page<0){
582 | prev_page = 0
583 | }
584 | var model = winform.model;
585 | var query = winform.CURR_QUERY;
586 | if(!query){
587 | query = {}
588 | query["keyword"] ="";
589 | }
590 | query["CURR_PAGE"] = prev_page
591 | var items = {}
592 | select(query["QUERY_MODE"]) {
593 | case "FILTER" {
594 | items = model.filter(query);
595 | }
596 | case "SEARCH" {
597 | items = model.search(query);
598 | }
599 | else {
600 |
601 | }
602 | }
603 |
604 | winform.resetlistview(items);
605 | winform.log(table.tostring(query))
606 | }
607 |
608 | winform.btnNext.oncommand = function(id,event){
609 | var model = winform.model;
610 | var query = winform.CURR_QUERY;
611 | if(!query){
612 | query={};
613 | query["keyword"] ="";
614 | }
615 |
616 | var curr_page = winform.comboCurrPage.text
617 | var pages = table.map(winform.comboCurrPage.items,function(v,k,result){
618 | return tonumber(v);
619 | })
620 | var min, max = table.range(pages)
621 | var next_page = tonumber(curr_page) + 1;
622 | if(next_page>max){
623 | next_page = max
624 | }
625 |
626 | query["CURR_PAGE"] = next_page;
627 | var items = {}
628 | select(query["QUERY_MODE"]) {
629 | case "FILTER" {
630 | items = model.filter(query);
631 | }
632 | case "SEARCH" {
633 | items = model.search(query);
634 | }
635 | else {
636 |
637 | }
638 | }
639 |
640 | winform.resetlistview(items);
641 |
642 | log(table.tostring(query))
643 | }
644 |
645 | winform.comboItemsPerpage.oncommand = function(id,event){
646 | if(event = 4/*_CBN_KILLFOCUS*/){
647 | winform.log("winform.comboItemsPerpage.oncommand _CBN_KILLFOCUS")
648 | var n = winform.LAST_ITEMS_PERPAGE;
649 |
650 | try{
651 | n = tonumber(winform.comboItemsPerpage.text)
652 | if(n != winform.LAST_ITEMS_PERPAGE){
653 | var model = winform.model;
654 | var query = winform.CURR_QUERY;
655 | if(query == null){
656 | query = {};
657 | query["keyword"] = "";
658 | query["QUERY_MODE"] = "SEARCH";
659 | }
660 |
661 | query["CURR_PAGE"] = 1;
662 | query["ITEMS_PERPAGE"] = n;
663 | winform.CURR_QUERY = query;
664 | var items = {}
665 | select(query["QUERY_MODE"]) {
666 | case "FILTER" {
667 | items = model.filter(query);
668 | }
669 | case "SEARCH" {
670 | items = model.search(query);
671 | }
672 | else {
673 |
674 | }
675 | }
676 |
677 | winform.resetlistview(items);
678 |
679 | //console.varDump(items)
680 |
681 | winform.log(table.tostring(query))
682 | winform.LAST_ITEMS_PERPAGE = n;
683 | }
684 | }
685 | catch(e){
686 | log(tostring(e))
687 | }
688 |
689 | }
690 | }
691 |
692 | winform.edit.oncommand = function(id,event){
693 | if(event=0x300/*_EN_CHANGE*/){
694 | winform.button.oncommand();
695 | }
696 | }
697 |
698 | winform.enableDpiScaling();
699 | winform.show();
700 |
701 | win.loopMessage();
702 | return winform;
--------------------------------------------------------------------------------
/dlg/select_fields.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import math;
3 | /*DSG{{*/
4 | var winform = win.form(text="选择字段";right=628;bottom=539)
5 | winform.add(
6 | button={cls="button";text=">>";left=254;top=83;right=295;bottom=119;z=3};
7 | button2={cls="button";text="<<";left=254;top=142;right=295;bottom=178;z=4};
8 | button3={cls="button";text="上移";left=565;top=83;right=606;bottom=119;z=6};
9 | button4={cls="button";text="下移";left=565;top=142;right=606;bottom=178;z=7};
10 | button5={cls="button";text="确定";left=441;top=497;right=540;bottom=529;z=8};
11 | button6={cls="button";text=">>>";left=254;top=241;right=295;bottom=277;z=9};
12 | button7={cls="button";text="<<<";left=255;top=297;right=296;bottom=333;z=10};
13 | checklist={cls="checklist";left=5;top=32;right=241;bottom=455;edge=1;items={};msel=1;vscroll=1;z=1};
14 | listbox={cls="listbox";left=314;top=32;right=550;bottom=455;edge=1;items={};msel=1;vscroll=1;z=5};
15 | static={cls="static";text="可选字段";left=19;top=10;right=168;bottom=29;transparent=1;z=2}
16 | )
17 | /*}}*/
18 |
19 | winform.button5.oncommand = function(id,event){
20 | //winform.msgbox( winform.button.text );
21 | var labels = {}
22 |
23 | for(i=1;winform.listbox.count;1){
24 | table.push(labels, winform.listbox.getItemText(i))
25 | }
26 |
27 |
28 |
29 | winform.endModal( labels )
30 |
31 | }
32 |
33 | winform.onClose = function(){
34 | winform.button5.oncommand()
35 | }
36 |
37 | winform.button.oncommand = function(id,event){
38 | var ids = {}
39 | for(i=1;winform.checklist.count;1){
40 | if(winform.checklist.getChecked(i)){
41 | table.push(ids, i)
42 | winform.listbox.add(winform.checklist.getItemText(i))
43 | }
44 | }
45 |
46 | table.reverse(ids);
47 |
48 | for(i=1;#ids;1){
49 | winform.checklist.delItem(ids[i]);
50 | }
51 |
52 | }
53 |
54 | winform.button2.oncommand = function(id,event){
55 | var ids = {}
56 | for(i=1;winform.listbox.count;1){
57 | if(i<=3){
58 | continue;
59 | }
60 | if(winform.listbox.getSelected(i)){
61 | table.push(ids, i)
62 | winform.checklist.addItem(winform.listbox.getItemText(i))
63 | }
64 | }
65 |
66 | var idx = 1;
67 |
68 |
69 | if(#ids>0){
70 | table.reverse(ids);
71 | for(i=1;#ids;1){
72 | winform.listbox.delete(ids[i]);
73 | }
74 |
75 | //console.log("ids")
76 | //console.varDump(ids)
77 |
78 | maxid = ids[1] - #ids + 1
79 |
80 | idx = math.min(winform.listbox.count, maxid)
81 |
82 | //console.log("maxid", maxid)
83 | //console.log("winform.listbox.count", winform.listbox.count)
84 | //console.log("idx", idx)
85 | }else {
86 | idx = winform.listbox.count;
87 | }
88 |
89 |
90 | if(winform.listbox.count>3){
91 | //winform.listbox.selIndex = idx;
92 | winform.listbox.setSelected(idx);
93 | }
94 | }
95 |
96 | winform.button3.oncommand = function(id,event){
97 | var idx = winform.listbox.selIndex
98 | var txt = winform.listbox.selText
99 |
100 | var upperIdx = idx - 1
101 | var upperTxt = winform.listbox.getItemText(upperIdx)
102 |
103 | var n = winform.listbox.count
104 |
105 | if(idx <=4 or txt==null){
106 | return
107 | }
108 |
109 | winform.listbox.delete(idx) //删掉当前项
110 | winform.listbox.add(upperTxt,idx) //又把当前项,加回来
111 |
112 | winform.listbox.delete(upperIdx) //删掉上一项
113 | winform.listbox.add(txt,upperIdx) //又把上一项,加回来
114 |
115 | winform.listbox.selIndex = upperIdx //一直选中, 就可以一直点 上移
116 | }
117 |
118 | winform.button4.oncommand = function(id,event){
119 | var n = winform.listbox.count
120 |
121 | var idx = winform.listbox.selIndex
122 | var txt = winform.listbox.selText
123 |
124 | if(idx == n or idx<=3 or txt==null){
125 | return
126 | }
127 |
128 | var lowerIdx = idx + 1
129 | var lowerTxt = winform.listbox.getItemText(lowerIdx)
130 |
131 | winform.listbox.delete(idx) //删掉当前项
132 | winform.listbox.add(lowerTxt,idx) //又把当前项,加回来
133 |
134 | winform.listbox.delete(lowerIdx) //删掉上一项
135 | winform.listbox.add(txt,lowerIdx) //又把上一项,加回来
136 |
137 | winform.listbox.selIndex = lowerIdx //一直选中, 就可以一直点 下移
138 | }
139 |
140 | winform.button6.oncommand = function(id,event){
141 | var ids = {}
142 | for(i=1;winform.checklist.count;1){
143 |
144 | table.push(ids, i)
145 | winform.listbox.add(winform.checklist.getItemText(i))
146 |
147 | }
148 |
149 | table.reverse(ids);
150 |
151 | for(i=1;#ids;1){
152 | winform.checklist.delItem(ids[i]);
153 | }
154 | }
155 |
156 | winform.button7.oncommand = function(id,event){
157 | var reversedTopN = 3;
158 |
159 | var ids = {}
160 | for(i=1;winform.listbox.count;1){
161 | if(i<=reversedTopN){
162 | continue;
163 | }
164 |
165 | table.push(ids, i)
166 | winform.checklist.addItem(winform.listbox.getItemText(i))
167 |
168 | }
169 |
170 | table.reverse(ids);
171 | for(i=1;#ids;1){
172 | winform.listbox.delete(ids[i]);
173 | }
174 |
175 | if(winform.listbox.count>reversedTopN){
176 | winform.listbox.selIndex = winform.listbox.count
177 | }
178 | }
179 |
180 | winform.show();
181 | win.loopMessage();
182 | return winform;
--------------------------------------------------------------------------------
/dlg/settings.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import fsys.dlg;
3 | import config;
4 | /*DSG{{*/
5 | var winform = win.form(text="设置";right=423;bottom=216;max=false;parent=...)
6 | winform.add(
7 | button={cls="button";text="选择";left=345;top=6;right=414;bottom=32;z=3};
8 | button2={cls="button";text="确定";left=346;top=183;right=415;bottom=209;z=7};
9 | button3={cls="button";text="取消";left=227;top=184;right=296;bottom=210;z=8};
10 | edit_Orgs={cls="edit";left=106;top=115;right=341;bottom=174;autohscroll=false;edge=1;multiline=1;vscroll=1;z=11};
11 | edit_companyname={cls="edit";left=105;top=84;right=340;bottom=108;edge=1;multiline=1;z=9};
12 | edit_dbpath={cls="edit";left=104;top=7;right=339;bottom=31;edge=1;multiline=1;z=1};
13 | rdConfirmDelete1={cls="radiobutton";text="是";left=106;top=50;right=175;bottom=69;z=5};
14 | rdConfirmDelete2={cls="radiobutton";text="否";left=185;top=50;right=254;bottom=69;z=6};
15 | static={cls="static";text="数据库路径";left=21;top=12;right=97;bottom=34;transparent=1;z=2};
16 | static2={cls="static";text="单位名称";left=20;top=85;right=96;bottom=107;transparent=1;z=10};
17 | static3={cls="static";text="部门处室";left=21;top=116;right=97;bottom=138;transparent=1;z=12};
18 | static5={cls="static";text="删除要求确认";left=21;top=51;right=105;bottom=73;transparent=1;z=4}
19 | )
20 | /*}}*/
21 |
22 | winform.button.oncommand = function(id,event){
23 | var lastpath = config.settings.dbpath;
24 | if(lastpath!=null and lastpath !=""){
25 | if(!io.exist(lastpath)){
26 | lastpath = "D:\"
27 | }
28 | }
29 |
30 | var path = fsys.dlg.opendir(lastpath)
31 | if(path==null){
32 | winform.msgbox("未选择数据库路径, 程序将不能正确运行")
33 | }else {
34 | winform.edit_dbpath.text=path
35 | config.settings.dbpath = path;
36 | }
37 | }
38 |
39 |
40 | winform.bindConfig( config.settings,{
41 | edit_dbpath = "text";
42 | edit_companyname = "text";
43 | edit_Orgs = "text";
44 | rdConfirmDelete1 = "checked";
45 | rdConfirmDelete2 = "checked";
46 | } );
47 |
48 |
49 |
50 | init = function(){
51 | winform.edit_dbpath.text = config.settings.dbpath;
52 | if(config.settings.confirm_delete){
53 | winform.rdConfirmDelete1.checked = true;
54 | }else {
55 | winform.rdConfirmDelete2.checked = true;
56 | }
57 |
58 | }
59 |
60 | winform.rdConfirmDelete1.oncommand = function(id,event){
61 | config.settings.confirm_delete = true;
62 | }
63 |
64 | winform.rdConfirmDelete2.oncommand = function(id,event){
65 | config.settings.confirm_delete = false;
66 | }
67 |
68 | winform.button2.oncommand = function(id,event){
69 | config.saveAll();
70 | winform.close();
71 | }
72 |
73 |
74 | winform.button3.oncommand = function(id,event){
75 | winform.close();
76 | }
77 |
78 | init()
79 |
80 | winform.enableDpiScaling();
81 | winform.show();
82 |
83 | win.loopMessage();
84 | return winform;
--------------------------------------------------------------------------------
/lib/config.aardio:
--------------------------------------------------------------------------------
1 | //config 配置文件
2 | import fsys.config;
3 | config = ..fsys.config("/config/");
4 |
5 | /**
6 | config = ..fsys.config(
7 | ..fsys.joinpath( ..fsys.getSpecial( 0x1c /*_CSIDL_LOCAL_APPDATA*/ ),"应用程序名" )
8 | );
9 | **/
10 |
11 | //不需要序列化的配置名字前请添加下划线
12 | namespace config {
13 | __appName = "应用程序名";
14 | __appVersion = "1.0.0.01";
15 | __appDescription = "这是一个测试程序";
16 | __website = "http://www.aardio.com/";
17 | }
18 |
19 | /**intellisense(config)
20 | __appName = 应用程序名
21 | __appVersion = 应用程序内部版本号
22 | __appDescription = 程序说明
23 | __website = 官方网站
24 |
25 | saveAll() = 写入所有配置到文件
26 | mainForm.load() = 从配置文件(文件名"default")载入\n加载成功返回对象,加载失败返回null空值\n!fsys_table.
27 | mainForm.save() = 存储到配置文件(文件名"default")
28 | mainForm.mixin = @.mixin(\n 键名 = 值__;\n 键名 = 值;\n);//该数会自动调用save函数保存配置到文件
29 | mainForm.控件名称 = 控件默认值\n调用save()函数同步控件当前值
30 | mainForm.属性名 = 自配置文件(文件名"default")读写属性\n属性值可以是支持序列化的普通变量,支持table对象.\n配置文件在首次使用时自动加载,退出程序时自动保存.
31 | end intellisense**/
32 |
--------------------------------------------------------------------------------
/lib/sqlitemodel/_.aardio:
--------------------------------------------------------------------------------
1 | //sqlitemodel 数据库操作
2 |
3 | import string.lcid;
4 | import sqlite;
5 | import time;
6 | import math;
7 | import console;
8 | namespace sqlitemodel;
9 |
10 | class Model {
11 |
12 | //db 数据库连接
13 | //tablename 数据表名称
14 | ctor(db, tablename, sql,
15 | filter_fields,
16 | search_fields,
17 | display_fields,
18 | field_choices,
19 | string_fields, //显示为字符串的字段
20 | DEFAULT_ITEMS_PERPAGE=100, ... ) {
21 | if(db==null){
22 | error("db is null, db connection must be initialized first",2)
23 | }
24 | this.db = db;
25 | this.tablename = tablename;
26 | this.label = tablename;
27 | this.sql = sql;
28 | if(this.sql == null){
29 | var msg = ..string.format("table(%s) sql is null, sql must be set first", tablename)
30 | error(msg, 2)
31 | }
32 | this.DEFAULT_ITEMS_PERPAGE = DEFAULT_ITEMS_PERPAGE;
33 | //filter_fields = {
34 | // "fullname";
35 | // "category";
36 | //}
37 | this.filter_fields = filter_fields;
38 | this.search_fields = search_fields;
39 | this.display_fields = display_fields;
40 | this.string_fields = string_fields;
41 | this.field_choices = field_choices;
42 | this.required_fields = {}; //导入Excel的时候必须要有的字段
43 | this.headers = {} //field_name -> 中文
44 | if(display_fields == null){
45 | this.display_fields= {}
46 | }
47 | this.fields = {}; //默认的全部fields列表, 不含数据id
48 |
49 | // this.field_names 是一个table{{};{};...{}}
50 | // 每一项是一个table = {name = xxx; label=yyy}
51 | // name是英文的字段名, label是中文的显示名称, 数据来源于 create_table_sql 建表语句
52 | // 特殊的sql语句, 里面的注释中包含中文显示名称
53 | this.field_names = {}
54 | this.item = {} //single record
55 | //init
56 | this.field_names = get_field_names(this.sql) //包含id字段
57 |
58 | var table_name= get_tablename(this.sql);
59 | if(table_name != tablename){
60 | var msg = ..string.format("tablename(%s) in function parameters, donot match the tablename(%s) in the sql", tablename, table_name )
61 | error(msg,2)
62 | }
63 |
64 | for(k,v in this.field_names){
65 | this.headers[v["name"]] = v["label"]
66 | }
67 |
68 | if(#this.display_fields <= 1){
69 | ..table.clear(this.display_fields)
70 | for(k,v in this.field_names){
71 | ..table.push(this.display_fields, v["name"])
72 | }
73 | }
74 |
75 | //..console.log(..table.tostring(this.headers))
76 | check_fields_exists(filter_fields, this, "filter_fields")
77 | check_fields_exists(search_fields, this, "search_fields")
78 | check_fields_exists(display_fields, this, "display_fields")
79 |
80 | if(#(this.required_fields)==0){
81 | this.required_fields = get_required_fields(this)
82 | }
83 |
84 | //..console.log(db, tablename, sql)
85 | if(!db.existsTable(tablename)){
86 | ..console.log(tablename,"not exists")
87 | db.exec(sql)
88 | }else {
89 | //..console.log(tablename,"ALREADY EXISTS!")
90 | }
91 |
92 | //..console.varDump(this.field_names)
93 |
94 | //..table.mixin(this,tm)
95 | };
96 |
97 |
98 | @_meta;
99 | //@_metaProperty;
100 | }
101 |
102 | namespace Model{
103 | //import util.metaProperty;
104 | //_metaProperty = util.metaProperty(
105 |
106 | _meta = {
107 | _type = "sqlite.table";
108 |
109 | _tostring = function(){
110 | return tostring( owner.string_fields );
111 | }
112 |
113 |
114 | //_serialize = function(){
115 | // return ..string.format(`..Model.ole(%s,"%s")`,tonumber(owner), owner.format);
116 | //}
117 |
118 |
119 |
120 |
121 | save = function(query){
122 |
123 | }
124 |
125 |
126 | //query is table type
127 | create = function(query){
128 | var field_names = owner.field_names; //不含id
129 |
130 | //
131 | //..console.log("field_names")
132 | //..console.varDump(field_names)
133 | //
134 |
135 | //
136 | ..console.log("insert query")
137 | ..console.varDump(query)
138 | //
139 |
140 | var field_values = {}
141 |
142 | for(i=1;#field_names;1){
143 | //create 需要屏蔽id
144 | if(field_names[i]["name"] == "id"){
145 | continue;
146 | }
147 | ..table.push(field_values, "@" ++field_names[i]["name"])
148 | }
149 | var str_field_values = ..string.join(field_values, ", ")
150 | str_field_values = " VALUES (null, " + str_field_values ++ ");"
151 |
152 | //
153 | //console.log(str_field_values)
154 | //
155 |
156 |
157 |
158 |
159 | var command = owner.db.prepare("INSERT INTO "+ owner.tablename + str_field_values ) ;
160 |
161 | //以下非空字段, 要在for循环前绑定, 绑不上去.
162 | //command.bind.parameterByName("", "@boss_name") //给@boss_name 绑定数据 ""
163 | //command.bind.parameterByName("", "@boss_cellphone") //给@boss_cellphone 绑定数据 ""
164 |
165 | //command.bind.parameterByName("", "@charger_name")
166 | //command.bind.parameterByName("", "@charger_cellphone")
167 |
168 | //command.bind.parameterByName(time.now(), "@created")
169 | //command.bind.parameterByName(time.now(), "@updated")
170 |
171 | //给 query 设置默认值
172 | query["created_at"] = default_value(query["created"], ..time.now())
173 | query["updated_at"] = default_value(query["updated"], ..time.now())
174 |
175 | //..console.varDump(query)
176 |
177 | for(i=1;#field_names;1){
178 | //args["@"++company_field_names[i]] = query[company_field_names[i]];
179 |
180 | //
181 | //console.log(company_field_names[i]["name"]," ", tostring(query[company_field_names[i]["name"]]))
182 | //
183 |
184 | var field = field_names[i]["name"]
185 | var value = query[field]
186 |
187 | //给 将数据绑定到 @field
188 | command.bind.parameterByName(value, '@' + field )
189 |
190 | }
191 |
192 | var ret = command.step();
193 |
194 | /*
195 | var sql = "select last_insert_rowid() from " + owner.tablename
196 | ..console.log(sql)
197 | var lastid = owner.db.exec(sql)
198 | ..console.log("lastid")
199 | ..console.varDump(lastid)
200 | */
201 | //上面的sql执行了没用.
202 | var lastid = owner.db.lastInsertRowid()
203 | ..console.varDump(lastid)
204 |
205 |
206 |
207 |
208 | ..console.log("sql insert result ", ret)
209 | command.finalize();
210 |
211 | //
212 | ..console.log(command.sql);
213 | //
214 |
215 | //
216 | //console.varDump(query)
217 | //
218 |
219 | if(ret<100){
220 | ..console.log(owner.db.lasterr())
221 | ..console.log("insert failed!")
222 | return false;
223 | }else {
224 | return lastid
225 | }
226 | //return true
227 | }
228 |
229 | /*update{{*/
230 | update = function(query){
231 | if(query["id"]==null or query["id"]==""){
232 | ..console.log("Failed , no query['id']")
233 | return false;
234 | }
235 |
236 | //
237 | //console.varDump(query)
238 | //
239 |
240 | old_data = owner.db.stepQuery("SELECT * FROM ["+ owner.tablename +"]", { id = query["id"]})
241 |
242 | ..console.log("get old data by id")
243 | ..console.varDump(old_data)
244 |
245 | if(old_data == null){
246 | return false;
247 | }
248 |
249 | var stmts = {}
250 |
251 | for(k,v in query){
252 | if(k=="created_at" or k=="updated_at"){
253 | continue
254 | }
255 | if(owner.headers[k]==null){
256 | ..console.log("not found:", k, ..table.tostring(owner.headers));
257 |
258 | continue
259 | }
260 | if(old_data[k] != v){
261 | ..table.push(stmts, " "+ k + " = @" ++ k)
262 | }
263 | }
264 |
265 | ..console.log("to be updated fileds:")
266 | ..console.varDump(stmts)
267 |
268 |
269 | if(#stmts<=0){
270 | //console.log("no fields to be updated")
271 | return false;
272 | }else {
273 | var k = "updated_at"
274 | ..table.push(stmts, " "+ k + " = @" ++ k)
275 | query[k] = ..time.now()
276 | }
277 |
278 |
279 | var str_set_stmts = ..string.join(stmts, ", ")
280 | str_set_stmts = " SET " + str_set_stmts ++ " WHERE id = @id;"
281 |
282 | //console.log("str_set_stmts")
283 |
284 | //console.log(str_set_stmts)
285 |
286 |
287 |
288 |
289 | var sql = "UPDATE ["+ owner.tablename + "] " + str_set_stmts;
290 | ..console.log("upadte sql:"+sql);
291 | ..console.log("user query:", ..table.tostring(query))
292 | var updated = false;
293 | try{
294 | owner.db.exec(sql, query);
295 | updated = true;
296 | //return true; //这里try语句里的 return true 并不能真的返回值, 函数最后返回的是null
297 | }
298 | catch(e){
299 | //console.varDump(e);
300 | //console.log(tostring(e))
301 | //return false;//这里try的catch语句里的 return false却可以真正使函数返回.函数最后返回的是false
302 | updated = false;
303 | }
304 |
305 | //console.log("updated!!!!")
306 |
307 | return updated
308 | };
309 | /*}}*/
310 |
311 | /*delete{{*/
312 | delete = function(query){
313 | var msg = {
314 | "Failed , query['id'] is null or empty"
315 | };
316 |
317 | if(query["id"]==null or query["id"]==""){
318 | return false, msg[1];
319 | }
320 |
321 | var sql = "DELETE FROM ["+ owner.tablename + "] WHERE id = @id;"
322 | //..console.log("sql:"+sql);
323 | var ret = owner.db.exec(sql, query);
324 | //..console.log("sql delete result ", ret)
325 | return true, "successed";
326 | };
327 | /*}}*/
328 |
329 | /*filter{{*/
330 | filter = function(query){
331 | //..console.log("filter data")
332 | //..console.varDump(query)
333 |
334 | var filter_fields = {}
335 |
336 | for(k,v in query){
337 | //..console.log(" k, v",k,v)
338 | if(..string.endWith(k, "_lt")){
339 | // <
340 | var field = ..string.left(k, -4);
341 | //..console.log(" filter field",field)
342 | if(owner.headers[field] != null){
343 | ..table.push(filter_fields, " "+ field + " < @" ++ k);
344 | }
345 |
346 | }elseif(..string.endWith(k, "_lte")){
347 | // <=
348 | var field = ..string.left(k, -5);
349 | if(owner.headers[field] != null){
350 | ..table.push(filter_fields, " "+ field + " <= @" ++ k);
351 | }
352 |
353 | }
354 | elseif(..string.endWith(k, "_gt")){
355 | // >
356 | var field = ..string.left(k, -4);
357 | if(owner.headers[field] != null){
358 | ..table.push(filter_fields, " "+ field + " > @" ++ k);
359 | }
360 |
361 | }
362 | elseif(..string.endWith(k, "_gte")){
363 | // >=
364 | var field = ..string.left(k, -5);
365 | if(owner.headers[field] != null){
366 | ..table.push(filter_fields, " "+ field + " >= @" ++ k);
367 | }
368 |
369 | }else{
370 | if(owner.headers[k] != null){
371 | // =
372 | ..table.push(filter_fields, " "+ k + " = @" ++ k);
373 | }
374 | }
375 | }
376 |
377 | //..console.log("to be filte fileds:")
378 | //..console.varDump(filter_fields)
379 |
380 |
381 | if(#filter_fields<=0){
382 | return {};
383 | }
384 |
385 | var where_stmts = ..string.join(filter_fields, " AND ")
386 | if(where_stmts!=""){
387 | where_stmts = " WHERE " + where_stmts ++ " "
388 | }
389 | //..console.log("where_stmts",where_stmts)
390 |
391 | var items = {}
392 | var filter_field = query["filter_field"]
393 | if(!query["model_name"]){
394 | query["model_name"] = owner.tablename
395 | }
396 |
397 | var keyword = query["keyword"]
398 |
399 | if(keyword == null){
400 | keyword=""
401 | }
402 | TABLE_NAME = owner.tablename
403 | DEFAULT_ITEMS_PERPAGE = owner.DEFAULT_ITEMS_PERPAGE
404 |
405 | if(query["ITEMS_PERPAGE"]){
406 | DEFAULT_ITEMS_PERPAGE = query["ITEMS_PERPAGE"]
407 | }
408 |
409 | CURR_PAGE = 0
410 | if(query["CURR_PAGE"]){
411 | CURR_PAGE = query["CURR_PAGE"] - 1;
412 | }
413 |
414 | //
415 | //console.log("keyword:"++keyword)
416 | //
417 |
418 | var sql = "Select * From ["+ TABLE_NAME + "] LIMIT " ++ DEFAULT_ITEMS_PERPAGE ++ " OFFSET " ++ DEFAULT_ITEMS_PERPAGE ++ " * " ++ CURR_PAGE ++ ";";
419 | var count_sql = "Select count(id) as total From ["+ TABLE_NAME + "]; "
420 | if(where_stmts != ""){
421 | sql = "Select * From ["+ TABLE_NAME + "] " + where_stmts +" LIMIT " ++ DEFAULT_ITEMS_PERPAGE ++ " OFFSET " ++ DEFAULT_ITEMS_PERPAGE ++ " * " ++ CURR_PAGE ++ ";";
422 | count_sql = "Select count(id) as total From ["+ TABLE_NAME + "] "+ where_stmts +";";
423 | }
424 |
425 | //..console.log("sql ", sql);
426 | //..console.log("count_sql ", count_sql);
427 |
428 | //所以最后只能使用手工sql
429 | items = owner.db.getTable(sql, query);//func(sql, paras)
430 | var total = owner.db.stepQuery(count_sql, query)["total"]
431 |
432 | var PAGES = ..math.ceil( total / DEFAULT_ITEMS_PERPAGE)
433 |
434 | items["CURR_PAGE"] = CURR_PAGE;
435 | items["ITEMS_PERPAGE"] = DEFAULT_ITEMS_PERPAGE;
436 | items["PAGES"] = PAGES;
437 | items["COUNT"] = total;
438 |
439 | if(items["CURR_PAGE"] >= items["PAGES"]){
440 | items["CURR_PAGE"] = items["PAGES"] -1
441 | }
442 |
443 | return items;
444 | };
445 | /*}}*/
446 |
447 | bulk_create = function(queryset){
448 | owner.db.beginTrans()
449 | for(i=1;#queryset;1){
450 | var query = queryset[i];
451 |
452 | var field_names = owner.field_names;
453 | var field_values = {}
454 |
455 | for(i=1;#field_names;1){
456 | //create 需要屏蔽id
457 | if(field_names[i]["name"] == "id"){
458 | continue;
459 | }
460 | ..table.push(field_values, "@" ++field_names[i]["name"])
461 | }
462 | var str_field_values = ..string.join(field_values, ", ")
463 | str_field_values = " VALUES (null, " + str_field_values ++ ");"
464 |
465 | var command = owner.db.prepare("INSERT INTO "+ owner.tablename + str_field_values ) ;
466 |
467 | //以下非空字段, 要在for循环前绑定, 绑不上去.
468 | //command.bind.parameterByName("", "@boss_name") //给@boss_name 绑定数据 ""
469 | //command.bind.parameterByName("", "@boss_cellphone") //给@boss_cellphone 绑定数据 ""
470 |
471 | //给 query 设置默认值
472 | query["created_at"] = default_value(query["created"], ..time.now())
473 | query["updated_at"] = default_value(query["updated"], ..time.now())
474 |
475 | for(i=1;#field_names;1){
476 | var field = field_names[i]["name"]
477 | var value = query[field]
478 | //给 将数据绑定到 @field
479 | command.bind.parameterByName(value, '@' + field )
480 | }
481 | var ret = command.step();
482 | }
483 | owner.db.commitTrans();
484 | }
485 |
486 | exclude = function(query){
487 |
488 | };
489 |
490 | search = function(query){
491 | if(!query){
492 | query = {}
493 | }
494 |
495 | var keyword = ""
496 | if(type(query) == "table"){
497 | keyword = query["keyword"]
498 | if(!query["model_name"]){
499 | query["model_name"] = owner.tablename
500 | }
501 |
502 | }elseif(type(query) == "string"){
503 | keyword = query
504 | query = {["keyword"]=keyword}
505 | }
506 |
507 |
508 | if(keyword==null){
509 | keyword=""
510 | }
511 | //..console.log("keyword")
512 | //..console.varDump(keyword)
513 | var items = {}
514 |
515 | TABLE_NAME = owner.tablename;
516 | DEFAULT_ITEMS_PERPAGE = owner.DEFAULT_ITEMS_PERPAGE;
517 | if(type(query) == "table" and query["ITEMS_PERPAGE"]){
518 | DEFAULT_ITEMS_PERPAGE = query["ITEMS_PERPAGE"]
519 | }
520 |
521 | if(!DEFAULT_ITEMS_PERPAGE){
522 | DEFAULT_ITEMS_PERPAGE = 100;
523 | }
524 |
525 | CURR_PAGE = 0
526 | if(query["CURR_PAGE"]){
527 | CURR_PAGE = query["CURR_PAGE"]-1;
528 | if(CURR_PAGE<0){
529 | CURR_PAGE = 0
530 | }
531 | }
532 |
533 | //..console.varDump(owner.search_fields)
534 | var sql = "Select * From ["+ TABLE_NAME + "] LIMIT " ++ DEFAULT_ITEMS_PERPAGE ++ " OFFSET " ++ DEFAULT_ITEMS_PERPAGE ++ " * " ++ CURR_PAGE ++ ";";
535 | var count_sql = "Select count(id) as total From ["+ TABLE_NAME + "];"
536 | if(keyword!=""){
537 | var where_stmts = {};
538 |
539 | for(i=1;#owner.search_fields;1){
540 | ..table.push(where_stmts, owner.search_fields[i] ++ " LIKE '%" ++ keyword ++ "%'")
541 | }
542 |
543 | if(#where_stmts){
544 | sql = "Select * From ["+ TABLE_NAME + "] WHERE " ++ ..string.join(where_stmts, " OR ") ++ " LIMIT " ++ DEFAULT_ITEMS_PERPAGE ++ " OFFSET " ++ DEFAULT_ITEMS_PERPAGE ++ " * " ++ CURR_PAGE ++ ";";
545 | count_sql = "Select count(id) as total From ["+ TABLE_NAME + "] WHERE " ++ ..string.join(where_stmts, " OR ") ++ ";"
546 | }
547 |
548 |
549 | }
550 |
551 | //..console.log("")
552 | //..console.log("sql:",sql)
553 | //..console.log("count_sql:",count_sql)
554 | //..console.log("#items",#items)
555 |
556 | //不太清楚 sql = "SELECT * FROM ["+ TABLE_NAME + "] WHERE fullname LIKE '%@keyword%' LIMIT " ++ DEFAULT_ITEMS_PERPAGE
557 | // 和
558 |
559 | //var command = db.prepare(sql) ;
560 | //console.log(command.sql);
561 | //command.bind.parameterByName(keyword, '@keyword')
562 | //var ret = command.step();
563 | //items = command.getTable(sql)
564 | //console.log("sql select result ", ret)
565 | //command.finalize();
566 | //console.log(command.sql);
567 | //if(ret<100){
568 | // console.log("insert failed!")
569 | // return false;
570 | //}
571 | //具体表现, 就是不知道这些参数是怎么最后表现的, 所以, like语句不好用parameterBy...之类的
572 | //
573 | //所以最后只能使用手工sql
574 | items = owner.db.getTable(sql);
575 |
576 | total = owner.db.stepQuery(count_sql)["total"]
577 | var PAGES = ..math.ceil( total / DEFAULT_ITEMS_PERPAGE)
578 |
579 | items["CURR_PAGE"] = CURR_PAGE;
580 | items["ITEMS_PERPAGE"] = DEFAULT_ITEMS_PERPAGE;
581 | items["PAGES"] = PAGES;
582 | if(items["CURR_PAGE"] >= items["PAGES"]){
583 | items["CURR_PAGE"] = items["PAGES"] -1
584 | }
585 | //..console.log("#items",#items)
586 | return items;
587 | }
588 |
589 |
590 | exec = function(sql, query){
591 | ..console.log("exec sql:", sql, '\r\n', "query:")
592 | ..console.varDump(query)
593 | return owner.db.exec(sql, query);
594 | }
595 |
596 | getTable = function(sql, query){
597 | //..console.log(sql)
598 | return owner.db.getTable(sql, query);
599 | }
600 |
601 | get = function(query){
602 | //var TABLE_NAME = owner.tablename;
603 | //var id = query["id"];
604 | //return owner.db.stepQuery("SELECT * FROM ["+ TABLE_NAME +"]", { id = id})
605 | //if(type(query) != type.table){
606 | // error("query must be table", 0)
607 | //}
608 | //..console.log("sqlitemodel.get query")
609 | //..console.varDump(query)
610 | var items = owner.filter(query)
611 | //..console.log("sqlitemodel.get items")
612 | //..console.varDump(items)
613 | if(#items>0){
614 | return items[1]
615 | }else {
616 | return {}
617 | }
618 | }
619 |
620 | get_or_create = function(query){
621 | return owner._fromnumber( ( tonumber(owner)*1440 + span)/1440 )
622 | }
623 |
624 | one = function(query){
625 | return owner.get(query)
626 | }
627 |
628 | all = function(query){
629 | return owner.get(query)
630 | }
631 |
632 |
633 | objects = function(query){
634 | return owner.filter(query)
635 | }
636 |
637 |
638 |
639 |
640 | } // _meta
641 | ..table.mix(_meta, { _get = _meta}, ..sqlitemodel._meta);
642 |
643 | //) //_metaProperty
644 |
645 | }
646 |
647 | namespace Model{
648 | /*get_field_names{{*/
649 | get_field_names = function(create_table_sql, include_id = true){
650 | // 返回一个table{{};{};...{}}
651 | // 每一项是一个table = {name = xxx; label=yyy}
652 | // name是英文的字段名, label是中文的显示名称, 数据来源于 create_table_sql 建表语句
653 | // 特殊的sql语句, 里面的注释中包含中文显示名称
654 | // create_table_sql 类似于
655 | // CREATE TABLE "company" (
656 | // "id" INTEGER NOT NULL PRIMARY KEY,
657 | // "fullname" VARCHAR(32) NOT NULL, /*姓名*/
658 | // "bank_opened" VARCHAR(32), /*开户行*/
659 | // "bank_name" VARCHAR(32), /*银行名称*/
660 | // "bank_account" VARCHAR(32), /*银行账号*/
661 | // "telephone" VARCHAR(32), /*电话*/
662 | // "logger_name" VARCHAR(32) NOT NULL, /*登记人*/
663 | // "logger_cellphone" VARCHAR(32) NOT NULL, /*登记人电话*/
664 | // "status" VARCHAR(16), /*公司状态*/
665 | // "created_at" DATE NOT NULL, /*创建时间*/
666 | // "updated_at" DATE NOT NULL /*更新时间*/
667 | // );
668 | //
669 | // include_id = true,则会包含ID, 默认不包含,
670 | // 因为导入的Excel中不需要,担心会覆盖已有的数据
671 | // 重置局部变量 field_names
672 | var field_names = {} //原来是全局变量, 加 var 变局部变量
673 |
674 | if(create_table_sql == null){
675 | create_table_sql = owner.sql;
676 | }
677 |
678 | var start_pos = ..string.indexOf(create_table_sql, "("); //第一个(
679 | var end_pos = ..string.lastIndexOf(create_table_sql, ")") //最后一个)
680 |
681 | //
682 | //..console.log(..string.sub(create_table_sql, start_pos+1, end_pos-1))
683 | //
684 |
685 | var str_fields = ..string.sub(create_table_sql, start_pos+1, end_pos-1)
686 | var field_lines = ..string.split(str_fields, '\r\n')
687 |
688 | for(i=1;#field_lines;1){
689 | // 每行数据格式, 显示列信息, 然后是自定义的注释/*单位名称*/作为中文名字
690 | // "fullname" VARCHAR(32) NOT NULL, /*单位名称*/
691 | //
692 | var line = "";
693 | line = ..string.trim(field_lines[i])
694 | if(line == ""){
695 | continue
696 | }
697 | var field = ..string.split(line, ' ')[1];
698 | field = ..string.trim(field, '"')
699 | if(field == "" or field == null){
700 | continue
701 | }
702 |
703 | var field_type = ..string.split(line, ' ')[2];
704 |
705 | var comment = ..string.match(line,"\/\*(.*)\*\/");//获得注释中的中文
706 | if(comment == null){
707 | comment = field;//如果没有中文注释, 使用英文字段名
708 | }
709 |
710 | //
711 | //..console.log(tostring(comment))
712 | //
713 |
714 | // 获取choices,选择数据
715 | var cs = {}
716 | var tmp = ..string.split(comment, "<:>")
717 | if(tmp[2]!=null){
718 | cs = ..string.split(tmp[2], "<,>")
719 | comment = tmp[1]
720 | }
721 | //
722 | //..console.log(..table.tostring(cs))
723 | //
724 |
725 |
726 | var notnull = ..string.match(line,"\s+(<@@NOT@>\s+<@@NULL@>)");//获得 NOT NULL
727 | if(notnull == null){
728 | required = false;//
729 | }else {
730 | required = true;
731 | }
732 |
733 | //
734 | //..console.log(field, "tostring(notnull)", tostring(notnull))
735 | //
736 |
737 |
738 | if(field == "id"){
739 | //
740 | //console.log("id is find")
741 | //
742 | if(include_id){
743 | ..table.push(field_names, {name=field;label=comment;field_type=field_type;choices=cs;required=required})
744 | }
745 | continue
746 | }else {
747 | ..table.push(field_names, {name=field;label=comment;field_type=field_type;choices=cs;required=required})
748 | }
749 |
750 |
751 | }
752 |
753 | return field_names
754 | }
755 | /*}}*/
756 |
757 |
758 | /*get_tablename{{*/
759 | get_tablename = function(create_table_sql){
760 | // create_table_sql 类似于
761 | // CREATE TABLE "company" (
762 | // ...
763 | // )
764 | var field_names = {} //原来是全局变量, 加 var 变局部变量
765 |
766 | if(create_table_sql == null){
767 | create_table_sql = owner.sql;
768 | }
769 |
770 | var start_pos = 0
771 | var end_pos = ..string.indexOf(create_table_sql, "(") //第一个(
772 |
773 | var str_maybe = ..string.sub(create_table_sql, start_pos, end_pos-1);
774 | //..console.log(str_maybe)
775 |
776 | var table_name = ..string.match(str_maybe, '\"(.*)\"');//获得""的tablename
777 | if(table_name == null){
778 | table_name = "notfound";
779 | }
780 |
781 | return table_name
782 | }
783 | /*}}*/
784 |
785 | /*default_value{{*/
786 | default_value = function(value, default){
787 | if(value == null){
788 | return default
789 | }
790 | return value
791 | }
792 | /*}}*/
793 |
794 | check_fields_exists = function(fields, model, label=""){
795 | for(i=1;#fields;1){
796 | var find = false
797 | var field_name = fields[i]
798 | for(j=1;#model.field_names;1){
799 | //..console.log("choices:",..table.tostring(model.field_names[j]["choices"]))
800 | if(field_name == model.field_names[j]["name"]){
801 | find=true;
802 | break
803 | }
804 | }
805 | if(find == false){
806 | var msg = ..string.format("%s('%s') not in table('%s') "++'\r\n'+"sql: %s", label, field_name, model.tablename, model.sql);
807 | error(msg, 2);
808 | }
809 | }
810 | }
811 |
812 | get_required_fields = function(model){
813 | var find = false
814 | var fields = {}
815 | for(j=1;#model.field_names;1){
816 | //..console.log(model.field_names[j]["name"], "required:", model.field_names[j]["required"])
817 | if(model.field_names[j]["required"]){
818 | ..table.push(fields, model.field_names[j]["name"])
819 | }
820 | }
821 | return fields;
822 | }
823 |
824 | }
825 |
826 |
827 |
828 |
829 | /*intellisense()
830 | sqlitemodel.Model(.(db, __, sql, filter_fields, search_fields) = !sqlitemodel_model.
831 | sqlitemodel.Model( = !sqlitemodel_model.
832 | sqlitemodel.Model() = !sqlitemodel_model.
833 | sqlitemodel.Model.now() = !sqlitemodel_model.
834 | sqlitemodel.Model.default_value(value, default) = 计算默认值
835 | sqlitemodel.Model.get_field_names(sql, true) = 计算fields_names
836 | end intellisense*/
837 |
838 | /**intellisense(!sqlitemodel_model)
839 | get(query)= 获取某个id的数据
840 | create(query/*指定table数据对象*/) = 根据item(query)中的数据,创建一条数据
841 | update(query/*指定table数据对象*/) = 根据item(query)中的数据,更新一条数据
842 | delete(query/*指定table数据对象*/) = 根据item(query)中的数据,删除一条数据
843 | search(query/*指定table数据对象*/) = 根据item(query)中的数据,查找数据
844 | save(query/*指定table数据对象*/) = 根据item(query)中的数据,保存数据
845 | field_names = model的field_names
846 | default_value(value, default) = 计算默认值
847 | end intellisense**/
848 |
849 |
850 |
--------------------------------------------------------------------------------
/lib/sqlitemodel/modelForm.aardio:
--------------------------------------------------------------------------------
1 | //modelForm model表单窗口库
2 |
3 | import string.lcid;
4 | import sqlite;
5 | import time;
6 | import math;
7 | import console;
8 |
9 | import win.ui;
10 | import math;
11 | import config;
12 | import win.ui.accelerator;
13 | namespace sqlitemodel;
14 |
15 | import util.metaProperty;
16 | class modelForm{
17 | ctor(model, parent, id){
18 |
19 |
20 | //..console.log( "modelForm id",id)
21 |
22 | var data = {};
23 | var field_names = model.field_names
24 | //
25 | //..console.varDump(field_names)
26 | //
27 |
28 | //for(i=1;#field_names;1){
29 | // ..console.varDump(field_names[i])
30 | //}
31 |
32 |
33 |
34 | var form_caption = ..string.format("添加%s数据", model.label);
35 | var btn_text="添加"
36 |
37 | if(id){
38 | var query = {}
39 | query["id"] = id
40 | data = model.get(query) //如果不存在, 就会突然赋值为null了
41 |
42 | form_caption = "修改数据"
43 | btn_text = "保存"
44 |
45 | if(data == null){
46 | data = {}
47 | }
48 | //..console.log( "modelForm data")
49 | //..console.varDump(data)
50 | }
51 |
52 | this = ..win._form(cls="";text="aardio form";border="resizable";max=false;
53 | right=642;bottom=437;parent=parent)
54 | //this = ..win.loadForm("\dlg\model_form.aardio",,parent);
55 |
56 | this.model = model;
57 |
58 | //..console.log(model.tablename)
59 | //..console.log(..table.tostring(model))
60 |
61 | this.add(
62 | button={cls="button";text="添加公司";left=95;top=379;right=199;bottom=407;dl=1;dt=1;z=1};
63 | checkbox={cls="checkbox";text="自动关闭本窗口";left=350;top=386;right=460;bottom=402;dl=1;dt=1;z=2}
64 | )
65 |
66 |
67 |
68 | var frmChild_width = 0
69 | var COLS_PADDING = 5 //列与列之间的间隔, 每列由一个标签和一个文本框组成
70 | var ROWS_PER_COL = 15;
71 | var LABEL_WIDTH = 84;
72 | var EDIT_WIDTH = 320; // 420;
73 |
74 | var ROW_WIDTH = EDIT_WIDTH + COLS_PADDING*2;
75 |
76 | var LABEL_HEIGHT = 20;
77 | var EDIT_HEIGHT = 20;
78 |
79 | var ROW_HEIGHT = LABEL_HEIGHT + EDIT_HEIGHT + 5;
80 |
81 | this.width = COLS_PADDING*2 + (..math.floor((#field_names-1) / ROWS_PER_COL)+1) * ROW_WIDTH + 200;
82 |
83 | for(i=1;#field_names;1){
84 |
85 | var k = field_names[i]["name"]
86 | var label = field_names[i]["label"]
87 | var field_type = field_names[i]["field_type"]
88 | //..console.log("modelForm ctor for loop")
89 | //var aaa = model.filter_fields;
90 | var field_choices = model.field_choices; //当sqlitemodel用_metaProperty的时候, 这一句会调用model.get("field_choices")
91 | //但是 model.filter_fields; 不会调用model.get("filter_fields");很奇怪
92 | //当sqlitemodel用_meta的时候, 并使用..table.mix(_meta, { _get = _meta},
93 | // ..sqlitemodel._meta);就不会有这种现象
94 | //最后使用了 _meta
95 | //..console.log("modelForm ctor field_choices")
96 | //..console.varDump(field_choices)
97 | //var choices = field_names[i]["choices"] //这里会导致修改了分类后, 新建窗口不更新
98 | var field_required = field_names[i]["required"]
99 | var value = ""
100 | //..console.log("modelForm ctor init field")
101 | //..console.log(k,label)
102 | //..console.log("data:")
103 | //..console.varDump(data)
104 | //..console.log(k,"type(choices)",type(choices))
105 | //if(#choices>0){
106 | // ..console.varDump(choices)
107 | //}
108 |
109 | //if(type(choices) == "table"){
110 | //这里会导致修改了分类后, 新建窗口不更新
111 | //if(#choices == 0){
112 | var choices = {}
113 | if(field_choices){
114 | var bind_model = field_choices[k];
115 | if(bind_model != null){
116 | var items = bind_model.search(); //这里会导致修改了分类后, 新建窗口不更新
117 | for(i=1;#items;1){
118 | var s = ""
119 | //..console.log("tostring", tostring())
120 | for(j=1; #bind_model.string_fields;1){
121 | var sfield = bind_model.string_fields[j]
122 | s = s ++ ..string.format("%s|%s", items[i]["id"], items[i][sfield])
123 | }
124 | ..table.push(choices, s)
125 | }
126 | }
127 | }
128 | //}
129 | //}
130 | //..console.log("..table.tostring(choices)")
131 | //..console.varDump(choices)
132 | if(#choices==0){
133 | //如果数据库中没有数据, 用sql定义中设置的初始数据
134 | choices = field_names[i]["choices"]
135 | }
136 |
137 |
138 | if(data[k] != null){
139 | value = tostring(data[k])
140 | }
141 |
142 | //
143 | //log(k++":"++label)
144 | //
145 |
146 | var ctrl = this["edit_"+k]
147 | if(ctrl!=null){
148 | ctrl.text = value
149 | }else {
150 |
151 | var staticLeft = COLS_PADDING + ..math.floor((i - 1) / ROWS_PER_COL) * ROW_WIDTH; //每一列的left是相同的。
152 | var staticTop = 13 + 22 * (i - (..math.floor((i - 1) / ROWS_PER_COL) * ROWS_PER_COL + 1));
153 | //console.log(staticLeft,", ", staticTop)
154 |
155 | if(field_required){
156 | this.add(
157 | ["static_" + k ] = {
158 | //border=1;
159 | cls="static"; text=label; notify=1; dl=1;dt=1;
160 | color=255;font=LOGFONT( name='宋体'; h=-13;weight=700 );
161 | transparent=1;
162 | bottom=staticTop + LABEL_HEIGHT;right=staticLeft+LABEL_WIDTH;
163 | left=staticLeft;top=staticTop;z=1;
164 | };
165 | )
166 | }else {
167 | this.add(
168 | ["static_" + k ] = {
169 | //border=1;
170 | cls="static"; text=label; notify=1; dl=1;dt=1;font=LOGFONT( name='宋体' );
171 | bottom=staticTop + LABEL_HEIGHT;right=staticLeft+LABEL_WIDTH;
172 | left=staticLeft;top=staticTop;z=1;
173 | };
174 | )
175 | }
176 |
177 |
178 |
179 | if(k=="id" or k=="taxno" or k=="created_at" or k=="updated_at" or k=="created" or k=="updated"){
180 | this.add(
181 | ["edit_" + k ] = {
182 | cls="edit"; text=value; disabled=1;notify=1; dl=1;dt=1;
183 | font=LOGFONT(name='Consolas');
184 | bottom=staticTop+EDIT_HEIGHT;right=staticLeft + EDIT_WIDTH;
185 | left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
186 | };
187 | )
188 | }else {
189 |
190 | if(field_required){
191 | if(#choices >= 1){
192 | this.add(
193 | ["edit_" + k ] = {
194 | cls="combobox";
195 | items = choices;
196 | mode="dropdown";
197 | tabstop=i; notify=1; db=1;dl=1;edge=1;
198 | font=LOGFONT(name='Consolas');bottom=staticTop+EDIT_HEIGHT;
199 | right=staticLeft + EDIT_WIDTH;left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
200 | required=1;name=label;
201 | };
202 | )
203 | }else {
204 | this.add(
205 | ["edit_" + k ] = {
206 | cls="edit"; text=value; tabstop=i; notify=1; dl=1;dt=1;
207 | font=LOGFONT(name='Consolas');bottom=staticTop+EDIT_HEIGHT;
208 | right=staticLeft + EDIT_WIDTH;left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
209 | required=1;name=label;
210 | };
211 | )
212 | }
213 | }else {
214 |
215 | if(#choices >= 1){
216 | this.add(
217 | ["edit_" + k ] = {
218 | cls="combobox";
219 | items = choices;
220 | mode="dropdown";
221 | tabstop=i; notify=1; db=1;dl=1;edge=1;
222 | font=LOGFONT(name='Consolas');bottom=staticTop+EDIT_HEIGHT;
223 | right=staticLeft + EDIT_WIDTH;left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
224 |
225 | };
226 | )
227 | }else {
228 | this.add(
229 | ["edit_" + k ] = {
230 | cls="edit"; text=value; tabstop=i; notify=1; dl=1;dt=1;
231 | font=LOGFONT(name='Consolas');bottom=staticTop+EDIT_HEIGHT;
232 | right=staticLeft + EDIT_WIDTH;left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
233 | };
234 | )
235 | }
236 |
237 | }
238 |
239 |
240 |
241 | }
242 |
243 |
244 |
245 |
246 | //
247 | //log("ctrl edit_" + k + " 不存在!创建一个")
248 | //
249 | }
250 | }
251 |
252 |
253 |
254 |
255 | this.text = form_caption
256 | this.button.text = btn_text
257 |
258 | this.onInitDialog = function(hwnd,message,wParam,lParam){
259 | //this.input.setFocus();
260 | var state = ..config.settings.autoclose_model_form;
261 | //
262 | //..console.log("..config.autoclose_model_form " ++ state);
263 | //
264 |
265 | if(state == null){
266 | state = false;
267 | }
268 | this.checkbox.checked = state;
269 |
270 | };
271 |
272 | this.button.oncommand = function(id,event){
273 |
274 | var field_names = this.model.field_names;
275 | var is_valid = true;
276 | for(i=1;#field_names;1){
277 | k = field_names[i]["name"]
278 | var ctrl = this["edit_"+k];
279 | if(ctrl==null){
280 | continue
281 | }
282 | if(ctrl.required){
283 | if(..string.trim(ctrl.text) == ""){
284 | is_valid = false; //校验表单失败
285 |
286 | this.msgbox(..string.format("【%s】数据不能为空!", ctrl.name))
287 | ctrl.setFocus();
288 | break;
289 | }
290 | }
291 |
292 | }
293 |
294 | if(!is_valid){
295 | return
296 | }
297 |
298 |
299 | if(this.button.text = "添加")
300 | {
301 | item = {}
302 |
303 | //..console.varDump(this["model"])
304 |
305 | var field_names = this["model"].field_names;
306 | for(i=1;#field_names;1){
307 | k = field_names[i]["name"]
308 | if(k=="id"){
309 | //添加数据不需要id
310 | continue;
311 | }
312 | var ctrl = this["edit_"+k];
313 | if(ctrl==null){
314 | //
315 | //console.log("ctrl edit_"+k +" does not exist")
316 | //
317 | item[k] = null;
318 | continue
319 | }
320 | //..console.log("console.varDump(ctrl);")
321 | //..console.varDump(ctrl);
322 | item[k] = ctrl.text;
323 | }
324 | //
325 | //..console.varDump(item);
326 | //
327 |
328 |
329 | for(k,v in model.field_choices){
330 | item[k] = ..string.split(item[k],"<|>")[1]
331 | }
332 |
333 | model.create(item);
334 |
335 | //this.msgbox("添加公司成功!");
336 | //抖动文件夹
337 | hwnd = this.hwnd;
338 | if(hwnd){
339 | ..shakewindow(hwnd,5,30)
340 | }
341 |
342 | if(this.checkbox.checked){
343 | ..win.delay(300);
344 | this.close();
345 | this.endModal();
346 | }else {
347 | for(i=1;#field_names;1){
348 | k = field_names[i]["name"]
349 | var ctrl = this["edit_"+k];
350 | if(ctrl==null){
351 | continue
352 | }
353 | ctrl.text="";
354 | }
355 | }
356 |
357 |
358 | }else {
359 | if(this["edit_id"].text==""){
360 | this.msgbox("不能保存, 不是正确的数据库id")
361 | return ;
362 | }
363 |
364 | //console.log(modelCompany.field_names)
365 |
366 | item = {}
367 | var field_names = this.model.field_names;
368 | for(i=1;#field_names;1){
369 | k = field_names[i]["name"]
370 | var ctrl = this["edit_"+k];
371 | if(ctrl==null){
372 | //
373 | //console.log("ctrl edit_"+k +" does not exist")
374 | //
375 | item[k] = null;
376 | continue
377 | }
378 | //..console.log("update: console.varDump(ctrl);")
379 | //..console.varDump(ctrl);
380 | item[k] = ctrl.text;
381 | }
382 |
383 | for(k,v in model.field_choices){
384 | item[k] = ..string.split(item[k],"<|>")[1]
385 | }
386 |
387 | //console.log("update database use new item data:---------------------")
388 | model.update(item);
389 |
390 | //console.log("reload data:---------------------")
391 | //load_company()
392 | //this.msgbox("添加公司成功!");
393 | //抖动文件夹
394 | hwnd = this.hwnd;
395 | if(hwnd){
396 | ..shakewindow(hwnd,5,30)
397 | }
398 |
399 | //oldRow = tonumber(this["edit_id"].text);
400 | if(this.checkbox.checked){
401 | ..win.delay(300);
402 | this.close();
403 | }
404 |
405 | //this.endModal( tonumber(this["edit_id"].text));
406 | this.endModal();
407 |
408 |
409 | }
410 |
411 | ..config.settings.autoclose_model_form = this.checkbox.checked
412 | ..config.saveAll();
413 |
414 | //..console.log("..config.settings.autoclose_model_form", ..config.settings.autoclose_model_form, this.checkbox.checked)
415 |
416 | //restoreListviewPos();
417 | };
418 |
419 |
420 | /*快捷键{{*/
421 | var accelerator = ..win.ui.accelerator({
422 |
423 | {
424 | ctrl = true; vkey = 'S'#; //保存
425 | oncommand = function(){
426 | this.button.oncommand()
427 | };
428 | };
429 | }, this);
430 | /*}}*/
431 |
432 |
433 |
434 | this.onClose = function(){
435 | this.endModal();
436 | };
437 |
438 | }
439 |
440 | }
441 |
442 |
443 | namespace modelForm{
444 |
445 | _metaProperty = ..util.metaProperty(
446 | _type = "sqlite.modelform";
447 |
448 |
449 | _tostring = function(format, locale){
450 | return owner.systemFormat(format,locale);
451 | };
452 |
453 | _serialize = function(){
454 | return ..string.format(`..Model.ole(%s,"%s")`,tonumber(owner), owner.format);
455 | }
456 |
457 | save = function(){
458 |
459 | }
460 |
461 |
462 | //query is table type
463 | render = function(query){
464 | var field_names = get_field_names(owner.sql)
465 |
466 | //
467 | //..console.log("field_names")
468 | //..console.varDump(field_names)
469 | //
470 |
471 | //
472 | //..console.log("query")
473 | //..console.varDump(query)
474 | //
475 |
476 | var field_values = {}
477 |
478 | for(i=1;#field_names;1){
479 | ..table.push(field_values, "@" ++field_names[i]["name"])
480 | }
481 | var str_field_values = ..string.join(field_values, ", ")
482 | str_field_values = " VALUES (null, " + str_field_values ++ ");"
483 |
484 | //
485 | //console.log(str_field_values)
486 | //
487 |
488 |
489 |
490 |
491 | var command = owner.db.prepare("INSERT INTO "+ owner.tablename + str_field_values ) ;
492 |
493 | //以下非空字段, 要在for循环前绑定, 绑不上去.
494 | //command.bind.parameterByName("", "@boss_name") //给@boss_name 绑定数据 ""
495 | //command.bind.parameterByName("", "@boss_cellphone") //给@boss_cellphone 绑定数据 ""
496 |
497 | //command.bind.parameterByName("", "@charger_name")
498 | //command.bind.parameterByName("", "@charger_cellphone")
499 |
500 | //command.bind.parameterByName(time.now(), "@created")
501 | //command.bind.parameterByName(time.now(), "@updated")
502 |
503 | //给 query 设置默认值
504 | query["created_at"] = default_value(query["created_at"], ..time.now())
505 | query["updated_at"] = default_value(query["updated_at"], ..time.now())
506 |
507 | for(i=1;#field_names;1){
508 | //args["@"++company_field_names[i]] = query[company_field_names[i]];
509 |
510 | //
511 | //console.log(company_field_names[i]["name"]," ", tostring(query[company_field_names[i]["name"]]))
512 | //
513 |
514 | var field = field_names[i]["name"]
515 | var value = query[field]
516 |
517 | //给 将数据绑定到 @field
518 | command.bind.parameterByName(value, '@' + field )
519 |
520 | }
521 |
522 | var ret = command.step();
523 |
524 | ..console.log("sql insert result ", ret)
525 | command.finalize();
526 |
527 | //
528 | ..console.log(command.sql);
529 | //
530 |
531 | //
532 | //console.varDump(query)
533 | //
534 |
535 | if(ret<100){
536 | ..console.log(owner.db.lasterr())
537 | ..console.log("insert failed!")
538 | return false;
539 | }
540 | return true
541 | }
542 |
543 | validate = function(query){
544 | if(query["id"]==null or query["id"]==""){
545 | //..console.log("Failed , no query['id']")
546 | return false;
547 | }
548 |
549 | //
550 | //console.varDump(query)
551 | //
552 |
553 | old_data = owner.db.stepQuery("SELECT * FROM ["+ owner.tablename +"]", { id = query["id"]})
554 |
555 | //..console.log("get old data by id")
556 | //..console.varDump(old_data)
557 |
558 | if(old_data == null){
559 | return false;
560 | }
561 |
562 | var stmts = {}
563 |
564 | for(k,v in query){
565 | if(k=="created_at" or k=="updated_at"){
566 | continue
567 | }
568 | if(old_data[k] != v){
569 | ..table.push(stmts, " "+ k + " = @" ++ k)
570 | }
571 | }
572 |
573 | ..console.log("to be updated fileds:")
574 | ..console.varDump(stmts)
575 |
576 |
577 | if(#stmts<=0){
578 | //console.log("no fields to be updated")
579 | return false;
580 | }else {
581 | var k = "updated_at"
582 | ..table.push(stmts, " "+ k + " = @" ++ k)
583 | query[k] = ..time.now()
584 | }
585 |
586 |
587 | var str_set_stmts = ..string.join(stmts, ", ")
588 | str_set_stmts = " SET " + str_set_stmts ++ " WHERE id = @id;"
589 |
590 | var sql = "UPDATE ["+ owner.tablename + "] " + str_set_stmts;
591 | //console.log("sql:"+sql);
592 | var updated = false;
593 | try{
594 | owner.db.exec(sql, query);
595 | updated = true;
596 | //return true; //这里try语句里的 return true 并不能真的返回值, 函数最后返回的是null
597 | }
598 | catch(e){
599 | //console.varDump(e);
600 | //console.log(tostring(e))
601 | //return false;//这里try的catch语句里的 return false却可以真正使函数返回.函数最后返回的是false
602 | updated = false;
603 | }
604 |
605 | //console.log("updated!!!!")
606 |
607 | return updated
608 | };
609 |
610 | show = function(){
611 |
612 | };
613 |
614 | )
615 | }
616 |
617 |
618 | /***intellisense()
619 | sqlitemodel.modelForm = 输入对话框
620 | sqlitemodel.modelForm( = 创建一个model编辑(添加,修改)窗口
621 | sqlitemodel.modelForm(.(model, 父窗口, id) = 创建一个model编辑(添加,修改)窗口,所有参数可选\nmodel为sqlitemodel.Model
622 | sqlitemodel.modelForm() = !modelform.
623 | end intellisense***/
624 |
625 | /***intellisense(!modelform)
626 | doModal() = 弹出输入对话框\n该函数返回用户输入的值\n取消则返回null空值
627 | onInitDialog = @.onInitDialog = function(hwnd,message,wParam,lParam){\n ??.center()__/*输入框初始化完成触发该函数*/\n}
628 | center() = 居中显示
629 | info = !edit.
630 | input = !edit.
631 | text = 输入框标题
632 | setPos(.(x,y,宽,高,插入位置,参数) = 调整窗口位置或排序\n所有参数可选
633 | getPos() = 返回相对坐标,宽,高
634 | topmost()=窗体始终最前
635 | topmost(false)=取消窗体始终最前
636 | modifyStyle(.(remove,add) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
637 | modifyStyleEx(.(remove,add) = 如果指定第三个参数,则使用此参数调用::SetWidnowPos
638 | setInterval = @var tmId = ??.setInterval( \n 1000,\n function(id){\n /*定时回调函数*/\n } \n)
639 | clearInterval(__/*请输入ID*/) = 删除定时器
640 | changeInterval(__/*请输入ID*/,1000) = 重新设定定时器的延时时间
641 | setTimeout(.(函数名,延时,其他参数) = 延时执行函数
642 | end intellisense***/
643 |
644 |
--------------------------------------------------------------------------------
/main.aardio:
--------------------------------------------------------------------------------
1 | import win.ui;
2 | import win.inputBox;
3 | import win.ui.menu;
4 | import win.ui.statusbar;
5 | import win.ui.accelerator;
6 | import win.cur;
7 | import win.ui.toolbar;
8 |
9 | import fsys;
10 | import fsys.dlg;
11 | import sqlite;
12 | import time;
13 | import config;
14 | import com.excel;
15 | import mouse;
16 | import process;
17 |
18 | import console
19 | //console.open()
20 |
21 | import sqlitemodel;
22 | import sqlitemodel.modelForm; //如果不导入, 后面调用就会报错 modelForm是null
23 | //===//
24 | /*DSG{{*/
25 | mainForm = win.form(text="简易进销存";right=945;bottom=617)
26 | mainForm.add(
27 | btnGotoNPage={cls="button";text="转到第N页";left=650;top=353;right=724;bottom=374;db=1;dl=1;z=10};
28 | btnNext={cls="button";text="下一页";left=385;top=353;right=450;bottom=374;db=1;dl=1;z=8};
29 | btnPrev={cls="button";text="上一页";left=305;top=353;right=370;bottom=374;db=1;dl=1;z=7};
30 | btnRefresh={cls="button";text="刷新";left=490;top=28;right=554;bottom=51;dl=1;dt=1;z=11};
31 | button={cls="button";text="搜索";left=417;top=28;right=481;bottom=51;dl=1;dt=1;z=4};
32 | button7={cls="button";text="选择显示字段";left=563;top=28;right=660;bottom=51;dl=1;dt=1;z=12};
33 | comboCurrPage={cls="combobox";left=562;top=353;right=643;bottom=374;db=1;dl=1;edge=1;items={};mode="dropdown";z=9};
34 | comboItemsPerpage={cls="combobox";left=215;top=354;right=293;bottom=374;db=1;dl=1;edge=1;items={"10";"20";"30";"50";"100"};mode="dropdown";z=5};
35 | edit={cls="edit";left=163;top=28;right=408;bottom=51;dl=1;dt=1;edge=1;z=13};
36 | listbox={cls="listbox";left=161;top=377;right=941;bottom=592;db=1;dl=1;dr=1;edge=1;hscroll=1;items={};vscroll=1;z=2};
37 | listview={cls="listview";left=162;top=56;right=934;bottom=346;db=1;dl=1;dr=1;dt=1;edge=1;font=LOGFONT(name='Consolas');fullRow=1;gridLines=1;hscroll=1;vscroll=1;z=3};
38 | static={cls="static";text="每页条数";left=160;top=354;right=211;bottom=369;db=1;dl=1;transparent=1;z=6};
39 | treeview={cls="treeview";left=5;top=56;right=156;bottom=592;asel=false;bgcolor=16777215;db=1;dl=1;dt=1;edge=1;vscroll=1;z=1}
40 | )
41 | /*}}*/
42 |
43 | //=============
44 | newLine = '\r\n'
45 | //====
46 | driver = null;
47 | browser = null;
48 |
49 | var mcur0 = win.cur.load(0x7F00/*_IDC_ARROW*/)
50 | var mcur1 = win.cur.load(32649/*_IDC_HAND*/)
51 | var mcur2 = win.cur.load(0x7F02/*_IDC_WAIT*/)
52 | var mcur3 = win.cur.load(0x7F88/*_IDC_NO*/)
53 |
54 | //var ss = win.cur.loadfile("e:\up_rm.cur");//这里可以是你自己制作的鼠标文件
55 |
56 |
57 | default_value = function(value, default){
58 | if(value == null){
59 | return default
60 | }
61 | return value
62 | }
63 |
64 |
65 | log=function(text){
66 | mainForm.listbox.add(tostring(text))
67 | mainForm.listbox.selIndex=mainForm.listbox.count
68 | }
69 |
70 | help = function(text){
71 | if(text != null and text != ""){
72 | mainForm.msgbox(tostring(text))
73 | }else {
74 | mainForm.msgbox("如需帮助 "++newLine++newLine++"请发邮件至330906552@QQ.com")
75 | }
76 | }
77 |
78 |
79 | // 全局变量
80 |
81 |
82 | // 全局变量, 数据库路径
83 | DEFAULT_DB_PATH = "/data/biz.db"
84 | dbpath = config.settings.dbpath;
85 |
86 |
87 | var exists = io.exist(io.fullpath(dbpath))
88 | if(exists){
89 | log(" 数据库文件是否存在: 是", dbpath);
90 | }else {
91 | log(" 数据库文件是否存在: 否", dbpath);
92 | }
93 |
94 | DEFAULT_ITEMS_PERPAGE = 200 //默认每页显示100条
95 | LAST_ITEMS_PERPAGE = DEFAULT_ITEMS_PERPAGE;
96 |
97 |
98 |
99 |
100 | if( dbpath==null or dbpath=="" or (io.exist(io.fullpath(dbpath))==null) ){
101 |
102 | log("数据库文件路径未设置, 请到config目录设置正确的 dbpath 参数!!!")
103 | mainForm.msgbox("数据库文件路径的文件不存在, 程序将创建和使用默认数据库!"++newLine++DEFAULT_DB_PATH)
104 |
105 | dbpath = DEFAULT_DB_PATH
106 | parentDir = fsys.getParentDir(dbpath)
107 |
108 | if(!fsys.isDir(parentDir)){
109 | fsys.createDir(parentDir)
110 | }
111 |
112 | config.settings.dbpath=dbpath;
113 | config.saveAll()
114 |
115 | }
116 |
117 | // 全局变量, 数据库连接
118 | db = sqlite(dbpath);
119 |
120 | // 全局变量,数据库表模型定义
121 | /*company和model表定义{{*/
122 | default_company_sql = string.load("/res/models/company.sql.aardio");
123 |
124 | //必须的字段,改进中,按照顺序显示
125 | //这些字段,必须在导入和导出Excel中用到,还要在listview中显示
126 | //有些字段,虽然不可少, 但是可以用默认值来填充,比如时间
127 | display_headers = {
128 | "id";
129 | "name";
130 | "created_at";
131 | }
132 |
133 |
134 | company_required_fields = {
135 | //类似于headers, 格式如下
136 | name="姓名";
137 | }
138 |
139 | company_filter_fields = {
140 | "name";
141 | }
142 |
143 |
144 |
145 |
146 |
147 | //全局变量headers, 主要是保存中文标题(含英文的字段)
148 | //用途:
149 | // listview的显示标题(中文)
150 | // 数据导出到Excel的第一行的标题(中文)
151 | headers = {
152 | //类似于 required_headers, 格式如下
153 | //zhangtaohao = "账套号";
154 | //shebao = "社保"
155 | }
156 |
157 |
158 |
159 |
160 | company_search_fields = {
161 | "name";
162 | };
163 |
164 | modCompany = sqlitemodel.Model(db, 'company',
165 | default_company_sql, company_filter_fields, company_search_fields)
166 | modCompany.label = "企业";
167 | /*}}*/
168 |
169 | /*goods_category和model表定义{{*/
170 | default_goods_category_sql = string.load("/res/models/goods_category.sql.aardio");
171 |
172 | goods_category_filter_fields = {
173 | "parent";
174 | }
175 |
176 | goods_category_search_fields = {
177 | "name";
178 | };
179 |
180 | goods_category_string_fields = {
181 | "name";
182 | };
183 |
184 | modGoodsCategory = sqlitemodel.Model(db, 'goods_category', default_goods_category_sql,
185 | goods_category_filter_fields,
186 | goods_category_search_fields,
187 | /*display_fields*/,
188 | /*field_choices*/,
189 | goods_category_string_fields
190 | )
191 |
192 | /*}}*/
193 |
194 | /*store和model表定义{{*/
195 | default_store_sql = string.load("/res/models/store.sql.aardio");
196 |
197 | store_filter_fields = {
198 | "cate";
199 | }
200 |
201 | store_search_fields = {
202 | "name";"code";
203 | };
204 |
205 | modStore = sqlitemodel.Model(db, 'store', default_store_sql,
206 | store_filter_fields,
207 | store_search_fields
208 | )
209 | modStore.label = "仓库";
210 | /*}}*/
211 |
212 | /*purchase和model表定义{{*/
213 | default_purchase_sql = /**CREATE TABLE "purchase" (
214 | "id" INTEGER NOT NULL PRIMARY KEY,
215 | "name" VARCHAR(32) NOT NULL, /*名称*/
216 | "org" VARCHAR(16) NOT NULL, /*部门*/
217 | "applier" VARCHAR(8) NOT NULL, /*申请人*/
218 | "subject" VARCHAR(16), /*事由*/
219 | "position" VARCHAR(16), /*位置*/
220 | "cate" VARCHAR(16), /*分类*/
221 | "from_store" VARCHAR(40), /*来源仓库*/
222 | "to_store" VARCHAR(40), /*去向仓库*/
223 | "created_at" DATE NOT NULL, /*创建时间*/
224 | "updated_at" DATE NOT NULL /*更新时间*/
225 | );
226 | **/
227 |
228 | purchase_filter_fields = {
229 | "cate";
230 | }
231 |
232 | purchase_search_fields = {
233 | "name";
234 | };
235 |
236 | modPurchase = sqlitemodel.Model(db, 'purchase', default_purchase_sql, purchase_filter_fields, purchase_search_fields)
237 | modPurchase.label = "采购";
238 | /*}}*/
239 |
240 | /*supplier和model表定义{{*/
241 | default_supplier_sql = /**CREATE TABLE "supplier" (
242 | "id" INTEGER NOT NULL PRIMARY KEY,
243 | "name" VARCHAR(32) NOT NULL, /*名称*/
244 | "position" VARCHAR(16), /*位置*/
245 | "cate" VARCHAR(16), /*地址*/
246 | "cellphone" VARCHAR(32), /*手机号码*/
247 | "tellphone" VARCHAR(32), /*电话号码*/
248 | "pos" INTEGER DEFAULT 0, /*排序*/
249 | "disabled" BOOLEAN DEFAULT 0, /*禁用*/
250 | "created_at" DATE NOT NULL, /*创建时间*/
251 | "updated_at" DATE NOT NULL /*更新时间*/
252 | );
253 | **/
254 |
255 | supplier_filter_fields = {
256 | "cate";
257 | }
258 |
259 | supplier_search_fields = {
260 | "name";
261 | };
262 |
263 | modSupplier = sqlitemodel.Model(db, 'supplier', default_supplier_sql, supplier_filter_fields, supplier_search_fields)
264 | modSupplier.label = "供应商"
265 | /*}}*/
266 |
267 | /*category和model表定义{{*/
268 | default_category_sql = /**CREATE TABLE "category" (
269 | "id" INTEGER NOT NULL PRIMARY KEY,
270 | "parent" INTEGER, /*父分类*/
271 | "name" VARCHAR(32) NOT NULL, /*名称*/
272 | "cate_type" VARCHAR(32) NOT NULL, /*名称*/
273 | "pos" VARCHAR(16), /*排序*/
274 | "created_at" DATE NOT NULL, /*创建时间*/
275 | "updated_at" DATE NOT NULL /*更新时间*/
276 | );
277 | **/
278 |
279 | category_filter_fields = {
280 | "cate_type";
281 | }
282 |
283 | category_search_fields = {
284 | "name";
285 | };
286 |
287 | modCategory = sqlitemodel.Model(db, 'category', default_category_sql,
288 | category_filter_fields,
289 | category_search_fields
290 | )
291 | modCategory.label = "分类"
292 | /*}}*/
293 |
294 | /*client和model表定义{{*/
295 | default_client_sql = /**CREATE TABLE "client" (
296 | "id" INTEGER NOT NULL PRIMARY KEY,
297 | "name" VARCHAR(32) NOT NULL, /*名称*/
298 | "code" VARCHAR(32), /*代码*/
299 | "cellphone" VARCHAR(16), /*联系电话*/
300 | "cid" INTEGER, /*分类ID*/
301 | "cate" VARCHAR(16), /*分类*/
302 | "org" VARCHAR(64), /*单位*/
303 | "orgid" VARCHAR(64), /*单位ID*/
304 | "pos" INTEGER DEFAULT 0, /*排序*/
305 | "created_at" DATE NOT NULL, /*创建时间*/
306 | "updated_at" DATE NOT NULL /*更新时间*/
307 | );
308 | **/
309 |
310 | client_filter_fields = {
311 | "cate";"org";
312 | }
313 |
314 | client_search_fields = {
315 | "name";"code";"cellphone";
316 | };
317 |
318 | modClient = sqlitemodel.Model(db, 'client', default_client_sql, client_filter_fields, client_search_fields)
319 | modClient.label = "客户"
320 | /*}}*/
321 |
322 | /*purchase_order和model表定义{{*/
323 | default_purchase_order_sql = /**CREATE TABLE "purchase_order" (
324 | "id" INTEGER NOT NULL PRIMARY KEY,
325 | "name" VARCHAR(32) NOT NULL, /*名称*/
326 | "position" VARCHAR(16), /*位置*/
327 | "cate" VARCHAR(16), /*地址*/
328 | "created_at" DATE NOT NULL, /*创建时间*/
329 | "updated_at" DATE NOT NULL /*更新时间*/
330 | );
331 | **/
332 |
333 | purchase_order_filter_fields = {
334 | "cate";
335 | }
336 |
337 | purchase_order_search_fields = {
338 | "name";
339 | };
340 |
341 | modPurchaseOrder = sqlitemodel.Model(db, 'purchase_order',
342 | default_purchase_order_sql,
343 | purchase_order_filter_fields,
344 | purchase_order_search_fields
345 | )
346 | modPurchaseOrder.label = "采购订单"
347 | /*}}*/
348 |
349 | /*order_goods和model表定义{{*/
350 | default_order_goods_sql = /**CREATE TABLE "order_goods" (
351 | "id" INTEGER NOT NULL PRIMARY KEY,
352 | "name" VARCHAR(32) NOT NULL, /*名称*/
353 | "position" VARCHAR(16), /*位置*/
354 | "cate" VARCHAR(16), /*地址*/
355 | "created_at" DATE NOT NULL, /*创建时间*/
356 | "updated_at" DATE NOT NULL /*更新时间*/
357 | );
358 | **/
359 |
360 | order_goods_filter_fields = {
361 | "cate";
362 | }
363 |
364 | order_goods_search_fields = {
365 | "name";
366 | };
367 |
368 | modOrderGoods = sqlitemodel.Model(db, 'order_goods',
369 | default_order_goods_sql,
370 | order_goods_filter_fields,
371 | order_goods_search_fields
372 | )
373 | modOrderGoods.label = "订单商品"
374 | /*}}*/
375 |
376 | /*goods和model表定义{{*/
377 | default_goods_sql = /**CREATE TABLE "goods" (
378 | "id" INTEGER NOT NULL PRIMARY KEY,
379 | "name" VARCHAR(32) NOT NULL, /*名称*/
380 | "code" VARCHAR(32) NOT NULL, /*代码*/
381 | "cid" INTEGER, /*分类ID*/
382 | "specs" VARCHAR(255), /*规格*/
383 | "price" FLOAT DEFAULT 1, /*单价*/
384 | "unit" VARCHAR(16), /*单位:个,把,包,盒,只*/
385 | "status" VARCHAR(16), /*状态*/
386 | "disabled" BOOLEAN DEFAULT 0, /*禁用*/
387 | "created_at" DATE NOT NULL, /*创建时间*/
388 | "updated_at" DATE NOT NULL /*更新时间*/
389 | );
390 | **/
391 |
392 | goods_filter_fields = {
393 | "cid";"unit";
394 | }
395 |
396 | goods_search_fields = {
397 | "name";"code";
398 | };
399 |
400 | goods_field_choices = {
401 | ["cid"] = modGoodsCategory;
402 | }
403 |
404 | modGoods = sqlitemodel.Model(db, 'goods',
405 | default_goods_sql, goods_filter_fields, goods_search_fields,/*display_fields*/,
406 | goods_field_choices)
407 | modGoods.label = "商品";
408 | /*}}*/
409 |
410 | /*goods_price和model表定义{{*/
411 | default_goods_price_sql = /**CREATE TABLE "goods_price" (
412 | "id" INTEGER NOT NULL PRIMARY KEY,
413 | "goods_id" INTEGER NOT NULL, /*排序*/
414 | "name" VARCHAR(32) NOT NULL, /*名称*/
415 | "price" FLOAT DEFAULT 1, /*单价*/
416 | "created_at" DATE NOT NULL, /*创建时间*/
417 | "updated_at" DATE NOT NULL /*更新时间*/
418 | );
419 | **/
420 |
421 | goods_price_filter_fields = {
422 | "goods_id";"price";
423 | }
424 |
425 | goods_price_search_fields = {
426 | "name";
427 | };
428 |
429 | goods_price_field_choices = {
430 | ["goods_id"] = modGoods;
431 | }
432 |
433 | modGoodsPrice = sqlitemodel.Model(db, 'goods_price',
434 | default_goods_price_sql, goods_price_filter_fields, goods_price_search_fields,/*display_fields*/,
435 | goods_price_field_choices)
436 | modGoodsPrice.label = "商品价格";
437 | /*}}*/
438 |
439 |
440 | /*goods_journal和model表定义{{*/
441 | default_goods_journal_sql = /**CREATE TABLE "goods_journal" (
442 | "id" INTEGER NOT NULL PRIMARY KEY,
443 | "ps_id" INTEGER DEFAULT 0, /*单据ID*/
444 | "goods_id" INTEGER NOT NULL, /*商品ID*/
445 | "name" VARCHAR(32) NOT NULL, /*名称*/
446 | "unit" VARCHAR(16), /*单位:个,把,包,盒,只*/
447 | "quantity" INTEGER NOT NULL, /*数量*/
448 | "price" FLOAT DEFAULT 1, /*单价*/
449 | "amount" DECIMAL, /*金额*/
450 | "store_id" INTEGER NOT NULL, /*库房ID*/
451 | "cate_id" INTEGER, /*分类ID*/
452 | "cate_name" VARCHAR(32), /*分类名称*/
453 | "trans_dir" VARCHAR(8), /*出入库方向*/
454 | "trans_type" INTEGER NOT NULL, /*出入库类型*/
455 | "trans_id" INTEGER DEFAULT 0, /*转库ID*/
456 | "balance" INTEGER, /*库存*/
457 | "created_at" DATE NOT NULL, /*创建时间*/
458 | "updated_at" DATE NOT NULL /*更新时间*/
459 | );
460 | **/
461 |
462 | goods_journal_filter_fields = {
463 | "store_id";"goods_id";
464 | }
465 |
466 | goods_journal_search_fields = {
467 | "name";
468 | };
469 |
470 | goods_journal_field_choices = {
471 | ["goods_id"] = modGoods;
472 | }
473 |
474 | modGoodsJournal = sqlitemodel.Model(db, 'goods_journal',
475 | default_goods_journal_sql, goods_journal_filter_fields, goods_journal_search_fields,/*display_fields*/,
476 | goods_journal_field_choices)
477 | modGoodsJournal.label = "出入库记录";
478 | /*}}*/
479 |
480 |
481 | /*goods_trans和model表定义{{*/
482 | default_goods_trans_sql = /**CREATE TABLE "goods_trans" (
483 | "id" INTEGER NOT NULL PRIMARY KEY,
484 | "goods_id" INTEGER NOT NULL, /*商品ID*/
485 | "name" VARCHAR(32) NOT NULL, /*名称*/
486 | "quantity" INTEGER NOT NULL, /*数量*/
487 | "amount" DECIMAL, /*金额*/
488 |
489 | "from_store_id" INTEGER NOT NULL, /*出库ID*/
490 | "from_store_name" VARCHAR(32), /*出库名称*/
491 | "from_journal_id" INTEGER NOT NULL, /*出库记录ID*/
492 |
493 | "to_store_id" INTEGER NOT NULL, /*入库ID*/
494 | "to_store_name" VARCHAR(32), /*入库名称*/
495 | "to_journal_id" INTEGER NOT NULL, /*入库记录ID*/
496 |
497 | "created_at" DATE NOT NULL, /*创建时间*/
498 | "updated_at" DATE NOT NULL /*更新时间*/
499 | );
500 | **/
501 |
502 | goods_trans_filter_fields = {
503 | "from_store_id";"to_store_id";
504 | }
505 |
506 | goods_trans_search_fields = {
507 | "name";
508 | };
509 |
510 | goods_trans_field_choices = {
511 | ["goods_id"] = modGoods;
512 | }
513 |
514 | modGoodsTrans = sqlitemodel.Model(db, 'goods_trans',
515 | default_goods_trans_sql, goods_trans_filter_fields, goods_trans_search_fields,/*display_fields*/,
516 | goods_trans_field_choices)
517 | modGoodsTrans.label = "转库";
518 | /*}}*/
519 |
520 | /*goods_balance和model表定义{{*/
521 | default_goods_balance_sql = /**CREATE TABLE "goods_balance" (
522 | "id" INTEGER NOT NULL PRIMARY KEY,
523 | "goods_id" INTEGER NOT NULL, /*商品ID*/
524 | "name" VARCHAR(32) NOT NULL, /*名称*/
525 |
526 | "store_id" INTEGER NOT NULL, /*库房ID*/
527 | "in_quantity" INTEGER NOT NULL, /*总入库数量*/
528 | "out_quantity" INTEGER NOT NULL, /*总出库数量*/
529 | "balance" INTEGER, /*总库存*/
530 | "amount" DECIMAL, /*总金额*/
531 | "created_at" DATE NOT NULL, /*创建时间*/
532 | "updated_at" DATE NOT NULL /*更新时间*/
533 | );
534 | **/
535 |
536 | goods_balance_filter_fields = {
537 | "goods_id";"store_id";
538 | }
539 |
540 | goods_balance_search_fields = {
541 | "name";
542 | };
543 |
544 | goods_balance_field_choices = {
545 | ["goods_id"] = modGoods;
546 | }
547 |
548 | modGoodsBalance = sqlitemodel.Model(db, 'goods_balance',
549 | default_goods_balance_sql, goods_balance_filter_fields, goods_balance_search_fields,/*display_fields*/,
550 | goods_balance_field_choices)
551 | modGoodsBalance.label = "库存";
552 | /*}}*/
553 |
554 | /*purchase_goods和model表定义{{*/
555 | default_purchase_goods_sql = /**CREATE TABLE "purchase_goods" (
556 | "id" INTEGER NOT NULL PRIMARY KEY,
557 | "purchase_id" INTEGER, /*采购单ID*/
558 | "goods_id" INTEGER, /*商品ID*/
559 | "name" VARCHAR(32), /*商品名称*/
560 | "price" FLOAT DEFAULT 0.0, /*单价*/
561 | "quantity" INTEGER, /*数量*/
562 | "unit" VARCHAR(16), /*单位:个,把,包,盒,只*/
563 | "amount" DECIMAL, /*金额*/
564 | "disabled" BOOLEAN DEFAULT 0, /*禁用*/
565 | "created_at" DATE NOT NULL, /*创建时间*/
566 | "updated_at" DATE NOT NULL /*更新时间*/
567 | );
568 | **/
569 |
570 | purchase_goods_filter_fields = {
571 | "purchase_id";"goods_id";
572 | }
573 |
574 | purchase_goods_search_fields = {
575 | "name";
576 | };
577 |
578 | purchase_goods_field_choices = {
579 | ["purchase_id"] = modPurchase;
580 | }
581 |
582 | modPurchaseGoods = sqlitemodel.Model(db, 'purchase_goods',
583 | default_purchase_goods_sql, purchase_goods_filter_fields, purchase_goods_search_fields,/*display_fields*/,
584 | purchase_goods_field_choices)
585 | modPurchaseGoods.label = "采购商品清单";
586 | /*}}*/
587 |
588 |
589 | /*contact和model表定义{{*/
590 | default_contact_sql = /**CREATE TABLE "contact" (
591 | "id" INTEGER NOT NULL PRIMARY KEY,
592 | "cid" INTEGER, /*分类ID*/
593 | "name" VARCHAR(32) NOT NULL, /*名称*/
594 | "sfzhm" VARCHAR(32), /*身份证号码*/
595 | "cellphone" VARCHAR(32) NOT NULL, /*手机号码*/
596 | "tellphone" VARCHAR(32), /*电话号码*/
597 | "shortnum" VARCHAR(6), /*短号*/
598 | "note" VARCHAR(64), /*备注*/
599 | "created_at" DATE NOT NULL, /*创建时间*/
600 | "updated_at" DATE NOT NULL /*更新时间*/
601 | );
602 | **/
603 |
604 | contact_filter_fields = {
605 | "cid";
606 | }
607 |
608 | contact_search_fields = {
609 | "name";
610 | "cellphone";
611 | "tellphone";
612 | "shortnum";
613 | };
614 |
615 | modContact = sqlitemodel.Model(db, 'contact', default_contact_sql,
616 | contact_filter_fields,
617 | contact_search_fields
618 | )
619 | modContact.label = "联系人";
620 | /*}}*/
621 |
622 |
623 | CURR_QUERY = {}; //整个程序中的当前查询query, table数据结构
624 | CURR_MODEL = modGoods; //整个程序中的当前model
625 | mainForm.lastListviewSelected = null;
626 | mainForm.model = modGoods;
627 |
628 | mainForm.onDestroy = function(){
629 | if(db != null){
630 | db.close();
631 | }
632 | }
633 |
634 | /*主菜单{{*/
635 | var menu = win.ui.menu(mainForm);//创建主菜单
636 | //------------------------------------
637 | var menuGoods = win.ui.popmenu(mainForm);//创建弹出菜单
638 |
639 |
640 | var idFileNew = menuGoods.add(
641 | '添加商品(&A)',
642 | function(id){
643 | goodsform = sqlitemodel.modelForm(modGoods, mainForm);
644 | goodsform.doModal(mainForm);
645 | load_model_data(modGoods);
646 | }
647 | );
648 |
649 | menuGoods.add(
650 | '商品分类(&C)',
651 | function(id){
652 | goodsCategoryMgr();
653 | }
654 | );
655 |
656 | menuGoods.add(
657 | '商品管理(&G)',
658 | function(id){
659 | goodsMgr();
660 | }
661 | );
662 |
663 | menuGoods.add(); //添加分隔线
664 | menuGoods.add(
665 | "批量导入商品",
666 | function(id){
667 | //import_company();
668 | var filepath = fsys.dlg.open("Excel文件(*.xsl;*xlsx)|*.xsl;*xlsx","请选择Excel文件",,mainForm)
669 | if(filepath){
670 | import_model(modGoods, filepath);
671 | }
672 | }
673 | )
674 |
675 | menuGoods.add(); //添加分隔线
676 | menuGoods.add(
677 | "退出(&X)",
678 | function(id){
679 | mainForm.close()
680 | }
681 | )
682 |
683 |
684 | menu.add('商品(&G)',menuGoods)
685 |
686 |
687 |
688 | //-------------------------------------
689 | var menuFile = win.ui.popmenu(mainForm);//创建弹出菜单
690 | menuFile.addTable({
691 |
692 | {
693 | "采购单(&I)";
694 | function(id){
695 |
696 | menu_goods_purchase()
697 |
698 | }
699 | };
700 |
701 | {
702 | "历史采购单(&I)";
703 | function(id){
704 |
705 | menu_goods_purchase_history()
706 |
707 | }
708 | };
709 |
710 | {
711 | "供应商管理(&E)";
712 | function(id){
713 | supplierMgr();
714 | }
715 | };
716 |
717 |
718 | })
719 |
720 | menu.add('入库(&R)',menuFile)
721 | //-------------------------------------
722 |
723 | var menuFile = win.ui.popmenu(mainForm);//创建弹出菜单
724 | menuFile.addTable({
725 |
726 | {
727 | "出库单(&O)";
728 | function(id){
729 | //import_company();
730 | menu_goods_sell();
731 | }
732 | };
733 |
734 | {
735 | "历史出库单(&I)";
736 | function(id){
737 |
738 | menu_goods_sell();
739 |
740 | }
741 | };
742 |
743 | {
744 | "客户管理(&C)";
745 | function(id){
746 | clientMgr();
747 | }
748 | };
749 |
750 |
751 | })
752 |
753 | menu.add('出库(&C)',menuFile)
754 | //-------------------------------------
755 | var menuFile = win.ui.popmenu(mainForm);//创建弹出菜单
756 | menuFile.addTable({
757 |
758 | {
759 | "库存查询(&I)";
760 | function(id){
761 | //import_company();
762 | mainForm.msgbox("批量导入工酬数据")
763 | }
764 | };
765 |
766 | {
767 | "物流情况(&I)";
768 | function(id){
769 | goodsTransMgr();
770 | }
771 | };
772 |
773 | {
774 | "仓库管理(&E)";
775 | function(id){
776 | storeMgr();
777 | }
778 | };
779 |
780 |
781 | })
782 |
783 | menu.add('库存(&K)',menuFile)
784 | //------------------------------------
785 | var menuFinance = win.ui.popmenu(mainForm);//创建弹出菜单
786 |
787 |
788 | menuFinance.add(
789 | "现金日记账",
790 | function(id){
791 | mainForm.msgbox("现金日记账")
792 | }
793 | )
794 | menuFinance.add(); //添加分隔线
795 |
796 | menuFinance.addTable( {
797 | { "存款日记账";
798 | function(id){
799 | mainForm.msgbox("存款日记账")
800 | }
801 | };
802 |
803 | } )
804 | menu.add('财务(&F)',menuFinance)
805 | //------------------------------------
806 | var menuReports = win.ui.popmenu(mainForm);//创建弹出菜单
807 |
808 |
809 | menuReports.add(
810 | "采购报表",
811 | function(id){
812 | mainForm.msgbox("版权所有")
813 | }
814 | )
815 |
816 | menuReports.addTable( {
817 | { "销售报表";
818 | function(id){
819 | mainForm.msgbox("如需帮助 "++newLine++newLine++"请发邮件至330906552@QQ.com")
820 | }
821 | };
822 |
823 | {};
824 |
825 | { "客户销量";
826 | function(id){
827 | help();
828 | }
829 | };
830 |
831 |
832 | { "商品销量";
833 | function(id){
834 | mainForm.msgbox("如需帮助 "++newLine++newLine++"请发邮件至330906552@QQ.com")
835 | }
836 | };
837 |
838 | } )
839 |
840 | menu.add('报表(&B)',menuReports)
841 |
842 | //----------------------------------------
843 | menu.addTable( {
844 |
845 |
846 | { "设置(&S)";
847 | {
848 | { "选项(&O)";
849 | function(id){
850 |
851 | config_setting();
852 |
853 | }
854 | };
855 |
856 | { "商品管理(&G)";
857 | function(id){
858 | goodsMgr();
859 | }
860 | };
861 |
862 | { "客户管理(&Z)";
863 | function(id){
864 | clientMgr();
865 | }
866 | };
867 | { "供应商管理(&S)";
868 | function(id){
869 | supplierMgr();
870 | }
871 | };
872 | { "仓库设置(&Y)";
873 | function(id){
874 | storeMgr();
875 | }
876 | };
877 | { "出入库流水账(&Y)";
878 | function(id){
879 | journalMgr();
880 | }
881 | };
882 | { "通讯录(&C)";
883 | function(id){
884 | contactMgr();
885 | }
886 | }
887 |
888 | }
889 | };
890 |
891 | /**{ "数据库(&R)";
892 | {
893 | {
894 | "备份数据库(&B)";
895 | function(id){
896 |
897 | var items = {}
898 | items = db.getTable("SELECT * FROM [company] ")
899 | export_company(items);
900 | }
901 | };
902 |
903 | {};
904 |
905 |
906 | }
907 | }; **/
908 |
909 | } )
910 | //------------------------------------
911 | var menuTools = win.ui.popmenu(mainForm);//创建弹出菜单
912 | menuTools.addTable({
913 |
914 | {
915 | "计算器(&I)";
916 | function(id){
917 | process.execute("calc.exe")
918 | }
919 | };
920 |
921 |
922 | { /*---分隔线---*/ };
923 |
924 | })
925 |
926 | menu.add('工具(&T)',menuTools)
927 |
928 |
929 |
930 |
931 |
932 |
933 |
934 | //------------------------------------
935 | var menuHelp = win.ui.popmenu(mainForm);//创建弹出菜单
936 |
937 |
938 | menuHelp.add(
939 | "关于",
940 | function(id){
941 | mainForm.msgbox("版权所有")
942 | }
943 | )
944 | menuHelp.add(); //添加分隔线
945 |
946 | menuHelp.addTable( {
947 | { "帮助";
948 | function(id){
949 | mainForm.msgbox("如需帮助 "++newLine++newLine++"请发邮件至330906552@QQ.com")
950 | }
951 | };
952 |
953 | } )
954 | menu.add('帮助(&H)',menuHelp)
955 |
956 | //主菜单构建完成后要用下面这句更新,menu.addTable()会自动调用redraw()
957 | menu.redraw();
958 |
959 | /*}}*/
960 |
961 | /*菜单函数{{*/
962 | clientMgr = function(){
963 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
964 | frmChild.init(modClient);
965 | frmChild.doModal(mainForm);
966 |
967 |
968 |
969 | }
970 |
971 |
972 | supplierMgr = function(){
973 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
974 | frmChild.init(modSupplier);
975 | frmChild.doModal(mainForm);
976 | }
977 |
978 | storeMgr = function(){
979 |
980 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
981 | frmChild.init(modStore);
982 | frmChild.doModal(mainForm);
983 | }
984 |
985 | journalMgr = function(){
986 |
987 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
988 | frmChild.init(modGoodsJournal);
989 | frmChild.doModal(mainForm);
990 | }
991 |
992 | contactMgr = function(){
993 |
994 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
995 | frmChild.init(modContact);
996 | frmChild.doModal(mainForm);
997 | }
998 |
999 | goodsCategoryMgr = function(){
1000 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
1001 | frmChild.init(modGoodsCategory);
1002 | //使用_metaProperty, modGoodsCategory.filter_fields 不会调用model.get("filter_fields")
1003 | //console.log("modGoodsCategory.filter_fields",modGoodsCategory.filter_fields);
1004 | //奇怪的是:
1005 | //使用_metaProperty, modGoodsCategory.field_choices 会调用model.get("field_choices")
1006 | //console.log("modGoodsCategory.field_choices", modGoodsCategory.field_choices);
1007 |
1008 | frmChild.doModal(mainForm);
1009 | }
1010 |
1011 | goodsMgr = function(){
1012 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
1013 | frmChild.init(modGoods);
1014 | frmChild.doModal(mainForm);
1015 | }
1016 |
1017 | goodsTransMgr = function(){
1018 | var frmChild = mainForm.loadForm("\dlg\model_list.aardio");
1019 | frmChild.init(modGoodsTrans);
1020 | frmChild.doModal(mainForm);
1021 | }
1022 |
1023 |
1024 | /*}}*/
1025 |
1026 | /*工具条{{*/
1027 | var toolbar = win.ui.toolbar(mainForm);
1028 | toolbar.create( style = 0x1000/*_TBSTYLE_LIST*/ ); // 创建工具条
1029 | toolbar.showLabel = true; //在按钮上显示文字
1030 | toolbar.imageList = win.imageList( 16, 16 ).add($"\res\toolbar.gif",0xFF00FF/*透明色*/) ;
1031 |
1032 | toolbar.add();// 添加分隔条
1033 | toolbar.add( "新建", , 1, idFileNew/*重用现有命令ID*/ );
1034 |
1035 | toolbar.add(
1036 | "采购",
1037 | function (id) {
1038 | menu_goods_purchase();
1039 | }, 2
1040 | );
1041 |
1042 | toolbar.add(
1043 | "禁用",
1044 | function (id) {
1045 | toolbar.getButton(4).disabled = false;
1046 | toolbar.getButtonById(id).disabled = true;
1047 | }, 3
1048 | );
1049 | toolbar.add(
1050 | "禁用2",
1051 | , 4
1052 | );
1053 |
1054 | /*}}*/
1055 |
1056 | /*快捷键{{*/
1057 | var accelerator = win.ui.accelerator({
1058 | {
1059 | vkey = 0x70/*_VK_F1*/; //进货
1060 | oncommand = function(){
1061 | menu_goods_purchase()
1062 | };
1063 | };
1064 |
1065 | {
1066 | vkey = 0x71/*_VK_F2*/; //销货
1067 | oncommand = function() mainForm.msgbox("销货");
1068 | };
1069 |
1070 | {
1071 | vkey = 0x72/*_VK_F3*/; //存货
1072 | oncommand = function() mainForm.msgbox("存货");
1073 | };
1074 |
1075 | {
1076 | vkey = 0x73/*_VK_F4*/; //财务
1077 | oncommand = function() mainForm.msgbox("财务");
1078 | };
1079 |
1080 | {
1081 | vkey = 0x74/*_VK_F5*/; //商品
1082 | oncommand = function(){
1083 | //发消息到 前面定义好的菜单项, 要转换为pointer
1084 | ::SendMessage(mainForm.hwnd, 0x111/*_WM_COMMAND*/, topointer(idFileNew), topointer(0));
1085 | }
1086 | };
1087 |
1088 | {
1089 | vkey = 0x75/*_VK_F6*/; //报表
1090 | oncommand = function() mainForm.msgbox("报表");
1091 | };
1092 |
1093 | //F10:用来激活Windows或程序中的菜单,按下Shift+F10会出现右键快捷菜单。
1094 | //如果你先按了F10, 那么F1, F2按的时候可能会失效, 只要再按一次F10, 或者按ESC退出F10的菜单模式.
1095 |
1096 | {
1097 | vkey = 0x7B/*_VK_F12*/; //盘库
1098 | oncommand = function() mainForm.msgbox("盘库");
1099 | };
1100 |
1101 | {
1102 | ctrl = true; vkey = '1'#; //分类
1103 | oncommand = function(){
1104 | goodsform = sqlitemodel.modelForm(modGoods, mainForm);
1105 | goodsform.doModal(mainForm);
1106 | load_model_data(modGoods);
1107 | }
1108 | };
1109 |
1110 | {
1111 | ctrl = true; vkey = '2'#; //
1112 | oncommand = function() mainForm.msgbox("Ctrl+2");
1113 | };
1114 |
1115 | {
1116 | ctrl = true; vkey = '3'#; //
1117 | oncommand = function() mainForm.msgbox("Ctrl+3");
1118 | };
1119 |
1120 | {
1121 | ctrl = true; vkey = '`'#; //没反应不知道怎么回事
1122 | oncommand = function() mainForm.msgbox("Ctrl+`");
1123 | };
1124 |
1125 | {
1126 | ctrl = true; vkey = 'N'#; //没反应不知道怎么回事
1127 | oncommand = function(){
1128 | goodsform = sqlitemodel.modelForm(modGoods, mainForm);
1129 | goodsform.doModal(mainForm);
1130 | load_model_data(modGoods);
1131 | };
1132 | };
1133 |
1134 | {
1135 | ctrl = true; vkey = 'A'#; //全选
1136 | oncommand = function(){
1137 | mainForm.listview.setFocus();
1138 | for(i=1;mainForm.listview.count;1){
1139 | mainForm.listview.setSelected(i)
1140 | }
1141 | };
1142 | };
1143 |
1144 |
1145 |
1146 |
1147 | }, mainForm);
1148 | /*}}*/
1149 |
1150 |
1151 | import_model = function(model, filepath){
1152 | // 从excel中导入某个model的数据信息,必须的字段,定义在全局变量headers里
1153 | // 其中的字段,在excel中必须有(主要是中文的标题要一致)
1154 | // 理想的导入,就是
1155 | // 1. 【已实现】给一个Excel表,用电脑自带的office的com接口打开
1156 | // 2. 【已实现】先检查第一行的标题,从第1列检查到最后一列的标题
1157 | // 3. 如果标题在数据库的字段里,就保留,并登记好对应第几列
1158 | // 4. 如果标题不在数据库的字段里,就舍弃
1159 | // 5. 如果数据库中的字段,并不在Excel的标题里,即缺少数据库必须的字段,则终止报错
1160 | //
1161 | var TABLE_NAME = model.tablename
1162 | var header_cols={} //Excel中的标题在第N列, 则model.headers中的英文Key对应在第N列
1163 | //数据导入用
1164 | for(k,v in model.headers){
1165 | //model.headers 是 {"name"="中文" ;...}
1166 | //标题位于第几列(第1列是A列,第2列是B列...),
1167 | //初始化默认设置为0列(默认不正常,正常的列应该从1开始).
1168 | header_cols[k]=0;
1169 | }
1170 |
1171 | //导入的时候,忽略以下字段
1172 | header_cols["id"] = null;
1173 | header_cols["created_at"] = null;
1174 | header_cols["updated_at"] = null;
1175 |
1176 | var required_cols = {
1177 | //类似与header_cols
1178 | }
1179 |
1180 | //数据导入用
1181 | for(i=1;#model.required_fields;1){
1182 | k = model.required_fields[i];
1183 | //标题位于第几列(第1列是A列,第2列是B列...),
1184 | //初始化默认设置为0列(默认不正常,正常的列应该从1开始).
1185 | required_cols[k]=0;
1186 | }
1187 |
1188 | required_cols["id"] = null;
1189 | required_cols["created_at"] = null;
1190 | required_cols["updated_at"] = null;
1191 |
1192 | if(io.exist(filepath)){
1193 | var excel = com.excel();
1194 | excel.Visible = true;
1195 | var workbook = excel.Open( filepath )
1196 |
1197 | sheet = workbook.Sheets(1); //默认只处理第一个标签
1198 |
1199 | var colCount = excel.Sheets(1).UsedRange.Columns.Count; //多少列
1200 | var rowCount = excel.Sheets(1).UsedRange.Rows.Count; //多少行
1201 | var cimP = excel.Sheets(1).Cells(1,colCount).value2;
1202 | var cellValue;
1203 |
1204 | var msgs ={info = {};errors={};warning={}}
1205 | win.cur.setCur(mcur2); //鼠标设置为忙碌状态, 使用户不去进行其他操作
1206 |
1207 | //【读取第1行】,第1行必须是标题,且标题必须在headers中定义好
1208 | //根据第1行的标题, 在headers中查找,是否存在
1209 | //然后反过来设置查header_cols表,该标题对应第几列
1210 | //比如 假设第5列的标题AAA,在headers的values中, 就在
1211 | //header_cols中设置header_cols[k]=5, 这个k是headers中headers[k]=AAA的k
1212 | for(i=1;colCount;1){
1213 | var cellValue = excel.Sheets(1).Cells(1,i).value2;
1214 | log("第"++i++"列: "++tostring(cellValue)) //第i列是什么标题, 标题是汉字
1215 |
1216 | // header_cols, 可选字段所在列, 可选字段是包含全部字段的.
1217 |
1218 | for(k,v in model.headers){
1219 | //遍历model.headers, 查找excel中的标题是否在headers里
1220 | //k 是英文字段名, v是中文字段名
1221 | //在 header_cols 设置该标题在headers中的key, 对应第几列数据
1222 | //【TODO】: 这里的循环有个逻辑问题, 就是外面的标题(cellValue),
1223 | //如果Excel中的标题有重复的, 就会有问题.除非两个同名列内容是一样的。
1224 | if(v==cellValue){
1225 | if(required_cols[k] != null){
1226 | //看看必须字段中, 是否有这个可选字段, 如果有, 设置所在列为i
1227 | required_cols[k]=i; //key->123
1228 | }
1229 |
1230 | header_cols[k]=i; //key->123
1231 | }
1232 | }
1233 | }
1234 |
1235 |
1236 | for(k,v in required_cols){
1237 | var msg = ""
1238 | if(v==0){
1239 | msg = "!!!!Excel文件不符合规范, 文件第1行标题行缺少 '"++model.headers[k]++"' 列, 程序将无法运行!"
1240 |
1241 | table.push(msgs.errors, msg)
1242 | }
1243 | }
1244 |
1245 |
1246 |
1247 | for(k,v in header_cols){
1248 | //
1249 | //console.log(k,v, headers[k])
1250 | //
1251 | var msg = ""
1252 | if(v==0){
1253 | msg = "!!!!Excel文件不完善, 文件第1行标题行缺少 '"++model.headers[k]++"' 列, 可以导入, 但是不保证数据完整"
1254 |
1255 | table.push(msgs.warning, msg)
1256 | }
1257 | }
1258 |
1259 | /*
1260 | required_cols = {
1261 |
1262 | key1 = 0;
1263 | key2 = 2;
1264 | key3 = 1;
1265 | ...
1266 | }
1267 | */
1268 |
1269 |
1270 | if(#msgs.errors>0){
1271 | for(i=1;#msgs.errors;1){
1272 | log(msgs.errors[i])
1273 | }
1274 | return;
1275 |
1276 | }
1277 |
1278 | if(#msgs.warning>0){
1279 | for(i=1;#msgs.warning;1){
1280 | log(msgs.warning[i])
1281 | }
1282 | }
1283 |
1284 | var items = {} //每次导入都初始化一次
1285 |
1286 |
1287 | //从第2行开始读取数据
1288 | for(iRow=2;sheet.UsedRange.Rows.Count;1){
1289 | //////log("第"++ iRow ++ "行")
1290 | data = {}
1291 | for(k,v in header_cols){
1292 | var currentKeyCol = header_cols[k]
1293 |
1294 | //log(k++"当前列:"++currentKeyCol)
1295 |
1296 | if(currentKeyCol==0){
1297 | msg = "!!!!列的index为0,跳过忽略第 '"++iRow++"' 行数据!"
1298 | table.push(msgs.warning, msg)
1299 | continue; //列的index为0, 会出错, 跳过, 即忽略这一行数据
1300 | }
1301 |
1302 | data[k] = default_value(sheet.Cells(iRow, currentKeyCol).getValue2(), "");
1303 |
1304 | }
1305 |
1306 | //////for(k,v in data){
1307 | ////// log(headers[k] ++ ":" ++ tostring(v) +" ") // + tostring(type(v)))
1308 | //////}
1309 | //////log("")
1310 |
1311 | table.push(items, data);
1312 |
1313 |
1314 | }
1315 |
1316 | for(i=1;#items;1){
1317 | var item = items[i]
1318 |
1319 | //var tab_text = {tostring(i)} //初始化序号id, 因为前面剔除了
1320 | //for(j=1;#display_headers;1){
1321 | // var v = data[display_headers[j]]
1322 | // if(v != null){
1323 | // table.push(tab_text, v)
1324 | // }
1325 | //}
1326 |
1327 |
1328 | var r = model.create(item);
1329 |
1330 | //if(r){//添加成功, 就加到listview中
1331 | // mainForm.listview.addItem({
1332 | // text=tab_text
1333 | // });
1334 | //}
1335 |
1336 | }
1337 |
1338 | //不再一条一条的往listview中添加. 直接加载数据库
1339 | //因为一条一条添加, 未能正确设置id
1340 | //load_model_data(model)
1341 | mainForm.msgbox("导入成功,请刷新窗口数据")
1342 |
1343 | win.cur.setCur(mcur0);//复原鼠标
1344 |
1345 | }else {
1346 | mainForm.msgbox("未选择数据表!")
1347 | }
1348 |
1349 | }
1350 |
1351 |
1352 | /*export_model{{*/
1353 | export_model = function(model, items, fields){
1354 | // 导出公司数据
1355 | // 1. 根据model.headers中定义的字段进行导出(必须包含的字段)
1356 | // 2. 根据items进行导出, 每个item都是一个table
1357 | // 是不是要给个框框, 让用户选择字段?
1358 |
1359 | var flat_items = {}
1360 | var display_fields = {} //获取全部显示的fields, 或者用户自定义的fields
1361 |
1362 |
1363 | if(fields == null){
1364 | var ub = #model.field_names
1365 |
1366 | //console.log("--------model.field_names");
1367 | //console.varDump(table.map(model.field_names,lambda(x) x.name));
1368 |
1369 |
1370 | //从全局变量model.field_names中获取field
1371 | for(i=1;ub;1){
1372 | table.push(display_fields, model.field_names[i]["name"])
1373 | }
1374 |
1375 | //剔除以下字段
1376 | table.removeByValue(display_fields, "created_at");
1377 | table.removeByValue(display_fields, "updated_at");
1378 |
1379 | }else {
1380 | if(type(fields)!= type.table){
1381 | mainForm.msgbox("程序错误, 参数display_fields类型不正确, 应该为table")
1382 | return
1383 | }else {
1384 | display_fields = fields;
1385 | }
1386 | }
1387 |
1388 | console.log("--------display_fields");
1389 | console.varDump(display_fields);
1390 |
1391 | //检查是否露了必须的字段, 没有就加进去
1392 | //比如前面去掉的created_at,这里又加回去了
1393 | for(i=1;#model.required_fields;1){
1394 | if(table.find(display_fields, model.required_fields[i])){
1395 |
1396 | }else {
1397 | table.push(display_fields, model.required_fields[i])
1398 | }
1399 |
1400 | }
1401 |
1402 | if(#display_fields <= 0){
1403 | mainForm.msgbox("程序错误, 数据字段display_fields未正确设置")
1404 | return
1405 | }
1406 |
1407 | //
1408 | //console.varDump(display_fields)
1409 | //
1410 |
1411 | //将items变为平展的数据, 即{"";"";"";...""}这种,可以快速给excel的一行赋值
1412 | for(i=1;#items;1){
1413 | item = {}
1414 | for(j=1;#display_fields;1){
1415 | var k = display_fields[j];
1416 | var value = string.trimright(default_value(items[i][k], ""));
1417 | table.push(item, value)
1418 | }
1419 | table.push(flat_items, item);
1420 | }
1421 |
1422 | if(#flat_items<=0){
1423 | mainForm.msgbox("无数据,或者未选中数据")
1424 | return
1425 | }
1426 |
1427 | import com.excel;
1428 |
1429 | var excel = com.excel();
1430 | excel.Visible = 0xC/*_xlVisible*/;
1431 | var wkbook = excel.WorkBooks.Add();
1432 | var sheet = wkbook.Sheets(1);
1433 |
1434 | excel.ActiveWorkbook.Sheets(1).Select();
1435 |
1436 | //表头标题行,第1行
1437 | for(i=1;#display_fields;1){
1438 | //从全局变量headers中获取field的中文标题
1439 | sheet.Cells(1,i).value2 = model.headers[display_fields[i]]
1440 | }
1441 |
1442 | var item_count = #flat_items + 1
1443 |
1444 | //cells(row1,col1),cells(row2,col2)
1445 |
1446 | //sheet.Range("A2:G"+item_count).value2= mainForm.listview.items
1447 | //
1448 | //for(k,v in items){
1449 | // console.varDump(v)
1450 | //}
1451 | //
1452 | //console.log(#display_fields,0, #flat_items[1])
1453 | //起点单元格, 终点单元格,宽度为7, items的宽度为9
1454 | //最后导出的数据就只有7列
1455 | sheet.Range(sheet.Cells(2,1), sheet.Cells(item_count, #display_fields)).value2 = flat_items;//Excel行快速赋值
1456 | var tm = time.now()
1457 |
1458 | newFilename = tostring(tm, "\" + model.tablename + "-%Y%m%d%H%M%S.xlsx", "chs");
1459 |
1460 | log("导出文件至:" + io.fullpath(newFilename))
1461 |
1462 | wkbook.SaveAs(io.fullpath(newFilename),0x33/*_xlOpenXMLWorkbook*/)
1463 |
1464 | wkbook.close();
1465 | excel.Quit();
1466 |
1467 | process.exploreSelect(io.fullpath(newFilename));
1468 | }
1469 | /*}}*/
1470 |
1471 | shakewindow = function(hwnd,r,s){
1472 | x,y=win.getPos(hwnd)
1473 | win.setPos(hwnd,x-r,y-r)
1474 | win.delay(s)
1475 | win.setPos(hwnd,x+r,y-r)
1476 | win.delay(s)
1477 | win.setPos(hwnd,x+r,y+r)
1478 | win.delay(s)
1479 | win.setPos(hwnd,x-r,y+r)
1480 | win.delay(s)
1481 | win.setPos(hwnd,x,y)
1482 | }
1483 |
1484 |
1485 |
1486 | /*add_company{{*/
1487 | add_company = function(query, default_sql){
1488 |
1489 | var field_names = get_field_names(default_sql)
1490 |
1491 | //
1492 | //console.log("field_names")
1493 | //console.varDump(field_names)
1494 | //
1495 |
1496 | var field_values = {}
1497 |
1498 | for(i=1;#field_names;1){
1499 | table.push(field_values, "@" ++field_names[i]["name"])
1500 | }
1501 | var str_field_values = string.join(field_values, ", ")
1502 | str_field_values = " VALUES (null, " + str_field_values ++ ");"
1503 |
1504 | //
1505 | //console.log(str_field_values)
1506 | //
1507 |
1508 |
1509 |
1510 |
1511 | var command = db.prepare("INSERT INTO "+ TABLE_NAME + str_field_values ) ;
1512 |
1513 | //以下非空字段, 要在for循环前绑定, 绑不上去.
1514 | //command.bind.parameterByName("", "@boss_name") //给@boss_name 绑定数据 ""
1515 | //command.bind.parameterByName("", "@boss_cellphone") //给@boss_cellphone 绑定数据 ""
1516 |
1517 | //command.bind.parameterByName("", "@charger_name")
1518 | //command.bind.parameterByName("", "@charger_cellphone")
1519 |
1520 | //command.bind.parameterByName(time.now(), "@created")
1521 | //command.bind.parameterByName(time.now(), "@updated")
1522 |
1523 | //给item设置默认值
1524 | query["boss_name"] = default_value(query["boss_name"], "")
1525 | query["boss_cellphone"] = default_value(query["boss_cellphone"], "")
1526 |
1527 | query["charger_name"] = default_value(query["charger_name"], "")
1528 | query["charger_cellphone"] = default_value(query["charger_cellphone"], "")
1529 |
1530 | query["created"] = default_value(query["created"], time.now())
1531 | query["updated"] = default_value(query["updated"], time.now())
1532 |
1533 |
1534 | for(i=1;#field_names;1){
1535 |
1536 | var field = field_names[i]["name"]
1537 | var value = query[field]
1538 |
1539 | //给 将数据绑定到 @field
1540 | command.bind.parameterByName(value, '@'+ field )
1541 |
1542 | }
1543 |
1544 |
1545 |
1546 |
1547 |
1548 |
1549 | var ret = command.step();
1550 |
1551 | //console.log("sql insert result ", ret)
1552 | command.finalize();
1553 |
1554 | //
1555 | //console.log(command.sql);
1556 | //
1557 |
1558 | //
1559 | //console.varDump(query)
1560 | //
1561 |
1562 | if(ret<100){
1563 | log(db.lasterr())
1564 | log("insert failed!")
1565 | return false;
1566 | }
1567 | return true
1568 | }
1569 | /*}}*/
1570 |
1571 | /*edit_company{{*/
1572 | edit_company = function(query){
1573 | if(query["id"]==null or query["id"]==""){
1574 | //log("Failed , no query['id']")
1575 | return false;
1576 | }
1577 |
1578 | //
1579 | //console.varDump(query)
1580 | //
1581 |
1582 | old_data = db.stepQuery("SELECT * FROM ["+ TABLE_NAME +"]", { id = query["id"]})
1583 |
1584 | //console.log("get old data by id")
1585 | //console.varDump(old_data)
1586 |
1587 | var stmts = {}
1588 |
1589 | for(k,v in query){
1590 | if(k=="created" or k=="updated"){
1591 | continue
1592 | }
1593 | if(old_data[k] != v){
1594 | table.push(stmts, " "+ k + " = @" ++ k)
1595 | }
1596 | }
1597 |
1598 | //console.log("to be updated fileds:")
1599 | //console.varDump(stmts)
1600 |
1601 |
1602 | if(#stmts<=0){
1603 | //console.log("no fields to be updated")
1604 | return false;
1605 | }else {
1606 | var k = "updated"
1607 | table.push(stmts, " "+ k + " = @" ++ k)
1608 | query[k]=time.now()
1609 | }
1610 |
1611 |
1612 | var str_set_stmts = string.join(stmts, ", ")
1613 | str_set_stmts = " SET " + str_set_stmts ++ " WHERE id = @id;"
1614 |
1615 | //console.log("str_set_stmts")
1616 |
1617 | //console.log(str_set_stmts)
1618 |
1619 |
1620 |
1621 |
1622 | var sql = "UPDATE ["+ TABLE_NAME + "] " + str_set_stmts;
1623 | //console.log("sql:"+sql);
1624 | var updated = false;
1625 | try{
1626 | db.exec(sql, query);
1627 | updated = true;
1628 | //return true; //这里try语句里的 return true 并不能真的返回值, 函数最后返回的是null
1629 | }
1630 | catch(e){
1631 | //console.varDump(e);
1632 | //console.log(tostring(e))
1633 | //return false;//这里try的catch语句里的 return false却可以真正使函数返回.函数最后返回的是false
1634 | updated = false;
1635 | }
1636 |
1637 |
1638 |
1639 |
1640 | /*
1641 |
1642 | command.bind.parameterByName("", "@boss_name")
1643 | command.bind.parameterByName("", "@boss_cellphone")
1644 |
1645 | command.bind.parameterByName("", "@charger_name")
1646 | command.bind.parameterByName("", "@charger_cellphone")
1647 |
1648 | command.bind.parameterByName(time.now(), "@created")
1649 | command.bind.parameterByName(time.now(), "@updated")
1650 |
1651 | */
1652 | //console.log("updated!!!!")
1653 |
1654 | return updated
1655 | }
1656 | /*}}*/
1657 |
1658 | /*load_model_data{{*/
1659 | load_model_data = function(model, user_query){
1660 | var items={};
1661 | var query = {}
1662 | if(type(user_query)=="table"){
1663 | query = user_query
1664 | }elseif(type(user_query)=="string"){
1665 | query["keyword"] = user_query;
1666 | }
1667 | query["QUERY_MODE"] = "SEARCH";
1668 | query["model_name"] = model.tablename;
1669 | CURR_QUERY = query; //记录到全局变量CURR_QUERY中
1670 | CURR_MODEL = model;
1671 | log(table.tostring(CURR_QUERY));
1672 | items = model.search(query);
1673 | console.log("items count:" ++ #items)
1674 |
1675 | reset_listview(model, items);
1676 | initTreeviewFilters(model)
1677 |
1678 |
1679 | }
1680 | /*}}*/
1681 |
1682 |
1683 |
1684 | /*reset_listview{{*/
1685 | reset_listview = function(model, items){
1686 |
1687 | mainForm.statusbar.setText("数据总数:" + #items);
1688 |
1689 | //如果获取了数据, 那么清空listview
1690 | if(#items>=1){
1691 | mainForm.listview.clear();
1692 | }else {
1693 | mainForm.listview.clear();
1694 | return
1695 | }
1696 |
1697 | var n = mainForm.listview.columnCount;
1698 | for(i=1;n;1){
1699 | mainForm.listview.delColumn(n+1-i);//从倒数开始删除, 以免删除前面的, 后面的索引都变了.
1700 | }
1701 |
1702 |
1703 | for(i=1;#model.display_fields;1){
1704 | var k = model.display_fields[i]
1705 | var caption = model.headers[k]
1706 | mainForm.listview.insertColumn(caption, 80, i);
1707 | }
1708 |
1709 | mainForm.listview.setColumn({cx=40},1)
1710 | mainForm.listview.setColumn({cx=180},2)
1711 | mainForm.listview.setColumn({cx=100},3)
1712 |
1713 |
1714 |
1715 | for(i=1;#items;1){
1716 |
1717 | var data ={}
1718 | for(j=1;#model.display_fields;1){
1719 | k = model.display_fields[j];
1720 | //if(k=="id"){
1721 | // table.push(data, tostring(i))
1722 | // continue
1723 | //}
1724 | //console.log('k', k);
1725 | if(items[i][k]!=null){
1726 | table.push(data, items[i][k])
1727 | }else {
1728 | table.push(data, "")
1729 | }
1730 |
1731 |
1732 | }
1733 | //
1734 | //console.varDump(items[i])
1735 | //
1736 |
1737 | mainForm.listview.addItem({
1738 | text = data
1739 | });
1740 | }
1741 |
1742 | if(items["ITEMS_PERPAGE"]){
1743 | mainForm.comboItemsPerpage.text = tostring(items["ITEMS_PERPAGE"])
1744 | }
1745 | if(items["PAGES"]){
1746 | mainForm.comboCurrPage.clear();
1747 | for(i=1;items["PAGES"];1){
1748 | mainForm.comboCurrPage.add(tostring(i))
1749 | }
1750 | }
1751 | if(items["CURR_PAGE"]!=null){
1752 | mainForm.comboCurrPage.text = tostring(items["CURR_PAGE"]+1)
1753 | }
1754 | }
1755 | /*}}*/
1756 |
1757 | initTreeviewFilters = function(model){
1758 |
1759 | var filter_fields = model.filter_fields
1760 | if(#filter_fields>0){
1761 | mainForm.treeview.clear();
1762 | }
1763 |
1764 | var item = {text = "显示全部数据"}
1765 | var hItem = mainForm.treeview.insertItem(item)
1766 |
1767 | console.log("filter_fields:")
1768 | console.varDump(filter_fields)
1769 |
1770 | for(i=1;#filter_fields;1){
1771 | var item = {}
1772 | /*{
1773 | text = "按区划分";
1774 | {
1775 | { text = "芙蓉区"; filter_field ="furong" };
1776 | { text = "天心区"; filter_field ="tianxin" };
1777 | { text = "岳麓区" };
1778 | { text = "开福区" };
1779 | { text = "雨花区" };
1780 | { text = "未分区" };
1781 | }
1782 | }*/
1783 |
1784 |
1785 |
1786 | var field = filter_fields[i]
1787 | var caption = model.headers[field]
1788 |
1789 | item["text"] = string.format("按%s过滤", caption);
1790 | item["field"] = ""
1791 | //query["filter_field"] = field
1792 |
1793 | var sql = string.format("SELECT DISTINCT %s FROM [%s]", field, model.tablename)
1794 | var items = model.getTable(sql)
1795 |
1796 | var data = {}
1797 | for(i=1;#items;1){
1798 | var value = items[i][field];
1799 | if(value == "" or value == null){
1800 | table.push(data, {text = "空值";filter_field=field})
1801 | }else {
1802 | table.push(data, {text = value; filter_field=field})
1803 | }
1804 | }
1805 |
1806 | table.push(item, data)
1807 |
1808 | var hItem = mainForm.treeview.insertItem(item)
1809 |
1810 | }
1811 |
1812 | mainForm.treeview.expandAll()
1813 | }
1814 |
1815 |
1816 | menu_edit_item = function(){
1817 | var iRow = mainForm.listview.getSelection(); //选中的行
1818 | if(!iRow){
1819 | mainForm.msgbox("请选中一项再操作");
1820 | return
1821 | }else {
1822 | var id = mainForm.listview.getItemText(iRow, 1)
1823 | var mform = sqlitemodel.modelForm(modGoods, mainForm, id);
1824 | mform.doModal(mainForm);
1825 | load_model_data(modGoods);
1826 | }
1827 | }
1828 |
1829 | menu_delete_item = function(){
1830 |
1831 | var iRow = mainForm.listview.getSelection();
1832 |
1833 | if(!iRow){
1834 | return
1835 | }
1836 |
1837 | var query = {}
1838 | var model = mainForm.model;
1839 | var display_fields = model.display_fields;
1840 | for(i=1;#display_fields;1){
1841 | k = display_fields[i]
1842 | query[k] = mainForm.listview.getItemText(iRow, i)
1843 | }
1844 |
1845 | var confirmed = false; //默认不删除
1846 | if(config.settings.confirm_delete){
1847 | confirmed = mainForm.msgboxTest(string.format("确认删除%s数据(id=%s)吗?", mainForm.model.label,query["id"])); //看用户选择
1848 | }else {
1849 | confirmed = true; //无需确认
1850 | }
1851 |
1852 | if(confirmed){
1853 | model.delete(query);
1854 | initTreeviewFilters(model);
1855 | load_model_data(model);
1856 | }
1857 | }
1858 |
1859 |
1860 |
1861 | mainForm.treeview.onnotify = function(id,code,ptr){
1862 | if(code = 0xFFFFFFFE/*_NM_CLICK*/){
1863 | //单击
1864 | var x,y = mouse.getPos()
1865 | var hItem,tvht = mainForm.treeview.hitTest(x,y,true);
1866 |
1867 | if(!hItem){
1868 | return
1869 | }
1870 |
1871 | mainForm.treeview.setSelected(hItem);
1872 | mainForm.treeview.expandAll()
1873 |
1874 | var hitem = mainForm.treeview.getSelection()
1875 | //mainForm.text = mainForm.treeview.getItemData(hitem);
1876 | var data = mainForm.treeview.getItemData(hitem);
1877 |
1878 | var filter_field = data["filter_field"];
1879 | //if(filter_field == null){ //点中了根节点,应该返回全部数据
1880 | // return
1881 | //}
1882 |
1883 | var keyword = "";
1884 |
1885 | if(data == null or #data>0){
1886 | //未选中节点, 或者选中节点有子节点(根节点)
1887 | keyword = ""
1888 | //return
1889 | }else {
1890 | //没有子节点的节点,如果是根节点, 那么也是在这里处理, 但是没有filter_field数据, 所以后面的filter
1891 | // 会因为没有filter_field数据, 而返回全部数据, 忽略keyword
1892 | keyword = data["text"];
1893 | if(string.indexOf(keyword, "|")){
1894 | keyword = string.split(keyword, "<|>")[1]
1895 | }
1896 | //mainForm.text = data["text"] ++ " 单位";
1897 | }
1898 |
1899 | var query = {};
1900 | if(filter_field != null){
1901 | query[filter_field] = keyword; //filter, field = value, field_lt = value
1902 | }
1903 |
1904 | var items_perpage = tonumber(mainForm.comboItemsPerpage.text);
1905 | query["ITEMS_PERPAGE"] = items_perpage
1906 | query["QUERY_MODE"] = "FILTER";
1907 |
1908 | CURR_QUERY = query;
1909 | log(table.tostring(CURR_QUERY));
1910 |
1911 |
1912 | var model = modGoods;
1913 | CURR_MODEL = model;
1914 |
1915 | var items = model.filter(query)
1916 | reset_listview(model, items);
1917 | //initTreeviewFilters(CURR_MODEL)
1918 |
1919 | }
1920 | }
1921 |
1922 | change_model_field = function(model, field, value){
1923 | var ids = {}
1924 | for(i=1;mainForm.listview.count;1){
1925 | if(mainForm.listview.getSelected(i)){
1926 | table.push(ids, mainForm.listview.getItemText(i, 1));
1927 | }
1928 | }
1929 |
1930 | var str_ids = string.join(table.map(ids,function(v,k,result){
1931 | return tostring(v)
1932 | }), ",")
1933 |
1934 | //console.log(str_ids, value)
1935 |
1936 | var sql = "UPDATE ["+ model.tablename +"] SET "+ field +"=@value where id in (" + str_ids + ")";
1937 | var query = {}
1938 | query["value"] = value;
1939 | //console.log("sql:"+sql);
1940 | var updated = false;
1941 | try{
1942 | var command = db.prepare(sql)
1943 | command.bind.parameterByName(value, "@value") //给@value 绑定数据 value
1944 | var ret = command.step()
1945 | command.finalize();
1946 |
1947 | //db.exec(sql, query);
1948 | //console.log("updated success!")
1949 | updated = true;
1950 | //return true; //这里try语句里的 return true 并不能真的返回值, 函数最后返回的是null
1951 | }
1952 | catch(e){
1953 | //console.varDump(e);
1954 | //console.log(tostring(e))
1955 | //return false;//这里try的catch语句里的 return false却可以真正使函数返回.函数最后返回的是false
1956 | updated = false;
1957 | }
1958 |
1959 | load_model_data(model)
1960 |
1961 | }
1962 |
1963 | mainForm.listview.wndproc = function(hwnd,message,wParam,lParam){
1964 | //无返回值则继续调用默认回调函数
1965 | select( message ) {
1966 | case 0x101/*_WM_KEYUP*/ {
1967 | if(wParam == 0x2E/*_VK_DELETE*/ ){
1968 | var iRow = mainForm.listview.getSelection();
1969 | menu_delete_item()
1970 |
1971 | if(mainForm.listview.count>0){
1972 | if(mainForm.listview.count >= iRow){
1973 | mainForm.listview.setSelected(iRow)
1974 | }else {
1975 | mainForm.listview.setSelected(mainForm.listview.count)
1976 | }
1977 | }
1978 | }
1979 | }
1980 | /**
1981 | case 0x202/*_WM_LBUTTONUP*/{
1982 | var listview = ::NMLISTVIEW()
1983 | raw.convert(topointer(lParam), listview);
1984 |
1985 | //得到选中的列
1986 | column = listview.iSubItem;
1987 | hdr = listview.hdr;
1988 |
1989 | console.varDump(hdr);
1990 |
1991 |
1992 | //console.log("column",listview.iItem, listview.iSubItem) //, LOWORD(wParam))
1993 |
1994 | if(hdr.code == 0xFFFFFEBA/*HDN_ENDTRACKW*/ || hdr.code == 0xFFFFFECE/*HDN_ENDTRACKA*/ ){
1995 | // console.varDump(hdr);
1996 | console.log("column",listview.iItem, listview.iSubItem) //, LOWORD(wParam))
1997 | return true;
1998 | }
1999 | }
2000 | **/
2001 | case 0x4e/*_WM_NOTIFY*/{
2002 | //这个片段虽然是mainForm中的,但是居然会影响每个winform中的listview,
2003 | //导致点击左键,程序就崩溃
2004 | //原因找到了, 不能直接使用lv = ::NMLISTVIEW(); 使用了就崩溃了。
2005 | var lv = win.ui.ctrl.listview.NMLISTVIEW();
2006 | raw.convert(topointer(lParam), lv);
2007 | //console.varDump(lv)
2008 |
2009 | //得到选中的列
2010 | column = lv.iSubItem;
2011 | hdr = lv.hdr
2012 |
2013 |
2014 |
2015 | //console.varDump(hdr)
2016 |
2017 | //console.log("column",listview.iItem, listview.iSubItem) //, LOWORD(wParam))
2018 |
2019 | if(hdr.code == 0xFFFFFEBA/*HDN_ENDTRACKW*/ || hdr.code == 0xFFFFFECE/*HDN_ENDTRACKA*/ ){
2020 | console.varDump(lv);
2021 | console.varDump(hdr)
2022 | console.log("column",lv.iItem, lv.iSubItem , LOWORD(wParam), HIWORD(wParam))
2023 | var lvcol = mainForm.listview.getColumn(,lv.iItem)
2024 | console.varDump(lvcol)
2025 |
2026 | console.log("lvcol.cx",lvcol.cx)
2027 |
2028 | return false;
2029 | }
2030 | //return true;
2031 | }
2032 |
2033 | }
2034 |
2035 | }
2036 |
2037 | mainForm.listview.onnotify = function(id,code,ptr){
2038 |
2039 | select(code) {
2040 |
2041 | /**
2042 | case 0xFFFFFFFE/*_NM_CLICK*/ {
2043 | mainForm.msgbox("单击")
2044 | }
2045 |
2046 | case 0xFFFFFFF4 { // 调整列宽
2047 | lv = raw.convert( ptr, win.ui.ctrl.listview.NMLISTVIEW() );
2048 | console.varDump(lv)
2049 | console.varDump(lv.hdr)
2050 | console.varDump(lv.ptAction)
2051 | return true;
2052 | }
2053 | **/
2054 | case 0xFFFFFFFD/*_NM_DBLCLK*/ {
2055 | var x,y = mouse.getPos()
2056 | var iRow, iCol = mainForm.listview.hitTest(x,y,true);
2057 | if(iRow){
2058 | mainForm.listview.setSelected(iRow);//利于后面的getSelection();
2059 | mainForm.lastListviewSelected = iRow;
2060 | menu_edit_item()
2061 | }
2062 | }
2063 | case 0xFFFFFFFB/*_NM_RCLICK*/ {
2064 | var x,y = mouse.getPos()
2065 | var iRow, iCol = mainForm.listview.hitTest(x,y,true);
2066 | if(iRow){
2067 | mainForm.listview.setSelected(iRow);//利于后面的getSelection();
2068 | mainForm.lastListviewSelected = iRow;
2069 | }
2070 |
2071 | var menu = win.ui.popmenu(mainForm)
2072 |
2073 | menu.add("修改",
2074 | function(){
2075 | menu_edit_item()
2076 | }
2077 | );
2078 |
2079 | var model = CURR_MODEL;
2080 | var filter_fields = model.filter_fields
2081 |
2082 | var filter_menus = {}
2083 |
2084 |
2085 |
2086 | for(i=1;#filter_fields;1){
2087 | var item = {}
2088 |
2089 | var k = filter_fields[i]
2090 | var caption = model.headers[k]
2091 |
2092 | table.push(item, string.format("更改选中项的%s为", caption))
2093 | var sql = string.format("select distinct %s from %s", k, model.tablename)
2094 | var items = model.getTable(sql)
2095 |
2096 | //console.varDump(items)
2097 |
2098 | var data = {}
2099 | for(i=1;#items;1){
2100 | //console.log("items[i][k]", items[i][k]);
2101 | var x = {
2102 | tostring(items[i][k]); //tostring() 避免 USTRING ERROR
2103 | function(id){
2104 | //mainForm.msgbox(tostring(items[i][k]))
2105 | change_model_field(model, k, items[i][k]);
2106 | }
2107 | }
2108 | //console.log(" console.varDump(x)")
2109 | //console.varDump(x)
2110 | table.push(data, x)
2111 | }
2112 |
2113 | if(#data){
2114 | //console.log("console.varDump(data)")
2115 | //console.varDump(data)
2116 | table.push(item, data)
2117 | }else {
2118 | continue;
2119 | }
2120 |
2121 | //console.log("continue;")
2122 |
2123 | //console.varDump(item)
2124 | table.push(filter_menus, item)
2125 | }
2126 |
2127 | //console.varDump(filter_menus)
2128 | if(#filter_menus){
2129 | menu.addTable(
2130 | //{filter_menus}
2131 | filter_menus
2132 | )
2133 | }
2134 |
2135 | menu.add({});
2136 |
2137 | menu.add("全选 Ctrl+A",
2138 | function(){
2139 | for(i=1;mainForm.listview.count;1){
2140 | mainForm.listview.setSelected(i)
2141 | }
2142 | }
2143 | );
2144 |
2145 | menu.add("反选",
2146 | function(){
2147 | for(i=1;mainForm.listview.count;1){
2148 | var status = mainForm.listview.getSelected(i);
2149 | mainForm.listview.setSelected(i,!status);
2150 | }
2151 | }
2152 | );
2153 |
2154 | menu.add("采购选中商品",
2155 | function(){
2156 | var items = {}
2157 | //console.log(mainForm.listview.columnCount)
2158 | var ids = {}
2159 | for(i=1;mainForm.listview.count;1){
2160 | if(mainForm.listview.getSelected(i)){
2161 | table.push(ids, mainForm.listview.getItemText(i,1)); //每一行的第1列就是goods_id
2162 | }
2163 | }
2164 | if(#ids){
2165 | var TABLE_NAME = model.tablename;
2166 | var sql = "SELECT * FROM [" ++ TABLE_NAME ++ "] where id in (" + string.join(ids, ", ") + ")"
2167 | items = model.getTable(sql);
2168 | menu_goods_purchase(items);
2169 | }
2170 | }
2171 | );
2172 |
2173 |
2174 |
2175 | menu.add("导出选中项数据",
2176 | function(){
2177 | var items = {}
2178 | //console.log(mainForm.listview.columnCount)
2179 | var ids = {}
2180 | for(i=1;mainForm.listview.count;1){
2181 |
2182 | if(mainForm.listview.getSelected(i)){
2183 | table.push(ids, mainForm.listview.getItemText(i,1)); //每一行的第1列就是id
2184 | }
2185 | }
2186 | if(#ids){
2187 | var TABLE_NAME = model.tablename;
2188 | var sql = "SELECT * FROM [" ++ TABLE_NAME ++ "] where id in (" + string.join(ids, ", ") + ")"
2189 | items = model.getTable(sql);
2190 | export_model(model, items);
2191 | }
2192 |
2193 | }
2194 | );
2195 |
2196 | menu.add({});
2197 |
2198 | menu.add("删除",
2199 | function(){
2200 | menu_delete_item();
2201 | }
2202 | );
2203 | menu.popup(x,y,true);
2204 | }
2205 |
2206 |
2207 | //case _lvn_
2208 | /*
2209 | case _hdn_
2210 | HD_NOTIFY* pHDN = (HD_NOTIFY*)lParam;
2211 | switch(((NMHDR*)lParam)->code)
2212 | {
2213 | HDN_ENDTRACKW
2214 |
2215 | case HDN_BEGINTRACKW:
2216 | case HDN_BEGINTRACKA:
2217 | case HDN_DIVIDERDBLCLICKA:
2218 | case HDN_DIVIDERDBLCLICKW:
2219 | for(int i=0; iiItem == m_vFrozenCols[i]) //如果拖动的列是设定固定列宽的列之一
2222 | {
2223 | *pResult = TRUE;
2224 | return TRUE;
2225 | }
2226 | }
2227 | }
2228 | */
2229 |
2230 | case !=0 {
2231 | }
2232 | else {
2233 | }
2234 | }
2235 | }
2236 |
2237 | menu_goods_add = function(){
2238 | var data = {};
2239 | var field_names = sqlitemodel.Model.get_field_names(modGoods.sql,true); //要包含id
2240 | //
2241 | //console.varDump(field_names)
2242 | //
2243 |
2244 | //for(i=1;#field_names;1){
2245 | // console.varDump(field_names[i])
2246 | //}
2247 |
2248 |
2249 |
2250 | var iRow = mainForm.listview.getSelection(); //选中的行
2251 | if(!iRow){
2252 | mainForm.msgbox("请选中一项再操作")
2253 | return
2254 | form_caption = "添加数据"
2255 | btn_text = "添加"
2256 | }else {
2257 | //var id = mainForm.listview.getItemText(3, 1)//第三行, 第一列的数据
2258 | var id = mainForm.listview.getItemText(iRow, 1)
2259 | var query = {}
2260 | query["id"] = id
2261 | data = modGoods.get(query)
2262 |
2263 | form_caption = "修改数据"
2264 | btn_text = "保存"
2265 |
2266 | }
2267 |
2268 | var frmChild = mainForm.loadForm("\dlg\model_form.aardio");
2269 |
2270 | var frmChild_width = 0
2271 | var COLS_PADDING = 5 //列与列之间的间隔, 每列由一个标签和一个文本框组成
2272 | var ROWS_PER_COL = 15;
2273 | var LABEL_WIDTH = 84;
2274 | var EDIT_WIDTH = 320; // 420;
2275 |
2276 | var ROW_WIDTH = EDIT_WIDTH + COLS_PADDING*2;
2277 |
2278 | var LABEL_HEIGHT = 20;
2279 | var EDIT_HEIGHT = 20;
2280 |
2281 | var ROW_HEIGHT = LABEL_HEIGHT + EDIT_HEIGHT + 5;
2282 |
2283 | frmChild.width = COLS_PADDING*2 + (math.floor((#field_names-1) / ROWS_PER_COL)+1) * ROW_WIDTH;
2284 |
2285 | for(i=1;#field_names;1){
2286 |
2287 | var k = field_names[i]["name"]
2288 | var label = field_names[i]["label"]
2289 | var value = ""
2290 |
2291 | if(data[k]!=null){
2292 | value = tostring(data[k])
2293 | }
2294 |
2295 | //
2296 | //log(k++":"++label)
2297 | //
2298 |
2299 | var ctrl = frmChild["edit_"+k]
2300 | if(ctrl!=null){
2301 | ctrl.text = value
2302 | }else {
2303 |
2304 | var staticLeft = COLS_PADDING + math.floor((i - 1) / ROWS_PER_COL) * ROW_WIDTH; //每一列的left是相同的。
2305 | var staticTop = 13 + 22 * (i - (math.floor((i - 1) / ROWS_PER_COL) * ROWS_PER_COL + 1));
2306 | //console.log(staticLeft,", ", staticTop)
2307 |
2308 |
2309 | frmChild.add(
2310 | ["static_" + k ] = {
2311 | //border=1;
2312 | cls="static"; text=label; notify=1; dl=1;dt=1;font=LOGFONT( name='宋体' );bottom=staticTop + LABEL_HEIGHT;right=staticLeft+LABEL_WIDTH;left=staticLeft;top=staticTop;z=1;
2313 | };
2314 | )
2315 |
2316 | if(k=="id" or k=="taxno" or k=="created" or k=="updated"){
2317 | frmChild.add(
2318 | ["edit_" + k ] = {
2319 | cls="edit"; text=value; disabled=1;notify=1; dl=1;dt=1;font=LOGFONT(name='Consolas');bottom=staticTop+EDIT_HEIGHT;right=staticLeft + EDIT_WIDTH;left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
2320 | };
2321 | )
2322 | }else {
2323 | frmChild.add(
2324 | ["edit_" + k ] = {
2325 | cls="edit"; text=value; tabstop=i; notify=1; dl=1;dt=1;font=LOGFONT(name='Consolas');bottom=staticTop+EDIT_HEIGHT;right=staticLeft + EDIT_WIDTH;left=staticLeft+LABEL_WIDTH + COLS_PADDING;top=staticTop;z=1;
2326 | };
2327 | )
2328 | }
2329 |
2330 |
2331 |
2332 |
2333 | //
2334 | //log("ctrl edit_" + k + " 不存在!创建一个")
2335 | //
2336 | }
2337 | }
2338 |
2339 | frmChild.text = form_caption
2340 | frmChild.button.text = btn_text
2341 |
2342 | frmChild.show();
2343 | }
2344 |
2345 |
2346 |
2347 | menu_goods_purchase = function(items){
2348 |
2349 | var frmChild,wb = mainForm.loadForm("\dlg\goods_purchase.aardio");
2350 |
2351 | var user_define_fields = {"id"; "goods_id"; "name"; "specs"; "unit"; };
2352 | frmChild.user_define_fields = user_define_fields;
2353 |
2354 | for(i=1;#items;1){
2355 | items[i]["goods_id"] = items[i]["id"];
2356 | items[i]["id"] = "";
2357 | }
2358 |
2359 | if(items and #items>0){
2360 | frmChild.reset_listview(modGoods, items, user_define_fields)
2361 | }
2362 | frmChild.doModal();
2363 | }
2364 |
2365 |
2366 | menu_goods_purchase_history = function(items){
2367 |
2368 | var frmChild,wb = mainForm.loadForm("\dlg\goods_purchase_history.aardio");
2369 | frmChild.doModal();
2370 | }
2371 |
2372 |
2373 | menu_goods_sell = function(items){
2374 |
2375 | var frmChild, wb = mainForm.loadForm("\dlg\goods_sell.aardio");
2376 | if(items and #items>0){
2377 | var user_define_fields = {"id"; "name"; "specs"; "unit"}
2378 | frmChild.reset_listview(modGoods, items, user_define_fields)
2379 | }
2380 | frmChild.doModal();
2381 |
2382 | }
2383 |
2384 |
2385 |
2386 | mainForm.button.oncommand = function(id,event){
2387 | var query={}
2388 | var items_perpage = tonumber(mainForm.comboItemsPerpage.text);
2389 | query["ITEMS_PERPAGE"] = items_perpage;
2390 | query["keyword"] = string.trim(mainForm.edit.text);
2391 | CURR_QUERY = query;
2392 | CURR_MODEL = modGoods;
2393 | load_model_data(CURR_MODEL, CURR_QUERY);
2394 | //mainForm.listview.setSelected(1);
2395 | //mainForm.listview.setFocus();
2396 | }
2397 |
2398 | mainForm.btnRefresh.oncommand = function(id,event){
2399 | load_model_data(mainForm.model);
2400 | }
2401 |
2402 | restoreListviewPos = function(){
2403 | if(mainForm.lastListviewSelected){
2404 | mainForm.listview.setFocus();
2405 | mainForm.listview.setSelected(mainForm.lastListviewSelected);
2406 | if(mainForm.lastListviewSelected+825){
2408 | mainForm.listview.ensureVisible(mainForm.lastListviewSelected+8);
2409 | }else {
2410 | mainForm.listview.ensureVisible(mainForm.lastListviewSelected);
2411 | }
2412 | }else {
2413 | mainForm.listview.ensureVisible(mainForm.listview.count);
2414 | }
2415 | }
2416 | }
2417 |
2418 | mainForm.button7.oncommand = function(id,event){
2419 |
2420 |
2421 | var frmChild = mainForm.loadForm("\dlg\select_fields.aardio");
2422 | //var field_names = sqlitemodel.Model.get_field_names(modGoods.sql, true)
2423 | var field_names = modGoods.field_names;
2424 | for(i=1;#field_names;1){
2425 | frmChild.checklist.addItem(field_names[i]["label"])
2426 | }
2427 |
2428 | var reservedTopN = 7
2429 | for(i=1;reservedTopN;1){
2430 | frmChild.listbox.add(frmChild.checklist.getItemText(i));
2431 |
2432 | }
2433 | for(i=1;reservedTopN;1){
2434 | frmChild.checklist.delItem(reservedTopN+1-i);
2435 | }
2436 |
2437 |
2438 | selected_labels = frmChild.doModal(mainForm);
2439 |
2440 | var selected_fields = {}
2441 | for(i=1;#selected_labels;1){
2442 | for(j=1;#field_names;1){
2443 | if(selected_labels[i] == field_names[j]["label"]){
2444 | table.push(selected_fields, field_names[j]["name"])
2445 | }
2446 | }
2447 | }
2448 |
2449 | //修改全局变量
2450 | if(#selected_fields){
2451 | CURR_QUERY = {};
2452 |
2453 | modGoods.display_fields = selected_fields;
2454 | CURR_MODEL = modGoods;
2455 |
2456 | load_model_data(CURR_MODEL, CURR_QUERY);
2457 | }
2458 |
2459 |
2460 | }
2461 |
2462 | config_setting = function(id,event){
2463 |
2464 |
2465 | var frmChild = mainForm.loadForm("\dlg\settings.aardio");
2466 |
2467 | var x = frmChild.doModal(mainForm);
2468 |
2469 |
2470 | }
2471 |
2472 |
2473 | init=function(){
2474 | //初始化
2475 | var model = modGoods;
2476 | var headers = {};
2477 | var header_cols = {};
2478 | var required_cols = {};
2479 |
2480 | for(k,v in model.field_names){
2481 | //field_names有id
2482 | headers[v.name]=v.label
2483 | }
2484 |
2485 | headers["id"]="ID"
2486 |
2487 | //数据导入用, 根据optional_headers(即数据库的字段)重新初始化header_cols
2488 | for(k,v in headers){
2489 | //标题位于第几列(第1列是A列,第2列是B列...), 初始化默认设置为0列(默认不正常,正常的列应该从1开始).
2490 | header_cols[k]=0;
2491 | }
2492 | header_cols["id"]=null; //导入的时候剔除 id 字段
2493 | required_cols["id"]=null; //导入的时候剔除 id 字段
2494 |
2495 |
2496 | win.ui.statusbar( mainForm ).addItem("公司:", 100/*宽度*/)
2497 |
2498 | mainForm.statusbar.addItem("数据库:"+io.fullpath(dbpath), 500);
2499 | mainForm.text = mainForm.text ++ " - 商品管理"
2500 |
2501 | /*
2502 | SELECT column-list
2503 | FROM table_name
2504 | WHERE [ conditions ]
2505 | GROUP BY column1, column2....columnN
2506 | ORDER BY column1, column2....columnN
2507 | */
2508 |
2509 | for(i=1;#model.display_fields;1){
2510 | var caption = headers[model.display_fields[i]]
2511 | mainForm.listview.insertColumn(caption, 60);
2512 | }
2513 |
2514 |
2515 | mainForm.listview.setColumn({cx=40},1)
2516 | mainForm.listview.setColumn({cx=160},2)
2517 | mainForm.listview.setColumn({cx=320},3)
2518 | mainForm.listview.setColumn({cx=80},4)
2519 | mainForm.listview.setColumn({cx=140},5)
2520 | mainForm.listview.setColumn({cx=140},6)
2521 | mainForm.listview.setColumn({cx=140},7)
2522 | mainForm.listview.setColumn({cx=140},8)
2523 | mainForm.listview.setColumn({cx=140},9)
2524 |
2525 |
2526 | initTreeviewFilters(model);
2527 | load_model_data(model);
2528 |
2529 | mainForm.edit.setFocus();
2530 |
2531 | }
2532 |
2533 |
2534 | mainForm.btnNext.oncommand = function(id,event){
2535 |
2536 | var model = CURR_MODEL;
2537 | var query = CURR_QUERY;
2538 |
2539 | var curr_page = mainForm.comboCurrPage.text
2540 | var pages = table.map(mainForm.comboCurrPage.items,function(v,k,result){
2541 | return tonumber(v);
2542 | })
2543 | var min, max = table.range(pages)
2544 | var next_page = tonumber(curr_page) + 1;
2545 | if(next_page>max){
2546 | next_page = max
2547 | }
2548 |
2549 | query["CURR_PAGE"] = next_page;
2550 | var items = {}
2551 | select(query["QUERY_MODE"]) {
2552 | case "FILTER" {
2553 | items = model.filter(query);
2554 | }
2555 | case "SEARCH" {
2556 | items = model.search(query);
2557 | }
2558 | else {
2559 |
2560 | }
2561 | }
2562 |
2563 | reset_listview(model, items)
2564 |
2565 | log(table.tostring(query))
2566 | }
2567 |
2568 | mainForm.btnPrev.oncommand = function(id,event){
2569 | var curr_page = mainForm.comboCurrPage.text
2570 | var prev_page = tonumber(curr_page) - 1;
2571 | if(prev_page<0){
2572 | prev_page = 0
2573 | }
2574 | var model = CURR_MODEL;
2575 | var query = CURR_QUERY;
2576 | query["CURR_PAGE"] = prev_page
2577 | var items = {}
2578 | select(query["QUERY_MODE"]) {
2579 | case "FILTER" {
2580 | items = model.filter(query);
2581 | }
2582 | case "SEARCH" {
2583 | items = model.search(query);
2584 | }
2585 | else {
2586 |
2587 | }
2588 | }
2589 |
2590 | reset_listview(model, items)
2591 |
2592 | log(table.tostring(query))
2593 | }
2594 |
2595 | mainForm.btnGotoNPage.oncommand = function(id,event){
2596 | var curr_page = mainForm.comboCurrPage.text
2597 | var model = CURR_MODEL;
2598 | var query = CURR_QUERY;
2599 | query["CURR_PAGE"] = tonumber(curr_page)
2600 | var items = {}
2601 | select(query["QUERY_MODE"]) {
2602 | case "FILTER" {
2603 | items = model.filter(query);
2604 | }
2605 | case "SEARCH" {
2606 | items = model.search(query);
2607 | }
2608 | else {
2609 |
2610 | }
2611 | }
2612 |
2613 | reset_listview(modGoods, items)
2614 |
2615 | log(table.tostring(query))
2616 | }
2617 |
2618 | mainForm.onMouseClick = function(wParam,lParam){
2619 | var x,y = win.getMessagePos(lParam);
2620 | mainForm.comboItemsPerpage.setFocus(false);
2621 | mainForm.edit.setFocus();
2622 | }
2623 |
2624 | mainForm.comboItemsPerpage.oncommand = function(id,event){
2625 | if(event = 4/*_CBN_KILLFOCUS*/){
2626 | var n = LAST_ITEMS_PERPAGE;
2627 |
2628 | try{
2629 | n = tonumber(mainForm.comboItemsPerpage.text)
2630 | if(n != LAST_ITEMS_PERPAGE){
2631 | var model = CURR_MODEL;
2632 | var query = CURR_QUERY;
2633 |
2634 | query["CURR_PAGE"] = 1;
2635 | query["ITEMS_PERPAGE"] = n;
2636 | var items = {}
2637 | select(query["QUERY_MODE"]) {
2638 | case "FILTER" {
2639 | items = model.filter(query);
2640 | }
2641 | case "SEARCH" {
2642 | items = model.search(query);
2643 | }
2644 | else {
2645 |
2646 | }
2647 | }
2648 |
2649 | reset_listview(model, items)
2650 |
2651 | log(table.tostring(query))
2652 | LAST_ITEMS_PERPAGE = n;
2653 | }
2654 | }
2655 | catch(e){
2656 | log(tostring(e))
2657 | }
2658 |
2659 | }
2660 | }
2661 |
2662 | mainForm.edit.translateAccelerator = function( msg ){
2663 | //edit搜索框回车键,相当于点击“搜索”按钮
2664 | if( msg.wParam == 0xD/*_VK_ENTER*/ ){
2665 | if( msg.message == 0x101/*_WM_KEYUP*/ ){
2666 | mainForm.button.oncommand()
2667 | }
2668 | return true;
2669 | }
2670 | }
2671 |
2672 | mainForm.edit.oncommand = function(id,event){
2673 | if(event=0x300/*_EN_CHANGE*/){
2674 | mainForm.button.oncommand();
2675 | }
2676 | }
2677 |
2678 | init()
2679 |
2680 | mainForm.enableDpiScaling();
2681 | //mainForm.show(3/*_SW_MAXIMIZE*/);
2682 | mainForm.show();
2683 | return win.loopMessage();
--------------------------------------------------------------------------------
/res/models/company.sql.aardio:
--------------------------------------------------------------------------------
1 | CREATE TABLE "company" (
2 | "id" INTEGER NOT NULL PRIMARY KEY,
3 | "name" VARCHAR(32) NOT NULL, /*名称*/
4 | "nsrsbh" VARCHAR(16), /*纳税人识别号*/
5 | "cate" VARCHAR(16), /*分类*/
6 | "created_at" DATE NOT NULL, /*创建时间*/
7 | "updated_at" DATE NOT NULL /*更新时间*/
8 | );
9 |
--------------------------------------------------------------------------------
/res/models/goods_category.sql.aardio:
--------------------------------------------------------------------------------
1 | CREATE TABLE "goods_category" (
2 | "id" INTEGER NOT NULL PRIMARY KEY,
3 | "name" VARCHAR(32) NOT NULL, /*分类名称*/
4 | "parent" INTEGER , /*上级分类*/
5 | "pos" INTEGER DEFAULT 0, /*排序*/
6 | "created_at" DATE NOT NULL, /*创建时间*/
7 | "updated_at" DATE NOT NULL /*更新时间*/
8 | );
9 |
--------------------------------------------------------------------------------
/res/models/store.sql.aardio:
--------------------------------------------------------------------------------
1 | CREATE TABLE "store" (
2 | "id" INTEGER NOT NULL PRIMARY KEY,
3 | "name" VARCHAR(32) NOT NULL, /*名称*/
4 | "code" VARCHAR(32), /*代码*/
5 | "title" VARCHAR(32), /*联系人*/
6 | "cellphone" VARCHAR(32), /*手机号码*/
7 | "tellphone" VARCHAR(32), /*电话号码*/
8 | "position" VARCHAR(16), /*位置*/
9 | "cate" VARCHAR(16), /*分类:库房,供应商,客户*/
10 | "created_at" DATE NOT NULL, /*创建时间*/
11 | "updated_at" DATE NOT NULL /*更新时间*/
12 | );
13 |
--------------------------------------------------------------------------------
/res/toolbar.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/encorehu/sqlitemodel/5c418a9381c0d5104ef2d6a26d03d12211224ec7/res/toolbar.gif
--------------------------------------------------------------------------------