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