owl-cli 6.102.0 → 6.104.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/.eslintrc.json +2 -2
  2. package/.vscode/launch.json +22 -22
  3. package/.vscode/settings.json +2 -2
  4. package/bin/createTables.js +94 -94
  5. package/bin/deploy.js +66 -66
  6. package/bin/dsl.js +223 -223
  7. package/bin/genEvents.js +188 -188
  8. package/bin/owl-init.js +50 -50
  9. package/bin/owl.js +295 -295
  10. package/bin/owlconfig.json +16 -16
  11. package/bin/table_mysql.js +189 -189
  12. package/bin/undeploy.js +56 -56
  13. package/defaultTemplate/api/build.xml +94 -94
  14. package/defaultTemplate/api/src/about.html +12 -12
  15. package/defaultTemplate/api/src/about.jsx +11 -11
  16. package/defaultTemplate/api/src/handlers/aggs.jsx +161 -161
  17. package/defaultTemplate/api/src/handlers/batchImport.jsx +68 -68
  18. package/defaultTemplate/api/src/handlers/delete.jsx +67 -67
  19. package/defaultTemplate/api/src/handlers/export.jsx +117 -117
  20. package/defaultTemplate/api/src/handlers/exportDoc.jsx +27 -27
  21. package/defaultTemplate/api/src/handlers/exportEx.jsx +77 -77
  22. package/defaultTemplate/api/src/handlers/exportWithTemplates.jsx +50 -50
  23. package/defaultTemplate/api/src/handlers/exportZip.jsx +26 -26
  24. package/defaultTemplate/api/src/handlers/get.jsx +41 -41
  25. package/defaultTemplate/api/src/handlers/getChildren.jsx +97 -97
  26. package/defaultTemplate/api/src/handlers/getExportTaskInfo.jsx +34 -34
  27. package/defaultTemplate/api/src/handlers/getSpec.jsx +40 -40
  28. package/defaultTemplate/api/src/handlers/include/checklogin.jsx +751 -751
  29. package/defaultTemplate/api/src/handlers/include/diff.jsx +315 -315
  30. package/defaultTemplate/api/src/handlers/include/util.jsx +60 -60
  31. package/defaultTemplate/api/src/handlers/list.jsx +239 -239
  32. package/defaultTemplate/api/src/handlers/reIndex.jsx +63 -63
  33. package/defaultTemplate/api/src/handlers/recovery.jsx +53 -53
  34. package/defaultTemplate/api/src/handlers/save.jsx +125 -110
  35. package/defaultTemplate/api/src/handlers/upload.jsx +72 -72
  36. package/defaultTemplate/api/src/init/indexConfigs/changeMapping.json +14 -14
  37. package/defaultTemplate/api/src/init/indexConfigs/createAliase.json +10 -10
  38. package/defaultTemplate/api/src/init/indexConfigs/createIndex.json +55 -55
  39. package/defaultTemplate/api/src/init/indexConfigs/rebuildIndex.sh +27 -27
  40. package/defaultTemplate/api/src/init/indexConfigs/reindex.json +10 -10
  41. package/defaultTemplate/api/src/init/init.jsx +25 -25
  42. package/defaultTemplate/api/src/meta.json +10 -10
  43. package/defaultTemplate/api/src/services/dblayer.jsx +251 -251
  44. package/defaultTemplate/api/src/services/modelService.jsx +1163 -1163
  45. package/defaultTemplate/api/src/services/sqlstring.jsx +240 -240
  46. package/defaultTemplate/api/src/tasks/export.jsx +355 -355
  47. package/defaultTemplate/api/src/tasks/exportDoc.jsx +87 -87
  48. package/defaultTemplate/api/src/tasks/exportExTask.jsx +325 -325
  49. package/defaultTemplate/api/src/tasks/exportWithTemplateTask.jsx +117 -117
  50. package/defaultTemplate/api/src/tasks/exportZip.jsx +49 -49
  51. package/examples/buildProperties/build.properties +2 -2
  52. package/examples/gitignore/gitignore_example.txt +1 -1
  53. package/examples/models/product.json +52 -52
  54. package/examples/models/shop.json +71 -71
  55. package/examples/models/sku.json +254 -254
  56. package/examples/models/user.json +49 -49
  57. package/examples/owlconfig.json +13 -13
  58. package/package.json +33 -33
  59. package/todo.txt +4 -4
@@ -1,1164 +1,1164 @@
1
- //#import pigeon.js
2
- //#import eventBus.js
3
- //#import Util.js
4
- //#import base64.js
5
- //#import deepmerge.js
6
- //#import underscore.js
7
- //#import HttpUtil.js
8
- //#import jobs.js
9
- //#import DigestUtil.js
10
- //#import moment.min.js
11
- //#import kafkautil.js
12
- //#import @services/dblayer.jsx
13
- //#import @handlers/include/diff.jsx
14
- //#import $owl_change_logs:services/modelService.jsx
15
-
16
- function trim(s){
17
- if(s){
18
- return s.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
19
- }
20
- return ""
21
- }
22
-
23
- var @projectCodeService = (function (pigeon) {
24
- var objPrefix = '@projectCode'
25
- var listPrefix = '@projectCode'
26
-
27
- var spec = @spec
28
-
29
- var formSpecs = @formSpecs
30
-
31
- var flattenedSpecs = @flattenedSpecs
32
-
33
- var idFunc = @idFunc
34
- var lockFunc = @lockFunc
35
-
36
- var f = {
37
- /**
38
- * 添加
39
- */
40
- getId: function (data) {
41
- //默认实现是直接返回一个递增的Id
42
- //其他实现方式包括从data中获取数据构造出一个Id
43
- if(data.id){
44
- return data.id;
45
- }
46
- //@idOrig
47
- if (idFunc) {
48
- return objPrefix + '_' + idFunc(data)
49
- }
50
- else {
51
- var seq = pigeon.getId(objPrefix)
52
- return objPrefix + '_' + seq
53
- }
54
- },
55
-
56
- getLock: function (data) {
57
- //@lockOrig
58
- if (lockFunc) {
59
- return lockFunc(data)
60
- }
61
- else {
62
- return data['id']
63
- }
64
- },
65
-
66
- lock:function(key){
67
- pigeon.lock(key);
68
- },
69
- unlock:function(key){
70
- pigeon.unlock(key);
71
- },
72
-
73
- /**
74
- * 返回一个树状结构
75
- * 本函数读进所有的数据进内存,在内存中构造一个树状结构
76
- * 所以对于大的数据不是很合适
77
- * 适用范围是中小型电商系统的商品分类数,地区管理等
78
- *
79
- */
80
- getTree(){},
81
-
82
- getAllListName: function (data) {
83
- return listPrefix + '_all'
84
- },
85
-
86
- getValue: function (fullkey, data) {
87
- var path = fullkey.split('.')
88
- var curData = data
89
- for (var i = 0; i < path.length; i++) {
90
- var curKey = path[i]
91
- if (typeof(curData) == 'object' && curData != null) {
92
- curData = curData[curKey]
93
- }
94
- else {
95
- return null
96
- }
97
- }
98
- return curData
99
- },
100
- deleteValue:function(fullkey,data){
101
- var path = fullkey.split('.')
102
- var curData = data
103
- for (var i = 0; i < path.length-1; i++) {
104
- var curKey = path[i]
105
- if (typeof(curData) == 'object' && curData != null) {
106
- curData = curData[curKey]
107
- }
108
- else {
109
- return null
110
- }
111
- }
112
- if(curData){
113
- var lastKey = path[path.length-1];
114
- delete curData[lastKey];
115
- }
116
- },
117
-
118
- setValue: function (fullkey, value, data) {
119
- var path = fullkey.split('.')
120
- var curData = data
121
- var objPath = [data]
122
- for (var i = 0; i < path.length; i++) {
123
- var curKey = path[i]
124
- if (i == path.length - 1) {
125
- curData[curKey] = value
126
- return
127
- }
128
-
129
- var subData = curData[curKey]
130
- if (!subData) {
131
- curData[curKey] = {}
132
- subData = curData[curKey]
133
-
134
- }
135
- curData = subData
136
- }
137
-
138
- },
139
-
140
- getEnvValue: function (v, env) {
141
- if (!v) {
142
- return v
143
- }
144
- if (v.indexOf('$') == 0) {
145
- var fullkey = v.substring(1)
146
- return f.getValue(fullkey, env)
147
- }
148
- return v
149
- },
150
-
151
-
152
-
153
- getUniqueObj:function(key,value){
154
- var pigeonKey = objPrefix+ '_' + key + '_' + DigestUtil.md5(value)
155
- var obj = pigeon.getObject(pigeonKey);
156
- if(obj==null){
157
- return null;
158
- }
159
- var id = obj.id;
160
- return pigeon.getObject(id);
161
- },
162
-
163
- isDuplicated: function (id, key, value) {
164
- var pigeonKey = objPrefix + '_' + key + '_' + DigestUtil.md5(value)
165
- var obj = pigeon.getObject(pigeonKey);
166
- if (obj == null) {
167
- return false
168
- }
169
- if (obj.id === id) {
170
- return false
171
- }
172
- return true
173
- },
174
-
175
-
176
-
177
- saveUniqueValue: function (objId, key, value) {
178
- var md5 = DigestUtil.md5(value)
179
- var pigeonKey = objPrefix + '_' + key + '_' + md5
180
- var obj = {
181
- id: objId,
182
- key: key,
183
- value: value,
184
- md5: md5,
185
- }
186
- pigeon.saveObject(pigeonKey, obj)
187
- },
188
-
189
- removeUniqueValue: function (id, key, value) {
190
- var md5 = DigestUtil.md5(value)
191
- var pigeonKey = objPrefix + '_' + key + '_' + md5
192
- pigeon.saveObject(pigeonKey, null)
193
- },
194
-
195
- validate: function (data, env) {
196
- //TODO:需要实现validate 服务器端
197
- var fields = flattenedSpecs.mainFields
198
- for (var i = 0; i < fields.length; i++) {
199
- var field = fields[i]
200
- var value = f.getValue(field.key, data)
201
- if(value==null || typeof(value)=='undefined'){
202
- value = field.defaultValue;
203
- f.setValue(field.key, value, data)
204
- }
205
- if (typeof(value) == 'string' && value.indexOf('$') == 0) {
206
- value = f.getEnvValue(value, env)
207
- f.setValue(field.key, value, data)
208
- }
209
- if((value==null || typeof(value)=='undefined') && field.autoGen=='true'){
210
- value =$.getUUID()
211
- f.setValue(field.key,value,data);
212
- }
213
- if ((value==null || typeof(value)=='undefined') && field.required == 'true') {
214
- return {'state': 'err', msg: field.fieldLabel + '不能为空。', code: 'required'}
215
- }
216
-
217
- //对于unique的字段,检查有没有重复
218
- if (field.unique === 'true') {
219
- if (f.isDuplicated(data.id, field.key, value)) {
220
- $.log("duplicated,key=" + field.key + ",value=" + value + ",call removeUniqueValue(data.id, field.key, value)");
221
- return {'state': 'err', msg: field.fieldLabel + '不能重复。' + value, code: 'duplicated'}
222
- }
223
- }
224
- }
225
-
226
- var arrFields = flattenedSpecs.details;
227
- for(var j=0; j<arrFields.length; j++){
228
- var arrFieldInfo = arrFields[j];
229
- var rows = f.getValue(arrFieldInfo.name,data);
230
- if(rows){
231
- for(var k=0; k<rows.length; k++){
232
- var row = rows[k];
233
- for(var l=0; l<arrFieldInfo.fields.length; l++){
234
- var subField = arrFieldInfo.fields[l];
235
- var value = row[subField.origKey];
236
- if(value==null || typeof value=='undefined'){
237
- value = subField.defaultValue;
238
- row[subField.origKey] = value;
239
- }
240
- if (typeof(value) == 'string' && value.indexOf('$') == 0) {
241
- value = f.getEnvValue(value, env)
242
- row[subField.origKey] = value;
243
- }
244
- if((value==null || typeof(value)=='undefined') && subField.autoGen=='true'){
245
- value = $.getUUID()
246
- row[subField.origKey] = value;
247
- }
248
- if ((value==null || typeof(value)=='undefined') && subField.required == 'true') {
249
- return {'state': 'err', msg: arrFieldInfo.field.fieldLabel + '.' + subField.fieldLabel + '不能为空。出错的行数为:' + k, code: 'required'}
250
- }
251
- }
252
- }
253
- }
254
- }
255
- return {'state': 'ok'}
256
- },
257
-
258
- saveUniqueFields: function (data, env) {
259
- var fields = flattenedSpecs.mainFields
260
- for (var i = 0; i < fields.length; i++) {
261
- var field = fields[i]
262
- //对于unique的字段,检查有没有重复
263
- if (field.unique === 'true') {
264
- var value = f.getValue(field.key, data)
265
- if (!value || (typeof(value) == 'string' && value.indexOf('$') == 0)) {
266
- value = f.getEnvValue(field.defaultValue, env)
267
- if (value) {
268
- f.setValue(field.key, value, data)
269
- }
270
- }
271
- if (!value && field.required == 'true') {
272
- throw {'state': 'err', msg: field.fieldLabel + '不能为空。', code: 'required'}
273
- }
274
-
275
- if(value && typeof(value)=='string'){
276
- if (f.isDuplicated(data.id, field.key, value)) {
277
- throw {'state': 'err', msg: field.fieldLabel + '不能重复。', code: 'duplicated'}
278
- }
279
-
280
- //对于没有重复的数据,保存起来
281
- f.saveUniqueValue(data.id, field.key, value)
282
- }
283
-
284
- }
285
- }
286
- },
287
-
288
- removeUniqueFields: function (data, env) {
289
- var fields = flattenedSpecs.mainFields
290
- for (var i = 0; i < fields.length; i++) {
291
- var field = fields[i]
292
- //对于unique的字段,检查有没有重复
293
- if (field.unique === 'true') {
294
- var value = f.getValue(field.key, data)
295
- if (!value || (typeof(value) == 'string' && value.indexOf('$') == 0)) {
296
- value = f.getEnvValue(field.defaultValue, env)
297
- if (value) {
298
- f.setValue(field.key, value, data)
299
- }
300
- }
301
- if(value && typeof(value)=='string'){
302
- f.removeUniqueValue(data.id, field.key, value)
303
- }
304
- }
305
- }
306
- },
307
-
308
- addToList: function (data) {
309
- var key = pigeon.getRKey(data['owl_createTime'], 13)
310
- pigeon.addToList(f.getAllListName(), key, data.id)
311
-
312
- var t = data['owl_createTime']
313
- var d = new Date(t)
314
- var year = d.getFullYear()
315
- var month = d.getMonth() + 1
316
- var day = d.getDate()
317
-
318
- var listName = listPrefix + '_' + year + '_' + month + '_' + day
319
-
320
- pigeon.addToList(listName, key, data.id)
321
- //如果这里有子系统的Id则加入子系统list
322
- if (data['subplatformId']) {
323
- var listName = listPrefix + '_' + data['subplatformId']
324
- pigeon.addToList(listName, key, data.id)
325
- }
326
-
327
- //如果这里有店铺id,则加入店铺list
328
- if (data['shopId']) {
329
- var listName = listPrefix + '_' + data['shopId']
330
- pigeon.addToList(listName, key, data.id)
331
- }
332
- },
333
-
334
- tranverseFields: function (formSpec, callback, ctx) {
335
- formSpec.fields.forEach(function (field) {
336
- if (field['_ft'] == 'field') {
337
- callback(field, ctx)
338
- }
339
- else if (field['_ft'] == 'subform') {
340
- var context = {parentField: field}
341
- f.tranverseFields(field, callback, context)
342
- }
343
- else if (field['_ft'] == 'array') {
344
- var context = {parentField: field}
345
- f.tranverseFields(field, callback, context)
346
- }
347
- })
348
- },
349
-
350
- normalizeValue: function (value, spec) {
351
- if (value == null) {
352
- return null
353
- }
354
- switch (spec.fieldType) {
355
- case 'string':
356
- if(typeof value=='number'){
357
- value = value + '';
358
- }
359
- return value + ''
360
- case 'number':
361
- if (isNaN(value)) {
362
- return null
363
- }
364
- else {
365
- value = Number(value)
366
- return value
367
- }
368
- case 'date':
369
- try{
370
- return moment(value);
371
- }
372
- catch(e){
373
- return null;
374
- }
375
-
376
- case 'choice':
377
- return value
378
- default:
379
- return value
380
- }
381
- },
382
-
383
-
384
- getNormalizedDoc: function (data) {
385
- var obj = JSON.parse(JSON.stringify(data))
386
-
387
- var fields = formSpecs.fields;
388
- for(var i=0; i<fields.length; i++){
389
- var field= fields[i];
390
- if (field['_ft'] === 'subform' || field['_ft'] === 'array') {
391
- var meta = field.meta;
392
- if(meta.index==='no'){
393
- delete obj[field.key]
394
- }
395
- }
396
- else if (field['_ft'] === 'field') {
397
- if(field.index==='no'){
398
- delete obj[field.key]
399
- }
400
- }
401
- }
402
- f.tranverseFields(formSpecs, function (field, ctx) {
403
- if (ctx.parentField && ctx.parentField._ft == 'array') {
404
- var items = f.getValue(ctx.parentField.key, obj)
405
- if (items) {
406
- for (var i = 0; i < items.length; i++) {
407
- var item = items[i]
408
- if(field.index==='no'){
409
- delete item[field.origKey]
410
- continue;
411
- }
412
- var value = item[field.origKey]
413
- value = f.normalizeValue(value, field)
414
- item[field.origKey] = value
415
- }
416
- }
417
- }
418
- else {
419
- if(field.index==='no'){
420
- f.deleteValue(field.key,obj);
421
- }
422
- else{
423
- var value = f.getValue(field.key, obj)
424
- value = f.normalizeValue(value, field)
425
- f.setValue(field.key, value, obj)
426
- }
427
-
428
- }
429
- }, {})
430
- return obj
431
- },
432
-
433
- index: function (doc) {
434
- var data = f.getNormalizedDoc(doc);
435
- var m = [];
436
- m.push(data.m);
437
- if (data['subplatformId']) {
438
- m.push(data['subplatformId']);
439
- }
440
- if (data['shopId']) {
441
- m.push(data['shopId'])
442
- }
443
- if(data['shop_id']){
444
- m.push(data['shop_id'])
445
- }
446
- data._m = m;
447
- var elasticSearchUrl = $.getEnv('elasticSearchUrl')
448
-
449
- var headers = {'Content-Type': 'application/json;charset=utf-8'}
450
- var elasticSearchUser = $.getEnv('elasticSearchUser')
451
- var elasticSearchPass = $.getEnv('elasticSearchPass')
452
- if (elasticSearchUser && elasticSearchPass) {
453
- var auth = Base64.encode(elasticSearchUser + ':' + elasticSearchPass)
454
- var basicAuth = 'Basic ' + auth
455
- headers['Authorization'] = basicAuth
456
- }
457
- var searchUrl = elasticSearchUrl + '/@projectCode/_doc/' + data.id
458
- var sndTxt = JSON.stringify(data)
459
- var s = HttpUtils.postRaw(searchUrl, sndTxt, headers)
460
- var r = JSON.parse(s)
461
- if (!r.result) {
462
- $.log(data.id + ',index error:' + JSON.stringify(s))
463
- }
464
- else {
465
- // $.log('index ok...')
466
- }
467
- },
468
-
469
- updateParentPath(treeNode){
470
- /*工具类,用于更新对应的parentPathIds和pathPathNames*/
471
- var parentId = treeNode.parent_id;
472
- var parentPathIds = [];
473
- var parentPathNames = [];
474
- var nSteps = 0;
475
- //获得parentId对应的node
476
- while(parentId && parentId!=='0'){
477
- nSteps++;
478
- if(nSteps>15){
479
- break;
480
- }
481
- var parentNode = f.get(parentId);
482
- if(parentNode){
483
- parentPathIds.push(parentNode.id);
484
- parentPathNames.push(parentNode.name);
485
- parentId = parentNode.parent_id;
486
- }
487
- else{
488
- break;
489
- }
490
- }
491
-
492
- treeNode.parentPathIds = parentPathIds;
493
- treeNode.parentPathNames = parentPathNames;
494
-
495
- },
496
- add: function (data, env) {
497
- env = env || {}
498
- var ret = f.validate(data, env)
499
- if(ret.state!='ok'){
500
- throw JSON.stringify(ret);
501
- }
502
-
503
-
504
- data['owl_createTime'] = new Date().getTime();
505
- data['owl_modifyTime'] = new Date().getTime();
506
- data['_v'] = 0
507
- data['_t'] = spec['_t']
508
- try {
509
- var meta = spec['#meta'];
510
- if(meta.isTree){
511
- f.updateParentPath(data);
512
- }
513
-
514
- EventBusService.fire(spec['_t'] + '_add_before', {data: data, env: env})
515
- data.id = f.getId(data)
516
- pigeon.lock(f.getLock(data))
517
- f.saveUniqueFields(data, env)
518
- pigeon.saveObject(data.id, data)
519
- f.addToList(data)
520
- f.index(data)
521
-
522
- if(meta && meta.enableJDBC){
523
- var sqls = insertObject(data);
524
- // $.log(sqls.join(";\n"));
525
- }
526
- // $.log("add,meta.push=" +meta.push + ",id=" + data.id);
527
- if(meta && meta.push){
528
- KafkaUtil.send('owlchange',JSON.stringify(data),data.id);
529
- }
530
- EventBusService.fire(spec['_t'] + '_add_after', {data: data, env: env})
531
- return data
532
- }
533
- finally {
534
- pigeon.unlock(f.getLock(data))
535
- }
536
-
537
- },
538
-
539
- get: function (id,includeDeleted) {
540
- var meta = spec['#meta'];
541
- if(meta && meta.push) {
542
- var cachedObj = appData.getObservableObject(id);
543
- if (cachedObj) {
544
- if (cachedObj.del === 'T' && !includeDeleted) {
545
- return null;
546
- }
547
- return cachedObj;
548
- }
549
- var obj = pigeon.getObject(id)
550
- if(obj){
551
- appData.setObservableObject(id,obj);
552
- }
553
- else{
554
- appData.removeObservableObject(id);
555
- }
556
-
557
- if (obj && obj.del === 'T' && !includeDeleted) {
558
- return null;
559
- }
560
- return obj;
561
- }
562
- else{
563
- var obj = pigeon.getObject(id)
564
- if (obj && obj.del === 'T' && !includeDeleted) {
565
- return null;
566
- }
567
- return obj;
568
- }
569
- },
570
-
571
- getEx:function(id,refresh){
572
- if(refresh){
573
- var obj = pigeon.getObject(id);
574
-
575
- if(obj){
576
- appData.setObservableObject(id,obj);
577
- }
578
- else{
579
- appData.removeObservableObject(id);
580
- }
581
- if(obj && obj.del==='T'){
582
- return null;
583
- }
584
- return obj;
585
- }
586
- else{
587
- return f.get(id);
588
- }
589
- },
590
-
591
- saveTempData: function (key, data) {
592
- return pigeon.saveObject(objPrefix + key, data)
593
-
594
- },
595
-
596
- getTempData: function (key) {
597
- return pigeon.getObject(objPrefix + key)
598
- },
599
-
600
- getObjects: function (ids) {
601
- return pigeon.getObjects(ids)
602
- },
603
-
604
- update: function (data, env) {
605
- env = env || {}
606
- var id = data.id
607
-
608
- try {
609
- var meta = spec['#meta'];
610
- if(meta.isTree){
611
- f.updateParentPath(data);
612
- }
613
- pigeon.lock(f.getLock(data))
614
- var obj = f.get(data.id,true)
615
- if (!obj) {
616
- throw {msg: '对象不存在!id=' + data.id, code: 'notFound'}
617
- }
618
- if (obj._v != data._v) {
619
- throw {code: 'concurrentupdate', msg: '对象已经修改过,本次修改被拒绝。old._v=' + obj._v + ',new._v=' + data._v}
620
- }
621
- var oldObj = JSON.parse(JSON.stringify(obj))
622
- //深度合并
623
- //obj = deepMerge(obj,data);//深度合并会引起 编辑出现bug
624
- obj = data
625
- obj['_v'] = obj['_v'] + 1
626
- f.validate(obj, env)
627
- data._v = obj._v
628
- obj.owl_modifyTime=new Date().getTime();
629
- EventBusService.fire(spec['_t'] + '_update_before', {old: oldObj, data: obj, env: env})
630
- f.addToList(obj)
631
- f.removeUniqueFields(oldObj, env)
632
- pigeon.saveObject(id, obj)
633
- f.saveUniqueFields(data, env)
634
- f.index(obj)
635
-
636
- if(formSpecs && formSpecs.meta && formSpecs.meta.changeLogEnabled){
637
- var diffresult = diff(oldObj,obj,[]);
638
- var userName = env.loginUser && env.loginUser.name;
639
- var changeLog = {
640
- nv : obj._v,
641
- ov : oldObj._v,
642
- oid : obj.id,
643
- ot: spec['_t'],
644
- ts: obj.owl_modifyTime,
645
- uid: env.loginUserId,
646
- nn: userName,
647
- cli: env.cli,
648
- jobId:env.jobId,
649
- diff:diffresult
650
- }
651
- owl_change_logsService.add(changeLog);
652
-
653
- }
654
-
655
- var meta = spec['#meta'];
656
- if(meta && meta.enableJDBC){
657
- var sqls = updateObject(obj);
658
- // $.log(sqls.join(";\n"));
659
- }
660
- if(meta){
661
- // $.log("updating meta.push=" + meta.push + ", id=" + obj.id);
662
- }
663
-
664
- if(meta && meta.push){
665
- // $.log("send owlchange," + obj.id)
666
- KafkaUtil.send('owlchange',JSON.stringify(obj),obj.id);
667
- }
668
- EventBusService.fire(spec['_t'] + '_update_after', {old: oldObj, data: obj, env: env})
669
- return data
670
- }
671
- finally {
672
- pigeon.unlock(f.getLock(data))
673
- }
674
- },
675
-
676
- del: function (id) {
677
- //只做软删除
678
- var data = f.get(id,true)
679
- if (!data) {
680
- throw '对象不存在!id=' + id
681
- }
682
- data.id = id;
683
- var key = pigeon.getRKey(data['owl_createTime'], 13)
684
- pigeon.deleteFromList(f.getAllListName(), key, id)
685
- if (data['subplatformId']) {
686
- var listName = listPrefix + '_' + data['subplatformId']
687
- pigeon.deleteFromList(listName, key, id)
688
- }
689
-
690
- //如果这里有店铺id,则加入店铺list
691
- if (data['shopId']) {
692
- var listName = listPrefix + '_' + data['shopId']
693
- pigeon.deleteFromList(listName, key, id)
694
- }
695
-
696
- var t = data['owl_createTime']
697
- var d = new Date(t)
698
- var year = d.getFullYear()
699
- var month = d.getMonth() + 1
700
- var day = d.getDate()
701
-
702
- var listName = listPrefix + '_' + year + '_' + month + '_' + day
703
-
704
- EventBusService.fire(spec['_t'] + '_delete_before', {data: data})
705
- pigeon.deleteFromList(listName, key, id)
706
-
707
- var deletedList = listPrefix + '_deleted'
708
- pigeon.addToList(deletedList, key, id)
709
- data.del = 'T'
710
-
711
- f.index(data)
712
- pigeon.saveObject(data.id, data)
713
- f.removeUniqueFields(data, {})
714
- var meta = spec['#meta'];
715
-
716
- if(meta && meta.enableJDBC){
717
- var sqls = deleteObject(data);
718
- // $.log(sqls.join(";\n"));
719
- }
720
-
721
- if(meta){
722
- // $.log("del meta.push=" + meta.push + ", id=" + data.id);
723
- }
724
-
725
- if(meta && meta.push){
726
- KafkaUtil.send('owlchange',JSON.stringify(data),data.id);
727
- }
728
- EventBusService.fire(spec['_t'] + '_delete_after', {data: data})
729
- },
730
- getList: function (listName, start, limit) {
731
- if (!listName) {
732
- return null
733
- }
734
- if (!start) {
735
- start = 0
736
- }
737
- if (!limit) {
738
- limit = 10
739
- }
740
- return pigeon.getListObjects(listName, start, limit)
741
- },
742
-
743
- getExportRunningList: function () {
744
- return listPrefix + '_exportRunning'
745
- },
746
-
747
- getExportFinishedList: function () {
748
- return listPrefix + '_exportFinished'
749
- },
750
-
751
- addExportTask: function (query, env) {
752
- var now = new Date().getTime()
753
- var taskInfo = {
754
- loginUser: f.getEnvValue('$loginUser', env),
755
- submitTime: now,
756
- startTime: 0,
757
- processState: 'processing',
758
- percent: 0,
759
- _v: 0,
760
- }
761
- //这个key如果不多加一个export,会把原有的单据数据覆盖
762
- var taskInfoId = objPrefix + '_export_' + pigeon.getId()
763
- var taskId = JobsService.submitExportTask('@projectCode', 'tasks/export.jsx', {
764
- query: query,
765
- env: env,
766
- taskInfoId: taskInfoId,
767
- }, now)
768
- taskInfo.taskId = '' + taskId
769
- taskInfo.id = taskInfoId
770
- var key = pigeon.getRKey(taskInfo.submitTime, 13)
771
- pigeon.addToList(f.getExportRunningList(), key, taskInfoId)
772
- pigeon.saveObject(taskInfoId, taskInfo)
773
-
774
- return taskInfoId
775
- },
776
-
777
- addDocExportTask: function (docId, env) {
778
- var now = new Date().getTime()
779
- var taskInfo = {
780
- loginUser: f.getEnvValue('$loginUser', env),
781
- submitTime: now,
782
- startTime: 0,
783
- processState: 'processing',
784
- percent: 0,
785
- total: 1,
786
- _v: 0,
787
- }
788
- //这个key如果不多加一个export,会把原有的单据数据覆盖
789
- var taskInfoId = objPrefix + '_export_' + pigeon.getId()
790
- var taskId = JobsService.submitExportTask('@projectCode', 'tasks/exportDoc.jsx', {
791
- id: docId,
792
- env: env,
793
- taskInfoId: taskInfoId,
794
- }, now)
795
- taskInfo.taskId = '' + taskId
796
- taskInfo.id = taskInfoId
797
- var key = pigeon.getRKey(taskInfo.submitTime, 13)
798
- pigeon.addToList(f.getExportRunningList(), key, taskInfoId)
799
- pigeon.saveObject(taskInfoId, taskInfo)
800
-
801
- return taskInfoId
802
- },
803
-
804
- addZipExportTask : function(env){
805
- var now = new Date().getTime()
806
- var taskInfo = {
807
- loginUser: f.getEnvValue('$loginUser', env),
808
- submitTime: now,
809
- startTime: 0,
810
- processState: 'processing',
811
- percent: 0,
812
- total: 0,
813
- _v: 0,
814
- }
815
- //这个key如果不多加一个export,会把原有的单据数据覆盖
816
- var taskInfoId = objPrefix + '_export_' + pigeon.getId()
817
- var taskId = JobsService.submitExportTask('@projectCode', 'tasks/exportZip.jsx', {
818
- env: env,
819
- taskInfoId: taskInfoId,
820
- }, now)
821
- taskInfo.taskId = '' + taskId
822
- taskInfo.id = taskInfoId
823
- var key = pigeon.getRKey(taskInfo.submitTime, 13)
824
- pigeon.addToList(f.getExportRunningList(), key, taskInfoId)
825
- pigeon.saveObject(taskInfoId, taskInfo)
826
- return taskInfoId
827
- },
828
-
829
- getExportTaskInfo: function (taskInfoId) {
830
- return pigeon.getObject(taskInfoId)
831
- },
832
-
833
- updateExportTaskInfo: function (taskInfoId, taskInfo) {
834
- var oInfo = f.getExportTaskInfo(taskInfoId)
835
- if (oInfo._v == taskInfo._v) {
836
- taskInfo._v += 1
837
- pigeon.saveObject(taskInfoId, taskInfo)
838
- }
839
- },
840
-
841
-
842
- reindexAll: function () {
843
- var listName = f.getAllListName()
844
- var count = pigeon.getListSize(listName)
845
- $.log("reindexAll " + listName);
846
- var pos = 0
847
- while (count > 0) {
848
- var indexCount = 2000
849
- if (indexCount > count) {
850
- indexCount = count
851
- }
852
- var objs = pigeon.getListObjects(listName, pos, indexCount)
853
- objs.forEach(function (data) {
854
- try {
855
- f.index(data)
856
- } catch (e) {
857
- $.log('重建索引异常:' + data.id)
858
- }
859
- })
860
- pos += indexCount
861
- count -= indexCount
862
- }
863
- },
864
-
865
- getAllSize:function(){
866
- var listName = f.getAllListName();
867
- var count = pigeon.getListSize(listName);
868
- return count;
869
- },
870
-
871
- getAllObjects:function(){
872
- var result = [];
873
- var listName = f.getAllListName()
874
- var count = pigeon.getListSize(listName)
875
- var pos = 0
876
- while (count > 0) {
877
- var indexCount = 2000
878
- if (indexCount > count) {
879
- indexCount = count
880
- }
881
- var objs = pigeon.getListObjects(listName, pos, indexCount)
882
- result = result.concat(objs);
883
- pos += indexCount
884
- count -= indexCount
885
- }
886
- return result;
887
- },
888
-
889
- getAllObjectsEx:function(from,count){
890
- var listName = f.getAllListName()
891
- var allsize = pigeon.getListSize(listName)
892
- var pos = from
893
- if(count+pos > allsize){
894
- count = allsize - pos;
895
- }
896
- var objs = pigeon.getListObjects(listName, pos, count)
897
- return objs;
898
- },
899
-
900
- createQuery:function(searchArgs){
901
- var filters = [];
902
- for(var k in searchArgs){
903
- var v = searchArgs[k];
904
- if(typeof v === 'object' && v.type === 'or'){
905
- if(Array.isArray(v.args)){
906
- var shouldClauses = [];
907
- v.args.forEach(function(q){
908
- var qFilters = f.createQuery(q);
909
- if(qFilters.length > 0){
910
- shouldClauses.push({
911
- "bool":{
912
- filters:qFilters
913
- }
914
- })
915
- }
916
- });
917
-
918
- filters.push({bool:{should:shouldClauses}});
919
- }
920
- else if(v.args && typeof(v.args)=='object'){
921
- var shouldClauses = [];
922
- var qFilters = f.createQuery(v.args);
923
- shouldClauses.push({bool:{filters:qFilters}});
924
- filters.push({bool:{should:shouldClauses}});
925
- }
926
-
927
- }
928
- else if(typeof(v)=='object' && Array.isArray(v)){
929
- var range={}
930
- range[k] = {
931
- 'gte':v[0],
932
- 'lte':v[1]
933
- }
934
- filters.push({range:range});
935
- }
936
- else if(typeof(v)=='object' && v.type==='terms'){
937
- var terms = {};
938
- if(v.values){
939
- terms[k + ".keyword"] = v.values;
940
- filters.push({terms:terms});
941
- }
942
- }
943
- else{
944
- var term = {};
945
- if(typeof v == 'string' ){
946
- if(v){
947
- term[k+".keyword"] = trim('' + v)
948
- filters.push({term:term})
949
- }
950
- }
951
- else if (typeof v == 'number'){
952
- term[k] = trim('' + v)
953
- filters.push({term:term})
954
- }
955
- }
956
- }
957
- return filters;
958
- },
959
-
960
- buildQuery:function(mfilters,searchArgs,keyword){
961
- delete searchArgs.keyword;
962
- var filters = [];
963
- var must_not = [{
964
- term:{
965
- "del.keyword":'T'
966
- }
967
- }];
968
- for(var k in searchArgs){
969
-
970
- var v = searchArgs[k];
971
-
972
- var isNotClause = false;
973
- if(k.indexOf("!")===0){
974
- isNotClause = true;
975
- k = k.substring(1);
976
- }
977
- if(typeof v === 'object' && v.type === 'or'){
978
- var shouldClauses = [];
979
- if(Array.isArray(v.args)){
980
- v.args.forEach(function(q){
981
- var shouldQueries = f.createQuery(q);
982
- if(shouldQueries.length>0){
983
- shouldClauses.push({bool:{filter:shouldQueries}});
984
- }
985
-
986
- });
987
- if(isNotClause){
988
- must_not.push({bool:{should:shouldClauses}});
989
- }else{
990
- filters.push({bool:{should:shouldClauses}});
991
- }
992
-
993
- }
994
- else{
995
- if(v.args && typeof(v.args)==='object'){
996
- var shouldQueries = f.createQuery(v);
997
- if(isNotClause){
998
- must_not.push({bool:{should:shouldClauses}});
999
- }else{
1000
- filters.push({bool:{should:shouldClauses}});
1001
- }
1002
- }
1003
- }
1004
- }
1005
- else if(typeof(v)=='object' && Array.isArray(v)){
1006
- var range={}
1007
- range[k] = {
1008
- 'gte':v[0],
1009
- 'lte':v[1]
1010
- }
1011
- if(isNotClause){
1012
- must_not.push({range:range});
1013
- }else{
1014
- filters.push({range:range});
1015
- }
1016
- }
1017
- else if(typeof(v)=='object' && v.type==='terms'){
1018
- var terms = {};
1019
- if(v.values){
1020
- terms[k + ".keyword"] = v.values;
1021
- if(isNotClause){
1022
- must_not.push({terms:terms});
1023
- }else{
1024
- filters.push({terms:terms});
1025
- }
1026
- }
1027
- }
1028
- else{
1029
- var term = {};
1030
- if(typeof v == 'string' ){
1031
- if(v){
1032
- term[k+".keyword"] = trim('' + v)
1033
- if(isNotClause){
1034
- must_not.push({term:term});
1035
- }else{
1036
- filters.push({term:term});
1037
- }
1038
-
1039
- }
1040
- }
1041
- else if (typeof v == 'number'){
1042
- term[k] = trim('' + v)
1043
- if(isNotClause){
1044
- must_not.push({term:term});
1045
- }else{
1046
- filters.push({term:term});
1047
- }
1048
- }
1049
- }
1050
- }
1051
- if(mfilters && Array.isArray(mfilters) && mfilters.length>0){
1052
- filters = filters.concat(mfilters);
1053
- }
1054
-
1055
- //getKeyword query
1056
- var keywordQuery = "";
1057
- if(keyword && trim(keyword).length>0){
1058
- keywordQuery = "\"" + trim(keyword) + "\""
1059
- }
1060
- else{
1061
- keywordQuery = "*"
1062
- }
1063
- var query = {
1064
- "query": {
1065
- "bool": {
1066
- "must": {
1067
- "query_string": {
1068
- "query":keywordQuery
1069
- }
1070
- },
1071
- "must_not": must_not,
1072
- "filter": filters
1073
- }
1074
- }
1075
- }
1076
- return query;
1077
- },
1078
-
1079
- count:function(mfilters,searchArgs,keyword,dataSource){
1080
- var query = f.buildQuery(mfilters,searchArgs,keyword);
1081
- var elasticSearchUrl = $.getEnv( "elasticSearchUrl" );
1082
-
1083
- var headers = { "Content-Type": "application/json;charset=utf-8" };
1084
- var elasticSearchUser = $.getEnv("elasticSearchUser");
1085
- var elasticSearchPass = $.getEnv("elasticSearchPass");
1086
- if(elasticSearchUser && elasticSearchPass){
1087
- var auth =Base64.encode(elasticSearchUser + ":" + elasticSearchPass);
1088
- var basicAuth = "Basic " + auth;
1089
- headers["Authorization"] = basicAuth;
1090
- }
1091
- var searchUrl = elasticSearchUrl+"/@projectCode/_count";
1092
- if(dataSource){
1093
- searchUrl = elasticSearchUrl + "/" + dataSource + "/_count";
1094
- }
1095
-
1096
- var sndTxt = JSON.stringify(query);
1097
- var s = HttpUtils.postRaw( searchUrl, sndTxt, headers);
1098
- var result = JSON.parse(s);
1099
- if(result.count){
1100
- return result.count;
1101
- }
1102
- return 0;
1103
- },
1104
- search: function(mfilters, searchArgs, keyword,from, pageSize, sort, dataSource){
1105
- var query = f.buildQuery(mfilters,searchArgs,keyword);
1106
- var effectiveSort = [{owl_createTime:{order:"desc"}}];
1107
- if(sort){
1108
- effectiveSort = sort;
1109
- } var effectiveSort = [{owl_createTime:{order:"desc"}}];
1110
- if(sort){
1111
- effectiveSort = sort;
1112
- }
1113
- query.from = from;
1114
- query.size = pageSize;
1115
- query.sort = effectiveSort;
1116
-
1117
- var elasticSearchUrl = $.getEnv( "elasticSearchUrl" );
1118
-
1119
- var headers = { "Content-Type": "application/json;charset=utf-8" };
1120
- var elasticSearchUser = $.getEnv("elasticSearchUser");
1121
- var elasticSearchPass = $.getEnv("elasticSearchPass");
1122
- if(elasticSearchUser && elasticSearchPass){
1123
- var auth =Base64.encode(elasticSearchUser + ":" + elasticSearchPass);
1124
- var basicAuth = "Basic " + auth;
1125
- headers["Authorization"] = basicAuth;
1126
- }
1127
- var searchUrl = elasticSearchUrl+"/@projectCode/_search";
1128
- if(dataSource){
1129
- searchUrl = elasticSearchUrl + "/" + dataSource + "/_search";
1130
- }
1131
-
1132
- var sndTxt = JSON.stringify(query);
1133
- var s = HttpUtils.postRaw( searchUrl, sndTxt, headers);
1134
- var result = JSON.parse(s);
1135
-
1136
- if(!result.hits || !result.hits.hits){
1137
- $.log("error search:sndQuery=" + sndTxt + "------\nresponse:\n" + s );
1138
- var ret = {
1139
- state:'ok',
1140
- list:[],
1141
- total:{value:0}
1142
- }
1143
- out.print(JSON.stringify(ret));
1144
- return;
1145
- }
1146
-
1147
- var hits = result.hits.hits;
1148
- var total = result.hits.total;
1149
-
1150
- var objs = hits.map(function(hit){return hit._source});
1151
-
1152
-
1153
- var ret = {
1154
- state:'ok',
1155
- list:objs,
1156
- total:total
1157
- }
1158
-
1159
- return ret;
1160
-
1161
- }
1162
- }
1163
- return f;
1
+ //#import pigeon.js
2
+ //#import eventBus.js
3
+ //#import Util.js
4
+ //#import base64.js
5
+ //#import deepmerge.js
6
+ //#import underscore.js
7
+ //#import HttpUtil.js
8
+ //#import jobs.js
9
+ //#import DigestUtil.js
10
+ //#import moment.min.js
11
+ //#import kafkautil.js
12
+ //#import @services/dblayer.jsx
13
+ //#import @handlers/include/diff.jsx
14
+ //#import $owl_change_logs:services/modelService.jsx
15
+
16
+ function trim(s){
17
+ if(s){
18
+ return s.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
19
+ }
20
+ return ""
21
+ }
22
+
23
+ var @projectCodeService = (function (pigeon) {
24
+ var objPrefix = '@projectCode'
25
+ var listPrefix = '@projectCode'
26
+
27
+ var spec = @spec
28
+
29
+ var formSpecs = @formSpecs
30
+
31
+ var flattenedSpecs = @flattenedSpecs
32
+
33
+ var idFunc = @idFunc
34
+ var lockFunc = @lockFunc
35
+
36
+ var f = {
37
+ /**
38
+ * 添加
39
+ */
40
+ getId: function (data) {
41
+ //默认实现是直接返回一个递增的Id
42
+ //其他实现方式包括从data中获取数据构造出一个Id
43
+ if(data.id){
44
+ return data.id;
45
+ }
46
+ //@idOrig
47
+ if (idFunc) {
48
+ return objPrefix + '_' + idFunc(data)
49
+ }
50
+ else {
51
+ var seq = pigeon.getId(objPrefix)
52
+ return objPrefix + '_' + seq
53
+ }
54
+ },
55
+
56
+ getLock: function (data) {
57
+ //@lockOrig
58
+ if (lockFunc) {
59
+ return lockFunc(data)
60
+ }
61
+ else {
62
+ return data['id']
63
+ }
64
+ },
65
+
66
+ lock:function(key){
67
+ pigeon.lock(key);
68
+ },
69
+ unlock:function(key){
70
+ pigeon.unlock(key);
71
+ },
72
+
73
+ /**
74
+ * 返回一个树状结构
75
+ * 本函数读进所有的数据进内存,在内存中构造一个树状结构
76
+ * 所以对于大的数据不是很合适
77
+ * 适用范围是中小型电商系统的商品分类数,地区管理等
78
+ *
79
+ */
80
+ getTree(){},
81
+
82
+ getAllListName: function (data) {
83
+ return listPrefix + '_all'
84
+ },
85
+
86
+ getValue: function (fullkey, data) {
87
+ var path = fullkey.split('.')
88
+ var curData = data
89
+ for (var i = 0; i < path.length; i++) {
90
+ var curKey = path[i]
91
+ if (typeof(curData) == 'object' && curData != null) {
92
+ curData = curData[curKey]
93
+ }
94
+ else {
95
+ return null
96
+ }
97
+ }
98
+ return curData
99
+ },
100
+ deleteValue:function(fullkey,data){
101
+ var path = fullkey.split('.')
102
+ var curData = data
103
+ for (var i = 0; i < path.length-1; i++) {
104
+ var curKey = path[i]
105
+ if (typeof(curData) == 'object' && curData != null) {
106
+ curData = curData[curKey]
107
+ }
108
+ else {
109
+ return null
110
+ }
111
+ }
112
+ if(curData){
113
+ var lastKey = path[path.length-1];
114
+ delete curData[lastKey];
115
+ }
116
+ },
117
+
118
+ setValue: function (fullkey, value, data) {
119
+ var path = fullkey.split('.')
120
+ var curData = data
121
+ var objPath = [data]
122
+ for (var i = 0; i < path.length; i++) {
123
+ var curKey = path[i]
124
+ if (i == path.length - 1) {
125
+ curData[curKey] = value
126
+ return
127
+ }
128
+
129
+ var subData = curData[curKey]
130
+ if (!subData) {
131
+ curData[curKey] = {}
132
+ subData = curData[curKey]
133
+
134
+ }
135
+ curData = subData
136
+ }
137
+
138
+ },
139
+
140
+ getEnvValue: function (v, env) {
141
+ if (!v) {
142
+ return v
143
+ }
144
+ if (v.indexOf('$') == 0) {
145
+ var fullkey = v.substring(1)
146
+ return f.getValue(fullkey, env)
147
+ }
148
+ return v
149
+ },
150
+
151
+
152
+
153
+ getUniqueObj:function(key,value){
154
+ var pigeonKey = objPrefix+ '_' + key + '_' + DigestUtil.md5(value)
155
+ var obj = pigeon.getObject(pigeonKey);
156
+ if(obj==null){
157
+ return null;
158
+ }
159
+ var id = obj.id;
160
+ return pigeon.getObject(id);
161
+ },
162
+
163
+ isDuplicated: function (id, key, value) {
164
+ var pigeonKey = objPrefix + '_' + key + '_' + DigestUtil.md5(value)
165
+ var obj = pigeon.getObject(pigeonKey);
166
+ if (obj == null) {
167
+ return false
168
+ }
169
+ if (obj.id === id) {
170
+ return false
171
+ }
172
+ return true
173
+ },
174
+
175
+
176
+
177
+ saveUniqueValue: function (objId, key, value) {
178
+ var md5 = DigestUtil.md5(value)
179
+ var pigeonKey = objPrefix + '_' + key + '_' + md5
180
+ var obj = {
181
+ id: objId,
182
+ key: key,
183
+ value: value,
184
+ md5: md5,
185
+ }
186
+ pigeon.saveObject(pigeonKey, obj)
187
+ },
188
+
189
+ removeUniqueValue: function (id, key, value) {
190
+ var md5 = DigestUtil.md5(value)
191
+ var pigeonKey = objPrefix + '_' + key + '_' + md5
192
+ pigeon.saveObject(pigeonKey, null)
193
+ },
194
+
195
+ validate: function (data, env) {
196
+ //TODO:需要实现validate 服务器端
197
+ var fields = flattenedSpecs.mainFields
198
+ for (var i = 0; i < fields.length; i++) {
199
+ var field = fields[i]
200
+ var value = f.getValue(field.key, data)
201
+ if(value==null || typeof(value)=='undefined'){
202
+ value = field.defaultValue;
203
+ f.setValue(field.key, value, data)
204
+ }
205
+ if (typeof(value) == 'string' && value.indexOf('$') == 0) {
206
+ value = f.getEnvValue(value, env)
207
+ f.setValue(field.key, value, data)
208
+ }
209
+ if((value==null || typeof(value)=='undefined') && field.autoGen=='true'){
210
+ value =$.getUUID()
211
+ f.setValue(field.key,value,data);
212
+ }
213
+ if ((value==null || typeof(value)=='undefined') && field.required == 'true') {
214
+ return {'state': 'err', msg: field.fieldLabel + '不能为空。', code: 'required'}
215
+ }
216
+
217
+ //对于unique的字段,检查有没有重复
218
+ if (field.unique === 'true') {
219
+ if (f.isDuplicated(data.id, field.key, value)) {
220
+ $.log("duplicated,key=" + field.key + ",value=" + value + ",call removeUniqueValue(data.id, field.key, value)");
221
+ return {'state': 'err', msg: field.fieldLabel + '不能重复。' + value, code: 'duplicated'}
222
+ }
223
+ }
224
+ }
225
+
226
+ var arrFields = flattenedSpecs.details;
227
+ for(var j=0; j<arrFields.length; j++){
228
+ var arrFieldInfo = arrFields[j];
229
+ var rows = f.getValue(arrFieldInfo.name,data);
230
+ if(rows){
231
+ for(var k=0; k<rows.length; k++){
232
+ var row = rows[k];
233
+ for(var l=0; l<arrFieldInfo.fields.length; l++){
234
+ var subField = arrFieldInfo.fields[l];
235
+ var value = row[subField.origKey];
236
+ if(value==null || typeof value=='undefined'){
237
+ value = subField.defaultValue;
238
+ row[subField.origKey] = value;
239
+ }
240
+ if (typeof(value) == 'string' && value.indexOf('$') == 0) {
241
+ value = f.getEnvValue(value, env)
242
+ row[subField.origKey] = value;
243
+ }
244
+ if((value==null || typeof(value)=='undefined') && subField.autoGen=='true'){
245
+ value = $.getUUID()
246
+ row[subField.origKey] = value;
247
+ }
248
+ if ((value==null || typeof(value)=='undefined') && subField.required == 'true') {
249
+ return {'state': 'err', msg: arrFieldInfo.field.fieldLabel + '.' + subField.fieldLabel + '不能为空。出错的行数为:' + k, code: 'required'}
250
+ }
251
+ }
252
+ }
253
+ }
254
+ }
255
+ return {'state': 'ok'}
256
+ },
257
+
258
+ saveUniqueFields: function (data, env) {
259
+ var fields = flattenedSpecs.mainFields
260
+ for (var i = 0; i < fields.length; i++) {
261
+ var field = fields[i]
262
+ //对于unique的字段,检查有没有重复
263
+ if (field.unique === 'true') {
264
+ var value = f.getValue(field.key, data)
265
+ if (!value || (typeof(value) == 'string' && value.indexOf('$') == 0)) {
266
+ value = f.getEnvValue(field.defaultValue, env)
267
+ if (value) {
268
+ f.setValue(field.key, value, data)
269
+ }
270
+ }
271
+ if (!value && field.required == 'true') {
272
+ throw {'state': 'err', msg: field.fieldLabel + '不能为空。', code: 'required'}
273
+ }
274
+
275
+ if(value && typeof(value)=='string'){
276
+ if (f.isDuplicated(data.id, field.key, value)) {
277
+ throw {'state': 'err', msg: field.fieldLabel + '不能重复。', code: 'duplicated'}
278
+ }
279
+
280
+ //对于没有重复的数据,保存起来
281
+ f.saveUniqueValue(data.id, field.key, value)
282
+ }
283
+
284
+ }
285
+ }
286
+ },
287
+
288
+ removeUniqueFields: function (data, env) {
289
+ var fields = flattenedSpecs.mainFields
290
+ for (var i = 0; i < fields.length; i++) {
291
+ var field = fields[i]
292
+ //对于unique的字段,检查有没有重复
293
+ if (field.unique === 'true') {
294
+ var value = f.getValue(field.key, data)
295
+ if (!value || (typeof(value) == 'string' && value.indexOf('$') == 0)) {
296
+ value = f.getEnvValue(field.defaultValue, env)
297
+ if (value) {
298
+ f.setValue(field.key, value, data)
299
+ }
300
+ }
301
+ if(value && typeof(value)=='string'){
302
+ f.removeUniqueValue(data.id, field.key, value)
303
+ }
304
+ }
305
+ }
306
+ },
307
+
308
+ addToList: function (data) {
309
+ var key = pigeon.getRKey(data['owl_createTime'], 13)
310
+ pigeon.addToList(f.getAllListName(), key, data.id)
311
+
312
+ var t = data['owl_createTime']
313
+ var d = new Date(t)
314
+ var year = d.getFullYear()
315
+ var month = d.getMonth() + 1
316
+ var day = d.getDate()
317
+
318
+ var listName = listPrefix + '_' + year + '_' + month + '_' + day
319
+
320
+ pigeon.addToList(listName, key, data.id)
321
+ //如果这里有子系统的Id则加入子系统list
322
+ if (data['subplatformId']) {
323
+ var listName = listPrefix + '_' + data['subplatformId']
324
+ pigeon.addToList(listName, key, data.id)
325
+ }
326
+
327
+ //如果这里有店铺id,则加入店铺list
328
+ if (data['shopId']) {
329
+ var listName = listPrefix + '_' + data['shopId']
330
+ pigeon.addToList(listName, key, data.id)
331
+ }
332
+ },
333
+
334
+ tranverseFields: function (formSpec, callback, ctx) {
335
+ formSpec.fields.forEach(function (field) {
336
+ if (field['_ft'] == 'field') {
337
+ callback(field, ctx)
338
+ }
339
+ else if (field['_ft'] == 'subform') {
340
+ var context = {parentField: field}
341
+ f.tranverseFields(field, callback, context)
342
+ }
343
+ else if (field['_ft'] == 'array') {
344
+ var context = {parentField: field}
345
+ f.tranverseFields(field, callback, context)
346
+ }
347
+ })
348
+ },
349
+
350
+ normalizeValue: function (value, spec) {
351
+ if (value == null) {
352
+ return null
353
+ }
354
+ switch (spec.fieldType) {
355
+ case 'string':
356
+ if(typeof value=='number'){
357
+ value = value + '';
358
+ }
359
+ return value + ''
360
+ case 'number':
361
+ if (isNaN(value)) {
362
+ return null
363
+ }
364
+ else {
365
+ value = Number(value)
366
+ return value
367
+ }
368
+ case 'date':
369
+ try{
370
+ return moment(value);
371
+ }
372
+ catch(e){
373
+ return null;
374
+ }
375
+
376
+ case 'choice':
377
+ return value
378
+ default:
379
+ return value
380
+ }
381
+ },
382
+
383
+
384
+ getNormalizedDoc: function (data) {
385
+ var obj = JSON.parse(JSON.stringify(data))
386
+
387
+ var fields = formSpecs.fields;
388
+ for(var i=0; i<fields.length; i++){
389
+ var field= fields[i];
390
+ if (field['_ft'] === 'subform' || field['_ft'] === 'array') {
391
+ var meta = field.meta;
392
+ if(meta.index==='no'){
393
+ delete obj[field.key]
394
+ }
395
+ }
396
+ else if (field['_ft'] === 'field') {
397
+ if(field.index==='no'){
398
+ delete obj[field.key]
399
+ }
400
+ }
401
+ }
402
+ f.tranverseFields(formSpecs, function (field, ctx) {
403
+ if (ctx.parentField && ctx.parentField._ft == 'array') {
404
+ var items = f.getValue(ctx.parentField.key, obj)
405
+ if (items) {
406
+ for (var i = 0; i < items.length; i++) {
407
+ var item = items[i]
408
+ if(field.index==='no'){
409
+ delete item[field.origKey]
410
+ continue;
411
+ }
412
+ var value = item[field.origKey]
413
+ value = f.normalizeValue(value, field)
414
+ item[field.origKey] = value
415
+ }
416
+ }
417
+ }
418
+ else {
419
+ if(field.index==='no'){
420
+ f.deleteValue(field.key,obj);
421
+ }
422
+ else{
423
+ var value = f.getValue(field.key, obj)
424
+ value = f.normalizeValue(value, field)
425
+ f.setValue(field.key, value, obj)
426
+ }
427
+
428
+ }
429
+ }, {})
430
+ return obj
431
+ },
432
+
433
+ index: function (doc) {
434
+ var data = f.getNormalizedDoc(doc);
435
+ var m = [];
436
+ m.push(data.m);
437
+ if (data['subplatformId']) {
438
+ m.push(data['subplatformId']);
439
+ }
440
+ if (data['shopId']) {
441
+ m.push(data['shopId'])
442
+ }
443
+ if(data['shop_id']){
444
+ m.push(data['shop_id'])
445
+ }
446
+ data._m = m;
447
+ var elasticSearchUrl = $.getEnv('elasticSearchUrl')
448
+
449
+ var headers = {'Content-Type': 'application/json;charset=utf-8'}
450
+ var elasticSearchUser = $.getEnv('elasticSearchUser')
451
+ var elasticSearchPass = $.getEnv('elasticSearchPass')
452
+ if (elasticSearchUser && elasticSearchPass) {
453
+ var auth = Base64.encode(elasticSearchUser + ':' + elasticSearchPass)
454
+ var basicAuth = 'Basic ' + auth
455
+ headers['Authorization'] = basicAuth
456
+ }
457
+ var searchUrl = elasticSearchUrl + '/@projectCode/_doc/' + data.id
458
+ var sndTxt = JSON.stringify(data)
459
+ var s = HttpUtils.postRaw(searchUrl, sndTxt, headers)
460
+ var r = JSON.parse(s)
461
+ if (!r.result) {
462
+ $.log(data.id + ',index error:' + JSON.stringify(s))
463
+ }
464
+ else {
465
+ // $.log('index ok...')
466
+ }
467
+ },
468
+
469
+ updateParentPath(treeNode){
470
+ /*工具类,用于更新对应的parentPathIds和pathPathNames*/
471
+ var parentId = treeNode.parent_id;
472
+ var parentPathIds = [];
473
+ var parentPathNames = [];
474
+ var nSteps = 0;
475
+ //获得parentId对应的node
476
+ while(parentId && parentId!=='0'){
477
+ nSteps++;
478
+ if(nSteps>15){
479
+ break;
480
+ }
481
+ var parentNode = f.get(parentId);
482
+ if(parentNode){
483
+ parentPathIds.push(parentNode.id);
484
+ parentPathNames.push(parentNode.name);
485
+ parentId = parentNode.parent_id;
486
+ }
487
+ else{
488
+ break;
489
+ }
490
+ }
491
+
492
+ treeNode.parentPathIds = parentPathIds;
493
+ treeNode.parentPathNames = parentPathNames;
494
+
495
+ },
496
+ add: function (data, env) {
497
+ env = env || {}
498
+ var ret = f.validate(data, env)
499
+ if(ret.state!='ok'){
500
+ throw JSON.stringify(ret);
501
+ }
502
+
503
+
504
+ data['owl_createTime'] = new Date().getTime();
505
+ data['owl_modifyTime'] = new Date().getTime();
506
+ data['_v'] = 0
507
+ data['_t'] = spec['_t']
508
+ try {
509
+ var meta = spec['#meta'];
510
+ if(meta.isTree){
511
+ f.updateParentPath(data);
512
+ }
513
+
514
+ EventBusService.fire(spec['_t'] + '_add_before', {data: data, env: env})
515
+ data.id = f.getId(data)
516
+ pigeon.lock(f.getLock(data))
517
+ f.saveUniqueFields(data, env)
518
+ pigeon.saveObject(data.id, data)
519
+ f.addToList(data)
520
+ f.index(data)
521
+
522
+ if(meta && meta.enableJDBC){
523
+ var sqls = insertObject(data);
524
+ // $.log(sqls.join(";\n"));
525
+ }
526
+ // $.log("add,meta.push=" +meta.push + ",id=" + data.id);
527
+ if(meta && meta.push){
528
+ KafkaUtil.send('owlchange',JSON.stringify(data),data.id);
529
+ }
530
+ EventBusService.fire(spec['_t'] + '_add_after', {data: data, env: env})
531
+ return data
532
+ }
533
+ finally {
534
+ pigeon.unlock(f.getLock(data))
535
+ }
536
+
537
+ },
538
+
539
+ get: function (id,includeDeleted) {
540
+ var meta = spec['#meta'];
541
+ if(meta && meta.push) {
542
+ var cachedObj = appData.getObservableObject(id);
543
+ if (cachedObj) {
544
+ if (cachedObj.del === 'T' && !includeDeleted) {
545
+ return null;
546
+ }
547
+ return cachedObj;
548
+ }
549
+ var obj = pigeon.getObject(id)
550
+ if(obj){
551
+ appData.setObservableObject(id,obj);
552
+ }
553
+ else{
554
+ appData.removeObservableObject(id);
555
+ }
556
+
557
+ if (obj && obj.del === 'T' && !includeDeleted) {
558
+ return null;
559
+ }
560
+ return obj;
561
+ }
562
+ else{
563
+ var obj = pigeon.getObject(id)
564
+ if (obj && obj.del === 'T' && !includeDeleted) {
565
+ return null;
566
+ }
567
+ return obj;
568
+ }
569
+ },
570
+
571
+ getEx:function(id,refresh){
572
+ if(refresh){
573
+ var obj = pigeon.getObject(id);
574
+
575
+ if(obj){
576
+ appData.setObservableObject(id,obj);
577
+ }
578
+ else{
579
+ appData.removeObservableObject(id);
580
+ }
581
+ if(obj && obj.del==='T'){
582
+ return null;
583
+ }
584
+ return obj;
585
+ }
586
+ else{
587
+ return f.get(id);
588
+ }
589
+ },
590
+
591
+ saveTempData: function (key, data) {
592
+ return pigeon.saveObject(objPrefix + key, data)
593
+
594
+ },
595
+
596
+ getTempData: function (key) {
597
+ return pigeon.getObject(objPrefix + key)
598
+ },
599
+
600
+ getObjects: function (ids) {
601
+ return pigeon.getObjects(ids)
602
+ },
603
+
604
+ update: function (data, env) {
605
+ env = env || {}
606
+ var id = data.id
607
+
608
+ try {
609
+ var meta = spec['#meta'];
610
+ if(meta.isTree){
611
+ f.updateParentPath(data);
612
+ }
613
+ pigeon.lock(f.getLock(data))
614
+ var obj = f.get(data.id,true)
615
+ if (!obj) {
616
+ throw {msg: '对象不存在!id=' + data.id, code: 'notFound'}
617
+ }
618
+ if (obj._v != data._v) {
619
+ throw {code: 'concurrentupdate', msg: '对象已经修改过,本次修改被拒绝。old._v=' + obj._v + ',new._v=' + data._v}
620
+ }
621
+ var oldObj = JSON.parse(JSON.stringify(obj))
622
+ //深度合并
623
+ //obj = deepMerge(obj,data);//深度合并会引起 编辑出现bug
624
+ obj = data
625
+ obj['_v'] = obj['_v'] + 1
626
+ f.validate(obj, env)
627
+ data._v = obj._v
628
+ obj.owl_modifyTime=new Date().getTime();
629
+ EventBusService.fire(spec['_t'] + '_update_before', {old: oldObj, data: obj, env: env})
630
+ f.addToList(obj)
631
+ f.removeUniqueFields(oldObj, env)
632
+ pigeon.saveObject(id, obj)
633
+ f.saveUniqueFields(data, env)
634
+ f.index(obj)
635
+
636
+ if(formSpecs && formSpecs.meta && formSpecs.meta.changeLogEnabled){
637
+ var diffresult = diff(oldObj,obj,[]);
638
+ var userName = env.loginUser && env.loginUser.name;
639
+ var changeLog = {
640
+ nv : obj._v,
641
+ ov : oldObj._v,
642
+ oid : obj.id,
643
+ ot: spec['_t'],
644
+ ts: obj.owl_modifyTime,
645
+ uid: env.loginUserId,
646
+ nn: userName,
647
+ cli: env.cli,
648
+ jobId:env.jobId,
649
+ diff:diffresult
650
+ }
651
+ owl_change_logsService.add(changeLog);
652
+
653
+ }
654
+
655
+ var meta = spec['#meta'];
656
+ if(meta && meta.enableJDBC){
657
+ var sqls = updateObject(obj);
658
+ // $.log(sqls.join(";\n"));
659
+ }
660
+ if(meta){
661
+ // $.log("updating meta.push=" + meta.push + ", id=" + obj.id);
662
+ }
663
+
664
+ if(meta && meta.push){
665
+ // $.log("send owlchange," + obj.id)
666
+ KafkaUtil.send('owlchange',JSON.stringify(obj),obj.id);
667
+ }
668
+ EventBusService.fire(spec['_t'] + '_update_after', {old: oldObj, data: obj, env: env})
669
+ return data
670
+ }
671
+ finally {
672
+ pigeon.unlock(f.getLock(data))
673
+ }
674
+ },
675
+
676
+ del: function (id) {
677
+ //只做软删除
678
+ var data = f.get(id,true)
679
+ if (!data) {
680
+ throw '对象不存在!id=' + id
681
+ }
682
+ data.id = id;
683
+ var key = pigeon.getRKey(data['owl_createTime'], 13)
684
+ pigeon.deleteFromList(f.getAllListName(), key, id)
685
+ if (data['subplatformId']) {
686
+ var listName = listPrefix + '_' + data['subplatformId']
687
+ pigeon.deleteFromList(listName, key, id)
688
+ }
689
+
690
+ //如果这里有店铺id,则加入店铺list
691
+ if (data['shopId']) {
692
+ var listName = listPrefix + '_' + data['shopId']
693
+ pigeon.deleteFromList(listName, key, id)
694
+ }
695
+
696
+ var t = data['owl_createTime']
697
+ var d = new Date(t)
698
+ var year = d.getFullYear()
699
+ var month = d.getMonth() + 1
700
+ var day = d.getDate()
701
+
702
+ var listName = listPrefix + '_' + year + '_' + month + '_' + day
703
+
704
+ EventBusService.fire(spec['_t'] + '_delete_before', {data: data})
705
+ pigeon.deleteFromList(listName, key, id)
706
+
707
+ var deletedList = listPrefix + '_deleted'
708
+ pigeon.addToList(deletedList, key, id)
709
+ data.del = 'T'
710
+
711
+ f.index(data)
712
+ pigeon.saveObject(data.id, data)
713
+ f.removeUniqueFields(data, {})
714
+ var meta = spec['#meta'];
715
+
716
+ if(meta && meta.enableJDBC){
717
+ var sqls = deleteObject(data);
718
+ // $.log(sqls.join(";\n"));
719
+ }
720
+
721
+ if(meta){
722
+ // $.log("del meta.push=" + meta.push + ", id=" + data.id);
723
+ }
724
+
725
+ if(meta && meta.push){
726
+ KafkaUtil.send('owlchange',JSON.stringify(data),data.id);
727
+ }
728
+ EventBusService.fire(spec['_t'] + '_delete_after', {data: data})
729
+ },
730
+ getList: function (listName, start, limit) {
731
+ if (!listName) {
732
+ return null
733
+ }
734
+ if (!start) {
735
+ start = 0
736
+ }
737
+ if (!limit) {
738
+ limit = 10
739
+ }
740
+ return pigeon.getListObjects(listName, start, limit)
741
+ },
742
+
743
+ getExportRunningList: function () {
744
+ return listPrefix + '_exportRunning'
745
+ },
746
+
747
+ getExportFinishedList: function () {
748
+ return listPrefix + '_exportFinished'
749
+ },
750
+
751
+ addExportTask: function (query, env) {
752
+ var now = new Date().getTime()
753
+ var taskInfo = {
754
+ loginUser: f.getEnvValue('$loginUser', env),
755
+ submitTime: now,
756
+ startTime: 0,
757
+ processState: 'processing',
758
+ percent: 0,
759
+ _v: 0,
760
+ }
761
+ //这个key如果不多加一个export,会把原有的单据数据覆盖
762
+ var taskInfoId = objPrefix + '_export_' + pigeon.getId()
763
+ var taskId = JobsService.submitExportTask('@projectCode', 'tasks/export.jsx', {
764
+ query: query,
765
+ env: env,
766
+ taskInfoId: taskInfoId,
767
+ }, now)
768
+ taskInfo.taskId = '' + taskId
769
+ taskInfo.id = taskInfoId
770
+ var key = pigeon.getRKey(taskInfo.submitTime, 13)
771
+ pigeon.addToList(f.getExportRunningList(), key, taskInfoId)
772
+ pigeon.saveObject(taskInfoId, taskInfo)
773
+
774
+ return taskInfoId
775
+ },
776
+
777
+ addDocExportTask: function (docId, env) {
778
+ var now = new Date().getTime()
779
+ var taskInfo = {
780
+ loginUser: f.getEnvValue('$loginUser', env),
781
+ submitTime: now,
782
+ startTime: 0,
783
+ processState: 'processing',
784
+ percent: 0,
785
+ total: 1,
786
+ _v: 0,
787
+ }
788
+ //这个key如果不多加一个export,会把原有的单据数据覆盖
789
+ var taskInfoId = objPrefix + '_export_' + pigeon.getId()
790
+ var taskId = JobsService.submitExportTask('@projectCode', 'tasks/exportDoc.jsx', {
791
+ id: docId,
792
+ env: env,
793
+ taskInfoId: taskInfoId,
794
+ }, now)
795
+ taskInfo.taskId = '' + taskId
796
+ taskInfo.id = taskInfoId
797
+ var key = pigeon.getRKey(taskInfo.submitTime, 13)
798
+ pigeon.addToList(f.getExportRunningList(), key, taskInfoId)
799
+ pigeon.saveObject(taskInfoId, taskInfo)
800
+
801
+ return taskInfoId
802
+ },
803
+
804
+ addZipExportTask : function(env){
805
+ var now = new Date().getTime()
806
+ var taskInfo = {
807
+ loginUser: f.getEnvValue('$loginUser', env),
808
+ submitTime: now,
809
+ startTime: 0,
810
+ processState: 'processing',
811
+ percent: 0,
812
+ total: 0,
813
+ _v: 0,
814
+ }
815
+ //这个key如果不多加一个export,会把原有的单据数据覆盖
816
+ var taskInfoId = objPrefix + '_export_' + pigeon.getId()
817
+ var taskId = JobsService.submitExportTask('@projectCode', 'tasks/exportZip.jsx', {
818
+ env: env,
819
+ taskInfoId: taskInfoId,
820
+ }, now)
821
+ taskInfo.taskId = '' + taskId
822
+ taskInfo.id = taskInfoId
823
+ var key = pigeon.getRKey(taskInfo.submitTime, 13)
824
+ pigeon.addToList(f.getExportRunningList(), key, taskInfoId)
825
+ pigeon.saveObject(taskInfoId, taskInfo)
826
+ return taskInfoId
827
+ },
828
+
829
+ getExportTaskInfo: function (taskInfoId) {
830
+ return pigeon.getObject(taskInfoId)
831
+ },
832
+
833
+ updateExportTaskInfo: function (taskInfoId, taskInfo) {
834
+ var oInfo = f.getExportTaskInfo(taskInfoId)
835
+ if (oInfo._v == taskInfo._v) {
836
+ taskInfo._v += 1
837
+ pigeon.saveObject(taskInfoId, taskInfo)
838
+ }
839
+ },
840
+
841
+
842
+ reindexAll: function () {
843
+ var listName = f.getAllListName()
844
+ var count = pigeon.getListSize(listName)
845
+ $.log("reindexAll " + listName);
846
+ var pos = 0
847
+ while (count > 0) {
848
+ var indexCount = 2000
849
+ if (indexCount > count) {
850
+ indexCount = count
851
+ }
852
+ var objs = pigeon.getListObjects(listName, pos, indexCount)
853
+ objs.forEach(function (data) {
854
+ try {
855
+ f.index(data)
856
+ } catch (e) {
857
+ $.log('重建索引异常:' + data.id)
858
+ }
859
+ })
860
+ pos += indexCount
861
+ count -= indexCount
862
+ }
863
+ },
864
+
865
+ getAllSize:function(){
866
+ var listName = f.getAllListName();
867
+ var count = pigeon.getListSize(listName);
868
+ return count;
869
+ },
870
+
871
+ getAllObjects:function(){
872
+ var result = [];
873
+ var listName = f.getAllListName()
874
+ var count = pigeon.getListSize(listName)
875
+ var pos = 0
876
+ while (count > 0) {
877
+ var indexCount = 2000
878
+ if (indexCount > count) {
879
+ indexCount = count
880
+ }
881
+ var objs = pigeon.getListObjects(listName, pos, indexCount)
882
+ result = result.concat(objs);
883
+ pos += indexCount
884
+ count -= indexCount
885
+ }
886
+ return result;
887
+ },
888
+
889
+ getAllObjectsEx:function(from,count){
890
+ var listName = f.getAllListName()
891
+ var allsize = pigeon.getListSize(listName)
892
+ var pos = from
893
+ if(count+pos > allsize){
894
+ count = allsize - pos;
895
+ }
896
+ var objs = pigeon.getListObjects(listName, pos, count)
897
+ return objs;
898
+ },
899
+
900
+ createQuery:function(searchArgs){
901
+ var filters = [];
902
+ for(var k in searchArgs){
903
+ var v = searchArgs[k];
904
+ if(typeof v === 'object' && v.type === 'or'){
905
+ if(Array.isArray(v.args)){
906
+ var shouldClauses = [];
907
+ v.args.forEach(function(q){
908
+ var qFilters = f.createQuery(q);
909
+ if(qFilters.length > 0){
910
+ shouldClauses.push({
911
+ "bool":{
912
+ filters:qFilters
913
+ }
914
+ })
915
+ }
916
+ });
917
+
918
+ filters.push({bool:{should:shouldClauses}});
919
+ }
920
+ else if(v.args && typeof(v.args)=='object'){
921
+ var shouldClauses = [];
922
+ var qFilters = f.createQuery(v.args);
923
+ shouldClauses.push({bool:{filters:qFilters}});
924
+ filters.push({bool:{should:shouldClauses}});
925
+ }
926
+
927
+ }
928
+ else if(typeof(v)=='object' && Array.isArray(v)){
929
+ var range={}
930
+ range[k] = {
931
+ 'gte':v[0],
932
+ 'lte':v[1]
933
+ }
934
+ filters.push({range:range});
935
+ }
936
+ else if(typeof(v)=='object' && v.type==='terms'){
937
+ var terms = {};
938
+ if(v.values){
939
+ terms[k + ".keyword"] = v.values;
940
+ filters.push({terms:terms});
941
+ }
942
+ }
943
+ else{
944
+ var term = {};
945
+ if(typeof v == 'string' ){
946
+ if(v){
947
+ term[k+".keyword"] = trim('' + v)
948
+ filters.push({term:term})
949
+ }
950
+ }
951
+ else if (typeof v == 'number'){
952
+ term[k] = trim('' + v)
953
+ filters.push({term:term})
954
+ }
955
+ }
956
+ }
957
+ return filters;
958
+ },
959
+
960
+ buildQuery:function(mfilters,searchArgs,keyword){
961
+ delete searchArgs.keyword;
962
+ var filters = [];
963
+ var must_not = [{
964
+ term:{
965
+ "del.keyword":'T'
966
+ }
967
+ }];
968
+ for(var k in searchArgs){
969
+
970
+ var v = searchArgs[k];
971
+
972
+ var isNotClause = false;
973
+ if(k.indexOf("!")===0){
974
+ isNotClause = true;
975
+ k = k.substring(1);
976
+ }
977
+ if(typeof v === 'object' && v.type === 'or'){
978
+ var shouldClauses = [];
979
+ if(Array.isArray(v.args)){
980
+ v.args.forEach(function(q){
981
+ var shouldQueries = f.createQuery(q);
982
+ if(shouldQueries.length>0){
983
+ shouldClauses.push({bool:{filter:shouldQueries}});
984
+ }
985
+
986
+ });
987
+ if(isNotClause){
988
+ must_not.push({bool:{should:shouldClauses}});
989
+ }else{
990
+ filters.push({bool:{should:shouldClauses}});
991
+ }
992
+
993
+ }
994
+ else{
995
+ if(v.args && typeof(v.args)==='object'){
996
+ var shouldQueries = f.createQuery(v);
997
+ if(isNotClause){
998
+ must_not.push({bool:{should:shouldClauses}});
999
+ }else{
1000
+ filters.push({bool:{should:shouldClauses}});
1001
+ }
1002
+ }
1003
+ }
1004
+ }
1005
+ else if(typeof(v)=='object' && Array.isArray(v)){
1006
+ var range={}
1007
+ range[k] = {
1008
+ 'gte':v[0],
1009
+ 'lte':v[1]
1010
+ }
1011
+ if(isNotClause){
1012
+ must_not.push({range:range});
1013
+ }else{
1014
+ filters.push({range:range});
1015
+ }
1016
+ }
1017
+ else if(typeof(v)=='object' && v.type==='terms'){
1018
+ var terms = {};
1019
+ if(v.values){
1020
+ terms[k + ".keyword"] = v.values;
1021
+ if(isNotClause){
1022
+ must_not.push({terms:terms});
1023
+ }else{
1024
+ filters.push({terms:terms});
1025
+ }
1026
+ }
1027
+ }
1028
+ else{
1029
+ var term = {};
1030
+ if(typeof v == 'string' ){
1031
+ if(v){
1032
+ term[k+".keyword"] = trim('' + v)
1033
+ if(isNotClause){
1034
+ must_not.push({term:term});
1035
+ }else{
1036
+ filters.push({term:term});
1037
+ }
1038
+
1039
+ }
1040
+ }
1041
+ else if (typeof v == 'number'){
1042
+ term[k] = trim('' + v)
1043
+ if(isNotClause){
1044
+ must_not.push({term:term});
1045
+ }else{
1046
+ filters.push({term:term});
1047
+ }
1048
+ }
1049
+ }
1050
+ }
1051
+ if(mfilters && Array.isArray(mfilters) && mfilters.length>0){
1052
+ filters = filters.concat(mfilters);
1053
+ }
1054
+
1055
+ //getKeyword query
1056
+ var keywordQuery = "";
1057
+ if(keyword && trim(keyword).length>0){
1058
+ keywordQuery = "\"" + trim(keyword) + "\""
1059
+ }
1060
+ else{
1061
+ keywordQuery = "*"
1062
+ }
1063
+ var query = {
1064
+ "query": {
1065
+ "bool": {
1066
+ "must": {
1067
+ "query_string": {
1068
+ "query":keywordQuery
1069
+ }
1070
+ },
1071
+ "must_not": must_not,
1072
+ "filter": filters
1073
+ }
1074
+ }
1075
+ }
1076
+ return query;
1077
+ },
1078
+
1079
+ count:function(mfilters,searchArgs,keyword,dataSource){
1080
+ var query = f.buildQuery(mfilters,searchArgs,keyword);
1081
+ var elasticSearchUrl = $.getEnv( "elasticSearchUrl" );
1082
+
1083
+ var headers = { "Content-Type": "application/json;charset=utf-8" };
1084
+ var elasticSearchUser = $.getEnv("elasticSearchUser");
1085
+ var elasticSearchPass = $.getEnv("elasticSearchPass");
1086
+ if(elasticSearchUser && elasticSearchPass){
1087
+ var auth =Base64.encode(elasticSearchUser + ":" + elasticSearchPass);
1088
+ var basicAuth = "Basic " + auth;
1089
+ headers["Authorization"] = basicAuth;
1090
+ }
1091
+ var searchUrl = elasticSearchUrl+"/@projectCode/_count";
1092
+ if(dataSource){
1093
+ searchUrl = elasticSearchUrl + "/" + dataSource + "/_count";
1094
+ }
1095
+
1096
+ var sndTxt = JSON.stringify(query);
1097
+ var s = HttpUtils.postRaw( searchUrl, sndTxt, headers);
1098
+ var result = JSON.parse(s);
1099
+ if(result.count){
1100
+ return result.count;
1101
+ }
1102
+ return 0;
1103
+ },
1104
+ search: function(mfilters, searchArgs, keyword,from, pageSize, sort, dataSource){
1105
+ var query = f.buildQuery(mfilters,searchArgs,keyword);
1106
+ var effectiveSort = [{owl_createTime:{order:"desc"}}];
1107
+ if(sort){
1108
+ effectiveSort = sort;
1109
+ } var effectiveSort = [{owl_createTime:{order:"desc"}}];
1110
+ if(sort){
1111
+ effectiveSort = sort;
1112
+ }
1113
+ query.from = from;
1114
+ query.size = pageSize;
1115
+ query.sort = effectiveSort;
1116
+
1117
+ var elasticSearchUrl = $.getEnv( "elasticSearchUrl" );
1118
+
1119
+ var headers = { "Content-Type": "application/json;charset=utf-8" };
1120
+ var elasticSearchUser = $.getEnv("elasticSearchUser");
1121
+ var elasticSearchPass = $.getEnv("elasticSearchPass");
1122
+ if(elasticSearchUser && elasticSearchPass){
1123
+ var auth =Base64.encode(elasticSearchUser + ":" + elasticSearchPass);
1124
+ var basicAuth = "Basic " + auth;
1125
+ headers["Authorization"] = basicAuth;
1126
+ }
1127
+ var searchUrl = elasticSearchUrl+"/@projectCode/_search";
1128
+ if(dataSource){
1129
+ searchUrl = elasticSearchUrl + "/" + dataSource + "/_search";
1130
+ }
1131
+
1132
+ var sndTxt = JSON.stringify(query);
1133
+ var s = HttpUtils.postRaw( searchUrl, sndTxt, headers);
1134
+ var result = JSON.parse(s);
1135
+
1136
+ if(!result.hits || !result.hits.hits){
1137
+ $.log("error search:sndQuery=" + sndTxt + "------\nresponse:\n" + s );
1138
+ var ret = {
1139
+ state:'ok',
1140
+ list:[],
1141
+ total:{value:0}
1142
+ }
1143
+ out.print(JSON.stringify(ret));
1144
+ return;
1145
+ }
1146
+
1147
+ var hits = result.hits.hits;
1148
+ var total = result.hits.total;
1149
+
1150
+ var objs = hits.map(function(hit){return hit._source});
1151
+
1152
+
1153
+ var ret = {
1154
+ state:'ok',
1155
+ list:objs,
1156
+ total:total
1157
+ }
1158
+
1159
+ return ret;
1160
+
1161
+ }
1162
+ }
1163
+ return f;
1164
1164
  })($S);