chengjie 2 anos atrás
commit
36b137bca2
89 arquivos alterados com 2244 adições e 0 exclusões
  1. 31 0
      .eslintrc.js
  2. 64 0
      app.js
  3. 15 0
      app.json
  4. 109 0
      app.wxss
  5. BIN
      pages/images/icon_add_01.png
  6. BIN
      pages/images/icon_b2t_01.png
  7. BIN
      pages/images/icon_check_01.png
  8. BIN
      pages/images/icon_compared_01.png
  9. BIN
      pages/images/icon_del_01.png
  10. BIN
      pages/images/icon_fav_01.png
  11. BIN
      pages/images/icon_fav_02.png
  12. BIN
      pages/images/icon_fav_03.png
  13. BIN
      pages/images/icon_filter_01.png
  14. BIN
      pages/images/icon_fold_03.png
  15. BIN
      pages/images/icon_fold_04.png
  16. BIN
      pages/images/icon_loc_01.png
  17. BIN
      pages/images/icon_magnifier_01.png
  18. BIN
      pages/images/icon_nextpage_1.png
  19. BIN
      pages/images/icon_share_01.png
  20. BIN
      pages/images/icon_sys_01.png
  21. BIN
      pages/images/icon_sys_02.png
  22. BIN
      pages/images/icon_sys_03.png
  23. BIN
      pages/images/icon_sys_04.png
  24. BIN
      pages/images/icon_sys_05.png
  25. BIN
      pages/images/icon_sys_06.png
  26. BIN
      pages/images/icon_sys_07.png
  27. BIN
      pages/images/icon_sys_08.png
  28. BIN
      pages/images/icon_sys_09.png
  29. BIN
      pages/images/icon_sys_10.png
  30. BIN
      pages/images/icon_sys_11.png
  31. BIN
      pages/images/icon_sys_12.png
  32. BIN
      pages/images/icon_web_01.png
  33. BIN
      pages/images/icon_web_02.png
  34. BIN
      pages/images/line_01.png
  35. BIN
      pages/images/logo_01b.png
  36. BIN
      pages/images/logo_01s.png
  37. BIN
      pages/images/logo_02b.png
  38. BIN
      pages/images/logo_02s.png
  39. BIN
      pages/images/logo_03b.png
  40. BIN
      pages/images/logo_03s.png
  41. BIN
      pages/images/logo_04b.png
  42. BIN
      pages/images/logo_04s.png
  43. BIN
      pages/images/logo_05b.png
  44. BIN
      pages/images/logo_05s.png
  45. BIN
      pages/images/logo_06b.png
  46. BIN
      pages/images/logo_06s.png
  47. BIN
      pages/images/logo_07b.png
  48. BIN
      pages/images/logo_07s.png
  49. BIN
      pages/images/logo_08b.png
  50. BIN
      pages/images/logo_08s.png
  51. BIN
      pages/images/logo_09b.png
  52. BIN
      pages/images/logo_09s.png
  53. BIN
      pages/images/logo_10b.png
  54. BIN
      pages/images/logo_10s.png
  55. BIN
      pages/images/logo_11b.png
  56. BIN
      pages/images/logo_11s.png
  57. BIN
      pages/images/logo_12b.png
  58. BIN
      pages/images/logo_12s.png
  59. BIN
      pages/images/logo_13b.png
  60. BIN
      pages/images/logo_13s.png
  61. BIN
      pages/images/logo_14b.png
  62. BIN
      pages/images/logo_14s.png
  63. BIN
      pages/images/logo_15b.png
  64. BIN
      pages/images/logo_15s.png
  65. BIN
      pages/images/logo_16b.png
  66. BIN
      pages/images/logo_16s.png
  67. BIN
      pages/images/mask_01.png
  68. BIN
      pages/images/pic_01.png
  69. BIN
      pages/images/pic_02.png
  70. BIN
      pages/images/pic_03.png
  71. BIN
      pages/images/toolbook.png
  72. 48 0
      pages/index/index.js
  73. 3 0
      pages/index/index.json
  74. 23 0
      pages/index/index.wxml
  75. 19 0
      pages/index/index.wxss
  76. 26 0
      pages/main/default.js
  77. 7 0
      pages/main/default.json
  78. 71 0
      pages/main/default.wxml
  79. 210 0
      pages/main/default.wxss
  80. 52 0
      project.config.json
  81. 7 0
      project.private.config.json
  82. 7 0
      sitemap.json
  83. 20 0
      utils/constant.js
  84. 8 0
      utils/cryptojs.js
  85. 402 0
      utils/lib/AES.js
  86. 378 0
      utils/lib/BlockModes.js
  87. 155 0
      utils/lib/Crypto.js
  88. 111 0
      utils/main.js
  89. 478 0
      utils/util.js

+ 31 - 0
.eslintrc.js

@@ -0,0 +1,31 @@
1
+/*
2
+ * Eslint config file
3
+ * Documentation: https://eslint.org/docs/user-guide/configuring/
4
+ * Install the Eslint extension before using this feature.
5
+ */
6
+module.exports = {
7
+  env: {
8
+    es6: true,
9
+    browser: true,
10
+    node: true,
11
+  },
12
+  ecmaFeatures: {
13
+    modules: true,
14
+  },
15
+  parserOptions: {
16
+    ecmaVersion: 2018,
17
+    sourceType: 'module',
18
+  },
19
+  globals: {
20
+    wx: true,
21
+    App: true,
22
+    Page: true,
23
+    getCurrentPages: true,
24
+    getApp: true,
25
+    Component: true,
26
+    requirePlugin: true,
27
+    requireMiniProgram: true,
28
+  },
29
+  // extends: 'eslint:recommended',
30
+  rules: {},
31
+}

+ 64 - 0
app.js

@@ -0,0 +1,64 @@
1
+// app.js
2
+App({
3
+
4
+  globalData: {
5
+    Version: "0.1.1",
6
+    IsProduction: true,
7
+    //IsProduction: false,
8
+    ShareTitle: "上海中考信息查询",
9
+    SharePath: "pages/index/index",
10
+    ShareImage: '../images/program_screenshot_main.png',
11
+    ProgramID: 173,
12
+    ProgramName: "秒过分数线",
13
+    AppID: "wx39bc498e7fdacb6b",
14
+    serverUrl: "https://www.kylx365.com/apiData/",
15
+    serverUrlServer: "https://www.kylx365.com/apiData/",
16
+    serverUrlLocalhost: "http://localhost:3020/apiData/",
17
+    uploadImageUrl: "https://miaguo-1253256735.file.myqcloud.com/",
18
+    IsIOS: true,
19
+    IsAndroid: false,
20
+    IsIPad: false,
21
+    IsIPhoneX: false,
22
+    IsOppo: false,
23
+    systemInfo: null,
24
+    userInfo: null,
25
+    SourceID: 0,//来源ID
26
+    
27
+  },
28
+  onLaunch: function (options) {
29
+    this.getSystemInfo();
30
+  },
31
+  onShow: function(options) {
32
+    if (options && options.scene) {
33
+      this.globalData.userSource = options.scene;
34
+      console.log("options.scene2:" + options.scene);
35
+    }
36
+  },
37
+  getSystemInfo: function () {
38
+    this.globalData.systemInfo = wx.getSystemInfoSync();
39
+    if (this.globalData.systemInfo.system.indexOf("Android") >= 0) {
40
+      this.globalData.IsIOS =false;
41
+      this.globalData.IsAndroid=true;
42
+    }
43
+    else if (this.globalData.systemInfo.system.indexOf("iOS") >= 0) {
44
+      this.globalData.IsIOS = true;
45
+      this.globalData.IsAndroid=false;
46
+
47
+      if (this.globalData.systemInfo.model.indexOf("X") >= 0
48
+        || this.globalData.systemInfo.model.indexOf("11") >= 0
49
+        || this.globalData.systemInfo.model.indexOf("12") >= 0
50
+        || this.globalData.systemInfo.model.indexOf("13") >= 0 
51
+        || this.globalData.systemInfo.model.indexOf("14") >= 0)
52
+        this.globalData.IsIPhoneX=true;
53
+    }
54
+
55
+    if (this.globalData.systemInfo.model.indexOf("iPad")>=0){
56
+      this.globalData.IsIPad=true;
57
+    }
58
+
59
+    if (this.globalData.systemInfo.brand.indexOf("OPPO")>=0){
60
+      this.globalData.IsOppo=true;
61
+    }
62
+  }
63
+
64
+})

+ 15 - 0
app.json

@@ -0,0 +1,15 @@
1
+{
2
+  "pages":[
3
+    "pages/main/default",
4
+    "pages/index/index"
5
+  ],
6
+  "window": {
7
+    "navigationBarBackgroundColor": "#ffffff",
8
+    "navigationBarTitleText": "秒过分数线",
9
+    "navigationBarTextStyle": "black",
10
+    "backgroundColor": "#ffffff",
11
+    "enablePullDownRefresh": false
12
+  },
13
+  "style": "v2",
14
+  "sitemapLocation": "sitemap.json"
15
+}

+ 109 - 0
app.wxss

@@ -0,0 +1,109 @@
1
+::-webkit-scrollbar {
2
+  width: 0;
3
+  height: 0;
4
+  color: transparent;
5
+  display: none;
6
+}
7
+
8
+.FlexColumn {
9
+  display: flex;
10
+  flex-direction: column;
11
+  align-items: center;
12
+  justify-content: center;
13
+}
14
+
15
+.FlexRow {
16
+  display: flex;
17
+  flex-direction: row;
18
+  align-items: center;
19
+  justify-content: center;
20
+}
21
+
22
+.container {
23
+  width:100%;
24
+  color: #4D4D4D;
25
+  justify-content: flex-start;
26
+  font-weight: 500;
27
+  background-color: #F2F2F2;
28
+} 
29
+.footerHeight{
30
+  width: 100%;
31
+  height: 100rpx;
32
+}
33
+.lineFooter{
34
+  width: 100%;
35
+  height: 1rpx;
36
+  background-color: #d2d2d2; 
37
+}
38
+.lineWidthAll{
39
+  width: 100%;
40
+  justify-content: flex-end;
41
+  background-color: #fff;
42
+  height: 1rpx;
43
+}
44
+.lineWidth750{
45
+  width: 100%;
46
+  height: 1rpx;
47
+  background-color: #E3E3E3; 
48
+}
49
+.lineWidth720{
50
+  width: 720rpx;
51
+  height: 1rpx;
52
+  background-color: #E3E3E3; 
53
+}
54
+.lineWidth700{
55
+  width: 700rpx;
56
+  height: 1rpx;
57
+  background-color: #E3E3E3; 
58
+}
59
+.lineWidth690{
60
+  width: 690rpx;
61
+  height: 1rpx;
62
+  background-color: #E3E3E3; 
63
+}
64
+.lineWidth680{
65
+  width: 680rpx;
66
+  height: 1rpx;
67
+  background-color: #E3E3E3; 
68
+}
69
+.lineWidth660{
70
+  width: 660rpx;
71
+  height: 1rpx;
72
+  background-color: #E3E3E3; 
73
+}
74
+.lineWidth650{
75
+  width: 650rpx;
76
+  height: 1rpx;
77
+  background-color: #E3E3E3; 
78
+}
79
+.lineWidth640{
80
+  width: 640rpx;
81
+  height: 1rpx;
82
+  background-color: #E3E3E3; 
83
+}
84
+.lineWidth620{
85
+  width: 620rpx;
86
+  height: 1rpx;
87
+  background-color: #E3E3E3; 
88
+}
89
+
90
+.lineWidth600{
91
+  width: 600rpx;
92
+  height: 1rpx;
93
+  background-color: #E3E3E3; 
94
+}
95
+.lineWidth580{
96
+  width: 580rpx;
97
+  height: 1rpx;
98
+  background-color: #E3E3E3; 
99
+}
100
+
101
+.PanelBorderTop{
102
+  border-top-left-radius: 20rpx;
103
+  border-top-right-radius: 20rpx;
104
+}
105
+
106
+.PanelBorderBottom{
107
+  border-bottom-left-radius: 20rpx;
108
+  border-bottom-right-radius: 20rpx;
109
+}

BIN
pages/images/icon_add_01.png


BIN
pages/images/icon_b2t_01.png


BIN
pages/images/icon_check_01.png


BIN
pages/images/icon_compared_01.png


BIN
pages/images/icon_del_01.png


BIN
pages/images/icon_fav_01.png


BIN
pages/images/icon_fav_02.png


BIN
pages/images/icon_fav_03.png


BIN
pages/images/icon_filter_01.png


BIN
pages/images/icon_fold_03.png


BIN
pages/images/icon_fold_04.png


BIN
pages/images/icon_loc_01.png


BIN
pages/images/icon_magnifier_01.png


BIN
pages/images/icon_nextpage_1.png


BIN
pages/images/icon_share_01.png


BIN
pages/images/icon_sys_01.png


BIN
pages/images/icon_sys_02.png


BIN
pages/images/icon_sys_03.png


BIN
pages/images/icon_sys_04.png


BIN
pages/images/icon_sys_05.png


BIN
pages/images/icon_sys_06.png


BIN
pages/images/icon_sys_07.png


BIN
pages/images/icon_sys_08.png


BIN
pages/images/icon_sys_09.png


BIN
pages/images/icon_sys_10.png


BIN
pages/images/icon_sys_11.png


BIN
pages/images/icon_sys_12.png


BIN
pages/images/icon_web_01.png


BIN
pages/images/icon_web_02.png


BIN
pages/images/line_01.png


BIN
pages/images/logo_01b.png


BIN
pages/images/logo_01s.png


BIN
pages/images/logo_02b.png


BIN
pages/images/logo_02s.png


BIN
pages/images/logo_03b.png


BIN
pages/images/logo_03s.png


BIN
pages/images/logo_04b.png


BIN
pages/images/logo_04s.png


BIN
pages/images/logo_05b.png


BIN
pages/images/logo_05s.png


BIN
pages/images/logo_06b.png


BIN
pages/images/logo_06s.png


BIN
pages/images/logo_07b.png


BIN
pages/images/logo_07s.png


BIN
pages/images/logo_08b.png


BIN
pages/images/logo_08s.png


BIN
pages/images/logo_09b.png


BIN
pages/images/logo_09s.png


BIN
pages/images/logo_10b.png


BIN
pages/images/logo_10s.png


BIN
pages/images/logo_11b.png


BIN
pages/images/logo_11s.png


BIN
pages/images/logo_12b.png


BIN
pages/images/logo_12s.png


BIN
pages/images/logo_13b.png


BIN
pages/images/logo_13s.png


BIN
pages/images/logo_14b.png


BIN
pages/images/logo_14s.png


BIN
pages/images/logo_15b.png


BIN
pages/images/logo_15s.png


BIN
pages/images/logo_16b.png


BIN
pages/images/logo_16s.png


BIN
pages/images/mask_01.png


BIN
pages/images/pic_01.png


BIN
pages/images/pic_02.png


BIN
pages/images/pic_03.png


BIN
pages/images/toolbook.png


+ 48 - 0
pages/index/index.js

@@ -0,0 +1,48 @@
1
+// index.js
2
+// 获取应用实例
3
+const app = getApp()
4
+
5
+Page({
6
+  data: {
7
+    motto: 'Hello World',
8
+    userInfo: {},
9
+    hasUserInfo: false,
10
+    canIUse: wx.canIUse('button.open-type.getUserInfo'),
11
+    canIUseGetUserProfile: false,
12
+    canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
13
+  },
14
+  // 事件处理函数
15
+  bindViewTap() {
16
+    wx.navigateTo({
17
+      url: '../logs/logs'
18
+    })
19
+  },
20
+  onLoad() {
21
+    if (wx.getUserProfile) {
22
+      this.setData({
23
+        canIUseGetUserProfile: true
24
+      })
25
+    }
26
+  },
27
+  getUserProfile(e) {
28
+    // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
29
+    wx.getUserProfile({
30
+      desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
31
+      success: (res) => {
32
+        console.log(res)
33
+        this.setData({
34
+          userInfo: res.userInfo,
35
+          hasUserInfo: true
36
+        })
37
+      }
38
+    })
39
+  },
40
+  getUserInfo(e) {
41
+    // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
42
+    console.log(e)
43
+    this.setData({
44
+      userInfo: e.detail.userInfo,
45
+      hasUserInfo: true
46
+    })
47
+  }
48
+})

+ 3 - 0
pages/index/index.json

@@ -0,0 +1,3 @@
1
+{
2
+  "usingComponents": {}
3
+}

+ 23 - 0
pages/index/index.wxml

@@ -0,0 +1,23 @@
1
+<!--index.wxml-->
2
+<view class="container">
3
+  <view class="userinfo">
4
+    <block wx:if="{{canIUseOpenData}}">
5
+      <view class="userinfo-avatar" bindtap="bindViewTap">
6
+        <open-data type="userAvatarUrl"></open-data>
7
+      </view>
8
+      <open-data type="userNickName"></open-data>
9
+    </block>
10
+    <block wx:elif="{{!hasUserInfo}}">
11
+      <button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
12
+      <button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
13
+      <view wx:else> 请使用1.4.4及以上版本基础库 </view>
14
+    </block>
15
+    <block wx:else>
16
+      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
17
+      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
18
+    </block>
19
+  </view>
20
+  <view class="usermotto">
21
+    <text class="user-motto">{{motto}}</text>
22
+  </view>
23
+</view>

+ 19 - 0
pages/index/index.wxss

@@ -0,0 +1,19 @@
1
+/**index.wxss**/
2
+.userinfo {
3
+  display: flex;
4
+  flex-direction: column;
5
+  align-items: center;
6
+  color: #aaa;
7
+}
8
+
9
+.userinfo-avatar {
10
+  overflow: hidden;
11
+  width: 128rpx;
12
+  height: 128rpx;
13
+  margin: 20rpx;
14
+  border-radius: 50%;
15
+}
16
+
17
+.usermotto {
18
+  margin-top: 200px;
19
+}

+ 26 - 0
pages/main/default.js

@@ -0,0 +1,26 @@
1
+import common from '../../utils/util';
2
+import main from '../../utils/main';
3
+import constant from '../../utils/constant';
4
+
5
+const app = getApp();
6
+
7
+Page({
8
+  data: {
9
+    IsSelect: true,
10
+    District:constant.arrDistrict,
11
+  },
12
+  onLoad: function (options) {
13
+    var that = this;
14
+    that.setData({
15
+      Containnerheight: main.getWindowHeight(),
16
+    });
17
+    
18
+  },
19
+  onShareAppMessage: function () {
20
+    return {
21
+      title: app.globalData.ShareTitle,
22
+      path: app.globalData.SharePath + '?UserID=' + app.globalData.userInfo.UserID,
23
+      imageUrl: app.globalData.ShareImage,
24
+    }
25
+  },
26
+})

+ 7 - 0
pages/main/default.json

@@ -0,0 +1,7 @@
1
+{
2
+  "navigationBarBackgroundColor": "#FFCC00",
3
+  "navigationBarTextStyle": "black",
4
+  "backgroundColor": "#FFCC00",
5
+  "backgroundColorTop": "#FFCC00",
6
+  "backgroundColorBottom": "#FFCC00"
7
+}

+ 71 - 0
pages/main/default.wxml

@@ -0,0 +1,71 @@
1
+<view class="container FlexColumn" style='min-height:{{Containnerheight}}rpx;'>
2
+  <image class="pic_01" src="../images/pic_01.png"></image>
3
+  <view class="panel1 FlexColumn">
4
+    <view class="panel11 FlexColumn">
5
+      <view class="panel111 FlexRow">
6
+        <image class="icon_magnifier_01" src="../images/icon_magnifier_01.png" ></image>
7
+        <view class="text01">搜学校</view>
8
+      </view>
9
+      <image class="line01" src="../images/line_01.png"></image>
10
+
11
+      <view class="text02">选区查志愿</view>
12
+
13
+      <view class="panel112 FlexRow">
14
+        <view class="panel1121 FlexRow" wx:for="{{District}}" wx:key="index">
15
+          <view class="panel11211 FlexColumn">
16
+            <view class="text03">{{item.Name}}</view>
17
+            <view class="text04">{{item.Count}}所高中</view>
18
+          </view>
19
+          <image class="imgLogo" src="../images/logo_{{item.ID}}s.png"></image>
20
+        </view>
21
+      </view>
22
+
23
+      <view class="line02"></view>
24
+
25
+      <view class="panel113 FlexRow">
26
+        <view class="panel1131">
27
+          <image class="icon_fav_03" src="../images/icon_fav_03.png"></image>
28
+        </view>
29
+
30
+        <view class="panel1132 FlexColumn">
31
+          <view class="text03">收藏学校</view>
32
+          <view class="text05">可以对比收藏的学校</view>
33
+        </view>
34
+        <image class="pic_02" src="../images/pic_02.png"></image>
35
+       
36
+      </view>
37
+
38
+      <view class="line02"></view>
39
+
40
+      <view class="panel1133 FlexRow">
41
+        <view class="text03">纠错与建议</view>
42
+        <image class="icon_nextpage_1" src="../images/icon_nextpage_1.png"></image>
43
+      </view>
44
+
45
+      <view class="line03 FlexColumn">
46
+        <image class="line01" src="../images/line_01.png"></image>
47
+      </view>
48
+    </view>
49
+    
50
+  </view>
51
+
52
+  <view class="panel2 FlexColumn">
53
+    <image class="toolbook" src="../images/toolbook.png"></image>
54
+    <view class="line04"></view>
55
+    <view class="text06">参考文章</view>
56
+
57
+    <block wx:for="{{[1,2,3,4]}}">
58
+      <view class="panel21 FlexRow">
59
+        <view class="panel211 FlexColumn">
60
+          <view class="text05">数据图表</view>
61
+          <view class="text07">上海16区2023年统一招生平行志愿各区情况汇总</view>
62
+        </view>
63
+        <image class="articleImage" src="../images/pic_03.png"></image> 
64
+      </view>
65
+      <view class="line04"></view>
66
+    </block>
67
+    <view class="footerHeight"></view>
68
+  </view>
69
+
70
+  
71
+</view>

+ 210 - 0
pages/main/default.wxss

@@ -0,0 +1,210 @@
1
+.container{
2
+  width:100%;
3
+  background-color: #FFCC00;
4
+}
5
+.pic_01{
6
+  width: 100%;
7
+  height:254rpx;
8
+}
9
+
10
+.panel1{
11
+  width:100%;
12
+}
13
+
14
+.panel11{
15
+  width:690rpx;
16
+  border-top-left-radius: 30rpx;
17
+  border-top-right-radius: 30rpx;
18
+  background-color: #fff;
19
+  min-height: 100rpx;
20
+  margin-top: 60rpx;
21
+  position: relative;
22
+}
23
+
24
+.panel111{
25
+  width:610rpx;
26
+  height:70rpx;
27
+  background-color: #F2F2F2;
28
+  border-radius: 14rpx;
29
+  margin: 40rpx 0 40rpx 0;
30
+  justify-content: flex-start;
31
+}
32
+
33
+.icon_magnifier_01{
34
+  width: 24rpx;
35
+  height: 24rpx;
36
+  margin-left: 23rpx;
37
+}
38
+
39
+.text01{
40
+  font-size:28rpx;
41
+  margin-left: 20rpx;
42
+}
43
+
44
+.line01{
45
+  width: 610rpx;
46
+  height:7rpx;
47
+}
48
+
49
+.text02{
50
+  font-size:36rpx;
51
+  margin-top: 50rpx;
52
+  align-self: flex-start;
53
+  margin-left:40rpx;
54
+}
55
+
56
+.panel112{
57
+  width: 650rpx;
58
+  flex-wrap: wrap;
59
+  margin-top: 30rpx;
60
+  justify-content: flex-start;
61
+  align-items: flex-start;
62
+}
63
+
64
+.panel1121{
65
+  width:190rpx;
66
+  height:121rpx;
67
+  border-radius: 10rpx;
68
+  background-color: #f2f2f2;
69
+  margin: 0 0 20rpx 20rpx;
70
+  align-items: flex-start;
71
+  justify-content: flex-start;
72
+}
73
+
74
+.panel11211{
75
+  align-items: flex-start;
76
+  margin-right: 34rpx;
77
+  margin: 30rpx 34rpx 0 16rpx;
78
+}
79
+
80
+.text03{
81
+  font-size:28rpx;
82
+}
83
+.text04{
84
+  font-size:18rpx;
85
+}
86
+
87
+.imgLogo{
88
+  width:34rpx;
89
+  height:34rpx;
90
+  margin-top: 36rpx;
91
+}
92
+
93
+.line02{
94
+  width:610rpx;
95
+  height:1rpx;
96
+  background-color: #E3E3E3;
97
+  margin-top: 40rpx;
98
+}
99
+
100
+.panel113{
101
+  width:610rpx;
102
+  height:180rpx;
103
+  background-color: #E0E0D8;
104
+  border-radius: 10rpx;
105
+  margin-top: 40rpx;
106
+  position: relative;
107
+  overflow: hidden;
108
+}
109
+
110
+.panel1131{
111
+  width:230rpx;
112
+  height:250rpx;
113
+  background-color: #F18B66;
114
+  border-radius: 68rpx;
115
+  position: absolute;
116
+  top:-178rpx;
117
+  left:-120rpx;
118
+}
119
+
120
+.icon_fav_03{
121
+  width:34rpx;
122
+  height:34rpx;
123
+  position: absolute;
124
+  right:47rpx;
125
+  bottom:20rpx;
126
+}
127
+
128
+.panel1132{
129
+  position: absolute;
130
+  top:92rpx;
131
+  left:20rpx;
132
+  align-items: flex-start;
133
+}
134
+
135
+.text05{
136
+  font-size: 20rpx;
137
+}
138
+
139
+.pic_02{
140
+  width:300rpx;
141
+  height:180rpx;
142
+  position: absolute;
143
+  right:0;
144
+}
145
+
146
+.panel1133{
147
+  width:601rpx;
148
+  height:140rpx;
149
+  justify-content: space-between;
150
+}
151
+
152
+.icon_nextpage_1{
153
+  width:16rpx;
154
+  height:26rpx;
155
+}
156
+
157
+
158
+.line03{
159
+  width:750rpx;
160
+  height:20rpx;
161
+  background-color:rgba(0,0,0,0.1);
162
+  justify-content: flex-end;
163
+}
164
+
165
+.panel2{
166
+  width: 100%;
167
+  background-color: #fff;
168
+}
169
+
170
+.toolbook{
171
+  width:670rpx;
172
+  height:180rpx;
173
+  margin: 60rpx 0;
174
+}
175
+
176
+.line04{
177
+  width:670rpx;
178
+  height:1rpx;
179
+  background-color: #E3E3E3;
180
+}
181
+
182
+
183
+.text06{
184
+  font-size: 36rpx;
185
+  margin: 60rpx 0 40rpx 0;
186
+  align-self: flex-start;
187
+  margin-left:40rpx;
188
+}
189
+
190
+.panel21{
191
+  width: 670rpx;
192
+  justify-content: space-between;
193
+  margin: 30rpx 0;
194
+}
195
+.panel211{
196
+  align-items: flex-start;
197
+  width: 440rpx;
198
+}
199
+
200
+.text07{
201
+  font-size:28rpx;
202
+  font-weight: 400;
203
+}
204
+
205
+.articleImage{
206
+  width:180rpx;
207
+  height:118rpx;
208
+  border-radius: 6rpx;
209
+}
210
+

+ 52 - 0
project.config.json

@@ -0,0 +1,52 @@
1
+{
2
+  "description": "项目配置文件",
3
+  "packOptions": {
4
+    "ignore": [],
5
+    "include": []
6
+  },
7
+  "setting": {
8
+    "bundle": false,
9
+    "userConfirmedBundleSwitch": false,
10
+    "urlCheck": true,
11
+    "scopeDataCheck": false,
12
+    "coverView": true,
13
+    "es6": true,
14
+    "postcss": true,
15
+    "compileHotReLoad": false,
16
+    "lazyloadPlaceholderEnable": false,
17
+    "preloadBackgroundData": false,
18
+    "minified": true,
19
+    "autoAudits": false,
20
+    "newFeature": false,
21
+    "uglifyFileName": false,
22
+    "uploadWithSourceMap": true,
23
+    "useIsolateContext": true,
24
+    "nodeModules": false,
25
+    "enhance": true,
26
+    "useMultiFrameRuntime": true,
27
+    "useApiHook": true,
28
+    "useApiHostProcess": true,
29
+    "showShadowRootInWxmlPanel": true,
30
+    "packNpmManually": false,
31
+    "enableEngineNative": false,
32
+    "packNpmRelationList": [],
33
+    "minifyWXSS": true,
34
+    "showES6CompileOption": false,
35
+    "minifyWXML": true,
36
+    "babelSetting": {
37
+      "ignore": [],
38
+      "disablePlugins": [],
39
+      "outputPath": ""
40
+    },
41
+    "condition": false
42
+  },
43
+  "compileType": "miniprogram",
44
+  "libVersion": "2.19.4",
45
+  "appid": "wx39bc498e7fdacb6b",
46
+  "projectname": "miniprogram-92",
47
+  "condition": {},
48
+  "editorSetting": {
49
+    "tabIndent": "insertSpaces",
50
+    "tabSize": 2
51
+  }
52
+}

+ 7 - 0
project.private.config.json

@@ -0,0 +1,7 @@
1
+{
2
+  "description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
3
+  "projectname": "%E7%A7%92%E8%BF%87%E5%88%86%E6%95%B0%E7%BA%BF",
4
+  "setting": {
5
+    "compileHotReLoad": true
6
+  }
7
+}

+ 7 - 0
sitemap.json

@@ -0,0 +1,7 @@
1
+{
2
+  "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html",
3
+  "rules": [{
4
+  "action": "allow",
5
+  "page": "*"
6
+  }]
7
+}

+ 20 - 0
utils/constant.js

@@ -0,0 +1,20 @@
1
+module.exports = {
2
+  arrDistrict:[
3
+    {ID:"01",Name:"黄浦区",Count:"17"},
4
+    {ID:"02",Name:"徐汇区",Count:"18"},
5
+    {ID:"03",Name:"长宁区",Count:"9"},
6
+    {ID:"04",Name:"静安区",Count:"21"},
7
+    {ID:"05",Name:"普陀区",Count:"13"},
8
+    {ID:"06",Name:"虹口区",Count:"11"},
9
+    {ID:"07",Name:"杨浦区",Count:"14"},
10
+    {ID:"08",Name:"闵行区",Count:"29"},
11
+    {ID:"09",Name:"宝山区",Count:"19"},
12
+    {ID:"10",Name:"嘉定区",Count:"12"},
13
+    {ID:"11",Name:"浦东新区",Count:"55"},
14
+    {ID:"12",Name:"金山区",Count:"10"},
15
+    {ID:"13",Name:"松江区",Count:"13"},
16
+    {ID:"14",Name:"青浦区",Count:"8"},
17
+    {ID:"15",Name:"奉贤区",Count:"9"},
18
+    {ID:"16",Name:"崇明区",Count:"8"},
19
+  ],
20
+}

+ 8 - 0
utils/cryptojs.js

@@ -0,0 +1,8 @@
1
+import BlockModes from '../utils/lib/BlockModes';
2
+import AES from '../utils/lib/AES';
3
+
4
+var Crypto = exports.Crypto = require('./lib/Crypto').Crypto;
5
+
6
+['BlockModes', 'AES'].forEach(function (path) {
7
+	require('./lib/' + path);
8
+});

+ 402 - 0
utils/lib/AES.js

@@ -0,0 +1,402 @@
1
+(function(){
2
+
3
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
4
+
5
+// Shortcuts
6
+var util = C.util,
7
+    charenc = C.charenc,
8
+    UTF8 = charenc.UTF8;
9
+
10
+// Precomputed SBOX
11
+var SBOX = [ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
12
+             0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
13
+             0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
14
+             0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
15
+             0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
16
+             0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
17
+             0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
18
+             0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
19
+             0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
20
+             0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
21
+             0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
22
+             0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
23
+             0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
24
+             0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
25
+             0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
26
+             0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
27
+             0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
28
+             0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
29
+             0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
30
+             0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
31
+             0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
32
+             0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
33
+             0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
34
+             0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
35
+             0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
36
+             0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
37
+             0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
38
+             0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
39
+             0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
40
+             0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
41
+             0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
42
+             0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 ];
43
+
44
+// Compute inverse SBOX lookup table
45
+for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
46
+
47
+// Compute mulitplication in GF(2^8) lookup tables
48
+var MULT2 = [],
49
+    MULT3 = [],
50
+    MULT9 = [],
51
+    MULTB = [],
52
+    MULTD = [],
53
+    MULTE = [];
54
+
55
+function xtime(a, b) {
56
+	for (var result = 0, i = 0; i < 8; i++) {
57
+		if (b & 1) result ^= a;
58
+		var hiBitSet = a & 0x80;
59
+		a = (a << 1) & 0xFF;
60
+		if (hiBitSet) a ^= 0x1b;
61
+		b >>>= 1;
62
+	}
63
+	return result;
64
+}
65
+
66
+for (var i = 0; i < 256; i++) {
67
+	MULT2[i] = xtime(i,2);
68
+	MULT3[i] = xtime(i,3);
69
+	MULT9[i] = xtime(i,9);
70
+	MULTB[i] = xtime(i,0xB);
71
+	MULTD[i] = xtime(i,0xD);
72
+	MULTE[i] = xtime(i,0xE);
73
+}
74
+
75
+// Precomputed RCon lookup
76
+var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
77
+
78
+// Inner state
79
+var state = [[], [], [], []],
80
+    keylength,
81
+    nrounds,
82
+    keyschedule;
83
+
84
+var AES = C.AES = {
85
+
86
+	/**
87
+	 * Public API
88
+	 */
89
+
90
+	encrypt: function (message, password, options) {
91
+
92
+		options = options || {};
93
+
94
+		// Determine mode
95
+		var mode = options.mode || new C.mode.OFB;
96
+
97
+		// Allow mode to override options
98
+		if (mode.fixOptions) mode.fixOptions(options);
99
+
100
+		var
101
+
102
+			// Convert to bytes if message is a string
103
+			m = (
104
+				message.constructor == String ?
105
+				UTF8.stringToBytes(message) :
106
+				message
107
+			),
108
+
109
+			// Generate random IV
110
+			iv = options.iv || util.randomBytes(AES._blocksize * 4),
111
+
112
+			// Generate key
113
+			k = (
114
+				password.constructor == String ?
115
+				// Derive key from passphrase
116
+				C.PBKDF2(password, iv, 32, { asBytes: true }) :
117
+				// else, assume byte array representing cryptographic key
118
+				password
119
+			);
120
+
121
+		// Encrypt
122
+		AES._init(k);
123
+		mode.encrypt(AES, m, iv);
124
+
125
+		// Return ciphertext
126
+		m = options.iv ? m : iv.concat(m);
127
+		return (options && options.asBytes) ? m : util.bytesToBase64(m);
128
+
129
+	},
130
+
131
+	decrypt: function (ciphertext, password, options) {
132
+
133
+		options = options || {};
134
+
135
+		// Determine mode
136
+		var mode = options.mode || new C.mode.OFB;
137
+
138
+		// Allow mode to override options
139
+		if (mode.fixOptions) mode.fixOptions(options);
140
+
141
+		var
142
+
143
+			// Convert to bytes if ciphertext is a string
144
+			c = (
145
+				ciphertext.constructor == String ?
146
+				util.base64ToBytes(ciphertext):
147
+			    ciphertext
148
+			),
149
+
150
+			// Separate IV and message
151
+			iv = options.iv || c.splice(0, AES._blocksize * 4),
152
+
153
+			// Generate key
154
+			k = (
155
+				password.constructor == String ?
156
+				// Derive key from passphrase
157
+				C.PBKDF2(password, iv, 32, { asBytes: true }) :
158
+				// else, assume byte array representing cryptographic key
159
+				password
160
+			);
161
+
162
+		// Decrypt
163
+		AES._init(k);
164
+		mode.decrypt(AES, c, iv);
165
+
166
+		// Return plaintext
167
+		return (options && options.asBytes) ? c : UTF8.bytesToString(c);
168
+
169
+	},
170
+
171
+
172
+	/**
173
+	 * Package private methods and properties
174
+	 */
175
+
176
+	_blocksize: 4,
177
+
178
+	_encryptblock: function (m, offset) {
179
+
180
+		// Set input
181
+		for (var row = 0; row < AES._blocksize; row++) {
182
+			for (var col = 0; col < 4; col++)
183
+				state[row][col] = m[offset + col * 4 + row];
184
+		}
185
+
186
+		// Add round key
187
+		for (var row = 0; row < 4; row++) {
188
+			for (var col = 0; col < 4; col++)
189
+				state[row][col] ^= keyschedule[col][row];
190
+		}
191
+
192
+		for (var round = 1; round < nrounds; round++) {
193
+
194
+			// Sub bytes
195
+			for (var row = 0; row < 4; row++) {
196
+				for (var col = 0; col < 4; col++)
197
+					state[row][col] = SBOX[state[row][col]];
198
+			}
199
+
200
+			// Shift rows
201
+			state[1].push(state[1].shift());
202
+			state[2].push(state[2].shift());
203
+			state[2].push(state[2].shift());
204
+			state[3].unshift(state[3].pop());
205
+
206
+			// Mix columns
207
+			for (var col = 0; col < 4; col++) {
208
+
209
+				var s0 = state[0][col],
210
+				    s1 = state[1][col],
211
+				    s2 = state[2][col],
212
+				    s3 = state[3][col];
213
+
214
+				state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
215
+				state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
216
+				state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
217
+				state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
218
+
219
+			}
220
+
221
+			// Add round key
222
+			for (var row = 0; row < 4; row++) {
223
+				for (var col = 0; col < 4; col++)
224
+					state[row][col] ^= keyschedule[round * 4 + col][row];
225
+			}
226
+
227
+		}
228
+
229
+		// Sub bytes
230
+		for (var row = 0; row < 4; row++) {
231
+			for (var col = 0; col < 4; col++)
232
+				state[row][col] = SBOX[state[row][col]];
233
+		}
234
+
235
+		// Shift rows
236
+		state[1].push(state[1].shift());
237
+		state[2].push(state[2].shift());
238
+		state[2].push(state[2].shift());
239
+		state[3].unshift(state[3].pop());
240
+
241
+		// Add round key
242
+		for (var row = 0; row < 4; row++) {
243
+			for (var col = 0; col < 4; col++)
244
+				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
245
+		}
246
+
247
+		// Set output
248
+		for (var row = 0; row < AES._blocksize; row++) {
249
+			for (var col = 0; col < 4; col++)
250
+				m[offset + col * 4 + row] = state[row][col];
251
+		}
252
+
253
+	},
254
+
255
+	_decryptblock: function (c, offset) {
256
+
257
+		// Set input
258
+		for (var row = 0; row < AES._blocksize; row++) {
259
+			for (var col = 0; col < 4; col++)
260
+				state[row][col] = c[offset + col * 4 + row];
261
+		}
262
+
263
+		// Add round key
264
+		for (var row = 0; row < 4; row++) {
265
+			for (var col = 0; col < 4; col++)
266
+				state[row][col] ^= keyschedule[nrounds * 4 + col][row];
267
+		}
268
+
269
+		for (var round = 1; round < nrounds; round++) {
270
+
271
+			// Inv shift rows
272
+			state[1].unshift(state[1].pop());
273
+			state[2].push(state[2].shift());
274
+			state[2].push(state[2].shift());
275
+			state[3].push(state[3].shift());
276
+
277
+			// Inv sub bytes
278
+			for (var row = 0; row < 4; row++) {
279
+				for (var col = 0; col < 4; col++)
280
+					state[row][col] = INVSBOX[state[row][col]];
281
+			}
282
+
283
+			// Add round key
284
+			for (var row = 0; row < 4; row++) {
285
+				for (var col = 0; col < 4; col++)
286
+					state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
287
+			}
288
+
289
+			// Inv mix columns
290
+			for (var col = 0; col < 4; col++) {
291
+
292
+				var s0 = state[0][col],
293
+				    s1 = state[1][col],
294
+				    s2 = state[2][col],
295
+				    s3 = state[3][col];
296
+
297
+				state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
298
+				state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
299
+				state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
300
+				state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
301
+
302
+			}
303
+
304
+		}
305
+
306
+		// Inv shift rows
307
+		state[1].unshift(state[1].pop());
308
+		state[2].push(state[2].shift());
309
+		state[2].push(state[2].shift());
310
+		state[3].push(state[3].shift());
311
+
312
+		// Inv sub bytes
313
+		for (var row = 0; row < 4; row++) {
314
+			for (var col = 0; col < 4; col++)
315
+				state[row][col] = INVSBOX[state[row][col]];
316
+		}
317
+
318
+		// Add round key
319
+		for (var row = 0; row < 4; row++) {
320
+			for (var col = 0; col < 4; col++)
321
+				state[row][col] ^= keyschedule[col][row];
322
+		}
323
+
324
+		// Set output
325
+		for (var row = 0; row < AES._blocksize; row++) {
326
+			for (var col = 0; col < 4; col++)
327
+				c[offset + col * 4 + row] = state[row][col];
328
+		}
329
+
330
+	},
331
+
332
+
333
+	/**
334
+	 * Private methods
335
+	 */
336
+
337
+	_init: function (k) {
338
+		keylength = k.length / 4;
339
+		nrounds = keylength + 6;
340
+		AES._keyexpansion(k);
341
+	},
342
+
343
+	// Generate a key schedule
344
+	_keyexpansion: function (k) {
345
+
346
+		keyschedule = [];
347
+
348
+		for (var row = 0; row < keylength; row++) {
349
+			keyschedule[row] = [
350
+				k[row * 4],
351
+				k[row * 4 + 1],
352
+				k[row * 4 + 2],
353
+				k[row * 4 + 3]
354
+			];
355
+		}
356
+
357
+		for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
358
+
359
+			var temp = [
360
+				keyschedule[row - 1][0],
361
+				keyschedule[row - 1][1],
362
+				keyschedule[row - 1][2],
363
+				keyschedule[row - 1][3]
364
+			];
365
+
366
+			if (row % keylength == 0) {
367
+
368
+				// Rot word
369
+				temp.push(temp.shift());
370
+
371
+				// Sub word
372
+				temp[0] = SBOX[temp[0]];
373
+				temp[1] = SBOX[temp[1]];
374
+				temp[2] = SBOX[temp[2]];
375
+				temp[3] = SBOX[temp[3]];
376
+
377
+				temp[0] ^= RCON[row / keylength];
378
+
379
+			} else if (keylength > 6 && row % keylength == 4) {
380
+
381
+				// Sub word
382
+				temp[0] = SBOX[temp[0]];
383
+				temp[1] = SBOX[temp[1]];
384
+				temp[2] = SBOX[temp[2]];
385
+				temp[3] = SBOX[temp[3]];
386
+
387
+			}
388
+
389
+			keyschedule[row] = [
390
+				keyschedule[row - keylength][0] ^ temp[0],
391
+				keyschedule[row - keylength][1] ^ temp[1],
392
+				keyschedule[row - keylength][2] ^ temp[2],
393
+				keyschedule[row - keylength][3] ^ temp[3]
394
+			];
395
+
396
+		}
397
+
398
+	}
399
+
400
+};
401
+
402
+})();

+ 378 - 0
utils/lib/BlockModes.js

@@ -0,0 +1,378 @@
1
+/*!
2
+ * Crypto-JS contribution from Simon Greatrix
3
+ */
4
+
5
+(function(){
6
+
7
+var C = (typeof window === 'undefined') ? require('./Crypto').Crypto : window.Crypto;
8
+
9
+// Create pad namespace
10
+var C_pad = C.pad = {};
11
+
12
+// Calculate the number of padding bytes required.
13
+function _requiredPadding(cipher, message) {
14
+    var blockSizeInBytes = cipher._blocksize * 4;
15
+    var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
16
+    return reqd;
17
+};
18
+
19
+// Remove padding when the final byte gives the number of padding bytes.
20
+var _unpadLength = function (message) {
21
+        var pad = message.pop();
22
+        for (var i = 1; i < pad; i++) {
23
+            message.pop();
24
+        }
25
+    };
26
+
27
+// No-operation padding, used for stream ciphers
28
+C_pad.NoPadding = {
29
+        pad : function (cipher,message) {},
30
+        unpad : function (message) {}
31
+    };
32
+
33
+// Zero Padding.
34
+//
35
+// If the message is not an exact number of blocks, the final block is
36
+// completed with 0x00 bytes. There is no unpadding.
37
+C_pad.ZeroPadding = {
38
+    pad : function (cipher, message) {
39
+        var blockSizeInBytes = cipher._blocksize * 4;
40
+        var reqd = message.length % blockSizeInBytes;
41
+        if( reqd!=0 ) {
42
+            for(reqd = blockSizeInBytes - reqd; reqd>0; reqd--) {
43
+                message.push(0x00);
44
+            }
45
+        }
46
+    },
47
+
48
+    unpad : function (message) {}
49
+};
50
+
51
+// ISO/IEC 7816-4 padding.
52
+//
53
+// Pads the plain text with an 0x80 byte followed by as many 0x00
54
+// bytes are required to complete the block.
55
+C_pad.iso7816 = {
56
+    pad : function (cipher, message) {
57
+        var reqd = _requiredPadding(cipher, message);
58
+        message.push(0x80);
59
+        for (; reqd > 1; reqd--) {
60
+            message.push(0x00);
61
+        }
62
+    },
63
+
64
+    unpad : function (message) {
65
+        while (message.pop() != 0x80) {}
66
+    }
67
+};
68
+
69
+// ANSI X.923 padding
70
+//
71
+// The final block is padded with zeros except for the last byte of the
72
+// last block which contains the number of padding bytes.
73
+C_pad.ansix923 = {
74
+    pad : function (cipher, message) {
75
+        var reqd = _requiredPadding(cipher, message);
76
+        for (var i = 1; i < reqd; i++) {
77
+            message.push(0x00);
78
+        }
79
+        message.push(reqd);
80
+    },
81
+
82
+    unpad : _unpadLength
83
+};
84
+
85
+// ISO 10126
86
+//
87
+// The final block is padded with random bytes except for the last
88
+// byte of the last block which contains the number of padding bytes.
89
+C_pad.iso10126 = {
90
+    pad : function (cipher, message) {
91
+        var reqd = _requiredPadding(cipher, message);
92
+        for (var i = 1; i < reqd; i++) {
93
+            message.push(Math.floor(Math.random() * 256));
94
+        }
95
+        message.push(reqd);
96
+    },
97
+
98
+    unpad : _unpadLength
99
+};
100
+
101
+// PKCS7 padding
102
+//
103
+// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
104
+// value of each added byte is the number of bytes that are added,
105
+// i.e. N bytes, each of value N are added.
106
+C_pad.pkcs7 = {
107
+    pad : function (cipher, message) {
108
+        var reqd = _requiredPadding(cipher, message);
109
+        for (var i = 0; i < reqd; i++) {
110
+            message.push(reqd);
111
+        }
112
+    },
113
+
114
+    unpad : _unpadLength
115
+};
116
+
117
+// Create mode namespace
118
+var C_mode = C.mode = {};
119
+
120
+/**
121
+ * Mode base "class".
122
+ */
123
+var Mode = C_mode.Mode = function (padding) {
124
+    if (padding) {
125
+        this._padding = padding;
126
+    }
127
+};
128
+
129
+Mode.prototype = {
130
+    encrypt: function (cipher, m, iv) {
131
+        this._padding.pad(cipher, m);
132
+        this._doEncrypt(cipher, m, iv);
133
+    },
134
+
135
+    decrypt: function (cipher, m, iv) {
136
+        this._doDecrypt(cipher, m, iv);
137
+        this._padding.unpad(m);
138
+    },
139
+
140
+    // Default padding
141
+    _padding: C_pad.iso7816
142
+};
143
+
144
+
145
+/**
146
+ * Electronic Code Book mode.
147
+ * 
148
+ * ECB applies the cipher directly against each block of the input.
149
+ * 
150
+ * ECB does not require an initialization vector.
151
+ */
152
+var ECB = C_mode.ECB = function () {
153
+    // Call parent constructor
154
+    Mode.apply(this, arguments);
155
+};
156
+
157
+// Inherit from Mode
158
+var ECB_prototype = ECB.prototype = new Mode;
159
+
160
+// Concrete steps for Mode template
161
+ECB_prototype._doEncrypt = function (cipher, m, iv) {
162
+    var blockSizeInBytes = cipher._blocksize * 4;
163
+    // Encrypt each block
164
+    for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
165
+        cipher._encryptblock(m, offset);
166
+    }
167
+};
168
+ECB_prototype._doDecrypt = function (cipher, c, iv) {
169
+    var blockSizeInBytes = cipher._blocksize * 4;
170
+    // Decrypt each block
171
+    for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
172
+        cipher._decryptblock(c, offset);
173
+    }
174
+};
175
+
176
+// ECB never uses an IV
177
+ECB_prototype.fixOptions = function (options) {
178
+    options.iv = [];
179
+};
180
+
181
+
182
+/**
183
+ * Cipher block chaining
184
+ * 
185
+ * The first block is XORed with the IV. Subsequent blocks are XOR with the
186
+ * previous cipher output.
187
+ */
188
+var CBC = C_mode.CBC = function () {
189
+    // Call parent constructor
190
+    Mode.apply(this, arguments);
191
+};
192
+
193
+// Inherit from Mode
194
+var CBC_prototype = CBC.prototype = new Mode;
195
+
196
+// Concrete steps for Mode template
197
+CBC_prototype._doEncrypt = function (cipher, m, iv) {
198
+    var blockSizeInBytes = cipher._blocksize * 4;
199
+
200
+    // Encrypt each block
201
+    for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
202
+        if (offset == 0) {
203
+            // XOR first block using IV
204
+            for (var i = 0; i < blockSizeInBytes; i++)
205
+            m[i] ^= iv[i];
206
+        } else {
207
+            // XOR this block using previous crypted block
208
+            for (var i = 0; i < blockSizeInBytes; i++)
209
+            m[offset + i] ^= m[offset + i - blockSizeInBytes];
210
+        }
211
+        // Encrypt block
212
+        cipher._encryptblock(m, offset);
213
+    }
214
+};
215
+CBC_prototype._doDecrypt = function (cipher, c, iv) {
216
+    var blockSizeInBytes = cipher._blocksize * 4;
217
+
218
+    // At the start, the previously crypted block is the IV
219
+    var prevCryptedBlock = iv;
220
+
221
+    // Decrypt each block
222
+    for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
223
+        // Save this crypted block
224
+        var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
225
+        // Decrypt block
226
+        cipher._decryptblock(c, offset);
227
+        // XOR decrypted block using previous crypted block
228
+        for (var i = 0; i < blockSizeInBytes; i++) {
229
+            c[offset + i] ^= prevCryptedBlock[i];
230
+        }
231
+        prevCryptedBlock = thisCryptedBlock;
232
+    }
233
+};
234
+
235
+
236
+/**
237
+ * Cipher feed back
238
+ * 
239
+ * The cipher output is XORed with the plain text to produce the cipher output,
240
+ * which is then fed back into the cipher to produce a bit pattern to XOR the
241
+ * next block with.
242
+ * 
243
+ * This is a stream cipher mode and does not require padding.
244
+ */
245
+var CFB = C_mode.CFB = function () {
246
+    // Call parent constructor
247
+    Mode.apply(this, arguments);
248
+};
249
+
250
+// Inherit from Mode
251
+var CFB_prototype = CFB.prototype = new Mode;
252
+
253
+// Override padding
254
+CFB_prototype._padding = C_pad.NoPadding;
255
+
256
+// Concrete steps for Mode template
257
+CFB_prototype._doEncrypt = function (cipher, m, iv) {
258
+    var blockSizeInBytes = cipher._blocksize * 4,
259
+        keystream = iv.slice(0);
260
+
261
+    // Encrypt each byte
262
+    for (var i = 0; i < m.length; i++) {
263
+
264
+        var j = i % blockSizeInBytes;
265
+        if (j == 0) cipher._encryptblock(keystream, 0);
266
+
267
+        m[i] ^= keystream[j];
268
+        keystream[j] = m[i];
269
+    }
270
+};
271
+CFB_prototype._doDecrypt = function (cipher, c, iv) {
272
+    var blockSizeInBytes = cipher._blocksize * 4,
273
+        keystream = iv.slice(0);
274
+
275
+    // Encrypt each byte
276
+    for (var i = 0; i < c.length; i++) {
277
+
278
+        var j = i % blockSizeInBytes;
279
+        if (j == 0) cipher._encryptblock(keystream, 0);
280
+
281
+        var b = c[i];
282
+        c[i] ^= keystream[j];
283
+        keystream[j] = b;
284
+    }
285
+};
286
+
287
+
288
+/**
289
+ * Output feed back
290
+ * 
291
+ * The cipher repeatedly encrypts its own output. The output is XORed with the
292
+ * plain text to produce the cipher text.
293
+ * 
294
+ * This is a stream cipher mode and does not require padding.
295
+ */
296
+var OFB = C_mode.OFB = function () {
297
+    // Call parent constructor
298
+    Mode.apply(this, arguments);
299
+};
300
+
301
+// Inherit from Mode
302
+var OFB_prototype = OFB.prototype = new Mode;
303
+
304
+// Override padding
305
+OFB_prototype._padding = C_pad.NoPadding;
306
+
307
+// Concrete steps for Mode template
308
+OFB_prototype._doEncrypt = function (cipher, m, iv) {
309
+
310
+    var blockSizeInBytes = cipher._blocksize * 4,
311
+        keystream = iv.slice(0);
312
+
313
+    // Encrypt each byte
314
+    for (var i = 0; i < m.length; i++) {
315
+
316
+        // Generate keystream
317
+        if (i % blockSizeInBytes == 0)
318
+            cipher._encryptblock(keystream, 0);
319
+
320
+        // Encrypt byte
321
+        m[i] ^= keystream[i % blockSizeInBytes];
322
+
323
+    }
324
+};
325
+OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
326
+
327
+/**
328
+ * Counter
329
+ * @author Gergely Risko
330
+ *
331
+ * After every block the last 4 bytes of the IV is increased by one
332
+ * with carry and that IV is used for the next block.
333
+ *
334
+ * This is a stream cipher mode and does not require padding.
335
+ */
336
+var CTR = C_mode.CTR = function () {
337
+    // Call parent constructor
338
+    Mode.apply(this, arguments);
339
+};
340
+
341
+// Inherit from Mode
342
+var CTR_prototype = CTR.prototype = new Mode;
343
+
344
+// Override padding
345
+CTR_prototype._padding = C_pad.NoPadding;
346
+
347
+CTR_prototype._doEncrypt = function (cipher, m, iv) {
348
+    var blockSizeInBytes = cipher._blocksize * 4;
349
+    var counter = iv.slice(0);
350
+
351
+    for (var i = 0; i < m.length;) {
352
+        // do not lose iv
353
+        var keystream = counter.slice(0);
354
+
355
+        // Generate keystream for next block
356
+        cipher._encryptblock(keystream, 0);
357
+
358
+        // XOR keystream with block
359
+        for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
360
+            m[i] ^= keystream[j];
361
+        }
362
+
363
+        // Increase counter
364
+        if(++(counter[blockSizeInBytes-1]) == 256) {
365
+            counter[blockSizeInBytes-1] = 0;
366
+            if(++(counter[blockSizeInBytes-2]) == 256) {
367
+                counter[blockSizeInBytes-2] = 0;
368
+                if(++(counter[blockSizeInBytes-3]) == 256) {
369
+                    counter[blockSizeInBytes-3] = 0;
370
+                    ++(counter[blockSizeInBytes-4]);
371
+                }
372
+            }
373
+        }
374
+    }
375
+};
376
+CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
377
+
378
+})();

+ 155 - 0
utils/lib/Crypto.js

@@ -0,0 +1,155 @@
1
+if (typeof Crypto == "undefined" || ! Crypto.util)
2
+{
3
+(function(){
4
+
5
+var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
6
+
7
+// Global Crypto object
8
+// with browser window or with node module
9
+var Crypto = (typeof window === 'undefined') ? exports.Crypto = {} : window.Crypto = {}; 
10
+
11
+// Crypto utilities
12
+var util = Crypto.util = {
13
+
14
+	// Bit-wise rotate left
15
+	rotl: function (n, b) {
16
+		return (n << b) | (n >>> (32 - b));
17
+	},
18
+
19
+	// Bit-wise rotate right
20
+	rotr: function (n, b) {
21
+		return (n << (32 - b)) | (n >>> b);
22
+	},
23
+
24
+	// Swap big-endian to little-endian and vice versa
25
+	endian: function (n) {
26
+
27
+		// If number given, swap endian
28
+		if (n.constructor == Number) {
29
+			return util.rotl(n,  8) & 0x00FF00FF |
30
+			       util.rotl(n, 24) & 0xFF00FF00;
31
+		}
32
+
33
+		// Else, assume array and swap all items
34
+		for (var i = 0; i < n.length; i++)
35
+			n[i] = util.endian(n[i]);
36
+		return n;
37
+
38
+	},
39
+
40
+	// Generate an array of any length of random bytes
41
+	randomBytes: function (n) {
42
+		for (var bytes = []; n > 0; n--)
43
+			bytes.push(Math.floor(Math.random() * 256));
44
+		return bytes;
45
+	},
46
+
47
+	// Convert a byte array to big-endian 32-bit words
48
+	bytesToWords: function (bytes) {
49
+		for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
50
+			words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
51
+		return words;
52
+	},
53
+
54
+	// Convert big-endian 32-bit words to a byte array
55
+	wordsToBytes: function (words) {
56
+		for (var bytes = [], b = 0; b < words.length * 32; b += 8)
57
+			bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
58
+		return bytes;
59
+	},
60
+
61
+	// Convert a byte array to a hex string
62
+	bytesToHex: function (bytes) {
63
+		for (var hex = [], i = 0; i < bytes.length; i++) {
64
+			hex.push((bytes[i] >>> 4).toString(16));
65
+			hex.push((bytes[i] & 0xF).toString(16));
66
+		}
67
+		return hex.join("");
68
+	},
69
+
70
+	// Convert a hex string to a byte array
71
+	hexToBytes: function (hex) {
72
+		for (var bytes = [], c = 0; c < hex.length; c += 2)
73
+			bytes.push(parseInt(hex.substr(c, 2), 16));
74
+		return bytes;
75
+	},
76
+
77
+	// Convert a byte array to a base-64 string
78
+	bytesToBase64: function (bytes) {
79
+
80
+		// Use browser-native function if it exists
81
+		if (typeof btoa == "function") return btoa(Binary.bytesToString(bytes));
82
+
83
+		for(var base64 = [], i = 0; i < bytes.length; i += 3) {
84
+			var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
85
+			for (var j = 0; j < 4; j++) {
86
+				if (i * 8 + j * 6 <= bytes.length * 8)
87
+					base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
88
+				else base64.push("=");
89
+			}
90
+		}
91
+
92
+		return base64.join("");
93
+
94
+	},
95
+
96
+	// Convert a base-64 string to a byte array
97
+	base64ToBytes: function (base64) {
98
+
99
+		// Use browser-native function if it exists
100
+		if (typeof atob == "function") return Binary.stringToBytes(atob(base64));
101
+
102
+		// Remove non-base-64 characters
103
+		base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
104
+
105
+		for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
106
+			if (imod4 == 0) continue;
107
+			bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
108
+			           (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
109
+		}
110
+
111
+		return bytes;
112
+
113
+	}
114
+
115
+};
116
+
117
+// Crypto character encodings
118
+var charenc = Crypto.charenc = {};
119
+
120
+// UTF-8 encoding
121
+var UTF8 = charenc.UTF8 = {
122
+
123
+	// Convert a string to a byte array
124
+	stringToBytes: function (str) {
125
+		return Binary.stringToBytes(unescape(encodeURIComponent(str)));
126
+	},
127
+
128
+	// Convert a byte array to a string
129
+	bytesToString: function (bytes) {
130
+		return decodeURIComponent(escape(Binary.bytesToString(bytes)));
131
+	}
132
+
133
+};
134
+
135
+// Binary encoding
136
+var Binary = charenc.Binary = {
137
+
138
+	// Convert a string to a byte array
139
+	stringToBytes: function (str) {
140
+		for (var bytes = [], i = 0; i < str.length; i++)
141
+			bytes.push(str.charCodeAt(i) & 0xFF);
142
+		return bytes;
143
+	},
144
+
145
+	// Convert a byte array to a string
146
+	bytesToString: function (bytes) {
147
+		for (var str = [], i = 0; i < bytes.length; i++)
148
+			str.push(String.fromCharCode(bytes[i]));
149
+		return str.join("");
150
+	}
151
+
152
+};
153
+
154
+})();
155
+}

+ 111 - 0
utils/main.js

@@ -0,0 +1,111 @@
1
+import common from '../utils/util';
2
+import constant from '../utils/constant';
3
+
4
+var app = getApp();
5
+
6
+function getData(url, callback) {
7
+  if (!app.globalData.IsProduction)
8
+    console.log("加密前的结果为===", url);
9
+  var url = common.Encrypt(url);
10
+  //console.log("加密后的结果为===",url);
11
+  wx.request({
12
+    url: app.globalData.serverUrl + url,
13
+    success: function (res) {
14
+      if (res.statusCode)
15
+        common.checkError(res.statusCode);
16
+      var data = res.data.result;
17
+      callback(data);
18
+    },
19
+    fail: function () {
20
+      wx.showToast({
21
+        title: '系统忙请稍候',
22
+        // image: "../images/universalpic_warning_white_126x120.png",
23
+        duration: 3000
24
+      });
25
+      var err={};
26
+      err.errCode=100;
27
+      err.errMsg="网络错误";
28
+      callback(null,err);
29
+    },
30
+  });
31
+}
32
+
33
+function postData(url, postData, callback) {
34
+  var url = common.Encrypt(url);
35
+  //console.log("加密后的结果为===",url);
36
+  wx.request({
37
+    url: app.globalData.serverUrl + url,
38
+    method: "POST",
39
+    data: postData,
40
+    success: function (res) {
41
+      if (res.statusCode)
42
+        common.checkError(res.statusCode);
43
+      var data = res.data.result;
44
+      callback(data);
45
+    },
46
+    fail: function () {
47
+      wx.showToast({
48
+        title: '系统忙请稍候',
49
+        duration: 3000
50
+      });
51
+    },
52
+  });
53
+}
54
+
55
+function getLocalHost(callback) {
56
+  if (!app.globalData.IsProduction) {
57
+    var url = common.Encrypt("Ping");
58
+    wx.request({
59
+      url: app.globalData.serverUrlLocalhost + url,
60
+      success: function (res) {
61
+        app.globalData.serverUrl = app.globalData.serverUrlLocalhost;
62
+        callback();
63
+      },
64
+      fail: function () {
65
+        app.globalData.serverUrl = app.globalData.serverUrlServer;
66
+        callback();
67
+      },
68
+    });
69
+  } else {
70
+    app.globalData.serverUrl = app.globalData.serverUrlServer;
71
+    callback();
72
+  }
73
+}
74
+
75
+
76
+function getWindowHeight() {
77
+
78
+  var height = app.globalData.systemInfo.windowHeight;
79
+  //console.log("app.globalData.systemInfo.windowHeight:" + app.globalData.systemInfo.windowHeight * 2);
80
+  if (app.globalData.systemInfo.model) {
81
+    if (height == 504 && (
82
+        app.globalData.systemInfo.model.indexOf("iPhone 6<") >= 0 ||
83
+        app.globalData.systemInfo.model.indexOf("iPhone 7<") >= 0 ||
84
+        app.globalData.systemInfo.model.indexOf("iPhone 6s<") >= 0 ||
85
+        app.globalData.systemInfo.model.indexOf("iPhone 5") >= 0 ||
86
+        app.globalData.systemInfo.model.indexOf("iPhone SE") >= 0
87
+      )) {
88
+      height = 596;
89
+    } else if (app.globalData.systemInfo.model.indexOf("iPad") >= 0) {
90
+      height = 470;
91
+    }
92
+  }
93
+
94
+  height = height * 2;
95
+  if (app.globalData.systemInfo.system && app.globalData.systemInfo.system.indexOf("Android") >= 0) {
96
+    height = height + 168;
97
+  } else {
98
+    height = height + 50;
99
+  }
100
+  //console.log("height:" + height);
101
+
102
+  //var height = app.globalData.systemInfo.screenHeight * 2;
103
+  return height;
104
+}
105
+
106
+module.exports = {
107
+  getData: getData,
108
+  postData: postData,
109
+  getLocalHost: getLocalHost,
110
+  getWindowHeight: getWindowHeight,
111
+}

+ 478 - 0
utils/util.js

@@ -0,0 +1,478 @@
1
+var Crypto = require('cryptojs.js').Crypto;
2
+var app = getApp();
3
+
4
+function formatTime(date, format, isShort) {
5
+  if (date) {
6
+    date = new Date(ReplaceAllString(date.toString(),"-","/"));
7
+    var year = date.getFullYear()
8
+    var month = date.getMonth() + 1
9
+    var day = date.getDate()
10
+
11
+    var hour = date.getHours()
12
+    var minute = date.getMinutes()
13
+    var second = date.getSeconds()
14
+
15
+    if (!format)
16
+      format = "/";
17
+
18
+    if (isShort)
19
+      return [year, month, day].map(formatNumber).join(format);
20
+    else
21
+      return [year, month, day].map(formatNumber).join(format) + ' ' + [hour, minute, second].map(formatNumber).join(':');
22
+  }
23
+  else
24
+    return "";
25
+}
26
+
27
+function checkIsArray(obj) {
28
+  return Object.prototype.toString.call(obj) === '[object Array]';
29
+}
30
+
31
+function formatDateCHS(date) {
32
+  if (date) {
33
+    date = date.toString();
34
+    var year = date.substr(0, 4);
35
+    var month = date.substr(5, 2);
36
+    var day = date.substr(8, 2);
37
+
38
+    if (year <= "1900")
39
+      return "";
40
+    else
41
+      return year + "年" + month + "月" + day + "日";
42
+  }
43
+  else
44
+    return "";
45
+}
46
+
47
+function formatDateENG(date, format) {
48
+  if (date) {
49
+    date = date.toString();
50
+    if (!format)
51
+      format = "/";
52
+    date = date.replace("年", format);
53
+    date = date.replace("月", format);
54
+    date = date.replace("日", "");
55
+    return date;
56
+  }
57
+  else
58
+    return "";
59
+}
60
+
61
+
62
+function formatNumber(n) {
63
+  n = n.toString()
64
+  return n[1] ? n : '0' + n
65
+}
66
+
67
+//给字符串左侧补零
68
+function addZero(str, length) {
69
+  while (str.length < length) {
70
+    str = "0" + str;
71
+  }
72
+  return str;
73
+}
74
+
75
+function getMinuteSecond(second, chs) {
76
+  if (!second)
77
+    second = 0;
78
+  var secondUnit = "″";
79
+  var minuteUnit = "′";
80
+  var hourUnit = ":";
81
+  if (chs) {
82
+    secondUnit = "秒";
83
+    minuteUnit = "分";
84
+    hourUnit = "时";
85
+    //second = Math.round(second);
86
+  }
87
+  if (second < 60)
88
+    return second + secondUnit;
89
+  else {
90
+    var minute = Math.floor(second / 60);
91
+    second = Math.round((second - minute * 60) * 1000) / 1000;
92
+
93
+    if (minute >= 60) {
94
+      var hour = Math.floor(minute / 60);
95
+      minute = minute - hour * 60;
96
+
97
+      if (minute == 0 && second == 0)
98
+        return hour + hourUnit;
99
+      else if (second == 0)
100
+        return hour + hourUnit + minute + minuteUnit;
101
+      else
102
+        return hour + hourUnit + minute + minuteUnit + second + secondUnit;
103
+    }
104
+    else {
105
+      if (second == 0)
106
+        return minute + minuteUnit;
107
+      else
108
+        return minute + minuteUnit + second + secondUnit;
109
+    }
110
+  }
111
+}
112
+
113
+function Random(start, end) {
114
+  var result = parseInt(Math.random() * (end - start + 1) + start);
115
+  return result;
116
+}
117
+//打乱数组
118
+function RandomArray(arr) {
119
+  var arrResult = [];
120
+  var maxCount = 0;
121
+  do {
122
+    var rnd = Random(0, arr.length - 1);
123
+    if (arr[rnd]) {
124
+      arrResult.push(arr[rnd]);
125
+      arr[rnd] = null;
126
+    }
127
+    maxCount++;
128
+  }
129
+  while (arrResult.length < arr.length && maxCount < 1000);
130
+  for (var i = 0; i < arr.length; i++)
131
+    arr[i] = arrResult[i];
132
+  return arrResult;
133
+}
134
+
135
+function Unique(arr) {
136
+  var res = [];
137
+  var json = {};
138
+  for (var i = 0; i < arr.length; i++) {
139
+    if (!json[arr[i]]) {
140
+      res.push(arr[i]);
141
+      json[arr[i]] = 1;
142
+    }
143
+  }
144
+  return res;
145
+}
146
+
147
+function getEnumerationName(id, list) {
148
+  for (var i = 0; i < list.length; i++) {
149
+    if (id == list[i].EnumID) {
150
+      return list[i].Name;
151
+    }
152
+  }
153
+  return "";
154
+}
155
+
156
+function getEnumerationNameByDescription(description, list) {
157
+  for (var i = 0; i < list.length; i++) {
158
+    if (description == list[i].Description) {
159
+      return list[i].Name;
160
+    }
161
+  }
162
+  return "";
163
+}
164
+
165
+function getStringMaxLength(str, len) {
166
+  if (str.length > len)
167
+    return str.substr(0, len) + "...";
168
+  else
169
+    return str;
170
+}
171
+
172
+function sort(array, sort_order, obj, objType, obj2, objType2) {
173
+  for (var i = 0; i < array.length - 1; i++) {
174
+    for (var j = i + 1; j < array.length; j++) {
175
+      var check;
176
+      if (objType == "Number") {
177
+        if (sort_order == "ASC")
178
+          check = array[i][obj] > array[j][obj];
179
+        else
180
+          check = array[i][obj] < array[j][obj];
181
+      }
182
+      else {
183
+        //console.log("array["+i+"]:"+array[i][obj]);
184
+        //console.log("array["+j+"]:"+array[j][obj]);
185
+        if (array[i][obj] && array[j][obj]) {
186
+          try {
187
+            if (sort_order == "ASC")
188
+              check = array[i][obj].toString().localeCompare(array[j][obj].toString()) >= 0;
189
+            else if (sort_order == "DESC")
190
+              check = array[i][obj].toString().localeCompare(array[j][obj].toString()) < 0;
191
+          }
192
+          catch (ex) {
193
+            console.log("ex:" + ex);
194
+            if (sort_order == "ASC")
195
+              check = array[i][obj].toString() >= array[j][obj].toString();
196
+            else if (sort_order == "DESC")
197
+              check = array[i][obj].toString() < array[j][obj].toString();
198
+
199
+          }
200
+        }
201
+        else {
202
+          check = false;
203
+        }
204
+      }
205
+      if (check) {
206
+        var temp = swap(array[i], array[j]);
207
+        array[i] = temp.a;
208
+        array[j] = temp.b;
209
+      }
210
+    }
211
+  }
212
+  return array;
213
+
214
+  function swap(a, b) {
215
+    var tempA = JSON.stringify(a);
216
+    var tempB = JSON.stringify(b);
217
+    return {
218
+      a: JSON.parse(tempB),
219
+      b: JSON.parse(tempA),
220
+    }
221
+  }
222
+}
223
+////测试sort
224
+// var a = [
225
+//   {
226
+//     time: "2017-2-1",
227
+//     a: 3,
228
+//   }, {
229
+//     time: "2017-4-1",
230
+//     a: 5,
231
+//   }, {
232
+//     time: "2017-1-1",
233
+//     a: 6
234
+//   },{
235
+//     time: "2017-2-1",
236
+//     a: 3
237
+//   },
238
+// ];
239
+// console.log(a);
240
+// // var a = common.sort(a,"ASC", "time","String");
241
+// // console.log(a);
242
+// var a = common.sort(a,"DESC", "time","String");
243
+// console.log(a);
244
+// //var a = common.sort(a,"DESC", "a","Number");
245
+// // console.log(a);
246
+
247
+function checkError(err) {
248
+  switch (err) {
249
+    case 404:
250
+    case 500:
251
+    case 501:
252
+    case 502:
253
+    case 503:
254
+    case 504:
255
+    case 505:
256
+      wx.redirectTo({
257
+        url: './error',
258
+      });
259
+      break;
260
+  }
261
+  return null;
262
+}
263
+
264
+function Encrypt(word) {
265
+  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
266
+  var eb = Crypto.charenc.UTF8.stringToBytes(word);
267
+  var kb = Crypto.charenc.UTF8.stringToBytes(app.globalData.Key);//KEY
268
+  var vb = Crypto.charenc.UTF8.stringToBytes(app.globalData.IV);//IV
269
+  var ub = Crypto.AES.encrypt(eb, kb, { iv: vb, mode: mode, asBpytes: true });
270
+  return ub;
271
+}
272
+
273
+function Decrypt(word) {
274
+  var mode = new Crypto.mode.CBC(Crypto.pad.pkcs7);
275
+  var eb = Crypto.util.base64ToBytes(word);
276
+  var kb = Crypto.charenc.UTF8.stringToBytes(app.globalData.Key);//KEY
277
+  var vb = Crypto.charenc.UTF8.stringToBytes(app.globalData.IV);//IV
278
+  var ub = Crypto.AES.decrypt(eb, kb, { asBpytes: true, mode: mode, iv: vb });
279
+  return ub;
280
+}
281
+
282
+function isExistStr(str1, str2) {
283
+  var result = false;
284
+  if (str1) {
285
+    if (str1.toString().indexOf(str2) >= 0) {
286
+      result = true;
287
+    }
288
+  }
289
+  return result;
290
+}
291
+
292
+//获取存储数据,若不存在,则获得缺省值。
293
+function getStorageValue(obj, name, defaultStatus, callback) {
294
+  wx.getStorage({
295
+    key: name,
296
+    success: function (res) {
297
+      obj.data[name] = res.data;
298
+      obj.setData(obj.data);
299
+      if (callback)
300
+        callback();
301
+    },
302
+    fail: function (res) {
303
+      obj.data[name] = defaultStatus;
304
+      obj.setData(obj.data);
305
+      if (callback)
306
+        callback();
307
+    },
308
+  });
309
+}
310
+
311
+function addDate(interval, number, date) {
312
+  switch (interval.toLowerCase()) {
313
+    case "y":
314
+      return new Date(date.setFullYear(date.getFullYear() + number));
315
+    case "m":
316
+      return new Date(date.setMonth(date.getMonth() + number));
317
+    case "d":
318
+      return new Date(date.setDate(date.getDate() + number));
319
+    case "w":
320
+      return new Date(date.setDate(date.getDate() + 7 * number));
321
+    case "h":
322
+      return new Date(date.setHours(date.getHours() + number));
323
+    case "n":
324
+      return new Date(date.setMinutes(date.getMinutes() + number));
325
+    case "s":
326
+      return new Date(date.setSeconds(date.getSeconds() + number));
327
+    case "l":
328
+      return new Date(date.setMilliseconds(date.getMilliseconds() + number));
329
+  }
330
+}
331
+
332
+function diffDate(interval, date1, date2) {
333
+  var long = date2.getTime() - date1.getTime(); //相差毫秒
334
+  switch (interval.toLowerCase()) {
335
+    case "y":
336
+      return parseInt(date2.getFullYear() - date1.getFullYear());
337
+    case "m":
338
+      return parseInt((date2.getFullYear() - date1.getFullYear()) * 12 + (date2.getMonth() - date1.getMonth()));
339
+    case "d":
340
+      return parseInt(long / 1000 / 60 / 60 / 24);
341
+    case "w":
342
+      return parseInt(long / 1000 / 60 / 60 / 24 / 7);
343
+    case "h":
344
+      return parseInt(long / 1000 / 60 / 60);
345
+    case "n":
346
+      return parseInt(long / 1000 / 60);
347
+    case "s":
348
+      return parseInt(long / 1000);
349
+    case "l":
350
+      return parseInt(long);
351
+  }
352
+}
353
+
354
+
355
+function ReplaceAllString(str, replaceStrFrom, replaceStrTo) {//替换
356
+  if (str && str.length > 0) {
357
+    var reg = new RegExp(replaceStrFrom, "g");
358
+    //console.log(str);
359
+    return str.toString().replace(reg, replaceStrTo);
360
+  }
361
+  else
362
+    return str;
363
+}
364
+
365
+
366
+function Trim(str) { //删除左右两端的空格
367
+  return str.replace(/(^\s*)|(\s*$)/g, "");
368
+}
369
+
370
+function IsNumber(value) {//判断是否是数字,true:是,false:不是
371
+  return !isNaN(value);
372
+}
373
+
374
+function formatMoney(money) {
375
+  var result;
376
+  if (money == 0)
377
+      result = "0.00";
378
+  else {
379
+      result = Math.round(money).toString();
380
+      //console.log("1:"+result);
381
+      if (result.indexOf(".") >= 0) {
382
+          if (result.substr(result.indexOf(".")).length < 3)
383
+              result += "0";
384
+      }
385
+      else {
386
+          result += ".00";
387
+      }
388
+      //console.log("2:"+result);
389
+
390
+  }
391
+  return result;
392
+}
393
+
394
+function initMonthCalendar(dates, line = 6,isNull=true) {
395
+  //console.log(dates); 
396
+  //dates="2022-07-19";
397
+  var date = new Date(dates);                          // 初始时间格式
398
+   
399
+   var y = date.getFullYear();
400
+   var m = date.getMonth();
401
+   var days = new Date(y, m+1, 0).getDate();          // 获取这个月共有多少天
402
+   var firstDayWeek = new Date(y, m, 1).getDay();       // 月份第一天星期几
403
+ 
404
+   firstDayWeek--
405
+   if (firstDayWeek==-1)
406
+    firstDayWeek=6;
407
+   //console.log("firstDayWeek:"+firstDayWeek); 
408
+   var arr = [];     // 存储日历格式的数组
409
+   var n = [];       // 日历格式中的一行
410
+   var d = 1;        // 日历格式中的天数
411
+ 
412
+   // 先根据这个月第一天排星期几
413
+   // 把上个月剩下几天留在这个月的'奸细'放在最前头
414
+   for(let i = 0; i < firstDayWeek; i++) {
415
+     if(isNull)
416
+        n.unshift("");
417
+     else
418
+        n.unshift(new Date(y, m, 0 - i).getDate());
419
+   }
420
+ 
421
+   // 开启循环
422
+   // 一星期占一行,一行一个外循环
423
+   // 这里我默认想要6行
424
+   for (let j = 0; j < line; j++) {
425
+     // 一天占一个格子,最多一星期7个格子
426
+     // 这里我想要7个格子
427
+     for (let i = 0; i < 7; i++) {
428
+       if(d > days) {
429
+         // 这个月都放完了,该放什么?
430
+         // new Date(2020, 8, 31)  --> 9月没有31 === 10月1
431
+          if (isNull){
432
+            //n.push("");
433
+          }
434
+          else
435
+            n.push(new Date(y, m, d++).getDate());
436
+          
437
+       } else {
438
+         // 放置这个月的天数
439
+        n.push(d++);
440
+       } 
441
+       if (n.length == 7) break;    // 放了7个格子该结束了
442
+     }
443
+ 
444
+     //arr.push(n);
445
+     //n = [];           // 这一行放完了,清空ba
446
+   }
447
+ 
448
+ 
449
+   return n;
450
+}
451
+
452
+module.exports = {
453
+  formatTime: formatTime,
454
+  formatDateCHS: formatDateCHS,
455
+  getMinuteSecond: getMinuteSecond,
456
+  random: Random,
457
+  randomArray: RandomArray,
458
+  unique: Unique,
459
+  getEnumerationName: getEnumerationName,
460
+  getStringMaxLength: getStringMaxLength,
461
+  sort: sort,
462
+  addZero: addZero,
463
+  checkError: checkError,
464
+  Encrypt: Encrypt,
465
+  Decrypt: Decrypt,
466
+  getEnumerationNameByDescription: getEnumerationNameByDescription,
467
+  isExistStr: isExistStr,
468
+  getStorageValue: getStorageValue,
469
+  ReplaceAllString: ReplaceAllString,
470
+  addDate: addDate,
471
+  diffDate: diffDate,
472
+  Trim: Trim,
473
+  IsNumber:IsNumber,
474
+  checkIsArray: checkIsArray,
475
+  formatDateENG: formatDateENG,
476
+  formatMoney:formatMoney,
477
+  initMonthCalendar:initMonthCalendar
478
+}