fs-danaus
2022-05-13 2e60c6034fdfbcfbc4d7a91f0a84926688a50009
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
package com.yc.app.v2.service.impl;
 
import com.google.gson.Gson;
import com.yc.action.grid.GridUtils;
import com.yc.action.grid.RecentAccessEntity;
import com.yc.api.service.ApiServiceIfc;
import com.yc.app.util.ResponseMessage;
import com.yc.app.v2.controller.APPController;
import com.yc.app.v2.entity.*;
import com.yc.app.v2.service.BaseFormService;
import com.yc.app.v2.utils.Page;
import com.yc.entity.TableColumnsDataTypeEntity;
import com.yc.exception.ApplicationException;
import com.yc.factory.FactoryBean;
import com.yc.service.BaseService;
import com.yc.service.build.top.FuncLinkSpellUtil;
import com.yc.service.grid.GridServiceIfc;
import com.yc.service.sqlformat.entity.SqlFormatEntity;
import com.yc.service.sqlformat.utils.SqlFormatUtils;
import com.yc.utils.FormOpUtil;
import com.yc.utils.PostfixExpression;
import com.yc.utils.SessionKey;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.SqlOutParameter;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
 
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.sql.Types;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
 
/**
 * 窗体类型基类
 */
@Service
public class BaseFormServiceImpl extends BaseService implements BaseFormService {
    @Autowired
    GridServiceIfc gridService;
    @Autowired
    ThreadPoolTaskExecutor threadPoolExecutor;
@Autowired
    ApiServiceIfc apiServiceIfc;
    protected static String sysfunclink = "b.[origformid]            " +
            ",b.[origformtype]         " +
            ",b.[sortid]               " +
            ",b.[linklabel]            " +
            ",b.[linkformid]           " +
            ",b.[linkformtype]         " +
            ",b.[linkdescribe]         " +
            ",b.[linkmode]             " +
            ",b.[hotkey]               " +
            ",b.[spfield]              " +
            ",b.[close_origform]       " +
            ",b.[origfields]           " +
            ",b.[linkfields]           " +
            ",b.[orighdfields]         " +
            ",b.[linkhdfields]         " +
            ",b.[efilter]              " +
            ",b.[warnmessage]          " +
            ",b.[self_datafields]      " +
            ",b.[link_datafields]      " +
            ",b.[firstrecord_editmode] " +
            ",b.[return_one_record]    " +
            ",b.[numfieldid]           " +
            ",b.[locksqlwhere]         " +
            ",b.[showbutton]           " +
            ",b.[returndataset]        " +
            ",b.[refresh_origform]     " +
            ",b.[numfieldid_origform]  " +
            ",b.[noshowspmessage]      " +
            ",b.[linkformdisplayfields]" +
            ",b.[ftlockconditionflag]  " +
            ",b.[groupname]            " +
            ",b.[navigateyn]           " +
            ",b.[editstatus]           " +
            ",b.[isshowpwdedit]        " +
            ",b.[selectchecker]        " +
            ",b.[returncurchecker]     " +
            ",b.[returncurcheckername] " +
            ",b.[smallimagefilename]   " +
            ",b.[smallimagefilepath]   " +
            ",b.[ft]                   " +
            ",b.[ftformtype]           " +
            ",b.[fk]                   " +
            ",b.[seekgroupid]          " +
            ",b.[spremissfield]        " +
            ",b.[dpremissfield]        " +
            ",b.[fkefilter]            " +
            ",b.[isautosaved]          " +
            ",b.[showitemexpression]   " +
            ",b.[linkscope]            ";
 
 
    private static String sysmasterdetail = "[formid]   " +
            ",[detailformid]    " +
            ",[masterfield]     " +
            ",[masterkeys]      " +
            ",[detailkeys]      " +
            ",[mastersumfields] " +
            ",[detailsumfields] " +
            ",[detailreadonly]  " +
            ",[detailmemo]      " +
            ",[sequenceid]      " +
            ",[gridheight]      ";
 
    protected static String systreeset = "[formid]              " +
            ",[formtype]           " +
            ",[treeformid]         " +
            ",[treeName]           " +
            ",[SortID]             " +
            ",[keyfield]           " +
            ",[parentfield]        " +
            ",[nodeid]             " +
            ",[listfield]          " +
            ",[displayfield]       " +
            ",[separatedst]        " +
            ",[treefield]          " +
            ",[autocodefield]      " +
            ",[treefilterstr]      " +
            ",[authcheck]          " +
            ",[allowdrag]          " +
            ",[defNodeTypeFilter]  " +
            ",[startnodetypefilter]" +
            ",[treewidth]";
 
    protected static String TabPageFormid = "[mainformid]      " +
            ",[mainformname]   " +
            ",[FormGroupID]    " +
            ",[FormGroupName] " +
            ",[SortBy]        " +
            ",[formid]        " +
            ",[formname]      " +
            ",[formtype]      " +
            ",[LabelName]     " +
            ",[FT]            " +
            ",[FTName]        " +
            ",[FK]            " +
            ",[SeekGroupID]   " +
            ",[GridHeight]    " +
            ",[GroupID]       " +
            ",[GroupName]     " +
            ",[TabID]         " +
            ",[TabName]         " +
            ",[TabHeight]     " +
            ",[isStartupCollapsed]";
    protected static String table3 =
            "a.[buttonID]              ," +
                    "a.[ButtonName]            ," +
                    "a.[formid]                ," +
                    "a.[headflag]              ," +
                    "a.[fieldid]               ," +
                    "a.[docitem]               ," +
                    "a.[ProcName]              ," +
                    "a.[Memo]                  ," +
                    "a.[isShowPwdEdit]         ," +
                    "a.[editStatus]            ," +
                    "a.[SelectChecker]         ," +
                    "a.[ReturnCurChecker]      ," +
                    "a.[ReturnCurCheckerName]  ," +
                    "a.[FT]                    ," +
                    "a.[FTFormType]            ," +
                    "a.[FK]                    ," +
                    "a.[SeekGroupID]           ," +
                    "a.[sPremissField]         ," +
                    "a.[dPremissField]         ," +
                    "a.[FKeFilter]             ," +
                    "a.[isAutoSaved]           ," +
                    "a.[showItemExpression]    ," +
                    "a.[isInspection]          ," +
                    "a.[isExchangeDataWithHost]," +
                    "a.[UrlShowLocation]       ," +
                    "a.[ExternalURL],           " +
                    "b.[IconPath],b.[isReturnToLastPage]          \n ";
 
    protected final String getDataType = "set nocount on select\n" +
            "col.COLUMN_NAME as ColumnName,\n" +
            "col.DATA_TYPE as DataType,\n" +
            "col.CHARACTER_OCTET_LENGTH as DataLength\n" +
            "--col.IS_NULLABLE as IsNullable,\n" +
            "--ccu.CONSTRAINT_NAME as IsPrimaryKey,\n" +
            "--de.value as Description\n" +
            "from INFORMATION_SCHEMA.COLUMNS col\n" +
            "left join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu\n" +
            "on ccu.TABLE_NAME=col.TABLE_NAME\n" +
            "and ccu.COLUMN_NAME=col.COLUMN_NAME\n" +
            "and ccu.CONSTRAINT_NAME like 'PK_%'\n" +
            "left join ::fn_listextendedproperty (NULL, 'user', 'dbo', 'table', ?,'column', default) as de\n" +
            "on col.COLUMN_NAME = de.objname COLLATE Chinese_PRC_CI_AS\n" +
            "where col.TABLE_NAME=?";
 
 
    /**
     * 获取功能号相关的配置信息
     * 各个不同类型的窗体需要重写,增加特定的配置
     *
     * @param formVOEntity
     * @return
     */
    @Override
    public MetaDataEntity getMetaData(FormVOEntity formVOEntity, Map<String, String> env) {
/**
 * 获取元数据流程
 *
 * 1,redis是否存在当前功能号的元数据
 *   不存在:
 *      按流程生成元数据,然后保存到redis
 *   存在:
 *      对比版本号:
 *          相同--不需要返回到前端,但需要取出来给取数的功能使用
 *         不相同---需要返回前端,继续给取数的功能使用
 * 2,
 *
 *
 *
 * 是否和redis的版本一致,是则不返回前端
 * 不是则
 *
 *
 *
 *
 * */
        if (formVOEntity.getVersion() != null) {
            final Integer version = this.getSimpleJdbcTemplate().queryForObject(" set nocount on ; declare @FormId int = ?,@OldVersion int = ?,@Version int,@isFound int = 0\n" +
                    "if @OldVersion is null\n" +
                    "begin\n" +
                    "   set @isFound = 1 \n" +
                    "end \n" +
                    "if isnull(@isFound,0) = 0\n" +
                    "begin \n" +
                    "   select @Version = Version from gform where formid=@FormId\n" +
                    "   if isnull(@version,0) <> isnull(@OldVersion,0)  set @isFound = 1 else set @isFound = 0 \n" +
                    "end\n" +
                    "select @isFound ", Integer.class, formVOEntity.getFormId(), formVOEntity.getVersion());
            //版本号相同表示不需要生成元数据
            if (version == 0) {
                //return null;
                formVOEntity.setNoMeta(true);
            }
        }
        Integer int_formid = formVOEntity.getFormId();
        Integer formType = formVOEntity.getFormType();
 
        Map<String, Object> map = new HashMap<String, Object>();
 
        map.put("formType", formType);
        GformEntity gformEntity = this.getSimpleJdbcTemplate().queryForObject(gridService.getGET_GFORM().toLowerCase(), new BeanPropertyRowMapper<>(GformEntity.class), int_formid);
        //----TODO 功能链接,放到二次请求,尽量输出重要的内容
        map.put("9842", this.getFunLinks(formVOEntity, env, gformEntity));
 
        //----菜单项权限(新单,保存,删单,确认...)
        map.put("9646", this.prossPersion(formVOEntity, gformEntity));
 
        //dataResult.put("9801", this.procc9801SQLFormat(gformEntity));
        map.put("9801", gformEntity);
        List<Map<String, Object>> gFieldEntityList = this.getSimpleJdbcTemplate().queryForList("set nocount on ; select " + gridService.getGET_GFIELD().toLowerCase() + " from gfield where formid=?  order by statisid asc", int_formid);
        if (isNotDanJuDetail(formVOEntity.getFormType())) {
            //----列表可查询字段
            map.put("queryFieldList", this.getQueryFieldList(gFieldEntityList));
        }
        //--功能号的颜色图样
        map.put("9685",apiServiceIfc.get9685List(gformEntity.getFormid()));
        //---处理生成动态sql
        //dataResult.put("9802", procc9802SQLFormat(gFieldEntityList));
        map.put("9802", gFieldEntityList);
        //----自定义时间查询,
        map.put("9816", this.getSysDateFilterEntitys(int_formid));
 
 
        return new MetaDataEntity(gformEntity, gFieldEntityList, map);
 
    }
 
    private boolean isNotDanJuDetail(Integer type) {
        //不是单据的列表
        return (type != 5 && type != 8 && type != 16 && type != 496 && type != 498) ? true : false;
    }
 
    protected Map<String, Object> Obj2Map(Object obj) {
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(obj));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return map;
    }
 
    protected Map procc9801SQLFormat(GformEntity gformEntity) {
        Map<String, Object> map9801 = Obj2Map(gformEntity);
        final Map<String, SqlFormatEntity> sqlFormat = SqlFormatUtils.createSQLFormat(map9801, 9801);
        map9801.putAll(sqlFormat);
        return map9801;
    }
 
    protected Map<String, List> procc9802SQLFormat(List<Map<String, Object>> gFieldEntityList) {
        gFieldEntityList.stream().map(x -> {
 
            final Map<String, SqlFormatEntity> sqlFormat = SqlFormatUtils.createSQLFormat(x, 9802);
            x.putAll(sqlFormat);
            return x;
        }).collect(toList());
        List<Map<String, Object>> master = gFieldEntityList.stream().filter(x -> GridUtils.prossRowSetDataType_Int(x, "Headflag") == 0).collect(toList());
        List<Map<String, Object>> slave = gFieldEntityList.stream().filter(x -> GridUtils.prossRowSetDataType_Int(x, "Headflag") == 1).collect(toList());
        Map<String, List> total = new HashMap<>(2);
        total.put("master", master);//主表
        total.put("slave", slave);//从表
        return total;
    }
 
 
    /**
     * 功能号的操作权限
     *
     * @return
     */
    private Map prossPersion(FormVOEntity formVOEntity, GformEntity gformEntity) {
        //权限值
        int perssionValue = 0;
        if (formVOEntity.isAdmin()) {
            //管理员有全部权限
            if (gformEntity.getOptype() != null) {
                perssionValue = gformEntity.getOptype() & FormOpUtil.TotalOP;
            } else {
                perssionValue = FormOpUtil.TotalOP;
            }
        } else {
            final Map map = (Map) formVOEntity.getPersion().get(formVOEntity.getFormId() + "");
            if (map == null) {
                //多表子功能号的权限取主功能号
                if (formVOEntity.getIs496() != null && formVOEntity.getIs496() == 1) {
                    return null;
                } else {
                    throw new ApplicationException("没有打开" + formVOEntity.getFormId() + "功能号权限,请联系系统管理员");
                }
            } else {
                //9801设置的操作权限,优先级最高
                if (gformEntity.getOptype() != null) {
                    perssionValue = gformEntity.getOptype() & (Integer) map.get("optype");
                } else {
                    perssionValue = (Integer) map.get("optype");
                }
            }
        }
        return getOPType(perssionValue);
    }
 
    /**
     * 通过当前权限值,取出所有的权限
     *
     * @param perssionValue
     * @return
     */
    private Map getOPType(int perssionValue) {
        Map map = new HashMap();
        if ((perssionValue & FormOpUtil.excutionProcess) == FormOpUtil.excutionProcess) {
            map.put(FormOpUtil.excutionProcess, "执行");
        }
        if ((perssionValue & FormOpUtil.ExportData) == FormOpUtil.ExportData) {
            map.put(FormOpUtil.ExportData, "导出");
        }
        if ((perssionValue & FormOpUtil.importData) == FormOpUtil.importData) {
            map.put(FormOpUtil.importData, "导入");
        }
        if ((perssionValue & FormOpUtil.cancelConfirmation) == FormOpUtil.cancelConfirmation) {
            map.put(FormOpUtil.cancelConfirmation, "取消确认");
        }
        if ((perssionValue & FormOpUtil.confirmDocument) == FormOpUtil.confirmDocument) {
            map.put(FormOpUtil.confirmDocument, "确认");
        }
        if ((perssionValue & FormOpUtil.copydoc) == FormOpUtil.copydoc) {
            map.put(FormOpUtil.copydoc, "复单");
        }
        if ((perssionValue & FormOpUtil.copyRecord) == FormOpUtil.copyRecord) {
            map.put(FormOpUtil.copyRecord, "复行");
        }
 
        if ((perssionValue & FormOpUtil.deleteDocument) == FormOpUtil.deleteDocument) {
            map.put(FormOpUtil.deleteDocument, "删单");
        }
 
        if ((perssionValue & FormOpUtil.deleteRecord) == FormOpUtil.deleteRecord) {
            map.put(FormOpUtil.deleteRecord, "删行");
        }
        if ((perssionValue & FormOpUtil.insertRecord) == FormOpUtil.insertRecord) {
            map.put(FormOpUtil.insertRecord, "增行");
        }
        if ((perssionValue & FormOpUtil.listDoc) == FormOpUtil.listDoc) {
            map.put(FormOpUtil.listDoc, "清单");
        }
        if ((perssionValue & FormOpUtil.newDocument) == FormOpUtil.newDocument) {
            map.put(FormOpUtil.newDocument, "新单");
        }
        if ((perssionValue & FormOpUtil.offsetDocument) == FormOpUtil.offsetDocument) {
            map.put(FormOpUtil.offsetDocument, "冲销");
        }
        if ((perssionValue & FormOpUtil.openQuery) == FormOpUtil.openQuery) {
            map.put(FormOpUtil.openQuery, "查询");
        }
        if ((perssionValue & FormOpUtil.printButton) == FormOpUtil.printButton) {
            map.put(FormOpUtil.printButton, "打印");
        }
        if ((perssionValue & FormOpUtil.reportEsign) == FormOpUtil.reportEsign) {
            map.put(FormOpUtil.reportEsign, "报表");
        }
        if ((perssionValue & FormOpUtil.revokeConfirmation) == FormOpUtil.revokeConfirmation) {
            map.put(FormOpUtil.revokeConfirmation, "撤消");
        }
        if ((perssionValue & FormOpUtil.saveRecord) == FormOpUtil.saveRecord) {
            map.put(FormOpUtil.saveRecord, "保存");
        }
 
        return map;
    }
 
    @Override
    public Page getData(FormVOEntity formVOEntity, Map<String, String> env, MetaDataEntity metaDataEntity) {
        Page page = new Page();
        GformEntity gformEntity = metaDataEntity.getGformEntity();
        if (formVOEntity.isNew()) {
            //新建直接返回
            this.orderBySql(gformEntity, formVOEntity, " desc");
            return page;
        }
//        //根据功能号,是否为主表,查出表名,需要查询的字段列表,where条件
//        //------TODO 9801
        //根据条件取主或从表的9802设置
        List<Map<String, Object>> gFieldEntityList = metaDataEntity.getGFieldEntity().stream().filter(x -> {
            if (x.get("headflag") != null && StringUtils.isNotBlank(x.get("headflag") + "")) {
                int flag = Integer.parseInt(x.get("headflag") + "");
                if (gformEntity.isGetHeadTabe()) {
                    //主表
                    return flag == 0;
                } else {
                    //从表
                    return flag == 1;
                }
            }
            return false;
        }).collect(toList());
 
        //------TODO 主键id
        //------TODO Filter
        //------TODO showFieldValueExpression
 
        //------TODO stylecss
        //------TODO TipsExpression
        //------TODO sql
 
        List<String> valueExp = new ArrayList<>();//字段(id,权限,css,tips)
        Map tbExpMap = new HashMap<>();//统计列权限
        List<String> tbCols = new ArrayList<>();//统计字段
        String tbColsFieldsList = "";//保存统计字段,方便取数后拼接输出
        Gson gson = new Gson();
        for (Map<String, Object> map : gFieldEntityList) {
            GFieldEntity gFieldEntity = gson.fromJson(gson.toJson(map), new com.google.gson.reflect.TypeToken<GFieldEntity>() {
            }.getType());
            //-----由各自实现指定是取面板还是格线的控件类型
            Integer controltype = getGridControlType(gFieldEntity, gformEntity);
            //----格线列表,设置不显示则也不需要生成
            boolean isLoad = (gFieldEntity == null || gFieldEntity.getIsload() == null || gFieldEntity.getIsload() == 0) ? false : true;
            if (controltype == 33 || controltype == 34 || controltype == 38 || controltype == 41) {//这些控件类型在数据库是不存在,需要排除
                isLoad = false;
            }
            String fieldId = gFieldEntity.getFieldid().toLowerCase();
            //---只能有列出来的字段都输出
            if (isLoad || (",entercode,enterdate,entername,modifydate,modifyname,postdate,postname,").contains("," + fieldId + ",")) {//符合条件
                if (StringUtils.isBlank(gFieldEntity.getFieldid())) {
                    throw new ApplicationException("字段Fieldid不能为空");
                }
 
                if (StringUtils.isBlank(page.getId())) {
                    page.setId(gFieldEntity.getFieldid());
                }
                if (StringUtils.isNotBlank(gFieldEntity.getShowfieldvalueexpression())) {
                    //----0,1,2的权限值
                    String expr = " case when (" + gFieldEntity.getShowfieldvalueexpression() + ") =1 then 1   when (" + gFieldEntity.getShowfieldvalueexpression() + ") =2 then 2 else 0 end as [" + fieldId + "_expr]";
                    //----统计列表,增加权限判断,如果没权限就变为0进行统计了
                    String tbexpr = " case when (" + gFieldEntity.getShowfieldvalueexpression() + ") = 0  then 0 else   " + fieldId + " end ";
                    valueExp.add(expr);
                    //----权限表达式决定是星号还是原值,
                    // 还没更新这个[由于前端公式需要用到原值,不能直接输出星号 by danaus 2021/3/15 15:46]
                    String valueExpr = " case  (" + gFieldEntity.getShowfieldvalueexpression() + ")  when  0  then '******'  else cast(" + fieldId + " as varchar(30)) end as [" + fieldId + "]";
                    valueExp.add(valueExpr);
                    // valueExp.add("[" + fieldId + "]");
                    tbExpMap.put(fieldId, tbexpr);
                } else {
                    valueExp.add("[" + fieldId + "]");
                }
                if (StringUtils.isNotBlank(gFieldEntity.getStylecss())) {
                    valueExp.add(" (" + prossExclamationMark(gFieldEntity.getStylecss()) + " ) as [" + fieldId + "_cssexpr]");
                }
                if (StringUtils.isNotBlank(gFieldEntity.getTipsexpression())) {
                    valueExp.add(" (" + prossExclamationMark(gFieldEntity.getTipsexpression()) + " ) as [" + fieldId + "_tipsexpr]");
                }
                //System.out.println(fieldId);
                //------TODO 统计列
                if (gFieldEntity.getSumfield() != null && gFieldEntity.getSumfield() != 0) {
                    tbColsFieldsList += fieldId.toLowerCase() + "#";
                    tbCols.add(fieldId.toLowerCase() + "#" + gFieldEntity.getSumfield() + ":" + (StringUtils.isNotBlank(gFieldEntity.getFunclinkname()) ? gFieldEntity.getFunclinkname() : ""));
                }
            }
        }
 
        page.setFormid(formVOEntity.getFormId());
        page.setTbColsFieldsList(tbColsFieldsList);
        page.setTbCols(String.join(",", tbCols));
        page.setTbExpr(tbExpMap);
        String expr = String.join(",", valueExp);
        expr += this.getCancelBtnAndRevokeBtn(gformEntity, formVOEntity);
        //替换参数
        page.setSql(prossExpressionFormSessionValues(expr, env));
//        if (StringUtils.isBlank(gformEntity.getHdtable())) {
//            throw new ApplicationException(gformEntity.getFormid() + "主表不能为空");
//        }
        //----通过子类重写实现不同的功能
        page.setOrderBy(this.orderBySql(gformEntity, formVOEntity, " desc"));
        if (StringUtils.isBlank(page.getOrderBy())) {
            //什么都没设置排序,取id,多数是视图才会出现这种情况
            page.setOrderBy(page.getId() + " asc");
        }
        page.setPageNum(this.setPageNum(formVOEntity));
        page.setTableName(this.setTableName(gformEntity));
        page.setOrigWhere(formVOEntity.getWhere());
        page.setPageSize(formVOEntity.getPageSize());
        //------处理where条件
        String where = this.parseWhere(formVOEntity.getWhere());
        //-----各个不同窗体类型需要重写这个方法实现各自的拼接规则
        where = this.customCondition(formVOEntity, gformEntity, where, env);
        //---处理数据组权限,参数替换
        String newwhere = this.compareWhere(gformEntity, where, env);
        page.setWhere(newwhere);
        //----执行前处理,
        // -----打开单据时执行
        perDanJuOpenProc(formVOEntity, env);
        //-----取数
        page.setUserCode(env.get(SessionKey.USERCODE));
        page.setUserName(env.get(SessionKey.USER_NAME));
        page.setEnv(env);
        page = this.loadDataByPage(page);
        //-----执行后处理
        //-----如:处理是否有权限查看单据...
        this.prossDanJuPerssion(page, metaDataEntity, env, formVOEntity);
        return page;
    }
 
    public void getMainFormData(FormVOEntity formVOEntity, Map<String, String> env) {
        if (formVOEntity.getIs496() != null && formVOEntity.getIs496().intValue() == 1 && !formVOEntity.isNew() && formVOEntity.getMainFormId() != null && formVOEntity.getMainFormId() != 0 && StringUtils.isNotBlank(formVOEntity.getDocCode())) {
            //表示是多表
 
            String sql = this.jdbcTemplate.queryForObject(" set nocount  on \n select stuff((SELECT ',' + CONVERT(VARCHAR, isnull(a.fieldid,''))+'#'+CONVERT(VARCHAR, isnull(b.hdtable,'')) from gField a join gform b on a.formid=b.formid where a.formid=? and isnull(a.headflag,0)=0 and a.controltype  in(1,2,3,5,6,7,9,19,30,31,32,3) and isnull(a.isLoad,0)=1 FOR XML PATH ('')),1,1,'')", String.class, formVOEntity.getMainFormId());
            final String[] split = sql.split(",");
            String tableNmae = "";
            for (String str : split) {
                final String[] split1 = str.split("#");
                tableNmae = split1[1];
                break;
            }
            sql = sql.replaceAll("#" + tableNmae, "");
            Map map = this.jdbcTemplate.queryForMap("select " + sql.toLowerCase() + " from " + tableNmae + " where docCode=?", formVOEntity.getDocCode());
            env.putAll(map);
        }
    }
 
    @Override
    public String getCancelBtnAndRevokeBtn(GformEntity gformEntity, FormVOEntity is496) {
        return "";
    }
 
    @Override
    public void perDanJuOpenProc(FormVOEntity formVOEntity, Map<String, String> env) {
 
    }
 
    @Override
    public void prossDanJuPerssion(Page page, MetaDataEntity metaDataEntity, Map<String, String> env, FormVOEntity formVOEntity) {
        // TODO ----由需要处理的子类来实现
    }
 
    @Override
    public void handleDataResultByposted(Page page, MetaDataEntity metaDataEntity) {
        // TODO ----有需要处理,由子类来实现
        //----1,处理9801,9802的动态sql替换
        GformEntity gformEntity = (GformEntity) metaDataEntity.getInfo().get("9801");
        metaDataEntity.getInfo().put("9801", procc9801SQLFormat(gformEntity));
        List<Map<String, Object>> gFieldEntityList = (List<Map<String, Object>>) metaDataEntity.getInfo().get("9802");
        metaDataEntity.getInfo().put("9802", procc9802SQLFormat(gFieldEntityList));
        //-----2,2类型下拉数据
        metaDataEntity.getInfo().put("select2", getSelect(gformEntity.getFormid()));
 
    }
 
    void handleData(Map dataResult, List<Map<String, Object>> gfieldsList, boolean isNew, Integer docStatus) {
        //处理只读
        for (Map gfield : gfieldsList) {
            //存在于数据集里面的才需要处理
            if (isNew || (dataResult != null && dataResult.containsKey(gfield.get("fieldid")))) {
                String fieldid = gfield.get("fieldid") + "";
                int readonly = GridUtils.prossRowSetDataType_Int(gfield, "readonly");
                int editStatus = GridUtils.prossRowSetDataType_Integer(gfield, "editstatus");
                //if(docStatus!=null&&editStatus)
 
 
            }
        }
    }
 
    /**
     * 获取功能号主从表的所有2类型下拉数据
     *
     * @return
     */
    protected Map getSelect(int formid) {
        String sql = " SET NOCOUNT ON   \n declare @dictValues varchar(max) ,@dictid int,@fieldid varchar(500)\n" +
                "declare @fieldValues varchar(max),@headFieldValues varchar(max),@headflag int\n" +
                "declare @table table (headflag int,fieldid varchar(500),dictid int,sequence int,dictvalue varchar(800),\n" +
                "  interValue varchar(800),Primary Key(headflag,fieldid,dictid,sequence))\n" +
                "insert into @table (fieldid,headflag,dictid,sequence,dictvalue,interValue)\n" +
                "select LOWER(a.fieldid),a.headflag,b.dictid,b.sequence,b.dictvalue,b.interValue \n" +
                "from gfield a  join  _sysdict b on a.ft = b.dictid\n" +
                "where   a.formid = ? and  a.ft < 0\n" +
                "order by a.headflag asc,a.fieldid asc,b.dictid asc,b.sequence asc \n" +
                "declare myFieldHeadFlagCur cursor for\n" +
                "select distinct headflag from @table order by headflag asc\n" +
                "open myFieldHeadFlagCur\n" +
                "fetch next from myFieldHeadFlagCur into @headflag \n" +
                "while @@FETCH_STATUS = 0\n" +
                "begin \n" +
                "\tselect @fieldValues = ''\n" +
                "\tdeclare myDictValueCur cursor for \n" +
                "\tselect distinct dictid,fieldid  from @table where headflag = @headflag\n" +
                "\torder by fieldid asc,dictid asc \n" +
                "\topen myDictValueCur \n" +
                "\tfetch next from myDictValueCur into @dictid ,@fieldid\n" +
                "\twhile @@FETCH_STATUS = 0 \n" +
                "\tbegin \n" +
                "\t\tset @dictValues = ''\n" +
                "\t\tselect @dictValues = case when isnull(@dictValues,'') = '' then '' else isnull(@dictValues,'')+',' end +\n" +
                "\t\t\t'{\"fieldid\":\"' + isnull(interValue,'') + '\",\"fieldname\":\"' + isnull(dictValue,'') + '\"}'\n" +
                "\t\tfrom @table a \n" +
                "\t\twhere a.fieldid = @fieldid and a.headflag = @headflag and a.dictid = @dictid \n" +
                "\t\torder by a.sequence asc\n" +
                "\n" +
                "\t\tselect @fieldValues = case when isnull(@fieldValues,'') = '' then '' else isnull(@fieldValues,'') + ',' end \n" +
                "\t\t   + '\"'+ @fieldid + '\":[' + @dictValues + ']'\n" +
                "\tfetch next from myDictValueCur into @dictid ,@fieldid\n" +
                "\tend \n" +
                "\tclose myDictValueCur\n" +
                "\tdeallocate myDictValueCur \n" +
                "\tselect @headFieldValues = case when isnull(@headFieldValues,'') = '' then '' else isnull(@headFieldValues,'') + ',' end \n" +
                "\t   +'\"'+  cast(isnull(@headflag,0) as varchar(20))+'\":{'+ isnull(@fieldValues,'') + '}'\n" +
                "\n" +
                "\tfetch next from myFieldHeadFlagCur into @headflag \n" +
                "end \n" +
                "close myFieldHeadFlagCur \n" +
                "deallocate myFieldHeadFlagCur \n" +
                "delete from @table \n" +
                "select '{'+isnull(@headFieldValues,'')+'}' as headFieldValues";
 
        String json = gridService.getSimpleJdbcTemplate().queryForObject(sql, String.class, formid);
        return GridUtils.fromJson(json);
    }
 
    /**
     * 不同窗体类型会有不同的规则处理,需要各自实现
     * 默认实现为不处理
     *
     * @param gformEntity
     * @param where
     * @param env
     * @return
     */
    protected String customCondition(FormVOEntity formVOEntity, GformEntity gformEntity, String where, Map<String, String> env) {
        return where;
    }
 
    /***
     * 组合各种条件
     *
     * @param where 解码后的where
     * @return
     */
    protected String compareWhere(GformEntity gformEntity, String where, Map<String, String> env) {
        if (!gformEntity.isGetHeadTabe()) return where;
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotBlank(where)) {
            sb.append(where.replaceAll("&gt;", ">").replaceAll("&lt;", "<").replaceAll("&nbsp;", " ")
                    .replaceAll("&amp;", "").replaceAll("nbsp;", " ").replaceAll("\\b_ycid_\\b", "id").replaceAll("@P@", ""));
        }
        //---表头过滤
        if (StringUtils.isNotBlank(gformEntity.getFormdatafilters())) {
            String formFilter = gformEntity.getFormdatafilters();
            if (StringUtils.isBlank(where)) {
                sb.append(formFilter);
            } else {
                sb.append(" and (").append(formFilter).append(") ");
            }
        }
        //-----dataFormid
        sb.append(this.getDataformid(gformEntity));
 
        //----数据组权限
 
        String dataGroup = this.prossDataGroupInfo(gformEntity.getFormid(), env.get(SessionKey.USERCODE), 0, env);
        sb.append(dataGroup);
        return sb.toString();
 
    }
 
    @Override
    public Integer getGridControlType(GFieldEntity gFieldEntity, GformEntity gformEntity) {
        //默认取格线的控件类型设置
        throw new ApplicationException("子类需要实现读取9802指定控件类型是取面板还是格线的设置");
    }
 
    protected String getDataformid(GformEntity gformEntity) {
        String dataFormid = "";
        if (StringUtils.isNotBlank(gformEntity.getDataformid()) && !"0".equalsIgnoreCase(gformEntity.getDataformid())) {
            dataFormid = " or (formid in(" + gformEntity.getDataformid().replaceAll(";", ",") + "))";
        }
        return dataFormid;
    }
 
    @Override
    public ResponseMessage loadData(FormVOEntity formVOEntity, Map<String, String> env) {
        ResponseMessage responseMessage = new ResponseMessage();
        Map map = new HashMap();
        Map otherMap = new HashMap();
        Map otherInfo = new HashMap();
        MetaDataEntity metaData = this.getMetaData(formVOEntity, env);//元数据
        Page page = this.getData(formVOEntity, env, metaData);
        //---由当前用户的权限,单据状态等再次加工处理返回前端的数据(拼接超链接,只读状态,操作权限....)
        this.handleDataResultByposted(page, metaData);
        if (page.getOtherInfo() == null) {
            otherMap.put("isView", formVOEntity.getIsView());
            otherMap.put("primaryKey", formVOEntity.getPrimaryKey());
            otherMap.put("tableName", formVOEntity.getTableName());
            otherInfo.put("master", otherMap);
            //---对9816,需要每次都是取最新的时间,所以不能做缓存处理
            otherInfo.put("9816", metaData.getInfo().get("9816"));
            map.put("otherInfo", otherInfo);
        } else {
            //----5,8类型
            map.put("otherInfo", page.getOtherInfo());
        }
        //---写入到最近浏览记录
        if(
                (formVOEntity.getMainFormId()==null||formVOEntity.getMainFormId()==0)//MainFormId有值都是表示子功能号的情况(8,496)
        ) {
            //不是子功能号才需要记录,用于496,8类型
            APPController appController = (APPController) FactoryBean.getBean("APPController");
            appController.execRecentAccessFormid(new RecentAccessEntity(
                    env.get(SessionKey.USERCODE),
                    env.get(SessionKey.USERNAME),
                    formVOEntity.getFormId(),
                    formVOEntity.getFormType(),
                    StringUtils.isNotBlank(formVOEntity.getWhere()) ? processWhere(formVOEntity.getWhere()) : null,
                    metaData.getGformEntity().getFormname(),
                    formVOEntity.getDocCode(),
                    env.get("dbid")
            ));
        }
        //------
        map.put("settings", formVOEntity.isNoMeta() ? null : metaData.getInfo());
        map.put("OABtnInfo", page.getOABtnInfo() == null ? null : page.getOABtnInfo());
        map.put("data", page.getData());
        responseMessage.setData(map).sendSuccessMessage(ResponseMessage.SUCCESS);
        return responseMessage;
    }
private  String processWhere(String where){
        return Base64.getEncoder().encodeToString(("where="+parseWhere(where)).getBytes(StandardCharsets.UTF_8));
}
    /**
     * 处理css,tips存在动态sql或静态sql的不同处理
     *
     * @param str
     * @return
     */
    protected String prossExclamationMark(String str) {
 
        return StringUtils.contains(str, "!") ? str.replaceFirst("!", "") : ("'" + str + "'");
    }
 
    /**
     * 替换会话值@xxxx,&...&取页面值的形式
     *
     * @param str
     * @param env
     * @return
     */
    @Override
    public String prossExpressionFormSessionValues(String str, Map<String, String> env) {
        if (org.apache.commons.lang.StringUtils.isBlank(str)) return str;
        Pattern p = Pattern.compile("@.*?\\w+");// 匹配以@开头的单词
        java.util.regex.Matcher propsMatcher = p.matcher(str);
        while (propsMatcher.find()) {
            str = str.replaceAll(propsMatcher.group(), env.get(propsMatcher.group().toLowerCase()));
        }
        p = Pattern.compile("&.*?\\w+&");// 匹配&...&的单词
        java.util.regex.Matcher propsMatcher2 = p.matcher(str);
        while (propsMatcher2.find()) {
            Object tempValue=env.get(propsMatcher2.group().replaceAll("&", "").toLowerCase());
            if(tempValue==null){
                //取不到值,表示找不到,需要把参数替换成字段名称,如:case when '&cccode&' in ('J','GC','I')==》case when cccode in ('J','GC','I')
                if(str.contains("'"+propsMatcher2.group()+"'")){
                    //有单引号,需要去掉
                    str = str.replaceAll("(?i)'" + propsMatcher2.group()+"'", propsMatcher2.group().replaceAll("&",""));
                }else{
                    str = str.replaceAll("(?i)" + propsMatcher2.group(), propsMatcher2.group().replaceAll("&",""));
                }
            }else {
                str = str.replaceAll("(?i)" + propsMatcher2.group(), String.valueOf(env.get(propsMatcher2.group().replaceAll("&", "").toLowerCase())));
            }
        }
        return str;
    }
 
    private String prossTbColsFormSessionValues(String str, Map<String, String> env) {
        if (org.apache.commons.lang.StringUtils.isBlank(str)) return str;
        Pattern p = Pattern.compile("@.*?\\w+");// 匹配以@开头的单词
        java.util.regex.Matcher propsMatcher = p.matcher(str);
        while (propsMatcher.find()) {
            str = str.replaceAll(propsMatcher.group(), env.get(propsMatcher.group().toLowerCase()));
        }
        p = Pattern.compile("&.*?\\w+&");// 匹配&...&的单词
        java.util.regex.Matcher propsMatcher2 = p.matcher(str);
        while (propsMatcher2.find()) {
            String key = propsMatcher2.group().replaceAll("&", "").toLowerCase();
            if (!env.containsKey(key)) {
                //主要用于统计列的权限参数替换,如果替换不了,表示需要作为字段名称处理,而不是null值
                if (str.contains("'" + propsMatcher2.group() + "'")) {
                    str = str.replaceAll("'" + propsMatcher2.group() + "'", key);
                } else {
                    str = str.replaceAll("(?i)" + propsMatcher2.group(), key);
                }
            } else {
                str = str.replaceAll("(?i)" + propsMatcher2.group(), String.valueOf(env.get(key)));
            }
        }
        return str;
    }
 
    /**
     * 处理参数替换
     *
     * @param str
     * @param env
     * @return
     */
    protected String replaceStringFormSessionValues(String str, Map<String, String> env) {
        if (org.apache.commons.lang.StringUtils.isBlank(str)) return str;
        String[] split = str.trim().split("\\s+");
        String parmStr = "";
        if (split.length > 0) {
            parmStr = split[1].replaceAll(";", ",");
            String[] parms = parmStr.split(",");
            for (String s : parms) {
                if (s.startsWith("'")) {
                    String sybo = "'";
                    parmStr = parmStr.replaceAll(s, sybo + env.get(s.replaceAll("'", "")) + sybo);
                } else {
                    try {
                        parmStr = parmStr.replaceAll(s, env.get(s));
                    } catch (Exception e) {
                        parmStr = parmStr.replaceAll(s, env.get("@" + s));
                    }
 
                }
            }
        }
        return split[0] + " " + parmStr;
    }
 
    /***
     * BASE64解码条件参数
     * @param where
     * @return
     */
    protected String parseWhere(String where) {
        if (StringUtils.isBlank(where)) return where;
        String temp = where;
        try {
            where = where.replaceAll("%2B", "+").replaceAll("%3D", "=").replaceAll("%2F", "/");
            String exwhere = new String(Base64.getDecoder().decode(where), "utf-8");//base64解密所有请求where参数
            // exwhere = temp;
            where = exwhere;
        } catch (Exception e) {
            String temp1 = null;
            try {
                temp1 = java.net.URLDecoder.decode(where.replaceAll("\\+", "%2B").replaceAll("\\/", "%2F"), "utf-8");
            } catch (UnsupportedEncodingException unsupportedEncodingException) {
                unsupportedEncodingException.printStackTrace();
            }
            where = temp1;
        }
 
 
        return where.replaceAll("@~", "%");
    }
 
    /**
     * 处理数据组权限
     *
     * @param formId
     * @param userCode
     * @param headFlag
     * @param env
     * @return
     */
    protected String prossDataGroupInfo(int formId, String userCode, int headFlag, Map<String, String> env) {
        List<Map<String, Object>> list = gridService.getDataGroupInfo(formId, userCode, headFlag);
        if (list.size() == 0) {
            return "";
        }
        boolean isoneGroup = true;//表示只有一种分组情况
        boolean isother = false;
        String fieldIds = list.stream().map(x -> x.get("fieldid") + "").collect(joining(","));//取所有字段以,号串成字符串
        List<TableColumnsDataTypeEntity> tableColumnsDataTypeEntities = gridService.getTableColumnsDataTypes(formId, headFlag, fieldIds);
        //保存所有分组拼接的sql
        Map<String, String> sql = new HashMap<>(8);
        //保存分组号和所用的连接符
        Map<String, String> JionFlagMap = new HashMap<>(8);
        int indexdx = 0;
        int tempJionFlagGroup = 0;//临时保存分组号
        //1.把每一行设置的拼接成sql,保存到一个以分组号为key的map,相同的就加到一起拼接,达到同一数据组放在一起
        for (Map map : list) {
            StringBuffer havingstr = new StringBuffer();
            //针对 between and 或 not between and 的情况 作判断 ,因为需要取第二个值来组装sql
            boolean isbetween = false;
            //分组号
            int jionFlagGroup = GridUtils.prossRowSetDataType_Int(map, "jionFlagGroup");
            //关系符
            String jionflag = GridUtils.prossRowSetDataType_String(map, "jionFlag");
            //连接符
            String conFlag = GridUtils.prossRowSetDataType_String(map, "conFlag");
            //数据组号,会存在多个数据组的情况
            String accessid = GridUtils.prossRowSetDataType_String(map, "accessid");
            //字段名称
            final String fieldid = GridUtils.prossRowSetDataType_String(map, "fieldid");
 
            //没有设置有关系符和连接符,表明关联不成立,不需要生成权限sql,提示需要进行相关设置
            if (jionflag.trim().equals("") && conFlag.trim().equals("")) {
                throw new ApplicationException(fieldid + "参数jionFlag,conFlag没有进行设置,请检查[功能号:9654(维护数据显示权限)]");
            }
            String newFieldid = fieldid;
            if (tableColumnsDataTypeEntities != null && tableColumnsDataTypeEntities.stream().filter(
                    x -> fieldid.equalsIgnoreCase(x.getFieldId()) &&
                            ("int".equalsIgnoreCase(x.getDataType())) ||
                            ("money".equalsIgnoreCase(x.getDataType())) ||
                            ("decimal".equalsIgnoreCase(x.getDataType())) ||
                            ("double".equalsIgnoreCase(x.getDataType())) ||
                            ("float".equalsIgnoreCase(x.getDataType())) ||
                            ("real".equalsIgnoreCase(x.getDataType())) ||
                            ("numeric".equalsIgnoreCase(x.getDataType())) ||
                            ("bigint".equalsIgnoreCase(x.getDataType())) ||
                            ("bit".equalsIgnoreCase(x.getDataType())) ||
                            ("smallint".equalsIgnoreCase(x.getDataType())) ||
                            ("smallmoney".equalsIgnoreCase(x.getDataType())) ||
                            ("tinyint".equalsIgnoreCase(x.getDataType()))
            ).count() > 0) {
                newFieldid = " isnull(" + fieldid + ",0) ";
            } else {
                newFieldid = " isnull(" + fieldid + ",'') ";
            }
            havingstr.append(" ( ").append(newFieldid);//字段名;
            Pattern p = Pattern.compile("@.*?\\w+");// 匹配以@开头的单词
            String modfvalues = GridUtils.prossRowSetDataType_String(map, "modfvalues");
            String modfvalues2 = GridUtils.prossRowSetDataType_String(map, "modfvalues2");
            if (modfvalues.length() == 0) {
                throw new ApplicationException("功能号:9654(维护数据显示权限)值1不能为空");
            }
            java.util.regex.Matcher propsMatcher = p.matcher(modfvalues);
            while (propsMatcher.find()) {
                try {
                    String tem = env.get(propsMatcher.group().toLowerCase());
                    modfvalues = modfvalues.replaceAll(propsMatcher.group(), tem);
                } catch (Exception e) {
                    throw new ApplicationException(propsMatcher.group() + "不存在于会话中,请检查数据组权限设置");
                }
 
            }
            if (conFlag.toLowerCase().indexOf("between") > -1 ||
                    conFlag.toLowerCase().indexOf("not between") > -1
            ) {
                isbetween = true;
            }
            if (isbetween && (modfvalues2 == null || modfvalues2.length() == 0)) {
                throw new ApplicationException("between and 或 not between and 的第二个值没有设置,请检查[功能号:9654(维护数据显示权限)]里面设置");
            }
            if (isbetween) {
                propsMatcher = p.matcher(modfvalues2);
                while (propsMatcher.find()) {
                    modfvalues2 = modfvalues2.replaceAll(propsMatcher.group(), env.get(propsMatcher.group().toLowerCase()));
                }
                havingstr.append(" " + conFlag)
                        .append("  " + modfvalues)
                        .append("  and  ")
                        .append(modfvalues2);
            } else if (conFlag.toLowerCase().indexOf("like") > -1 ||
                    conFlag.toLowerCase().indexOf("not like") > -1) {
                //处理有单引号情况 'dddd'
                modfvalues = modfvalues.replaceAll("'", "");
                havingstr.append(" " + conFlag)
                        .append(" '%" + modfvalues + "%'");
 
            } else if (conFlag.toLowerCase().indexOf("in") > -1 ||
                    conFlag.toLowerCase().indexOf("not in") > -1) {
                //*****处理广陶 CS版兼容问题,增加单引号  by 2016-3-4
                String temp = "";
                String[] arr = modfvalues.replaceAll(";", ",").split(",");
                for (String r : arr) {
                    if (r.startsWith("'") && r.endsWith("'")) {
                        temp += r + ",";
                    } else {
                        if (r.startsWith("'") || r.endsWith("'")) {//存在一种情况需要去掉单引号
                            temp += "'" + r.replaceAll("'", "") + "',";
                        } else {
                            temp += "'" + r + "',";
                        }
                    }
                }
                havingstr.append("  " + conFlag)
                        .append(" (" + temp.substring(0, temp.length() - 1) + ")");
 
            } else {
                havingstr.append(" " + conFlag)
                        .append(" " + modfvalues);
            }
            havingstr.append(" ) ");//当前项结束
 
            String temp = sql.get(accessid.trim());
 
            //1,拼接同一数据组的sql,前提条件是数据已按照数据组,分组号排好序
            // temp为空表示是一个数据组里面的第一个sql
            if (temp == null) {
                sql.put(accessid.trim(), "( " + havingstr.toString());
                JionFlagMap.put(accessid.trim(), "".equals(jionflag.trim()) ? " and " : jionflag.trim());
                tempJionFlagGroup = jionFlagGroup;
            } else {
                //中间连接符不能为空,不填则用默认用and连接
                if ("".equals(jionflag.trim())) {
                    jionflag = " and ";
                }
                String str = sql.get(accessid.trim()) + "" + jionflag + havingstr.toString();
                if (tempJionFlagGroup != jionFlagGroup) {
                    tempJionFlagGroup = jionFlagGroup;
                    //处理下一个分组
                    str = sql.get(accessid.trim()) + " ) " + jionflag + " (" + havingstr.toString();
                }
 
                sql.put(accessid.trim(), str);
            }
            //处理数据组结束时加上闭合
            if (
                //1,最后一条数据时,要闭合
                    indexdx == list.size() - 1 ||
                            //2,判断下一个的数据组号是不是和当前在同一个组,不是则表明也需要闭合起来
                            ((indexdx + 1) <= list.size() && list.get(indexdx + 1) != null && !accessid.trim().equals((list.get(indexdx + 1).get("accessid") + "").trim()))
            ) {
                String strs = sql.get(accessid.trim());
                strs += " )";
                sql.put(accessid.trim(), strs);
            }
            indexdx++;
        }
 
        //2.再拼接最终sql的顺序,根据数据组用or拼接起来
        StringBuilder st = new StringBuilder();
        int index = 0;
        String temAccessid = "";
        boolean isFrist = false;
        boolean other = false;
        for (Map.Entry<String, String> entry : sql.entrySet()) {
            String temJionFlag = "";
            if ("".equals(temAccessid)) {
                temAccessid = entry.getKey();
                isFrist = true;
            } else {
                isFrist = false;
                if (!temAccessid.equals(entry.getKey())) {
                    //表明这里是另一个数据组的开始,需要闭合,且用or 连接起来
                    st.append(" ) or ( ");
                    temAccessid = entry.getKey();
                    isFrist = true;
                    other = true;
                }
            }
            if (!isFrist) {
                temJionFlag = JionFlagMap.get(entry.getKey());
                st.append(" " + temJionFlag + " (" + entry.getValue() + ")");
            } else {
                //other=true表示已经不是第一个数据组,不需要加开始括号
                st.append((other ? "" : " ( ") + entry.getValue());
            }
        }
        st.append(" )");
        return " and (" + st.toString() + ")";
    }
 
    /**
     * 处理统计列,组装成字符串到数据库里执行
     *
     * @param page
     * @return
     */
    protected String proccTbCols(Page page) {
        // digit#1:null,totalmoney2#1:
        // 组装统计成:cast(sum(isnull(digit,0)) as nvarchar) +''|''+ cast(sum(isnull(totalmoney2,0)) as nvarchar)
        String tb = page.getTbCols();
        if (tb == null || "".equalsIgnoreCase(tb)) return "";
//        if (org.apache.commons.codec.binary.Base64.isBase64(tb)) {
//            try {
//                tb = EncodeUtil.base64Decode(tb);
//                tb = tb.replaceAll("%2F", "/").replaceAll("%2B", "+");
//            } catch (UnsupportedEncodingException e) {
//                // tb = tb;
//            } // base64解密所有请求where参数
//        } else {//表示之前已解码,不需要再执行一次,直接返回,主要是用在18类型分页返回,会调用多一次做的处理
//            return tb.replaceAll("%2F", "/").replaceAll("%2B", "+");
//        }
        StringBuffer sb = new StringBuffer();
 
        String[] s1 = tb.split(",");
        for (String s : s1) {
            String[] s2 = s.split("#");// 分出每个统计的列
            String[] s3 = s2[1].split(":");// 分离出统计统计和格式,1-汇总 ,2-计数,3-平均,4-百分比,5-自定义,6最大值,7最小值
 
            String filed = s2[0];
 
            if (page.getTbExpr() != null && page.getTbExpr().get(s2[0].toLowerCase()) != null
                    && !"".equalsIgnoreCase(page.getTbExpr().get(s2[0].toLowerCase())))
                filed = page.getTbExpr().get(s2[0].toLowerCase());
            //替换页面值
            filed = this.prossTbColsFormSessionValues(filed, page.getEnv());
            switch (Integer.parseInt(s3[0])) {
                case 1:
                    sb.append(" replace(rtrim(replace(convert(varchar(100),sum(cast(isnull(").append(filed).append(",0) as decimal(38,18)) ) ),'0',' ')),' ','0')").append("+'#p#'+");
                    break;
                case 2:
                    sb.append(" cast(count(isnull(").append(filed).append(",0)) as nvarchar )").append("+'#p#'+");
                    break;
                case 3:
                    sb.append(" replace(rtrim(replace(convert(varchar(100),avg(cast(isnull(").append(filed).append(",0) as decimal(38,18)) ) ),'0',' ')),' ','0')").append("+'#p#'+");
                    break;
                case 6:
                    sb.append(" replace(rtrim(replace(convert(varchar(100),max(cast(isnull(").append(filed).append(",0) as decimal(38,18)) ) ),'0',' ')),' ','0')").append("+'#p#'+");
                    break;
                case 7:
                    sb.append(" replace(rtrim(replace(convert(varchar(100),min(cast(isnull(").append(filed).append(",0) as decimal(38,18)) ) ),'0',' ')),' ','0')").append("+'#p#'+");
                    break;
                case 4:
                    sb.append(" replace(rtrim(replace(convert(varchar(100),sum(cast(isnull(").append(filed).append(",0) as decimal(38,18)) )*100.00 ),'0',' ')),' ','0')").append("+'#p#'+");
                    break;
                case 5:// 需要把后缀转成中缀传给sql查询 !format2  digit price * othermoney +  //add 2018-4-14
                    if (s3[1] == null || s3[1].length() == 0) throw new ApplicationException(filed + "-没有设置自定义公式");
                    String str = "";
                    String newString = s3[1].trim(); //.replaceAll("@p@", ",");
                    if (newString.startsWith("!format")) {
                        str = newString.replaceAll("!\\w+?\\b", "");//去掉!format2取得digit price * othermoney +
                        str = PostfixExpression.midToPost(str.trim(), "sum");
 
                    } else if (newString.startsWith("case when")) {
                        str = newString;
                    } else {
                        throw new ApplicationException(filed + "-汇总自定义公式【" + newString + "】需要以【!format或case when】格式开始");
                    }
                    //处理被除数为0的情况
                    String divisor = "";
                    if (str.indexOf("/") > 0) {//有除数
                        Pattern p = Pattern.compile("\\/\\w*[^\\+\\-\\*\\/]+");
                        Matcher m = p.matcher(str);
                        while (m.find()) {
                            String value = m.group();
                            if (value.indexOf("(") >= 0) {//有括号"("表示需要取到")"为止
                                // 1种情况,括号刚好匹配,: / sum( isnull(  totalmoney2, 0 )) else 0 end
                                //第2种情况,)多出来,是匹配其他地方的:/sum(isnull(digit,0)),4)))) else 0 end
                                //需要做判断
                                Pattern p2 = Pattern.compile("[\\(\\)]");
                                Matcher m2 = p2.matcher(value);
                                int leftIndex = 0;//左括号次数
                                int rightIndex = 0;//右括号次数
                                while (m2.find()) {
                                    if ("(".equals(m2.group())) {
                                        leftIndex++;
                                    } else {
                                        rightIndex++;
                                    }
 
                                }
                                if (rightIndex >= leftIndex) {
                                    for (int i = 0; i < leftIndex; i++) {//把匹配的括号替换成#
                                        value = value.replaceFirst("\\)", "#");
                                    }
                                }
                                value = value.substring(0, value.lastIndexOf("#") + 1).replaceAll("#", ")");//转回来括号形式
                            } else {//后面还有字符的情况,因为没括号的情况下第二空格就代表了结束
                                // : / totalmoney2 else 0 end
                                String[] strings = value.split("\\s+");
                                if (strings[0].trim().equalsIgnoreCase("/") && strings.length > 1) {
                                    value = strings[1];
                                } else {
                                    value = strings[0];
                                }
                            }
                            divisor += value.replace("/", "") + ",";
                        }
                    }
                    if (org.apache.commons.lang.StringUtils.isNotBlank(divisor)) {
                        str = " case when 0 in(" + divisor.substring(0, divisor.length() - 1) + ") then 0 else " + str + " end ";
                    }
                    str = PostfixExpression.replaceDotByrecover(str);//还原运算符
                    sb.append(" replace(rtrim(replace(convert(varchar(100),cast(isnull(").append(str).append(",0) as decimal(38,18) ) ),'0',' ')),' ','0')").append("+'#p#'+");
                    break;
                default:
                    break;
            }
 
        }
 
        return sb.length() > 0 ? sb.toString().substring(0, sb.lastIndexOf("+'#p#'+")) : "";
    }
 
    /**
     * 分页加载数据
     *
     * @param page
     * @return
     */
    protected Page loadDataByPage(Page page) {
        page.setTbCols(this.proccTbCols(page));
        //----生成10个数组处理参数内容过长,需要截断分组传
        String[] tbcols = new String[10];
        int len = page.getTbCols().length();
        if (len > 0) {
            for (int i = 0; i < 10; i++) {
                if (len >= (i + 1) * 3500) {
                    tbcols[i] = page.getTbCols().substring(i * 3500, (i + 1) * 3500);
                } else {
                    tbcols[i] = page.getTbCols().substring(i * 3500, len);  //endIndex只能是>=beginIndex
                    break;
                }
            }
        }
        //----end
        if (page.getWhere().trim().startsWith("and")) {
            page.setWhere("1=1 " + page.getWhere());
        }
        if (StringUtils.isBlank(page.getWhere())) {
            page.setWhere(" 1=1 ");
        }
        page.setSql(page.getSql().replaceAll("%2F", "/").replaceAll("%2B", "+"));
 
        Map<String, Object> map = null;
        if ("SP_viewPageV4".equals(page.getPROC_NAME())) {
            map = this.simpleJdbcCall.withProcedureName(page.getPROC_NAME())
                    .declareParameters(// 定义存储过程参数返回值
                            new SqlOutParameter("TotalCount", Types.INTEGER), new SqlOutParameter("TotalPageCount", Types.INTEGER), new SqlOutParameter("TotalTbColsOut", Types.VARCHAR))
                    .execute(page.getTableName(), page.getSql(),
                            page.getWhere(), page.getOrderBy(), page.getAutopaging(), 0,
                            page.getPageSize(), page.getPageNum(), page.getGroupby(),
                            tbcols[0], tbcols[1], tbcols[2], tbcols[3], tbcols[4],
                            tbcols[5], tbcols[6], tbcols[7], tbcols[8], tbcols[9],
                            page.getFormid(), page.getUserCode(), page.getUserName(),
                            0, 0, null);
        } else {
            map = this.simpleJdbcCallByProc.withProcedureName(page.getPROC_NAME())
                    .declareParameters(// 定义存储过程参数返回值
                            new SqlOutParameter("TotalCount", Types.INTEGER), new SqlOutParameter("TotalPageCount", Types.INTEGER), new SqlOutParameter("TotalTbColsOut", Types.VARCHAR))
                    .execute(page.getTableName(), page.getSql(),
                            page.getWhere(), page.getOrderBy(), page.getAutopaging(), 0,
                            page.getPageSize(), page.getPageNum(), page.getGroupby(),
                            tbcols[0], tbcols[1], tbcols[2], tbcols[3], tbcols[4],
                            tbcols[5], tbcols[6], tbcols[7], tbcols[8], tbcols[9],
                            page.getFormid(), page.getUserCode(), page.getUserName(),
                            0, 0, null);
        }
        page.setData(map.get("#result-set-1"));
        page.setTotalRowNum(map.get("TotalCount") == null ? 0 : (Integer) map.get("TotalCount"));
        page.setTotalPageNum(map.get("TotalPageCount") == null ? 0 : (Integer) map.get("TotalPageCount"));
        page.setTbColsOut((String) map.get("TotalTbColsOut"));
 
        if (page.getTbColsOut() != null && !"".equals(page.getTbColsOut())) {//处理返回是0.的情况,在前端会显示NaN
            String temp = page.getTbColsOut().replaceAll("\\.#", "#");
            page.setTbColsOut(temp);
            if (page.getData() != null && ((List) page.getData()).size() > 0) {
                if (StringUtils.isNotBlank(page.getTbColsFieldsList()) && StringUtils.isNotBlank(page.getTbColsOut())) {
                    //0#p#1020#p#15909.45#p#16929.45#p#0#p#16929.45#p#0#M#30
                    String[] arry = page.getTbColsOut().split("#M#");
                    ////0#p#1020#p#15909.45#p#16929.45#p#0#p#16929.45#p#0
                    String[] colsValues = arry[0].split("#p#");
                    String[] cols = page.getTbColsFieldsList().split("#");
                    int index = 0;
                    Map<String, String> colMap = new HashMap<>();
                    for (String s : cols) {
                        colMap.put(s, colsValues[index]);
                        index++;
                    }
                    ((Map) ((List) page.getData()).get(0)).put("_RowNo", colMap);
                }
            }
        }
        return page;
    }
 
    /**
     * 取排序步骤,及优化级顺序从上到下一层层查找,只要上层存在就返回
     * 1,取表关键字设置
     * 2,取9801排序设置
     * 3,取表的主键设置
     * 4,取9802定义的第一个字段(保存在page.id属性)
     *
     * @param gformEntity
     * @param formVOEntity
     * @param orderbyStr
     * @return
     */
    @Override
    public String orderBySql(GformEntity gformEntity, FormVOEntity formVOEntity, String orderbyStr) {
 
        try {
            String primaryStr = "";
            String tableName = this.setTableName(gformEntity);
            //----取表关键字设置
            //keys = gridService.getTableKeyFields(tableName);
            //-----取表主键
            final List<String> primaryKey = gridService.getPrimaryKey(tableName);
            if (primaryKey != null && primaryKey.size() > 0) {
                primaryStr = String.join(";", primaryKey);
            }
            //---把表名,主键保存输出
            formVOEntity.setPrimaryKey(primaryStr);
            formVOEntity.setTableName(tableName);
            if (StringUtils.isBlank(primaryStr)) {
                //-----取9801设置
                String indexField = gformEntity.isGetHeadTabe() ? gformEntity.getIndex1() : gformEntity.getIndex2();
                if (StringUtils.isNotBlank(indexField)) {//取9801的排序设置
                    primaryStr = indexField;
 
                }
            }
            if (StringUtils.isNotBlank(primaryStr)) {
                String orderFields = primaryStr.replaceAll(";", ",");
                String newOrderFiled = "";
                String[] sorts = orderFields.split(",");
                int index = 0;
                for (String s : sorts) {
                    String[] str = s.split("\\s");
                    if (str.length == 2) {
                        if (index > 0)
                            newOrderFiled += "," + str[0] + " " + str[1];
                        else
                            newOrderFiled += str[0] + " " + str[1];
                    } else {
                        //--没指定asc desc,由入参指定
                        if (index > 0)
                            newOrderFiled += "," + str[0] + orderbyStr;
                        else
                            newOrderFiled += str[0] + orderbyStr;
                    }
                    index++;
                }
                primaryStr = newOrderFiled;// keys.replace(";"," desc, ")+" desc";
            }
            return primaryStr;
        } catch (SQLException e) {
            return "";
        }
 
    }
 
    /**
     * 返回加载哪一页数据
     *
     * @param formVOEntity
     * @return
     */
    protected int setPageNum(FormVOEntity formVOEntity) {
        return formVOEntity.getPos() == 0 ? 1 : formVOEntity.getPos() + 1;
    }
 
    /**
     * 获取指定功能号的时间过滤设置,返回处理过的时间
     *
     * @return
     */
    protected SysDateFilterEntity getSysDateFilterEntitys(int formId) {
        SysDateFilterEntity sysDateFilterEntity = new SysDateFilterEntity();
        try {
            sysDateFilterEntity = this.getSimpleJdbcTemplate().queryForObject("select formid,formName,datefield,begindatestr,enddatestr,docstate,ShowAllNopost,dateLimitYn,MonthRangeYN,selfdocYn,hidescrapYn from _sysDateFilter where formid=? ", new BeanPropertyRowMapper<>(SysDateFilterEntity.class), formId);
 
        } catch (EmptyResultDataAccessException e) {
 
        } catch (Exception e) {
            throw new ApplicationException(formId + "-在9816存在多条记录,请确保只有一条记录存在");
        }
        //处理时间,执行sql返回日期
        String sql = "";
        if (sysDateFilterEntity != null
                && StringUtils.isNotBlank(sysDateFilterEntity.getBegindatestr())
                && StringUtils.isNotBlank(sysDateFilterEntity.getEnddatestr())) {
            sql = "set nocount on \n select convert(varchar(10)," + sysDateFilterEntity.getBegindatestr() + ",120) as [start],convert(varchar(10)," + sysDateFilterEntity.getEnddatestr() + ",120) as [end]";
        } else {
 
            sql = "set nocount on \n select convert(varchar(10),GETDATE()-7,120) as [start],convert(varchar(10),GETDATE(),120) as [end]\n";
 
        }
        Map map = this.getSimpleJdbcTemplate().queryForMap(sql);
        sysDateFilterEntity.setBegindatestr(GridUtils.prossRowSetDataType_String(map, "start"));
        sysDateFilterEntity.setEnddatestr(GridUtils.prossRowSetDataType_String(map, "end"));
        return sysDateFilterEntity;
    }
 
    /**
     * 获取可查询字段列表,用于组装列表的查询功能
     *
     * @return
     */
    protected List getQueryFieldList(List<Map<String, Object>> gFieldEntityList) {
        List<Map> list = new ArrayList<>();
        //---9802可查询字段
        List<String> str = new ArrayList<>();
        for (Map<String, Object> gFieldEntity : gFieldEntityList) {
            if (GridUtils.prossRowSetDataType_Int(gFieldEntity, "Statisflag") == 1) {//同时为1才取数
                Map map = new HashMap();
                map.put(GridUtils.prossRowSetDataType_String(gFieldEntity, "Fieldid").toLowerCase(), GridUtils.prossRowSetDataType_String(gFieldEntity, "Fieldname"));
                str.add(GridUtils.prossRowSetDataType_String(gFieldEntity, "Fieldid").toLowerCase());
                list.add(map);
            }
        }
        if (str != null && str.size() > 0) {
            Map map = new HashMap();
            map.put(String.join(";", str), "查询所有字段");
            list.add(0, map);
            return list;
        } else {
            return null;
        }
    }
 
    /***
     * 获取功能连接
     * @param formVOEntity
     * @return
     */
    public List getFunLinks(FormVOEntity formVOEntity, Map<String, String> env, GformEntity gformEntity) {
 
        List<Map<String, Object>> list = null;//所有功能链接集合
        String sql = "set nocount on select  " + sysfunclink +
                " ,a.largImagePath from _sysfunclink b left join _sysMenu a on cast(a.formid as varchar(50))=cast(b.linkformid as varchar(50)) where b.origformid=? and b.origformtype=? order by b.sortid asc \n";
        ;
        //-----TODO 因为现在生成元数据都是分开独立生成,所以各自生成
        //496多表
//            if(formVOEntity.getFormType()==496||formVOEntity.getFormType()==498) {
//                sql="set nocount on \n select  " +sysfunclink+
//                        "  from _sysFuncLink b \n" +
//                        "where exists(select 1 from _sys_TabPageFormid a where a.mainformid = ? \n" +
//                        "   and a.formid = b.origformid \n" +
//                        "   and ((a.mainformid = a.formid and b.origformtype = 496) or (a.mainformid = a.formid and b.origformtype = 498)\n" +
//                        "   or (a.mainformid <> a.formid and  a.formtype = b.origformtype ))\n" +
//                        "   )\n" +
//                        " order by b.origformid asc ,b.sortid asc \n";
//                list=this.getSimpleJdbcTemplate().queryForList(sql,formVOEntity.getFormId());
//            }
//            else{
        list = this.getSimpleJdbcTemplate().queryForList(sql, formVOEntity.getFormId(), formVOEntity.getFormType());
 
        // }
        List<Map<String, Object>> result = new ArrayList<>();
        String tempFormid = null;
        if (list != null && list.size() > 0) {
            for (int k = 0; k < list.size(); k++) {
                Map<String, Object> tempMap = list.get(k);
                String formid = tempMap.get("origformid") + "";
                if (tempFormid != null) {
                    if (tempFormid.equalsIgnoreCase(formid))
                        continue;
                }
                tempFormid = formid;
                final List<Map<String, Object>> tempList = list.stream().filter(x -> (x.get("origformid") != null && formid.equals(x.get("origformid") + ""))).collect(toList());//处理同一个功能号里所有表达式的数据
                final List<Map<String, Object>> collectNotitemexpression = list.stream().filter(x -> (x.get("origformid") != null && formid.equals(x.get("origformid") + "")) && (x.get("showitemexpression") == null || "".equals(x.get("showitemexpression")))).collect(toList());//没有表达式的数据
 
 
                Map<String, Object> map = this.buildFuncLinkExpression(formVOEntity.getFormId(), Integer.parseInt(tempMap.get("origformtype") + ""), formVOEntity.getDocCode(), gformEntity.getHdtable(), env, tempList);
                if (map != null) {
                    //有结果
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        if ("1".equals(entry.getValue() + "")) {//取值为1,表示有权限,(没有表达式的也在里面设置为1)
                            String[] key = entry.getKey().split("_");
                            result.addAll(
                                    tempList.stream().filter(obj -> (obj.get("sortid") + "").equals(key[1] + "") && (obj.get("linkformid") + "").equals(key[0] + "")).collect(toList()
                                    ));
                        }
                    }
 
                } else {
                    //条件不成立,返回null,则取没有表达式的链接
                    result.addAll(collectNotitemexpression);
                }
            }
        }
        return result;
 
    }
 
    /**
     * 计算功能链接的权限表达式,决定需要返回哪些
     *
     * @param formId
     * @param origformtype
     * @param docCode
     * @param dhtable
     * @param env
     * @param hasFuncLinkExpression
     * @return
     */
    private Map<String, Object> buildFuncLinkExpression(Integer formId, int origformtype, String docCode, String dhtable, Map<String, String> env, List<Map<String, Object>> hasFuncLinkExpression) {
        Map<String, Object> map2 = new HashMap<String, Object>();
        if (hasFuncLinkExpression.size() > 0 && StringUtils.isNotBlank(docCode)) {
            //拼接sql
            String sql = FuncLinkSpellUtil.spellFunclinkSQL2_APPV2(hasFuncLinkExpression, formId, origformtype, dhtable, docCode);
            sql = this.prossExpressionFormSessionValues(sql, env);
            try {
                map2 = this.getSimpleJdbcTemplate().queryForMap(sql);
            } catch (EmptyResultDataAccessException e) {
                //不需要处理
            }
        }
        return map2;
    }
 
    @Override
    public String setTableName(GformEntity gformEntity) {
        //默认取主表
        if (gformEntity.isGetHeadTabe()) {
            return gformEntity.getHdtable();
        } else {
            return gformEntity.getDttable();
        }
    }
 
    /**
     * @param map 通过传需要替换的字符串,用map替换值
     */
    protected String getRecordValues(Map map, String prams, Map<String, String> env) {
        if (org.apache.commons.lang.StringUtils.isBlank(prams)) {
            return "";
        }
        String[] temp = null;
        String[] ss = prams.trim().split("\\s+");
        boolean flg = false;
        if (ss.length == 1) {
            prams = ss[0];
            flg = true;
        } else {
            prams = ss[1];
        }
        if (prams.indexOf(",") > -1) {
            temp = prams.split(",");
        } else if (prams.indexOf(";") > -1) {
            temp = prams.split(";");
        } else {
            temp = prams.split(";");
        }
        String str = "";
        for (String s : temp) {
            if (s.trim().equalsIgnoreCase("''") || s.matches("'\\s+'")) {
                str += s + ",";
                continue;
            }
            boolean fg = s.matches("'.*'");// 存在''号的情况
            boolean flag = false;
            if (fg) {
                s = s.substring(1, s.length() - 1);// 去除''号}
            }
            String key = s.trim().toLowerCase();
            if (map.containsKey(key)) {
                String obj = map.get(key) == null ? "" : String.valueOf(map.get(key));//取到对应值
                str += "'" + obj.replaceAll("\\s", "") + "',";
                flag = true;
            }
            if (!flag) {// 在当前表格数据找不到则查找以@开头的变量
                if (env.get(s.toLowerCase()) != null) {
                    str += "'" + String.valueOf(env.get(s.toLowerCase().trim())) + "',";
                } else {// 参数本身就是作为值传过去
                    if (fg) { // 已经去除''号,所以要再加上
                        str += "'" + s + "',";
                    } else {
                        str += s + ",";
                    }
                }
            }
        }
        if (flg) {
            return (str.lastIndexOf(",") == str.length() - 1) ? str.substring(0, str.length() - 1) : str;
        } else {
            return (str.lastIndexOf(",") == str.length() - 1) ? ss[0] + " " + str.substring(0, str.length() - 1) : ss[0] + " " + str;
        }
    }
 
}