Holla-Tako 8 maanden geleden
commit
b42c018c59
100 gewijzigde bestanden met toevoegingen van 10228 en 0 verwijderingen
  1. BIN
      price-collection/.DS_Store
  2. 16 0
      price-collection/.hbuilderx/launch.json
  3. 67 0
      price-collection/App.vue
  4. 36 0
      price-collection/api/collect.js
  5. 20 0
      price-collection/api/login.js
  6. 7 0
      price-collection/config/system.js
  7. 20 0
      price-collection/index.html
  8. 27 0
      price-collection/main.js
  9. 115 0
      price-collection/manifest.json
  10. 20 0
      price-collection/node_modules/.package-lock.json
  11. 2 0
      price-collection/node_modules/jsbn/.npmignore
  12. 16 0
      price-collection/node_modules/jsbn/CHANGELOG.md
  13. 40 0
      price-collection/node_modules/jsbn/LICENSE
  14. 173 0
      price-collection/node_modules/jsbn/README.md
  15. 11 0
      price-collection/node_modules/jsbn/example.html
  16. 5 0
      price-collection/node_modules/jsbn/example.js
  17. 1361 0
      price-collection/node_modules/jsbn/index.js
  18. 21 0
      price-collection/node_modules/jsbn/package.json
  19. 3 0
      price-collection/node_modules/jsbn/test/es6-import.js
  20. 3 0
      price-collection/node_modules/sm-crypto/.babelrc
  21. 97 0
      price-collection/node_modules/sm-crypto/.eslintrc.js
  22. 82 0
      price-collection/node_modules/sm-crypto/CHANGELOG.md
  23. 7 0
      price-collection/node_modules/sm-crypto/LICENCE_MIT
  24. 171 0
      price-collection/node_modules/sm-crypto/README.md
  25. 1 0
      price-collection/node_modules/sm-crypto/dist/sm2.js
  26. 1 0
      price-collection/node_modules/sm-crypto/dist/sm3.js
  27. 1 0
      price-collection/node_modules/sm-crypto/dist/sm4.js
  28. 42 0
      price-collection/node_modules/sm-crypto/package.json
  29. 5 0
      price-collection/node_modules/sm-crypto/src/index.js
  30. 161 0
      price-collection/node_modules/sm-crypto/src/sm2/asn1.js
  31. 332 0
      price-collection/node_modules/sm-crypto/src/sm2/ec.js
  32. 261 0
      price-collection/node_modules/sm-crypto/src/sm2/index.js
  33. 170 0
      price-collection/node_modules/sm-crypto/src/sm2/sm3.js
  34. 194 0
      price-collection/node_modules/sm-crypto/src/sm2/utils.js
  35. 94 0
      price-collection/node_modules/sm-crypto/src/sm3/index.js
  36. 359 0
      price-collection/node_modules/sm-crypto/src/sm4/index.js
  37. 26 0
      price-collection/node_modules/sm-crypto/webpack.config.js
  38. 40 0
      price-collection/package-lock.json
  39. 5 0
      price-collection/package.json
  40. 53 0
      price-collection/pages.json
  41. 45 0
      price-collection/pages/collectionDetail/components/item.vue
  42. 641 0
      price-collection/pages/collectionDetail/index.vue
  43. 48 0
      price-collection/pages/collectionList/components/infoItem.vue
  44. 93 0
      price-collection/pages/collectionList/index.vue
  45. 52 0
      price-collection/pages/index/index.vue
  46. 168 0
      price-collection/pages/login/index.vue
  47. BIN
      price-collection/static/.DS_Store
  48. BIN
      price-collection/static/bg-item-title-1.png
  49. BIN
      price-collection/static/bg-item-title.png
  50. BIN
      price-collection/static/icon-add.png
  51. BIN
      price-collection/static/login-bg-top.png
  52. BIN
      price-collection/static/login/login-bg-bottom.png
  53. BIN
      price-collection/static/login/login-btn.png
  54. BIN
      price-collection/static/logo.png
  55. BIN
      price-collection/static/title.png
  56. 10 0
      price-collection/uni.promisify.adaptor.js
  57. 83 0
      price-collection/uni.scss
  58. 40 0
      price-collection/uni_modules/uni-icons/changelog.md
  59. 91 0
      price-collection/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
  60. 110 0
      price-collection/uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  61. 664 0
      price-collection/uni_modules/uni-icons/components/uni-icons/uniicons.css
  62. BIN
      price-collection/uni_modules/uni-icons/components/uni-icons/uniicons.ttf
  63. 664 0
      price-collection/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
  64. 649 0
      price-collection/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
  65. 88 0
      price-collection/uni_modules/uni-icons/package.json
  66. 8 0
      price-collection/uni_modules/uni-icons/readme.md
  67. 51 0
      price-collection/uni_modules/uni-nav-bar/changelog.md
  68. 357 0
      price-collection/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
  69. 24 0
      price-collection/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
  70. 86 0
      price-collection/uni_modules/uni-nav-bar/package.json
  71. 15 0
      price-collection/uni_modules/uni-nav-bar/readme.md
  72. 8 0
      price-collection/uni_modules/uni-scss/changelog.md
  73. 1 0
      price-collection/uni_modules/uni-scss/index.scss
  74. 82 0
      price-collection/uni_modules/uni-scss/package.json
  75. 4 0
      price-collection/uni_modules/uni-scss/readme.md
  76. 7 0
      price-collection/uni_modules/uni-scss/styles/index.scss
  77. 3 0
      price-collection/uni_modules/uni-scss/styles/setting/_border.scss
  78. 66 0
      price-collection/uni_modules/uni-scss/styles/setting/_color.scss
  79. 55 0
      price-collection/uni_modules/uni-scss/styles/setting/_radius.scss
  80. 56 0
      price-collection/uni_modules/uni-scss/styles/setting/_space.scss
  81. 167 0
      price-collection/uni_modules/uni-scss/styles/setting/_styles.scss
  82. 24 0
      price-collection/uni_modules/uni-scss/styles/setting/_text.scss
  83. 146 0
      price-collection/uni_modules/uni-scss/styles/setting/_variables.scss
  84. 19 0
      price-collection/uni_modules/uni-scss/styles/tools/functions.scss
  85. 31 0
      price-collection/uni_modules/uni-scss/theme.scss
  86. 62 0
      price-collection/uni_modules/uni-scss/variables.scss
  87. 21 0
      price-collection/uni_modules/uview-ui/LICENSE
  88. 66 0
      price-collection/uni_modules/uview-ui/README.md
  89. 374 0
      price-collection/uni_modules/uview-ui/changelog.md
  90. 78 0
      price-collection/uni_modules/uview-ui/components/u--form/u--form.vue
  91. 47 0
      price-collection/uni_modules/uview-ui/components/u--image/u--image.vue
  92. 73 0
      price-collection/uni_modules/uview-ui/components/u--input/u--input.vue
  93. 44 0
      price-collection/uni_modules/uview-ui/components/u--text/u--text.vue
  94. 48 0
      price-collection/uni_modules/uview-ui/components/u--textarea/u--textarea.vue
  95. 54 0
      price-collection/uni_modules/uview-ui/components/u-action-sheet/props.js
  96. 278 0
      price-collection/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue
  97. 59 0
      price-collection/uni_modules/uview-ui/components/u-album/props.js
  98. 259 0
      price-collection/uni_modules/uview-ui/components/u-album/u-album.vue
  99. 44 0
      price-collection/uni_modules/uview-ui/components/u-alert/props.js
  100. 0 0
      price-collection/uni_modules/uview-ui/components/u-alert/u-alert.vue

BIN
price-collection/.DS_Store


+ 16 - 0
price-collection/.hbuilderx/launch.json

@@ -0,0 +1,16 @@
1
+{
2
+    "version" : "1.0",
3
+    "configurations" : [
4
+        {
5
+            "playground" : "standard",
6
+            "type" : "uni-app:app-android"
7
+        },
8
+	{
9
+		"app-plus" : 
10
+		{
11
+			"launchtype" : "local"
12
+		},
13
+		"type" : "uniCloud"
14
+	}
15
+    ]
16
+}

+ 67 - 0
price-collection/App.vue

@@ -0,0 +1,67 @@
1
+<script>
2
+	export default {
3
+		onLaunch: function() {
4
+			// console.log('App Launch')
5
+		},
6
+		onShow: function() {
7
+			// console.log('App Show')
8
+		},
9
+		onHide: function() {
10
+			// console.log('App Hide')
11
+		}
12
+	}
13
+</script>
14
+
15
+
16
+<style lang="scss">
17
+	/*每个页面公共css */
18
+	@import "@/uni_modules/uview-ui/index.scss";
19
+	
20
+	.content{
21
+		.title-box {
22
+			position: relative;
23
+			padding-bottom: 80rpx;
24
+			width: 100%;
25
+			height: 344rpx;
26
+			color: white;
27
+			display: flex;
28
+			flex-direction: column;
29
+			justify-content: center;
30
+			align-items: center;
31
+			background:url(@/static/title.png) top center no-repeat;
32
+			background-size: 100% 100%;
33
+			
34
+			.title{
35
+				width: 100%;
36
+				height: 50rpx;
37
+				height: fit-content;
38
+				display: flex;
39
+				justify-content: center;
40
+				align-items: center;
41
+			}
42
+			.icon-add{
43
+				position: absolute;
44
+				right: 0;
45
+				margin-right: 40rpx;
46
+				width: 40rpx;
47
+				height: 40rpx;
48
+				background: url(@/static/icon-add.png) top center no-repeat;
49
+				background-size: 100% 100%;
50
+			}
51
+		}
52
+		
53
+		.container-box{
54
+			position: relative;
55
+			margin-top: -120rpx;
56
+			padding: 40rpx 30rpx;
57
+			width: 100%;
58
+			height: fit-content;
59
+			// display: flex;
60
+			// flex-direction: column;
61
+			// align-items: center;
62
+			background: #f0f7ff;
63
+			border-radius: 60rpx 60rpx 0 0;
64
+			z-index: 2;
65
+		}
66
+	}
67
+</style>

+ 36 - 0
price-collection/api/collect.js

@@ -0,0 +1,36 @@
1
+import request from "@/utils/request"
2
+
3
+export const findAppPage = (data) => {
4
+	return request.get({
5
+		// url: '/basic.info/grainPriceCollect/findPage',
6
+		url: '/client/c/grainPriceCollect/findAppPage',
7
+		data,
8
+	})
9
+}
10
+
11
+/**
12
+ * 获取最近的站点
13
+ */
14
+export const getMonitorInfoByPoint = (data) => {
15
+	return request.get({
16
+		url: '/client/c/grainPriceCollect/getMonitorInfoByPoint',
17
+		data,
18
+	})
19
+}
20
+
21
+/**
22
+ * 获取所有站点信息
23
+ */
24
+export const getMonitorInfo = (data) => {
25
+	return request.get({
26
+		url: '/client/c/grainPriceCollect/getMonitorInfo',
27
+		data,
28
+	})
29
+}
30
+
31
+export const addCollect = (data) => {
32
+	return request.post({
33
+		url: '/client/c/grainPriceCollect/add',
34
+		data,
35
+	})
36
+}

+ 20 - 0
price-collection/api/login.js

@@ -0,0 +1,20 @@
1
+import request from "@/utils/request"
2
+import { sm2 } from 'sm-crypto'
3
+import { pub_key } from "../config/system";
4
+
5
+export const cryptoPassword = (pwd) => {
6
+	const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3
7
+	const encryptData = sm2.doEncrypt(pwd, pub_key, cipherMode)
8
+	console.log(`加密前 ${pwd} 加密后 ${encryptData}`)
9
+	return encryptData
10
+}
11
+
12
+export const login = ({username, password}) => {
13
+	return request.post({
14
+		url: '/auth/c/userCollect/login',
15
+		data: {
16
+			phone: username,
17
+			password,
18
+		}
19
+	})
20
+}

+ 7 - 0
price-collection/config/system.js

@@ -0,0 +1,7 @@
1
+export const server_host = "http://101.36.160.210:31055/province"
2
+
3
+// export const server_host = 'http://172.16.0.36:82'
4
+
5
+export const pub_key = "04298364ec840088475eae92a591e01284d1abefcda348b47eb324bb521bb03b0b2a5bc393f6b71dabb8f15c99a0050818b56b23f31743b93df9cf8948f15ddb54"
6
+
7
+// export const user_id_mock = '1777220845606899714'

+ 20 - 0
price-collection/index.html

@@ -0,0 +1,20 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+  <head>
4
+    <meta charset="UTF-8" />
5
+    <script>
6
+      var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
7
+        CSS.supports('top: constant(a)'))
8
+      document.write(
9
+        '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
10
+        (coverSupport ? ', viewport-fit=cover' : '') + '" />')
11
+    </script>
12
+    <title></title>
13
+    <!--preload-links-->
14
+    <!--app-context-->
15
+  </head>
16
+  <body>
17
+    <div id="app"><!--app-html--></div>
18
+    <script type="module" src="/main.js"></script>
19
+  </body>
20
+</html>

+ 27 - 0
price-collection/main.js

@@ -0,0 +1,27 @@
1
+import App from './App'
2
+
3
+// #ifndef VUE3
4
+import Vue from 'vue'
5
+import './uni.promisify.adaptor'
6
+
7
+import uView from '@/uni_modules/uview-ui'
8
+Vue.use(uView)
9
+
10
+
11
+Vue.config.productionTip = false
12
+App.mpType = 'app'
13
+const app = new Vue({
14
+  ...App
15
+})
16
+app.$mount()
17
+// #endif
18
+
19
+// #ifdef VUE3
20
+import { createSSRApp } from 'vue'
21
+export function createApp() {
22
+  const app = createSSRApp(App)
23
+  return {
24
+    app
25
+  }
26
+}
27
+// #endif

+ 115 - 0
price-collection/manifest.json

@@ -0,0 +1,115 @@
1
+{
2
+    "name" : "粮食价格采集",
3
+    "appid" : "__UNI__7ED3A40",
4
+    "description" : "",
5
+    "versionName" : "1.0.0",
6
+    "versionCode" : "100",
7
+    "transformPx" : false,
8
+    /* 5+App特有相关 */
9
+    "app-plus" : {
10
+        "usingComponents" : true,
11
+        "nvueStyleCompiler" : "uni-app",
12
+        "compilerVersion" : 3,
13
+        "splashscreen" : {
14
+            "alwaysShowBeforeRender" : true,
15
+            "waiting" : true,
16
+            "autoclose" : true,
17
+            "delay" : 0
18
+        },
19
+        /* 模块配置 */
20
+        "modules" : {
21
+            "Geolocation" : {}
22
+        },
23
+        /* 应用发布信息 */
24
+        "distribute" : {
25
+            /* android打包配置 */
26
+            "android" : {
27
+                "permissions" : [
28
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
29
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
30
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
31
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
32
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
33
+                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
34
+                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
35
+                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
36
+                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
37
+                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
38
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
39
+                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
40
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
41
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
42
+                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
43
+                ]
44
+            },
45
+            /* ios打包配置 */
46
+            "ios" : {
47
+                "dSYMs" : false
48
+            },
49
+            /* SDK配置 */
50
+            "sdkConfigs" : {
51
+                "geolocation" : {
52
+                    "system" : {
53
+                        "__platform__" : [ "android" ]
54
+                    }
55
+                },
56
+                "ad" : {}
57
+            },
58
+            "icons" : {
59
+                "android" : {
60
+                    "hdpi" : "unpackage/res/icons/72x72.png",
61
+                    "xhdpi" : "unpackage/res/icons/96x96.png",
62
+                    "xxhdpi" : "unpackage/res/icons/144x144.png",
63
+                    "xxxhdpi" : "unpackage/res/icons/192x192.png"
64
+                },
65
+                "ios" : {
66
+                    "appstore" : "unpackage/res/icons/1024x1024.png",
67
+                    "ipad" : {
68
+                        "app" : "unpackage/res/icons/76x76.png",
69
+                        "app@2x" : "unpackage/res/icons/152x152.png",
70
+                        "notification" : "unpackage/res/icons/20x20.png",
71
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
72
+                        "proapp@2x" : "unpackage/res/icons/167x167.png",
73
+                        "settings" : "unpackage/res/icons/29x29.png",
74
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
75
+                        "spotlight" : "unpackage/res/icons/40x40.png",
76
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png"
77
+                    },
78
+                    "iphone" : {
79
+                        "app@2x" : "unpackage/res/icons/120x120.png",
80
+                        "app@3x" : "unpackage/res/icons/180x180.png",
81
+                        "notification@2x" : "unpackage/res/icons/40x40.png",
82
+                        "notification@3x" : "unpackage/res/icons/60x60.png",
83
+                        "settings@2x" : "unpackage/res/icons/58x58.png",
84
+                        "settings@3x" : "unpackage/res/icons/87x87.png",
85
+                        "spotlight@2x" : "unpackage/res/icons/80x80.png",
86
+                        "spotlight@3x" : "unpackage/res/icons/120x120.png"
87
+                    }
88
+                }
89
+            }
90
+        }
91
+    },
92
+    /* 快应用特有相关 */
93
+    "quickapp" : {},
94
+    /* 小程序特有相关 */
95
+    "mp-weixin" : {
96
+        "appid" : "",
97
+        "setting" : {
98
+            "urlCheck" : false
99
+        },
100
+        "usingComponents" : true
101
+    },
102
+    "mp-alipay" : {
103
+        "usingComponents" : true
104
+    },
105
+    "mp-baidu" : {
106
+        "usingComponents" : true
107
+    },
108
+    "mp-toutiao" : {
109
+        "usingComponents" : true
110
+    },
111
+    "uniStatistics" : {
112
+        "enable" : false
113
+    },
114
+    "vueVersion" : "2"
115
+}

+ 20 - 0
price-collection/node_modules/.package-lock.json

@@ -0,0 +1,20 @@
1
+{
2
+  "name": "price-collection",
3
+  "lockfileVersion": 2,
4
+  "requires": true,
5
+  "packages": {
6
+    "node_modules/jsbn": {
7
+      "version": "1.1.0",
8
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
9
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
10
+    },
11
+    "node_modules/sm-crypto": {
12
+      "version": "0.3.13",
13
+      "resolved": "https://registry.npmjs.org/sm-crypto/-/sm-crypto-0.3.13.tgz",
14
+      "integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
15
+      "dependencies": {
16
+        "jsbn": "^1.1.0"
17
+      }
18
+    }
19
+  }
20
+}

+ 2 - 0
price-collection/node_modules/jsbn/.npmignore

@@ -0,0 +1,2 @@
1
+node_modules
2
+.DS_Store

+ 16 - 0
price-collection/node_modules/jsbn/CHANGELOG.md

@@ -0,0 +1,16 @@
1
+# v1.1.0
2
+
3
+- Allow for es6 "default import", e.g. `import BigInteger from 'jsbn'`.
4
+- Updated license file to read MIT
5
+
6
+
7
+# v1.0.0
8
+
9
+- breaking change: `require('jsbn')` no longer returns `BigInteger`. Use `require('jsbn').BigInteger` instead.
10
+
11
+
12
+
13
+# v0.1.1
14
+
15
+- fixed backwards-incompatible change in v0.1.0 where `require('jsbn') != BigInteger`. This patch version allows for `var BigInteger = require('jsbn')` or `var BigInteger = require('jsbn').BigInteger`.
16
+

+ 40 - 0
price-collection/node_modules/jsbn/LICENSE

@@ -0,0 +1,40 @@
1
+Licensing
2
+---------
3
+
4
+This software is covered under the following copyright:
5
+
6
+/*
7
+ * Copyright (c) 2003-2005  Tom Wu
8
+ * All Rights Reserved.
9
+ *
10
+ * Permission is hereby granted, free of charge, to any person obtaining
11
+ * a copy of this software and associated documentation files (the
12
+ * "Software"), to deal in the Software without restriction, including
13
+ * without limitation the rights to use, copy, modify, merge, publish,
14
+ * distribute, sublicense, and/or sell copies of the Software, and to
15
+ * permit persons to whom the Software is furnished to do so, subject to
16
+ * the following conditions:
17
+ *
18
+ * The above copyright notice and this permission notice shall be
19
+ * included in all copies or substantial portions of the Software.
20
+ *
21
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
22
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
23
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
24
+ *
25
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
26
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
27
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
28
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
29
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30
+ *
31
+ * In addition, the following condition applies:
32
+ *
33
+ * All redistributions must retain an intact copy of this copyright notice
34
+ * and disclaimer.
35
+ */
36
+
37
+Address all questions regarding this license to:
38
+
39
+  Tom Wu
40
+  tjw@cs.Stanford.EDU

File diff suppressed because it is too large
+ 173 - 0
price-collection/node_modules/jsbn/README.md


+ 11 - 0
price-collection/node_modules/jsbn/example.html

@@ -0,0 +1,11 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+    <head>
4
+        <meta charset="utf-8">
5
+        <title></title>
6
+    </head>
7
+    <body>
8
+      <script src="index.js"></script>
9
+      <script src="example.js"></script>
10
+    </body>
11
+</html>

+ 5 - 0
price-collection/node_modules/jsbn/example.js

@@ -0,0 +1,5 @@
1
+(function () {
2
+  var BigInteger = jsbn.BigInteger;
3
+  var a = new BigInteger('91823918239182398123');
4
+  console.log(a.bitLength());
5
+}());

File diff suppressed because it is too large
+ 1361 - 0
price-collection/node_modules/jsbn/index.js


+ 21 - 0
price-collection/node_modules/jsbn/package.json

@@ -0,0 +1,21 @@
1
+{
2
+  "name": "jsbn",
3
+  "version": "1.1.0",
4
+  "description": "The jsbn library is a fast, portable implementation of large-number math in pure JavaScript, enabling public-key crypto and other applications on desktop and mobile browsers.",
5
+  "main": "index.js",
6
+  "scripts": {
7
+    "test": "mocha test.js"
8
+  },
9
+  "repository": {
10
+    "type": "git",
11
+    "url": "https://github.com/andyperlitch/jsbn.git"
12
+  },
13
+  "keywords": [
14
+    "biginteger",
15
+    "bignumber",
16
+    "big",
17
+    "integer"
18
+  ],
19
+  "author": "Tom Wu",
20
+  "license": "MIT"
21
+}

+ 3 - 0
price-collection/node_modules/jsbn/test/es6-import.js

@@ -0,0 +1,3 @@
1
+import {BigInteger} from '../';
2
+
3
+console.log(typeof BigInteger)

+ 3 - 0
price-collection/node_modules/sm-crypto/.babelrc

@@ -0,0 +1,3 @@
1
+{
2
+    "presets": ["es2015"]
3
+}

+ 97 - 0
price-collection/node_modules/sm-crypto/.eslintrc.js

@@ -0,0 +1,97 @@
1
+module.exports = {
2
+  'extends': [
3
+    'airbnb-base',
4
+    'plugin:promise/recommended'
5
+  ],
6
+  'parserOptions': {
7
+    'ecmaVersion': 9,
8
+    'ecmaFeatures': {
9
+      'jsx': false
10
+    },
11
+    'sourceType': 'module'
12
+  },
13
+  'env': {
14
+    'es6': true,
15
+    'node': true,
16
+    'jest': true
17
+  },
18
+  'plugins': [
19
+    'import',
20
+    'node',
21
+    'promise'
22
+  ],
23
+  'rules': {
24
+    'arrow-parens': 'off',
25
+    'comma-dangle': [
26
+      'error',
27
+      'only-multiline'
28
+    ],
29
+    'complexity': ['error', 20],
30
+    'func-names': 'off',
31
+    'global-require': 'off',
32
+    'handle-callback-err': [
33
+      'error',
34
+      '^(err|error)$'
35
+    ],
36
+    'import/no-unresolved': [
37
+      'error',
38
+      {
39
+        'caseSensitive': true,
40
+        'commonjs': true,
41
+        'ignore': ['^[^.]']
42
+      }
43
+    ],
44
+    'import/prefer-default-export': 'off',
45
+    'linebreak-style': 'off',
46
+    'no-catch-shadow': 'error',
47
+    'no-continue': 'off',
48
+    'no-div-regex': 'warn',
49
+    'no-else-return': 'off',
50
+    'no-param-reassign': 'off',
51
+    'no-plusplus': 'off',
52
+    'no-shadow': 'off',
53
+    'no-multi-assign': 'off',
54
+    'no-underscore-dangle': 'off',
55
+    'node/no-deprecated-api': 'error',
56
+    'node/process-exit-as-throw': 'error',
57
+    'object-curly-spacing': [
58
+      'error',
59
+      'never'
60
+    ],
61
+    'operator-linebreak': [
62
+      'error',
63
+      'after',
64
+      {
65
+        'overrides': {
66
+          ':': 'before',
67
+          '?': 'before'
68
+        }
69
+      }
70
+    ],
71
+    'prefer-arrow-callback': 'off',
72
+    'prefer-destructuring': 'off',
73
+    'prefer-template': 'off',
74
+    'quote-props': [
75
+      1,
76
+      'as-needed',
77
+      {
78
+        'unnecessary': true
79
+      }
80
+    ],
81
+    'semi': [
82
+      'error',
83
+      'never'
84
+    ],
85
+    'max-len': 'off',
86
+    'no-bitwise': 'off',
87
+    'no-mixed-operators': 'off',
88
+  },
89
+  'globals': {
90
+    'window': true,
91
+    'document': true,
92
+    'App': true,
93
+    'Page': true,
94
+    'Component': true,
95
+    'Behavior': true
96
+  }
97
+}

+ 82 - 0
price-collection/node_modules/sm-crypto/CHANGELOG.md

@@ -0,0 +1,82 @@
1
+## 0.3.13
2
+
3
+* 支持根据私钥获取公钥
4
+
5
+## 0.3.12
6
+
7
+* 优化 sm3 运行性能
8
+
9
+## 0.3.11
10
+
11
+* sm2 支持压缩公钥
12
+
13
+## 0.3.10
14
+
15
+* 支持 sm3 hmac 模式
16
+
17
+
18
+## 0.3.9
19
+
20
+* 补充 sm4 解密时的 padding 判断
21
+
22
+## 0.3.8
23
+
24
+* sm2 解密时兼容密文可能是大写的情况
25
+
26
+## 0.3.7
27
+
28
+* 默认填充改为 pkcs#7,如传入 pkcs#5 也转到 pkcs#7 逻辑
29
+
30
+## 0.3.6
31
+
32
+* sm2 加解密支持二进制数据
33
+
34
+## 0.3.5
35
+
36
+* sm2.generateKeyPairHex 支持完整的 BigInteger 入参
37
+
38
+## 0.3.4
39
+
40
+* sm2 支持验证公钥接口
41
+* sm2 生成密钥时支持自定义随机数
42
+
43
+## 0.3.3
44
+
45
+* dist 输出改成 umd 模式
46
+
47
+## 0.3.2
48
+
49
+* 修复 sm2 在 userId 长度大于 31 时新旧版本验签不通过的问题
50
+## 0.3.0
51
+
52
+* sm2、sm3 重构
53
+* sm4 支持 cbc 模式
54
+
55
+## 0.2.7
56
+
57
+* 优化 sm3 性能
58
+
59
+## 0.2.5
60
+
61
+* sm3 支持字节数组输入
62
+
63
+## 0.2.4
64
+
65
+* 修复 sm4 四字节字符输出编码
66
+
67
+## 0.2.3
68
+
69
+* sm3/sm4 支持输入四字节字符
70
+
71
+## 0.2.2
72
+
73
+* sm3 支持中文输入
74
+
75
+## 0.2.1
76
+
77
+* 修复 sm2 点 16 进制串可能不满 64 位的问题
78
+
79
+## 0.2.0
80
+
81
+* sm4 默认支持 pkcs#5 填充方式
82
+* sm4 支持输入输出为字符串

+ 7 - 0
price-collection/node_modules/sm-crypto/LICENCE_MIT

@@ -0,0 +1,7 @@
1
+Copyright © 2018 june01
2
+
3
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 171 - 0
price-collection/node_modules/sm-crypto/README.md

@@ -0,0 +1,171 @@
1
+# sm-crypto
2
+
3
+国密算法sm2、sm3和sm4的js实现。
4
+
5
+## 安装
6
+
7
+```bash
8
+npm install --save sm-crypto
9
+```
10
+
11
+## sm2
12
+
13
+### 获取密钥对
14
+
15
+```js
16
+const sm2 = require('sm-crypto').sm2
17
+
18
+let keypair = sm2.generateKeyPairHex()
19
+
20
+publicKey = keypair.publicKey // 公钥
21
+privateKey = keypair.privateKey // 私钥
22
+
23
+// 默认生成公钥 130 位太长,可以压缩公钥到 66 位
24
+const compressedPublicKey = sm2.compressPublicKeyHex(publicKey) // compressedPublicKey 和 publicKey 等价
25
+sm2.comparePublicKeyHex(publicKey, compressedPublicKey) // 判断公钥是否等价
26
+
27
+// 自定义随机数,参数会直接透传给 jsbn 库的 BigInteger 构造器
28
+// 注意:开发者使用自定义随机数,需要自行确保传入的随机数符合密码学安全
29
+let keypair2 = sm2.generateKeyPairHex('123123123123123')
30
+let keypair3 = sm2.generateKeyPairHex(256, SecureRandom)
31
+
32
+let verifyResult = sm2.verifyPublicKey(publicKey) // 验证公钥
33
+verifyResult = sm2.verifyPublicKey(compressedPublicKey) // 验证公钥
34
+```
35
+
36
+### 加密解密
37
+
38
+```js
39
+const sm2 = require('sm-crypto').sm2
40
+const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为1
41
+
42
+let encryptData = sm2.doEncrypt(msgString, publicKey, cipherMode) // 加密结果
43
+let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) // 解密结果
44
+
45
+encryptData = sm2.doEncrypt(msgArray, publicKey, cipherMode) // 加密结果,输入数组
46
+decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode, {output: 'array'}) // 解密结果,输出数组
47
+```
48
+
49
+> ps:密文会在解密时自动补充 `04`,如遇到其他工具补充的 `04` 需手动去除再传入。
50
+
51
+### 签名验签
52
+
53
+> ps:理论上来说,只做纯签名是最快的。
54
+
55
+```js
56
+const sm2 = require('sm-crypto').sm2
57
+
58
+// 纯签名 + 生成椭圆曲线点
59
+let sigValueHex = sm2.doSignature(msg, privateKey) // 签名
60
+let verifyResult = sm2.doVerifySignature(msg, sigValueHex, publicKey) // 验签结果
61
+
62
+// 纯签名
63
+let sigValueHex2 = sm2.doSignature(msg, privateKey, {
64
+    pointPool: [sm2.getPoint(), sm2.getPoint(), sm2.getPoint(), sm2.getPoint()], // 传入事先已生成好的椭圆曲线点,可加快签名速度
65
+}) // 签名
66
+let verifyResult2 = sm2.doVerifySignature(msg, sigValueHex2, publicKey) // 验签结果
67
+
68
+// 纯签名 + 生成椭圆曲线点 + der编解码
69
+let sigValueHex3 = sm2.doSignature(msg, privateKey, {
70
+    der: true,
71
+}) // 签名
72
+let verifyResult3 = sm2.doVerifySignature(msg, sigValueHex3, publicKey, {
73
+    der: true,
74
+}) // 验签结果
75
+
76
+// 纯签名 + 生成椭圆曲线点 + sm3杂凑
77
+let sigValueHex4 = sm2.doSignature(msg, privateKey, {
78
+    hash: true,
79
+}) // 签名
80
+let verifyResult4 = sm2.doVerifySignature(msg, sigValueHex4, publicKey, {
81
+    hash: true,
82
+}) // 验签结果
83
+
84
+// 纯签名 + 生成椭圆曲线点 + sm3杂凑(不做公钥推导)
85
+let sigValueHex5 = sm2.doSignature(msg, privateKey, {
86
+    hash: true,
87
+    publicKey, // 传入公钥的话,可以去掉sm3杂凑中推导公钥的过程,速度会比纯签名 + 生成椭圆曲线点 + sm3杂凑快
88
+})
89
+let verifyResult5 = sm2.doVerifySignature(msg, sigValueHex5, publicKey, {
90
+    hash: true,
91
+    publicKey,
92
+})
93
+
94
+// 纯签名 + 生成椭圆曲线点 + sm3杂凑 + 不做公钥推 + 添加 userId(长度小于 8192)
95
+// 默认 userId 值为 1234567812345678
96
+let sigValueHex6 = sm2.doSignature(msgString, privateKey, {
97
+    hash: true,
98
+    publicKey,
99
+    userId: 'testUserId',
100
+})
101
+let verifyResult6 = sm2.doVerifySignature(msgString, sigValueHex6, publicKey, {
102
+    hash: true,
103
+    userId: 'testUserId',
104
+})
105
+```
106
+
107
+### 获取椭圆曲线点
108
+
109
+```js
110
+const sm2 = require('sm-crypto').sm2
111
+
112
+let point = sm2.getPoint() // 获取一个椭圆曲线点,可在sm2签名时传入
113
+```
114
+
115
+### 根据私钥获取公钥
116
+
117
+```js
118
+const sm2 = require('sm-crypto).sm2
119
+
120
+let publicKey = sm2.getPublicKeyFromPrivateKey(privateKey)
121
+```
122
+
123
+## sm3
124
+
125
+```js
126
+const sm3 = require('sm-crypto').sm3
127
+
128
+let hashData = sm3('abc') // 杂凑
129
+
130
+// hmac
131
+hashData = sm3('abc', {
132
+    key: 'daac25c1512fe50f79b0e4526b93f5c0e1460cef40b6dd44af13caec62e8c60e0d885f3c6d6fb51e530889e6fd4ac743a6d332e68a0f2a3923f42585dceb93e9', // 要求为 16 进制串或字节数组
133
+})
134
+```
135
+
136
+## sm4
137
+
138
+### 加密
139
+
140
+```js
141
+const sm4 = require('sm-crypto').sm4
142
+const msg = 'hello world! 我是 juneandgreen.' // 可以为 utf8 串或字节数组
143
+const key = '0123456789abcdeffedcba9876543210' // 可以为 16 进制串或字节数组,要求为 128 比特
144
+
145
+let encryptData = sm4.encrypt(msg, key) // 加密,默认输出 16 进制字符串,默认使用 pkcs#7 填充(传 pkcs#5 也会走 pkcs#7 填充)
146
+let encryptData = sm4.encrypt(msg, key, {padding: 'none'}) // 加密,不使用 padding
147
+let encryptData = sm4.encrypt(msg, key, {padding: 'none', output: 'array'}) // 加密,不使用 padding,输出为字节数组
148
+let encryptData = sm4.encrypt(msg, key, {mode: 'cbc', iv: 'fedcba98765432100123456789abcdef'}) // 加密,cbc 模式
149
+```
150
+
151
+### 解密
152
+
153
+```js
154
+const sm4 = require('sm-crypto').sm4
155
+const encryptData = '0e395deb10f6e8a17e17823e1fd9bd98a1bff1df508b5b8a1efb79ec633d1bb129432ac1b74972dbe97bab04f024e89c' // 可以为 16 进制串或字节数组
156
+const key = '0123456789abcdeffedcba9876543210' // 可以为 16 进制串或字节数组,要求为 128 比特
157
+
158
+let decryptData = sm4.decrypt(encryptData, key) // 解密,默认输出 utf8 字符串,默认使用 pkcs#7 填充(传 pkcs#5 也会走 pkcs#7 填充)
159
+let decryptData = sm4.decrypt(encryptData, key, {padding: 'none'}) // 解密,不使用 padding
160
+let decryptData = sm4.decrypt(encryptData, key, {padding: 'none', output: 'array'}) // 解密,不使用 padding,输出为字节数组
161
+let decryptData = sm4.decrypt(encryptData, key, {mode: 'cbc', iv: 'fedcba98765432100123456789abcdef'}) // 解密,cbc 模式
162
+```
163
+
164
+## 其他实现
165
+
166
+* 小程序移植版:[https://github.com/wechat-miniprogram/sm-crypto](https://github.com/wechat-miniprogram/sm-crypto)
167
+* java 实现(感谢 @antherd 提供):[https://github.com/antherd/sm-crypto](https://github.com/antherd/sm-crypto)
168
+* dart 实现(感谢 @luckykellan 提供):[https://github.com/luckykellan/dart_sm](https://github.com/luckykellan/dart_sm)
169
+## 协议
170
+
171
+MIT

File diff suppressed because it is too large
+ 1 - 0
price-collection/node_modules/sm-crypto/dist/sm2.js


File diff suppressed because it is too large
+ 1 - 0
price-collection/node_modules/sm-crypto/dist/sm3.js


File diff suppressed because it is too large
+ 1 - 0
price-collection/node_modules/sm-crypto/dist/sm4.js


+ 42 - 0
price-collection/node_modules/sm-crypto/package.json

@@ -0,0 +1,42 @@
1
+{
2
+  "name": "sm-crypto",
3
+  "version": "0.3.13",
4
+  "description": "sm-crypto",
5
+  "main": "src/index.js",
6
+  "scripts": {
7
+    "prepublish": "npm run build",
8
+    "test": "jest ./test/*",
9
+    "lint": "eslint \"src/**/*.js\" --fix",
10
+    "build": "npm run lint && webpack"
11
+  },
12
+  "repository": {
13
+    "type": "git",
14
+    "url": "git+https://github.com/JuneAndGreen/sm-crypto.git"
15
+  },
16
+  "keywords": [
17
+    "sm",
18
+    "js",
19
+    "crypto"
20
+  ],
21
+  "jest": {
22
+    "testEnvironment": "jsdom",
23
+    "testURL": "https://jest.test"
24
+  },
25
+  "author": "june_01",
26
+  "license": "MIT",
27
+  "dependencies": {
28
+    "jsbn": "^1.1.0"
29
+  },
30
+  "devDependencies": {
31
+    "babel-core": "^6.26.0",
32
+    "babel-loader": "^7.1.2",
33
+    "babel-preset-es2015": "^6.24.1",
34
+    "jest": "^22.1.4",
35
+    "webpack": "^3.10.0",
36
+    "eslint": "^5.3.0",
37
+    "eslint-config-airbnb-base": "13.1.0",
38
+    "eslint-plugin-import": "^2.14.0",
39
+    "eslint-plugin-node": "^7.0.1",
40
+    "eslint-plugin-promise": "^3.8.0"
41
+  }
42
+}

+ 5 - 0
price-collection/node_modules/sm-crypto/src/index.js

@@ -0,0 +1,5 @@
1
+module.exports = {
2
+  sm2: require('./sm2/index'),
3
+  sm3: require('./sm3/index'),
4
+  sm4: require('./sm4/index'),
5
+}

+ 161 - 0
price-collection/node_modules/sm-crypto/src/sm2/asn1.js

@@ -0,0 +1,161 @@
1
+/* eslint-disable class-methods-use-this */
2
+const {BigInteger} = require('jsbn')
3
+
4
+function bigintToValue(bigint) {
5
+  let h = bigint.toString(16)
6
+  if (h[0] !== '-') {
7
+    // 正数
8
+    if (h.length % 2 === 1) h = '0' + h // 补齐到整字节
9
+    else if (!h.match(/^[0-7]/)) h = '00' + h // 非0开头,则补一个全0字节
10
+  } else {
11
+    // 负数
12
+    h = h.substr(1)
13
+
14
+    let len = h.length
15
+    if (len % 2 === 1) len += 1 // 补齐到整字节
16
+    else if (!h.match(/^[0-7]/)) len += 2 // 非0开头,则补一个全0字节
17
+
18
+    let mask = ''
19
+    for (let i = 0; i < len; i++) mask += 'f'
20
+    mask = new BigInteger(mask, 16)
21
+
22
+    // 对绝对值取反,加1
23
+    h = mask.xor(bigint).add(BigInteger.ONE)
24
+    h = h.toString(16).replace(/^-/, '')
25
+  }
26
+  return h
27
+}
28
+
29
+class ASN1Object {
30
+  constructor() {
31
+    this.tlv = null
32
+    this.t = '00'
33
+    this.l = '00'
34
+    this.v = ''
35
+  }
36
+
37
+  /**
38
+   * 获取 der 编码比特流16进制串
39
+   */
40
+  getEncodedHex() {
41
+    if (!this.tlv) {
42
+      this.v = this.getValue()
43
+      this.l = this.getLength()
44
+      this.tlv = this.t + this.l + this.v
45
+    }
46
+    return this.tlv
47
+  }
48
+
49
+  getLength() {
50
+    const n = this.v.length / 2 // 字节数
51
+    let nHex = n.toString(16)
52
+    if (nHex.length % 2 === 1) nHex = '0' + nHex // 补齐到整字节
53
+
54
+    if (n < 128) {
55
+      // 短格式,以 0 开头
56
+      return nHex
57
+    } else {
58
+      // 长格式,以 1 开头
59
+      const head = 128 + nHex.length / 2 // 1(1位) + 真正的长度占用字节数(7位) + 真正的长度
60
+      return head.toString(16) + nHex
61
+    }
62
+  }
63
+
64
+  getValue() {
65
+    return ''
66
+  }
67
+}
68
+
69
+class DERInteger extends ASN1Object {
70
+  constructor(bigint) {
71
+    super()
72
+
73
+    this.t = '02' // 整型标签说明
74
+    if (bigint) this.v = bigintToValue(bigint)
75
+  }
76
+
77
+  getValue() {
78
+    return this.v
79
+  }
80
+}
81
+
82
+class DERSequence extends ASN1Object {
83
+  constructor(asn1Array) {
84
+    super()
85
+
86
+    this.t = '30' // 序列标签说明
87
+    this.asn1Array = asn1Array
88
+  }
89
+
90
+  getValue() {
91
+    this.v = this.asn1Array.map(asn1Object => asn1Object.getEncodedHex()).join('')
92
+    return this.v
93
+  }
94
+}
95
+
96
+/**
97
+ * 获取 l 占用字节数
98
+ */
99
+function getLenOfL(str, start) {
100
+  if (+str[start + 2] < 8) return 1 // l 以0开头,则表示短格式,只占一个字节
101
+  return +str.substr(start + 2, 2) & 0x7f + 1 // 长格式,取第一个字节后7位作为长度真正占用字节数,再加上本身
102
+}
103
+
104
+/**
105
+ * 获取 l
106
+ */
107
+function getL(str, start) {
108
+  // 获取 l
109
+  const len = getLenOfL(str, start)
110
+  const l = str.substr(start + 2, len * 2)
111
+
112
+  if (!l) return -1
113
+  const bigint = +l[0] < 8 ? new BigInteger(l, 16) : new BigInteger(l.substr(2), 16)
114
+
115
+  return bigint.intValue()
116
+}
117
+
118
+/**
119
+ * 获取 v 的位置
120
+ */
121
+function getStartOfV(str, start) {
122
+  const len = getLenOfL(str, start)
123
+  return start + (len + 1) * 2
124
+}
125
+
126
+module.exports = {
127
+  /**
128
+   * ASN.1 der 编码,针对 sm2 签名
129
+   */
130
+  encodeDer(r, s) {
131
+    const derR = new DERInteger(r)
132
+    const derS = new DERInteger(s)
133
+    const derSeq = new DERSequence([derR, derS])
134
+
135
+    return derSeq.getEncodedHex()
136
+  },
137
+
138
+  /**
139
+   * 解析 ASN.1 der,针对 sm2 验签
140
+   */
141
+  decodeDer(input) {
142
+    // 结构:
143
+    // input = | tSeq | lSeq | vSeq |
144
+    // vSeq = | tR | lR | vR | tS | lS | vS |
145
+    const start = getStartOfV(input, 0)
146
+
147
+    const vIndexR = getStartOfV(input, start)
148
+    const lR = getL(input, start)
149
+    const vR = input.substr(vIndexR, lR * 2)
150
+
151
+    const nextStart = vIndexR + vR.length
152
+    const vIndexS = getStartOfV(input, nextStart)
153
+    const lS = getL(input, nextStart)
154
+    const vS = input.substr(vIndexS, lS * 2)
155
+
156
+    const r = new BigInteger(vR, 16)
157
+    const s = new BigInteger(vS, 16)
158
+
159
+    return {r, s}
160
+  }
161
+}

+ 332 - 0
price-collection/node_modules/sm-crypto/src/sm2/ec.js

@@ -0,0 +1,332 @@
1
+/* eslint-disable no-case-declarations, max-len */
2
+const {BigInteger} = require('jsbn')
3
+
4
+/**
5
+ * thanks for Tom Wu : http://www-cs-students.stanford.edu/~tjw/jsbn/
6
+ *
7
+ * Basic Javascript Elliptic Curve implementation
8
+ * Ported loosely from BouncyCastle's Java EC code
9
+ * Only Fp curves implemented for now
10
+ */
11
+
12
+const TWO = new BigInteger('2')
13
+const THREE = new BigInteger('3')
14
+
15
+/**
16
+ * 椭圆曲线域元素
17
+ */
18
+class ECFieldElementFp {
19
+  constructor(q, x) {
20
+    this.x = x
21
+    this.q = q
22
+    // TODO if (x.compareTo(q) >= 0) error
23
+  }
24
+
25
+  /**
26
+   * 判断相等
27
+   */
28
+  equals(other) {
29
+    if (other === this) return true
30
+    return (this.q.equals(other.q) && this.x.equals(other.x))
31
+  }
32
+
33
+  /**
34
+   * 返回具体数值
35
+   */
36
+  toBigInteger() {
37
+    return this.x
38
+  }
39
+
40
+  /**
41
+   * 取反
42
+   */
43
+  negate() {
44
+    return new ECFieldElementFp(this.q, this.x.negate().mod(this.q))
45
+  }
46
+
47
+  /**
48
+   * 相加
49
+   */
50
+  add(b) {
51
+    return new ECFieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q))
52
+  }
53
+
54
+  /**
55
+   * 相减
56
+   */
57
+  subtract(b) {
58
+    return new ECFieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q))
59
+  }
60
+
61
+  /**
62
+   * 相乘
63
+   */
64
+  multiply(b) {
65
+    return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q))
66
+  }
67
+
68
+  /**
69
+   * 相除
70
+   */
71
+  divide(b) {
72
+    return new ECFieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q))
73
+  }
74
+
75
+  /**
76
+   * 平方
77
+   */
78
+  square() {
79
+    return new ECFieldElementFp(this.q, this.x.square().mod(this.q))
80
+  }
81
+}
82
+
83
+class ECPointFp {
84
+  constructor(curve, x, y, z) {
85
+    this.curve = curve
86
+    this.x = x
87
+    this.y = y
88
+    // 标准射影坐标系:zinv == null 或 z * zinv == 1
89
+    this.z = z == null ? BigInteger.ONE : z
90
+    this.zinv = null
91
+    // TODO: compression flag
92
+  }
93
+
94
+  getX() {
95
+    if (this.zinv === null) this.zinv = this.z.modInverse(this.curve.q)
96
+
97
+    return this.curve.fromBigInteger(this.x.toBigInteger().multiply(this.zinv).mod(this.curve.q))
98
+  }
99
+
100
+  getY() {
101
+    if (this.zinv === null) this.zinv = this.z.modInverse(this.curve.q)
102
+
103
+    return this.curve.fromBigInteger(this.y.toBigInteger().multiply(this.zinv).mod(this.curve.q))
104
+  }
105
+
106
+  /**
107
+   * 判断相等
108
+   */
109
+  equals(other) {
110
+    if (other === this) return true
111
+    if (this.isInfinity()) return other.isInfinity()
112
+    if (other.isInfinity()) return this.isInfinity()
113
+
114
+    // u = y2 * z1 - y1 * z2
115
+    const u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q)
116
+    if (!u.equals(BigInteger.ZERO)) return false
117
+
118
+    // v = x2 * z1 - x1 * z2
119
+    const v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q)
120
+    return v.equals(BigInteger.ZERO)
121
+  }
122
+
123
+  /**
124
+   * 是否是无穷远点
125
+   */
126
+  isInfinity() {
127
+    if ((this.x === null) && (this.y === null)) return true
128
+    return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO)
129
+  }
130
+
131
+  /**
132
+   * 取反,x 轴对称点
133
+   */
134
+  negate() {
135
+    return new ECPointFp(this.curve, this.x, this.y.negate(), this.z)
136
+  }
137
+
138
+  /**
139
+   * 相加
140
+   *
141
+   * 标准射影坐标系:
142
+   *
143
+   * λ1 = x1 * z2
144
+   * λ2 = x2 * z1
145
+   * λ3 = λ1 − λ2
146
+   * λ4 = y1 * z2
147
+   * λ5 = y2 * z1
148
+   * λ6 = λ4 − λ5
149
+   * λ7 = λ1 + λ2
150
+   * λ8 = z1 * z2
151
+   * λ9 = λ3^2
152
+   * λ10 = λ3 * λ9
153
+   * λ11 = λ8 * λ6^2 − λ7 * λ9
154
+   * x3 = λ3 * λ11
155
+   * y3 = λ6 * (λ9 * λ1 − λ11) − λ4 * λ10
156
+   * z3 = λ10 * λ8
157
+   */
158
+  add(b) {
159
+    if (this.isInfinity()) return b
160
+    if (b.isInfinity()) return this
161
+
162
+    const x1 = this.x.toBigInteger()
163
+    const y1 = this.y.toBigInteger()
164
+    const z1 = this.z
165
+    const x2 = b.x.toBigInteger()
166
+    const y2 = b.y.toBigInteger()
167
+    const z2 = b.z
168
+    const q = this.curve.q
169
+
170
+    const w1 = x1.multiply(z2).mod(q)
171
+    const w2 = x2.multiply(z1).mod(q)
172
+    const w3 = w1.subtract(w2)
173
+    const w4 = y1.multiply(z2).mod(q)
174
+    const w5 = y2.multiply(z1).mod(q)
175
+    const w6 = w4.subtract(w5)
176
+
177
+    if (BigInteger.ZERO.equals(w3)) {
178
+      if (BigInteger.ZERO.equals(w6)) {
179
+        return this.twice() // this == b,计算自加
180
+      }
181
+      return this.curve.infinity // this == -b,则返回无穷远点
182
+    }
183
+
184
+    const w7 = w1.add(w2)
185
+    const w8 = z1.multiply(z2).mod(q)
186
+    const w9 = w3.square().mod(q)
187
+    const w10 = w3.multiply(w9).mod(q)
188
+    const w11 = w8.multiply(w6.square()).subtract(w7.multiply(w9)).mod(q)
189
+
190
+    const x3 = w3.multiply(w11).mod(q)
191
+    const y3 = w6.multiply(w9.multiply(w1).subtract(w11)).subtract(w4.multiply(w10)).mod(q)
192
+    const z3 = w10.multiply(w8).mod(q)
193
+
194
+    return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3)
195
+  }
196
+
197
+  /**
198
+   * 自加
199
+   *
200
+   * 标准射影坐标系:
201
+   *
202
+   * λ1 = 3 * x1^2 + a * z1^2
203
+   * λ2 = 2 * y1 * z1
204
+   * λ3 = y1^2
205
+   * λ4 = λ3 * x1 * z1
206
+   * λ5 = λ2^2
207
+   * λ6 = λ1^2 − 8 * λ4
208
+   * x3 = λ2 * λ6
209
+   * y3 = λ1 * (4 * λ4 − λ6) − 2 * λ5 * λ3
210
+   * z3 = λ2 * λ5
211
+   */
212
+  twice() {
213
+    if (this.isInfinity()) return this
214
+    if (!this.y.toBigInteger().signum()) return this.curve.infinity
215
+
216
+    const x1 = this.x.toBigInteger()
217
+    const y1 = this.y.toBigInteger()
218
+    const z1 = this.z
219
+    const q = this.curve.q
220
+    const a = this.curve.a.toBigInteger()
221
+
222
+    const w1 = x1.square().multiply(THREE).add(a.multiply(z1.square())).mod(q)
223
+    const w2 = y1.shiftLeft(1).multiply(z1).mod(q)
224
+    const w3 = y1.square().mod(q)
225
+    const w4 = w3.multiply(x1).multiply(z1).mod(q)
226
+    const w5 = w2.square().mod(q)
227
+    const w6 = w1.square().subtract(w4.shiftLeft(3)).mod(q)
228
+
229
+    const x3 = w2.multiply(w6).mod(q)
230
+    const y3 = w1.multiply(w4.shiftLeft(2).subtract(w6)).subtract(w5.shiftLeft(1).multiply(w3)).mod(q)
231
+    const z3 = w2.multiply(w5).mod(q)
232
+
233
+    return new ECPointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3)
234
+  }
235
+
236
+  /**
237
+   * 倍点计算
238
+   */
239
+  multiply(k) {
240
+    if (this.isInfinity()) return this
241
+    if (!k.signum()) return this.curve.infinity
242
+
243
+    // 使用加减法
244
+    const k3 = k.multiply(THREE)
245
+    const neg = this.negate()
246
+    let Q = this
247
+
248
+    for (let i = k3.bitLength() - 2; i > 0; i--) {
249
+      Q = Q.twice()
250
+
251
+      const k3Bit = k3.testBit(i)
252
+      const kBit = k.testBit(i)
253
+
254
+      if (k3Bit !== kBit) {
255
+        Q = Q.add(k3Bit ? this : neg)
256
+      }
257
+    }
258
+
259
+    return Q
260
+  }
261
+}
262
+
263
+/**
264
+ * 椭圆曲线 y^2 = x^3 + ax + b
265
+ */
266
+class ECCurveFp {
267
+  constructor(q, a, b) {
268
+    this.q = q
269
+    this.a = this.fromBigInteger(a)
270
+    this.b = this.fromBigInteger(b)
271
+    this.infinity = new ECPointFp(this, null, null) // 无穷远点
272
+  }
273
+
274
+  /**
275
+   * 判断两个椭圆曲线是否相等
276
+   */
277
+  equals(other) {
278
+    if (other === this) return true
279
+    return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b))
280
+  }
281
+
282
+  /**
283
+   * 生成椭圆曲线域元素
284
+   */
285
+  fromBigInteger(x) {
286
+    return new ECFieldElementFp(this.q, x)
287
+  }
288
+
289
+  /**
290
+   * 解析 16 进制串为椭圆曲线点
291
+   */
292
+  decodePointHex(s) {
293
+    switch (parseInt(s.substr(0, 2), 16)) {
294
+      // 第一个字节
295
+      case 0:
296
+        return this.infinity
297
+      case 2:
298
+      case 3:
299
+        // 压缩
300
+        const x = this.fromBigInteger(new BigInteger(s.substr(2), 16))
301
+        // 对 p ≡ 3 (mod4),即存在正整数 u,使得 p = 4u + 3
302
+        // 计算 y = (√ (x^3 + ax + b) % p)^(u + 1) modp
303
+        let y = this.fromBigInteger(x.multiply(x.square()).add(
304
+          x.multiply(this.a)
305
+        ).add(this.b).toBigInteger()
306
+          .modPow(
307
+            this.q.divide(new BigInteger('4')).add(BigInteger.ONE), this.q
308
+          ))
309
+        // 算出结果 2 进制最后 1 位不等于第 1 个字节减 2 则取反
310
+        if (!y.toBigInteger().mod(TWO).equals(new BigInteger(s.substr(0, 2), 16).subtract(TWO))) {
311
+          y = y.negate()
312
+        }
313
+        return new ECPointFp(this, x, y)
314
+      case 4:
315
+      case 6:
316
+      case 7:
317
+        const len = (s.length - 2) / 2
318
+        const xHex = s.substr(2, len)
319
+        const yHex = s.substr(len + 2, len)
320
+
321
+        return new ECPointFp(this, this.fromBigInteger(new BigInteger(xHex, 16)), this.fromBigInteger(new BigInteger(yHex, 16)))
322
+      default:
323
+        // 不支持
324
+        return null
325
+    }
326
+  }
327
+}
328
+
329
+module.exports = {
330
+  ECPointFp,
331
+  ECCurveFp,
332
+}

+ 261 - 0
price-collection/node_modules/sm-crypto/src/sm2/index.js

@@ -0,0 +1,261 @@
1
+/* eslint-disable no-use-before-define */
2
+const {BigInteger} = require('jsbn')
3
+const {encodeDer, decodeDer} = require('./asn1')
4
+const _ = require('./utils')
5
+const sm3 = require('./sm3').sm3
6
+
7
+const {G, curve, n} = _.generateEcparam()
8
+const C1C2C3 = 0
9
+
10
+/**
11
+ * 加密
12
+ */
13
+function doEncrypt(msg, publicKey, cipherMode = 1) {
14
+  msg = typeof msg === 'string' ? _.hexToArray(_.utf8ToHex(msg)) : Array.prototype.slice.call(msg)
15
+  publicKey = _.getGlobalCurve().decodePointHex(publicKey) // 先将公钥转成点
16
+
17
+  const keypair = _.generateKeyPairHex()
18
+  const k = new BigInteger(keypair.privateKey, 16) // 随机数 k
19
+
20
+  // c1 = k * G
21
+  let c1 = keypair.publicKey
22
+  if (c1.length > 128) c1 = c1.substr(c1.length - 128)
23
+
24
+  // (x2, y2) = k * publicKey
25
+  const p = publicKey.multiply(k)
26
+  const x2 = _.hexToArray(_.leftPad(p.getX().toBigInteger().toRadix(16), 64))
27
+  const y2 = _.hexToArray(_.leftPad(p.getY().toBigInteger().toRadix(16), 64))
28
+
29
+  // c3 = hash(x2 || msg || y2)
30
+  const c3 = _.arrayToHex(sm3([].concat(x2, msg, y2)))
31
+
32
+  let ct = 1
33
+  let offset = 0
34
+  let t = [] // 256 位
35
+  const z = [].concat(x2, y2)
36
+  const nextT = () => {
37
+    // (1) Hai = hash(z || ct)
38
+    // (2) ct++
39
+    t = sm3([...z, ct >> 24 & 0x00ff, ct >> 16 & 0x00ff, ct >> 8 & 0x00ff, ct & 0x00ff])
40
+    ct++
41
+    offset = 0
42
+  }
43
+  nextT() // 先生成 Ha1
44
+
45
+  for (let i = 0, len = msg.length; i < len; i++) {
46
+    // t = Ha1 || Ha2 || Ha3 || Ha4
47
+    if (offset === t.length) nextT()
48
+
49
+    // c2 = msg ^ t
50
+    msg[i] ^= t[offset++] & 0xff
51
+  }
52
+  const c2 = _.arrayToHex(msg)
53
+
54
+  return cipherMode === C1C2C3 ? c1 + c2 + c3 : c1 + c3 + c2
55
+}
56
+
57
+/**
58
+ * 解密
59
+ */
60
+function doDecrypt(encryptData, privateKey, cipherMode = 1, {
61
+  output = 'string',
62
+} = {}) {
63
+  privateKey = new BigInteger(privateKey, 16)
64
+
65
+  let c3 = encryptData.substr(128, 64)
66
+  let c2 = encryptData.substr(128 + 64)
67
+
68
+  if (cipherMode === C1C2C3) {
69
+    c3 = encryptData.substr(encryptData.length - 64)
70
+    c2 = encryptData.substr(128, encryptData.length - 128 - 64)
71
+  }
72
+
73
+  const msg = _.hexToArray(c2)
74
+  const c1 = _.getGlobalCurve().decodePointHex('04' + encryptData.substr(0, 128))
75
+
76
+  const p = c1.multiply(privateKey)
77
+  const x2 = _.hexToArray(_.leftPad(p.getX().toBigInteger().toRadix(16), 64))
78
+  const y2 = _.hexToArray(_.leftPad(p.getY().toBigInteger().toRadix(16), 64))
79
+
80
+  let ct = 1
81
+  let offset = 0
82
+  let t = [] // 256 位
83
+  const z = [].concat(x2, y2)
84
+  const nextT = () => {
85
+    // (1) Hai = hash(z || ct)
86
+    // (2) ct++
87
+    t = sm3([...z, ct >> 24 & 0x00ff, ct >> 16 & 0x00ff, ct >> 8 & 0x00ff, ct & 0x00ff])
88
+    ct++
89
+    offset = 0
90
+  }
91
+  nextT() // 先生成 Ha1
92
+
93
+  for (let i = 0, len = msg.length; i < len; i++) {
94
+    // t = Ha1 || Ha2 || Ha3 || Ha4
95
+    if (offset === t.length) nextT()
96
+
97
+    // c2 = msg ^ t
98
+    msg[i] ^= t[offset++] & 0xff
99
+  }
100
+
101
+  // c3 = hash(x2 || msg || y2)
102
+  const checkC3 = _.arrayToHex(sm3([].concat(x2, msg, y2)))
103
+
104
+  if (checkC3 === c3.toLowerCase()) {
105
+    return output === 'array' ? msg : _.arrayToUtf8(msg)
106
+  } else {
107
+    return output === 'array' ? [] : ''
108
+  }
109
+}
110
+
111
+/**
112
+ * 签名
113
+ */
114
+function doSignature(msg, privateKey, {
115
+  pointPool, der, hash, publicKey, userId
116
+} = {}) {
117
+  let hashHex = typeof msg === 'string' ? _.utf8ToHex(msg) : _.arrayToHex(msg)
118
+
119
+  if (hash) {
120
+    // sm3杂凑
121
+    publicKey = publicKey || getPublicKeyFromPrivateKey(privateKey)
122
+    hashHex = getHash(hashHex, publicKey, userId)
123
+  }
124
+
125
+  const dA = new BigInteger(privateKey, 16)
126
+  const e = new BigInteger(hashHex, 16)
127
+
128
+  // k
129
+  let k = null
130
+  let r = null
131
+  let s = null
132
+
133
+  do {
134
+    do {
135
+      let point
136
+      if (pointPool && pointPool.length) {
137
+        point = pointPool.pop()
138
+      } else {
139
+        point = getPoint()
140
+      }
141
+      k = point.k
142
+
143
+      // r = (e + x1) mod n
144
+      r = e.add(point.x1).mod(n)
145
+    } while (r.equals(BigInteger.ZERO) || r.add(k).equals(n))
146
+
147
+    // s = ((1 + dA)^-1 * (k - r * dA)) mod n
148
+    s = dA.add(BigInteger.ONE).modInverse(n).multiply(k.subtract(r.multiply(dA))).mod(n)
149
+  } while (s.equals(BigInteger.ZERO))
150
+
151
+  if (der) return encodeDer(r, s) // asn.1 der 编码
152
+
153
+  return _.leftPad(r.toString(16), 64) + _.leftPad(s.toString(16), 64)
154
+}
155
+
156
+/**
157
+ * 验签
158
+ */
159
+function doVerifySignature(msg, signHex, publicKey, {der, hash, userId} = {}) {
160
+  let hashHex = typeof msg === 'string' ? _.utf8ToHex(msg) : _.arrayToHex(msg)
161
+
162
+  if (hash) {
163
+    // sm3杂凑
164
+    hashHex = getHash(hashHex, publicKey, userId)
165
+  }
166
+
167
+  let r; let
168
+    s
169
+  if (der) {
170
+    const decodeDerObj = decodeDer(signHex) // asn.1 der 解码
171
+    r = decodeDerObj.r
172
+    s = decodeDerObj.s
173
+  } else {
174
+    r = new BigInteger(signHex.substring(0, 64), 16)
175
+    s = new BigInteger(signHex.substring(64), 16)
176
+  }
177
+
178
+  const PA = curve.decodePointHex(publicKey)
179
+  const e = new BigInteger(hashHex, 16)
180
+
181
+  // t = (r + s) mod n
182
+  const t = r.add(s).mod(n)
183
+
184
+  if (t.equals(BigInteger.ZERO)) return false
185
+
186
+  // x1y1 = s * G + t * PA
187
+  const x1y1 = G.multiply(s).add(PA.multiply(t))
188
+
189
+  // R = (e + x1) mod n
190
+  const R = e.add(x1y1.getX().toBigInteger()).mod(n)
191
+
192
+  return r.equals(R)
193
+}
194
+
195
+/**
196
+ * sm3杂凑算法
197
+ */
198
+function getHash(hashHex, publicKey, userId = '1234567812345678') {
199
+  // z = hash(entl || userId || a || b || gx || gy || px || py)
200
+  userId = _.utf8ToHex(userId)
201
+  const a = _.leftPad(G.curve.a.toBigInteger().toRadix(16), 64)
202
+  const b = _.leftPad(G.curve.b.toBigInteger().toRadix(16), 64)
203
+  const gx = _.leftPad(G.getX().toBigInteger().toRadix(16), 64)
204
+  const gy = _.leftPad(G.getY().toBigInteger().toRadix(16), 64)
205
+  let px
206
+  let py
207
+  if (publicKey.length === 128) {
208
+    px = publicKey.substr(0, 64)
209
+    py = publicKey.substr(64, 64)
210
+  } else {
211
+    const point = G.curve.decodePointHex(publicKey)
212
+    px = _.leftPad(point.getX().toBigInteger().toRadix(16), 64)
213
+    py = _.leftPad(point.getY().toBigInteger().toRadix(16), 64)
214
+  }
215
+  const data = _.hexToArray(userId + a + b + gx + gy + px + py)
216
+
217
+  const entl = userId.length * 4
218
+  data.unshift(entl & 0x00ff)
219
+  data.unshift(entl >> 8 & 0x00ff)
220
+
221
+  const z = sm3(data)
222
+
223
+  // e = hash(z || msg)
224
+  return _.arrayToHex(sm3(z.concat(_.hexToArray(hashHex))))
225
+}
226
+
227
+/**
228
+ * 计算公钥
229
+ */
230
+function getPublicKeyFromPrivateKey(privateKey) {
231
+  const PA = G.multiply(new BigInteger(privateKey, 16))
232
+  const x = _.leftPad(PA.getX().toBigInteger().toString(16), 64)
233
+  const y = _.leftPad(PA.getY().toBigInteger().toString(16), 64)
234
+  return '04' + x + y
235
+}
236
+
237
+/**
238
+ * 获取椭圆曲线点
239
+ */
240
+function getPoint() {
241
+  const keypair = _.generateKeyPairHex()
242
+  const PA = curve.decodePointHex(keypair.publicKey)
243
+
244
+  keypair.k = new BigInteger(keypair.privateKey, 16)
245
+  keypair.x1 = PA.getX().toBigInteger()
246
+
247
+  return keypair
248
+}
249
+
250
+module.exports = {
251
+  generateKeyPairHex: _.generateKeyPairHex,
252
+  compressPublicKeyHex: _.compressPublicKeyHex,
253
+  comparePublicKeyHex: _.comparePublicKeyHex,
254
+  doEncrypt,
255
+  doDecrypt,
256
+  doSignature,
257
+  doVerifySignature,
258
+  getPublicKeyFromPrivateKey,
259
+  getPoint,
260
+  verifyPublicKey: _.verifyPublicKey,
261
+}

+ 170 - 0
price-collection/node_modules/sm-crypto/src/sm2/sm3.js

@@ -0,0 +1,170 @@
1
+// 消息扩展
2
+const W = new Uint32Array(68)
3
+const M = new Uint32Array(64) // W'
4
+
5
+/**
6
+ * 循环左移
7
+ */
8
+function rotl(x, n) {
9
+  const s = n & 31
10
+  return (x << s) | (x >>> (32 - s))
11
+}
12
+
13
+/**
14
+ * 二进制异或运算
15
+ */
16
+function xor(x, y) {
17
+  const result = []
18
+  for (let i = x.length - 1; i >= 0; i--) result[i] = (x[i] ^ y[i]) & 0xff
19
+  return result
20
+}
21
+
22
+/**
23
+ * 压缩函数中的置换函数 P0(X) = X xor (X <<< 9) xor (X <<< 17)
24
+ */
25
+function P0(X) {
26
+  return (X ^ rotl(X, 9)) ^ rotl(X, 17)
27
+}
28
+
29
+/**
30
+ * 消息扩展中的置换函数 P1(X) = X xor (X <<< 15) xor (X <<< 23)
31
+ */
32
+function P1(X) {
33
+  return (X ^ rotl(X, 15)) ^ rotl(X, 23)
34
+}
35
+
36
+/**
37
+ * sm3 本体
38
+ */
39
+function sm3(array) {
40
+  let len = array.length * 8
41
+
42
+  // k 是满足 len + 1 + k = 448mod512 的最小的非负整数
43
+  let k = len % 512
44
+  // 如果 448 <= (512 % len) < 512,需要多补充 (len % 448) 比特'0'以满足总比特长度为512的倍数
45
+  k = k >= 448 ? 512 - (k % 448) - 1 : 448 - k - 1
46
+
47
+  // 填充
48
+  const kArr = new Array((k - 7) / 8)
49
+  const lenArr = new Array(8)
50
+  for (let i = 0, len = kArr.length; i < len; i++) kArr[i] = 0
51
+  for (let i = 0, len = lenArr.length; i < len; i++) lenArr[i] = 0
52
+  len = len.toString(2)
53
+  for (let i = 7; i >= 0; i--) {
54
+    if (len.length > 8) {
55
+      const start = len.length - 8
56
+      lenArr[i] = parseInt(len.substr(start), 2)
57
+      len = len.substr(0, start)
58
+    } else if (len.length > 0) {
59
+      lenArr[i] = parseInt(len, 2)
60
+      len = ''
61
+    }
62
+  }
63
+  const m = new Uint8Array([...array, 0x80, ...kArr, ...lenArr])
64
+  const dataView = new DataView(m.buffer, 0)
65
+
66
+  // 迭代压缩
67
+  const n = m.length / 64
68
+  const V = new Uint32Array([0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e])
69
+  for (let i = 0; i < n; i++) {
70
+    W.fill(0)
71
+    M.fill(0)
72
+
73
+    // 将消息分组B划分为 16 个字 W0, W1,……,W15
74
+    const start = 16 * i
75
+    for (let j = 0; j < 16; j++) {
76
+      W[j] = dataView.getUint32((start + j) * 4, false)
77
+    }
78
+
79
+    // W16 ~ W67:W[j] <- P1(W[j−16] xor W[j−9] xor (W[j−3] <<< 15)) xor (W[j−13] <<< 7) xor W[j−6]
80
+    for (let j = 16; j < 68; j++) {
81
+      W[j] = (P1((W[j - 16] ^ W[j - 9]) ^ rotl(W[j - 3], 15)) ^ rotl(W[j - 13], 7)) ^ W[j - 6]
82
+    }
83
+
84
+    // W′0 ~ W′63:W′[j] = W[j] xor W[j+4]
85
+    for (let j = 0; j < 64; j++) {
86
+      M[j] = W[j] ^ W[j + 4]
87
+    }
88
+
89
+    // 压缩
90
+    const T1 = 0x79cc4519
91
+    const T2 = 0x7a879d8a
92
+    // 字寄存器
93
+    let A = V[0]
94
+    let B = V[1]
95
+    let C = V[2]
96
+    let D = V[3]
97
+    let E = V[4]
98
+    let F = V[5]
99
+    let G = V[6]
100
+    let H = V[7]
101
+    // 中间变量
102
+    let SS1
103
+    let SS2
104
+    let TT1
105
+    let TT2
106
+    let T
107
+    for (let j = 0; j < 64; j++) {
108
+      T = j >= 0 && j <= 15 ? T1 : T2
109
+      SS1 = rotl(rotl(A, 12) + E + rotl(T, j), 7)
110
+      SS2 = SS1 ^ rotl(A, 12)
111
+
112
+      TT1 = (j >= 0 && j <= 15 ? ((A ^ B) ^ C) : (((A & B) | (A & C)) | (B & C))) + D + SS2 + M[j]
113
+      TT2 = (j >= 0 && j <= 15 ? ((E ^ F) ^ G) : ((E & F) | ((~E) & G))) + H + SS1 + W[j]
114
+
115
+      D = C
116
+      C = rotl(B, 9)
117
+      B = A
118
+      A = TT1
119
+      H = G
120
+      G = rotl(F, 19)
121
+      F = E
122
+      E = P0(TT2)
123
+    }
124
+
125
+    V[0] ^= A
126
+    V[1] ^= B
127
+    V[2] ^= C
128
+    V[3] ^= D
129
+    V[4] ^= E
130
+    V[5] ^= F
131
+    V[6] ^= G
132
+    V[7] ^= H
133
+  }
134
+
135
+  // 转回 uint8
136
+  const result = []
137
+  for (let i = 0, len = V.length; i < len; i++) {
138
+    const word = V[i]
139
+    result.push((word & 0xff000000) >>> 24, (word & 0xff0000) >>> 16, (word & 0xff00) >>> 8, word & 0xff)
140
+  }
141
+
142
+  return result
143
+}
144
+
145
+/**
146
+ * hmac 实现
147
+ */
148
+const blockLen = 64
149
+const iPad = new Uint8Array(blockLen)
150
+const oPad = new Uint8Array(blockLen)
151
+for (let i = 0; i < blockLen; i++) {
152
+  iPad[i] = 0x36
153
+  oPad[i] = 0x5c
154
+}
155
+function hmac(input, key) {
156
+  // 密钥填充
157
+  if (key.length > blockLen) key = sm3(key)
158
+  while (key.length < blockLen) key.push(0)
159
+
160
+  const iPadKey = xor(key, iPad)
161
+  const oPadKey = xor(key, oPad)
162
+
163
+  const hash = sm3([...iPadKey, ...input])
164
+  return sm3([...oPadKey, ...hash])
165
+}
166
+
167
+module.exports = {
168
+  sm3,
169
+  hmac,
170
+}

+ 194 - 0
price-collection/node_modules/sm-crypto/src/sm2/utils.js

@@ -0,0 +1,194 @@
1
+/* eslint-disable no-bitwise, no-mixed-operators, no-use-before-define, max-len */
2
+const {BigInteger, SecureRandom} = require('jsbn')
3
+const {ECCurveFp} = require('./ec')
4
+
5
+const rng = new SecureRandom()
6
+const {curve, G, n} = generateEcparam()
7
+
8
+/**
9
+ * 获取公共椭圆曲线
10
+ */
11
+function getGlobalCurve() {
12
+  return curve
13
+}
14
+
15
+/**
16
+ * 生成ecparam
17
+ */
18
+function generateEcparam() {
19
+  // 椭圆曲线
20
+  const p = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF', 16)
21
+  const a = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC', 16)
22
+  const b = new BigInteger('28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', 16)
23
+  const curve = new ECCurveFp(p, a, b)
24
+
25
+  // 基点
26
+  const gxHex = '32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7'
27
+  const gyHex = 'BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0'
28
+  const G = curve.decodePointHex('04' + gxHex + gyHex)
29
+
30
+  const n = new BigInteger('FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 16)
31
+
32
+  return {curve, G, n}
33
+}
34
+
35
+/**
36
+ * 生成密钥对:publicKey = privateKey * G
37
+ */
38
+function generateKeyPairHex(a, b, c) {
39
+  const random = a ? new BigInteger(a, b, c) : new BigInteger(n.bitLength(), rng)
40
+  const d = random.mod(n.subtract(BigInteger.ONE)).add(BigInteger.ONE) // 随机数
41
+  const privateKey = leftPad(d.toString(16), 64)
42
+
43
+  const P = G.multiply(d) // P = dG,p 为公钥,d 为私钥
44
+  const Px = leftPad(P.getX().toBigInteger().toString(16), 64)
45
+  const Py = leftPad(P.getY().toBigInteger().toString(16), 64)
46
+  const publicKey = '04' + Px + Py
47
+
48
+  return {privateKey, publicKey}
49
+}
50
+
51
+/**
52
+ * 生成压缩公钥
53
+ */
54
+function compressPublicKeyHex(s) {
55
+  if (s.length !== 130) throw new Error('Invalid public key to compress')
56
+
57
+  const len = (s.length - 2) / 2
58
+  const xHex = s.substr(2, len)
59
+  const y = new BigInteger(s.substr(len + 2, len), 16)
60
+
61
+  let prefix = '03'
62
+  if (y.mod(new BigInteger('2')).equals(BigInteger.ZERO)) prefix = '02'
63
+
64
+  return prefix + xHex
65
+}
66
+
67
+/**
68
+ * utf8串转16进制串
69
+ */
70
+function utf8ToHex(input) {
71
+  input = unescape(encodeURIComponent(input))
72
+
73
+  const length = input.length
74
+
75
+  // 转换到字数组
76
+  const words = []
77
+  for (let i = 0; i < length; i++) {
78
+    words[i >>> 2] |= (input.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8)
79
+  }
80
+
81
+  // 转换到16进制
82
+  const hexChars = []
83
+  for (let i = 0; i < length; i++) {
84
+    const bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
85
+    hexChars.push((bite >>> 4).toString(16))
86
+    hexChars.push((bite & 0x0f).toString(16))
87
+  }
88
+
89
+  return hexChars.join('')
90
+}
91
+
92
+/**
93
+ * 补全16进制字符串
94
+ */
95
+function leftPad(input, num) {
96
+  if (input.length >= num) return input
97
+
98
+  return (new Array(num - input.length + 1)).join('0') + input
99
+}
100
+
101
+/**
102
+ * 转成16进制串
103
+ */
104
+function arrayToHex(arr) {
105
+  return arr.map(item => {
106
+    item = item.toString(16)
107
+    return item.length === 1 ? '0' + item : item
108
+  }).join('')
109
+}
110
+
111
+/**
112
+ * 转成utf8串
113
+ */
114
+function arrayToUtf8(arr) {
115
+  const words = []
116
+  let j = 0
117
+  for (let i = 0; i < arr.length * 2; i += 2) {
118
+    words[i >>> 3] |= parseInt(arr[j], 10) << (24 - (i % 8) * 4)
119
+    j++
120
+  }
121
+
122
+  try {
123
+    const latin1Chars = []
124
+
125
+    for (let i = 0; i < arr.length; i++) {
126
+      const bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
127
+      latin1Chars.push(String.fromCharCode(bite))
128
+    }
129
+
130
+    return decodeURIComponent(escape(latin1Chars.join('')))
131
+  } catch (e) {
132
+    throw new Error('Malformed UTF-8 data')
133
+  }
134
+}
135
+
136
+/**
137
+ * 转成字节数组
138
+ */
139
+function hexToArray(hexStr) {
140
+  const words = []
141
+  let hexStrLength = hexStr.length
142
+
143
+  if (hexStrLength % 2 !== 0) {
144
+    hexStr = leftPad(hexStr, hexStrLength + 1)
145
+  }
146
+
147
+  hexStrLength = hexStr.length
148
+
149
+  for (let i = 0; i < hexStrLength; i += 2) {
150
+    words.push(parseInt(hexStr.substr(i, 2), 16))
151
+  }
152
+  return words
153
+}
154
+
155
+/**
156
+ * 验证公钥是否为椭圆曲线上的点
157
+ */
158
+function verifyPublicKey(publicKey) {
159
+  const point = curve.decodePointHex(publicKey)
160
+  if (!point) return false
161
+
162
+  const x = point.getX()
163
+  const y = point.getY()
164
+
165
+  // 验证 y^2 是否等于 x^3 + ax + b
166
+  return y.square().equals(x.multiply(x.square()).add(x.multiply(curve.a)).add(curve.b))
167
+}
168
+
169
+/**
170
+ * 验证公钥是否等价,等价返回true
171
+ */
172
+function comparePublicKeyHex(publicKey1, publicKey2) {
173
+  const point1 = curve.decodePointHex(publicKey1)
174
+  if (!point1) return false
175
+
176
+  const point2 = curve.decodePointHex(publicKey2)
177
+  if (!point2) return false
178
+
179
+  return point1.equals(point2)
180
+}
181
+
182
+module.exports = {
183
+  getGlobalCurve,
184
+  generateEcparam,
185
+  generateKeyPairHex,
186
+  compressPublicKeyHex,
187
+  utf8ToHex,
188
+  leftPad,
189
+  arrayToHex,
190
+  arrayToUtf8,
191
+  hexToArray,
192
+  verifyPublicKey,
193
+  comparePublicKeyHex,
194
+}

+ 94 - 0
price-collection/node_modules/sm-crypto/src/sm3/index.js

@@ -0,0 +1,94 @@
1
+const {sm3, hmac} = require('../sm2/sm3')
2
+
3
+/**
4
+ * 补全16进制字符串
5
+ */
6
+function leftPad(input, num) {
7
+  if (input.length >= num) return input
8
+
9
+  return (new Array(num - input.length + 1)).join('0') + input
10
+}
11
+
12
+/**
13
+ * 字节数组转 16 进制串
14
+ */
15
+function ArrayToHex(arr) {
16
+  return arr.map(item => {
17
+    item = item.toString(16)
18
+    return item.length === 1 ? '0' + item : item
19
+  }).join('')
20
+}
21
+
22
+/**
23
+ * 转成字节数组
24
+ */
25
+function hexToArray(hexStr) {
26
+  const words = []
27
+  let hexStrLength = hexStr.length
28
+
29
+  if (hexStrLength % 2 !== 0) {
30
+    hexStr = leftPad(hexStr, hexStrLength + 1)
31
+  }
32
+
33
+  hexStrLength = hexStr.length
34
+
35
+  for (let i = 0; i < hexStrLength; i += 2) {
36
+    words.push(parseInt(hexStr.substr(i, 2), 16))
37
+  }
38
+  return words
39
+}
40
+
41
+/**
42
+ * utf8 串转字节数组
43
+ */
44
+function utf8ToArray(str) {
45
+  const arr = []
46
+
47
+  for (let i = 0, len = str.length; i < len; i++) {
48
+    const point = str.codePointAt(i)
49
+
50
+    if (point <= 0x007f) {
51
+      // 单字节,标量值:00000000 00000000 0zzzzzzz
52
+      arr.push(point)
53
+    } else if (point <= 0x07ff) {
54
+      // 双字节,标量值:00000000 00000yyy yyzzzzzz
55
+      arr.push(0xc0 | (point >>> 6)) // 110yyyyy(0xc0-0xdf)
56
+      arr.push(0x80 | (point & 0x3f)) // 10zzzzzz(0x80-0xbf)
57
+    } else if (point <= 0xD7FF || (point >= 0xE000 && point <= 0xFFFF)) {
58
+      // 三字节:标量值:00000000 xxxxyyyy yyzzzzzz
59
+      arr.push(0xe0 | (point >>> 12)) // 1110xxxx(0xe0-0xef)
60
+      arr.push(0x80 | ((point >>> 6) & 0x3f)) // 10yyyyyy(0x80-0xbf)
61
+      arr.push(0x80 | (point & 0x3f)) // 10zzzzzz(0x80-0xbf)
62
+    } else if (point >= 0x010000 && point <= 0x10FFFF) {
63
+      // 四字节:标量值:000wwwxx xxxxyyyy yyzzzzzz
64
+      i++
65
+      arr.push((0xf0 | (point >>> 18) & 0x1c)) // 11110www(0xf0-0xf7)
66
+      arr.push((0x80 | ((point >>> 12) & 0x3f))) // 10xxxxxx(0x80-0xbf)
67
+      arr.push((0x80 | ((point >>> 6) & 0x3f))) // 10yyyyyy(0x80-0xbf)
68
+      arr.push((0x80 | (point & 0x3f))) // 10zzzzzz(0x80-0xbf)
69
+    } else {
70
+      // 五、六字节,暂时不支持
71
+      arr.push(point)
72
+      throw new Error('input is not supported')
73
+    }
74
+  }
75
+
76
+  return arr
77
+}
78
+
79
+module.exports = function (input, options) {
80
+  input = typeof input === 'string' ? utf8ToArray(input) : Array.prototype.slice.call(input)
81
+
82
+  if (options) {
83
+    const mode = options.mode || 'hmac'
84
+    if (mode !== 'hmac') throw new Error('invalid mode')
85
+
86
+    let key = options.key
87
+    if (!key) throw new Error('invalid key')
88
+
89
+    key = typeof key === 'string' ? hexToArray(key) : Array.prototype.slice.call(key)
90
+    return ArrayToHex(hmac(input, key))
91
+  }
92
+
93
+  return ArrayToHex(sm3(input))
94
+}

+ 359 - 0
price-collection/node_modules/sm-crypto/src/sm4/index.js

@@ -0,0 +1,359 @@
1
+/* eslint-disable no-bitwise, no-mixed-operators, complexity */
2
+const DECRYPT = 0
3
+const ROUND = 32
4
+const BLOCK = 16
5
+
6
+const Sbox = [
7
+  0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05,
8
+  0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99,
9
+  0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62,
10
+  0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6,
11
+  0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8,
12
+  0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35,
13
+  0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87,
14
+  0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e,
15
+  0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1,
16
+  0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3,
17
+  0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f,
18
+  0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
19
+  0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8,
20
+  0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0,
21
+  0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84,
22
+  0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48
23
+]
24
+
25
+const CK = [
26
+  0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
27
+  0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
28
+  0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
29
+  0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
30
+  0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
31
+  0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
32
+  0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
33
+  0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
34
+]
35
+
36
+/**
37
+ * 16 进制串转字节数组
38
+ */
39
+function hexToArray(str) {
40
+  const arr = []
41
+  for (let i = 0, len = str.length; i < len; i += 2) {
42
+    arr.push(parseInt(str.substr(i, 2), 16))
43
+  }
44
+  return arr
45
+}
46
+
47
+/**
48
+ * 字节数组转 16 进制串
49
+ */
50
+function ArrayToHex(arr) {
51
+  return arr.map(item => {
52
+    item = item.toString(16)
53
+    return item.length === 1 ? '0' + item : item
54
+  }).join('')
55
+}
56
+
57
+/**
58
+ * utf8 串转字节数组
59
+ */
60
+function utf8ToArray(str) {
61
+  const arr = []
62
+
63
+  for (let i = 0, len = str.length; i < len; i++) {
64
+    const point = str.codePointAt(i)
65
+
66
+    if (point <= 0x007f) {
67
+      // 单字节,标量值:00000000 00000000 0zzzzzzz
68
+      arr.push(point)
69
+    } else if (point <= 0x07ff) {
70
+      // 双字节,标量值:00000000 00000yyy yyzzzzzz
71
+      arr.push(0xc0 | (point >>> 6)) // 110yyyyy(0xc0-0xdf)
72
+      arr.push(0x80 | (point & 0x3f)) // 10zzzzzz(0x80-0xbf)
73
+    } else if (point <= 0xD7FF || (point >= 0xE000 && point <= 0xFFFF)) {
74
+      // 三字节:标量值:00000000 xxxxyyyy yyzzzzzz
75
+      arr.push(0xe0 | (point >>> 12)) // 1110xxxx(0xe0-0xef)
76
+      arr.push(0x80 | ((point >>> 6) & 0x3f)) // 10yyyyyy(0x80-0xbf)
77
+      arr.push(0x80 | (point & 0x3f)) // 10zzzzzz(0x80-0xbf)
78
+    } else if (point >= 0x010000 && point <= 0x10FFFF) {
79
+      // 四字节:标量值:000wwwxx xxxxyyyy yyzzzzzz
80
+      i++
81
+      arr.push((0xf0 | (point >>> 18) & 0x1c)) // 11110www(0xf0-0xf7)
82
+      arr.push((0x80 | ((point >>> 12) & 0x3f))) // 10xxxxxx(0x80-0xbf)
83
+      arr.push((0x80 | ((point >>> 6) & 0x3f))) // 10yyyyyy(0x80-0xbf)
84
+      arr.push((0x80 | (point & 0x3f))) // 10zzzzzz(0x80-0xbf)
85
+    } else {
86
+      // 五、六字节,暂时不支持
87
+      arr.push(point)
88
+      throw new Error('input is not supported')
89
+    }
90
+  }
91
+
92
+  return arr
93
+}
94
+
95
+/**
96
+ * 字节数组转 utf8 串
97
+ */
98
+function arrayToUtf8(arr) {
99
+  const str = []
100
+  for (let i = 0, len = arr.length; i < len; i++) {
101
+    if (arr[i] >= 0xf0 && arr[i] <= 0xf7) {
102
+      // 四字节
103
+      str.push(String.fromCodePoint(((arr[i] & 0x07) << 18) + ((arr[i + 1] & 0x3f) << 12) + ((arr[i + 2] & 0x3f) << 6) + (arr[i + 3] & 0x3f)))
104
+      i += 3
105
+    } else if (arr[i] >= 0xe0 && arr[i] <= 0xef) {
106
+      // 三字节
107
+      str.push(String.fromCodePoint(((arr[i] & 0x0f) << 12) + ((arr[i + 1] & 0x3f) << 6) + (arr[i + 2] & 0x3f)))
108
+      i += 2
109
+    } else if (arr[i] >= 0xc0 && arr[i] <= 0xdf) {
110
+      // 双字节
111
+      str.push(String.fromCodePoint(((arr[i] & 0x1f) << 6) + (arr[i + 1] & 0x3f)))
112
+      i++
113
+    } else {
114
+      // 单字节
115
+      str.push(String.fromCodePoint(arr[i]))
116
+    }
117
+  }
118
+
119
+  return str.join('')
120
+}
121
+
122
+/**
123
+ * 32 比特循环左移
124
+ */
125
+function rotl(x, n) {
126
+  const s = n & 31
127
+  return (x << s) | (x >>> (32 - s))
128
+}
129
+
130
+/**
131
+ * 非线性变换
132
+ */
133
+function byteSub(a) {
134
+  return (Sbox[a >>> 24 & 0xFF] & 0xFF) << 24 |
135
+    (Sbox[a >>> 16 & 0xFF] & 0xFF) << 16 |
136
+    (Sbox[a >>> 8 & 0xFF] & 0xFF) << 8 |
137
+    (Sbox[a & 0xFF] & 0xFF)
138
+}
139
+
140
+/**
141
+ * 线性变换,加密/解密用
142
+ */
143
+function l1(b) {
144
+  return b ^ rotl(b, 2) ^ rotl(b, 10) ^ rotl(b, 18) ^ rotl(b, 24)
145
+}
146
+
147
+/**
148
+ * 线性变换,生成轮密钥用
149
+ */
150
+function l2(b) {
151
+  return b ^ rotl(b, 13) ^ rotl(b, 23)
152
+}
153
+
154
+/**
155
+ * 以一组 128 比特进行加密/解密操作
156
+ */
157
+function sms4Crypt(input, output, roundKey) {
158
+  const x = new Array(4)
159
+
160
+  // 字节数组转成字数组(此处 1 字 = 32 比特)
161
+  const tmp = new Array(4)
162
+  for (let i = 0; i < 4; i++) {
163
+    tmp[0] = input[4 * i] & 0xff
164
+    tmp[1] = input[4 * i + 1] & 0xff
165
+    tmp[2] = input[4 * i + 2] & 0xff
166
+    tmp[3] = input[4 * i + 3] & 0xff
167
+    x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3]
168
+  }
169
+
170
+  // x[i + 4] = x[i] ^ l1(byteSub(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ roundKey[i]))
171
+  for (let r = 0, mid; r < 32; r += 4) {
172
+    mid = x[1] ^ x[2] ^ x[3] ^ roundKey[r + 0]
173
+    x[0] ^= l1(byteSub(mid)) // x[4]
174
+
175
+    mid = x[2] ^ x[3] ^ x[0] ^ roundKey[r + 1]
176
+    x[1] ^= l1(byteSub(mid)) // x[5]
177
+
178
+    mid = x[3] ^ x[0] ^ x[1] ^ roundKey[r + 2]
179
+    x[2] ^= l1(byteSub(mid)) // x[6]
180
+
181
+    mid = x[0] ^ x[1] ^ x[2] ^ roundKey[r + 3]
182
+    x[3] ^= l1(byteSub(mid)) // x[7]
183
+  }
184
+
185
+  // 反序变换
186
+  for (let j = 0; j < 16; j += 4) {
187
+    output[j] = x[3 - j / 4] >>> 24 & 0xff
188
+    output[j + 1] = x[3 - j / 4] >>> 16 & 0xff
189
+    output[j + 2] = x[3 - j / 4] >>> 8 & 0xff
190
+    output[j + 3] = x[3 - j / 4] & 0xff
191
+  }
192
+}
193
+
194
+/**
195
+ * 密钥扩展算法
196
+ */
197
+function sms4KeyExt(key, roundKey, cryptFlag) {
198
+  const x = new Array(4)
199
+
200
+  // 字节数组转成字数组(此处 1 字 = 32 比特)
201
+  const tmp = new Array(4)
202
+  for (let i = 0; i < 4; i++) {
203
+    tmp[0] = key[0 + 4 * i] & 0xff
204
+    tmp[1] = key[1 + 4 * i] & 0xff
205
+    tmp[2] = key[2 + 4 * i] & 0xff
206
+    tmp[3] = key[3 + 4 * i] & 0xff
207
+    x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3]
208
+  }
209
+
210
+  // 与系统参数做异或
211
+  x[0] ^= 0xa3b1bac6
212
+  x[1] ^= 0x56aa3350
213
+  x[2] ^= 0x677d9197
214
+  x[3] ^= 0xb27022dc
215
+
216
+  // roundKey[i] = x[i + 4] = x[i] ^ l2(byteSub(x[i + 1] ^ x[i + 2] ^ x[i + 3] ^ CK[i]))
217
+  for (let r = 0, mid; r < 32; r += 4) {
218
+    mid = x[1] ^ x[2] ^ x[3] ^ CK[r + 0]
219
+    roundKey[r + 0] = x[0] ^= l2(byteSub(mid)) // x[4]
220
+
221
+    mid = x[2] ^ x[3] ^ x[0] ^ CK[r + 1]
222
+    roundKey[r + 1] = x[1] ^= l2(byteSub(mid)) // x[5]
223
+
224
+    mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2]
225
+    roundKey[r + 2] = x[2] ^= l2(byteSub(mid)) // x[6]
226
+
227
+    mid = x[0] ^ x[1] ^ x[2] ^ CK[r + 3]
228
+    roundKey[r + 3] = x[3] ^= l2(byteSub(mid)) // x[7]
229
+  }
230
+
231
+  // 解密时使用反序的轮密钥
232
+  if (cryptFlag === DECRYPT) {
233
+    for (let r = 0, mid; r < 16; r++) {
234
+      mid = roundKey[r]
235
+      roundKey[r] = roundKey[31 - r]
236
+      roundKey[31 - r] = mid
237
+    }
238
+  }
239
+}
240
+
241
+function sm4(inArray, key, cryptFlag, {
242
+  padding = 'pkcs#7', mode, iv = [], output = 'string'
243
+} = {}) {
244
+  if (mode === 'cbc') {
245
+    // CBC 模式,默认走 ECB 模式
246
+    if (typeof iv === 'string') iv = hexToArray(iv)
247
+    if (iv.length !== (128 / 8)) {
248
+      // iv 不是 128 比特
249
+      throw new Error('iv is invalid')
250
+    }
251
+  }
252
+
253
+  // 检查 key
254
+  if (typeof key === 'string') key = hexToArray(key)
255
+  if (key.length !== (128 / 8)) {
256
+    // key 不是 128 比特
257
+    throw new Error('key is invalid')
258
+  }
259
+
260
+  // 检查输入
261
+  if (typeof inArray === 'string') {
262
+    if (cryptFlag !== DECRYPT) {
263
+      // 加密,输入为 utf8 串
264
+      inArray = utf8ToArray(inArray)
265
+    } else {
266
+      // 解密,输入为 16 进制串
267
+      inArray = hexToArray(inArray)
268
+    }
269
+  } else {
270
+    inArray = [...inArray]
271
+  }
272
+
273
+  // 新增填充,sm4 是 16 个字节一个分组,所以统一走到 pkcs#7
274
+  if ((padding === 'pkcs#5' || padding === 'pkcs#7') && cryptFlag !== DECRYPT) {
275
+    const paddingCount = BLOCK - inArray.length % BLOCK
276
+    for (let i = 0; i < paddingCount; i++) inArray.push(paddingCount)
277
+  }
278
+
279
+  // 生成轮密钥
280
+  const roundKey = new Array(ROUND)
281
+  sms4KeyExt(key, roundKey, cryptFlag)
282
+
283
+  const outArray = []
284
+  let lastVector = iv
285
+  let restLen = inArray.length
286
+  let point = 0
287
+  while (restLen >= BLOCK) {
288
+    const input = inArray.slice(point, point + 16)
289
+    const output = new Array(16)
290
+
291
+    if (mode === 'cbc') {
292
+      for (let i = 0; i < BLOCK; i++) {
293
+        if (cryptFlag !== DECRYPT) {
294
+          // 加密过程在组加密前进行异或
295
+          input[i] ^= lastVector[i]
296
+        }
297
+      }
298
+    }
299
+
300
+    sms4Crypt(input, output, roundKey)
301
+
302
+
303
+    for (let i = 0; i < BLOCK; i++) {
304
+      if (mode === 'cbc') {
305
+        if (cryptFlag === DECRYPT) {
306
+          // 解密过程在组解密后进行异或
307
+          output[i] ^= lastVector[i]
308
+        }
309
+      }
310
+
311
+      outArray[point + i] = output[i]
312
+    }
313
+
314
+    if (mode === 'cbc') {
315
+      if (cryptFlag !== DECRYPT) {
316
+        // 使用上一次输出作为加密向量
317
+        lastVector = output
318
+      } else {
319
+        // 使用上一次输入作为解密向量
320
+        lastVector = input
321
+      }
322
+    }
323
+
324
+    restLen -= BLOCK
325
+    point += BLOCK
326
+  }
327
+
328
+  // 去除填充,sm4 是 16 个字节一个分组,所以统一走到 pkcs#7
329
+  if ((padding === 'pkcs#5' || padding === 'pkcs#7') && cryptFlag === DECRYPT) {
330
+    const len = outArray.length
331
+    const paddingCount = outArray[len - 1]
332
+    for (let i = 1; i <= paddingCount; i++) {
333
+      if (outArray[len - i] !== paddingCount) throw new Error('padding is invalid')
334
+    }
335
+    outArray.splice(len - paddingCount, paddingCount)
336
+  }
337
+
338
+  // 调整输出
339
+  if (output !== 'array') {
340
+    if (cryptFlag !== DECRYPT) {
341
+      // 加密,输出转 16 进制串
342
+      return ArrayToHex(outArray)
343
+    } else {
344
+      // 解密,输出转 utf8 串
345
+      return arrayToUtf8(outArray)
346
+    }
347
+  } else {
348
+    return outArray
349
+  }
350
+}
351
+
352
+module.exports = {
353
+  encrypt(inArray, key, options) {
354
+    return sm4(inArray, key, 1, options)
355
+  },
356
+  decrypt(inArray, key, options) {
357
+    return sm4(inArray, key, 0, options)
358
+  }
359
+}

+ 26 - 0
price-collection/node_modules/sm-crypto/webpack.config.js

@@ -0,0 +1,26 @@
1
+const path = require('path');
2
+const webpack = require('webpack');
3
+
4
+module.exports = {
5
+    entry: {
6
+        sm2: './src/sm2/index.js',
7
+        sm3: './src/sm3/index.js',
8
+        sm4: './src/sm4/index.js',
9
+    },
10
+    output: {
11
+        path: path.resolve(__dirname, 'dist'),
12
+        filename: '[name].js',
13
+        library: '[name]',
14
+        libraryTarget: 'umd',
15
+    },
16
+    module: {    
17
+        loaders: [{    
18
+            test: /\.js$/,    
19
+            exclude: /node_modules/,    
20
+            loader: 'babel-loader'    
21
+        }]    
22
+    },
23
+    plugins: [
24
+        new webpack.optimize.UglifyJsPlugin(),
25
+    ]
26
+};

+ 40 - 0
price-collection/package-lock.json

@@ -0,0 +1,40 @@
1
+{
2
+  "name": "price-collection",
3
+  "lockfileVersion": 2,
4
+  "requires": true,
5
+  "packages": {
6
+    "": {
7
+      "dependencies": {
8
+        "sm-crypto": "^0.3.13"
9
+      }
10
+    },
11
+    "node_modules/jsbn": {
12
+      "version": "1.1.0",
13
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
14
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
15
+    },
16
+    "node_modules/sm-crypto": {
17
+      "version": "0.3.13",
18
+      "resolved": "https://registry.npmjs.org/sm-crypto/-/sm-crypto-0.3.13.tgz",
19
+      "integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
20
+      "dependencies": {
21
+        "jsbn": "^1.1.0"
22
+      }
23
+    }
24
+  },
25
+  "dependencies": {
26
+    "jsbn": {
27
+      "version": "1.1.0",
28
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
29
+      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="
30
+    },
31
+    "sm-crypto": {
32
+      "version": "0.3.13",
33
+      "resolved": "https://registry.npmjs.org/sm-crypto/-/sm-crypto-0.3.13.tgz",
34
+      "integrity": "sha512-ztNF+pZq6viCPMA1A6KKu3bgpkmYti5avykRHbcFIdSipFdkVmfUw2CnpM2kBJyppIalqvczLNM3wR8OQ0pT5w==",
35
+      "requires": {
36
+        "jsbn": "^1.1.0"
37
+      }
38
+    }
39
+  }
40
+}

+ 5 - 0
price-collection/package.json

@@ -0,0 +1,5 @@
1
+{
2
+  "dependencies": {
3
+    "sm-crypto": "^0.3.13"
4
+  }
5
+}

+ 53 - 0
price-collection/pages.json

@@ -0,0 +1,53 @@
1
+{
2
+	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
3
+		{
4
+			"path" : "pages/login/index",
5
+			"style" : 
6
+			{
7
+				"navigationBarTitleText" : "",
8
+				"enablePullDownRefresh" : false,
9
+				"navigationStyle": "custom",
10
+				"app-plus": {
11
+					"scrollIndicator": false
12
+				}
13
+			}
14
+		},
15
+		{
16
+			"path": "pages/index/index",
17
+			"style": {
18
+				"navigationBarTitleText": "uni-app"
19
+			}
20
+		},
21
+		{
22
+			"path" : "pages/collectionList/index",
23
+			"style" : 
24
+			{
25
+				"navigationBarTitleText" : "价格采集",
26
+				"enablePullDownRefresh" : false,
27
+				"navigationStyle": "custom",
28
+				"app-plus": {
29
+					"scrollIndicator": false
30
+				}
31
+			}
32
+		},
33
+		{
34
+			"path" : "pages/collectionDetail/index",
35
+			"style" : 
36
+			{
37
+				"navigationBarTitleText" : "价格采集",
38
+				"enablePullDownRefresh" : false,
39
+				"navigationStyle": "custom",
40
+				"app-plus": {
41
+					"scrollIndicator": false
42
+				}
43
+			}
44
+		}
45
+	],
46
+	"globalStyle": {
47
+		"navigationBarTextStyle": "black",
48
+		"navigationBarTitleText": "uni-app",
49
+		"navigationBarBackgroundColor": "#F8F8F8",
50
+		"backgroundColor": "#F8F8F8"
51
+	},
52
+	"uniIdRouter": {}
53
+}

+ 45 - 0
price-collection/pages/collectionDetail/components/item.vue

@@ -0,0 +1,45 @@
1
+<template>
2
+	<view class="content">
3
+		<view>粮食品类: {{name}}</view>
4
+		<u--form labelPosition="left" :model="price1">
5
+			<u-form-item label="姓名" prop="userInfo.name">
6
+			</u-form-item>
7
+		</u--form>
8
+	</view>
9
+</template>
10
+
11
+<script>
12
+	export default {
13
+		props: {
14
+			name: {
15
+				type: String,
16
+				require: false,
17
+				default: ""
18
+			},
19
+			types: {
20
+				type: Array,
21
+				require: false,
22
+				default: () => {return []}
23
+			},
24
+			items: {
25
+				type: Array,
26
+				require: false,
27
+				default: () => {return []}
28
+			}
29
+		},
30
+		data() {
31
+			return {
32
+
33
+			}
34
+		},
35
+		methods: {
36
+
37
+		}
38
+	}
39
+</script>
40
+
41
+<style scoped lang="scss">
42
+	.content {
43
+
44
+	}
45
+</style>

+ 641 - 0
price-collection/pages/collectionDetail/index.vue

@@ -0,0 +1,641 @@
1
+<template>
2
+	<view class="content">
3
+		<view class="title-box">
4
+			<view class="title">
5
+				<view class="title">价格采集</view>
6
+			</view>
7
+		</view>
8
+		
9
+		<view class="container-box">
10
+			<view class="container">
11
+				<view class="info-box">
12
+					<!-- <view>
13
+						<u-cell title="经度" :value="position.longitude"></u-cell>
14
+						<u-cell title="纬度" :value="position.latitude"></u-cell>
15
+					</view> -->
16
+					<view>
17
+					<u-cell title="站点名称" v-if="isSelfPriceMonitor" :value="monitor.name"></u-cell>
18
+					<u-cell title="站点名称" v-if="!isSelfPriceMonitor" :value="monitor.name" :is-link="true" @click="show = true"></u-cell>
19
+					<u-cell title="详细地址" :value="monitor.address"></u-cell>
20
+					<u-cell title="价格采集人" :value="monitor.userName"></u-cell>
21
+					<u-cell title="市州" :value="monitor.sysOrgName"></u-cell>
22
+					<u-cell title="联系方式" :value="monitor.userPhone"></u-cell>
23
+					<u-cell title="采集时间" :value="nowDate"></u-cell>
24
+				</view>
25
+				</view>
26
+				<view class="price">
27
+					<view class="title">价格信息</view>
28
+					<view class="item-table">
29
+						<view class="center title-1">粮食品类: 原粮</view>
30
+						<u-row class="row">
31
+							<u-col :span="4">
32
+								<view class="center">品种</view>
33
+							</u-col>
34
+							<u-col :span="8">
35
+								<view class="center">收购价</view>
36
+							</u-col>
37
+						</u-row>
38
+						<u-row v-for="(item, index) in price1" :key="index" class="row">
39
+							<u-col :span="4">
40
+								<view class="center">{{item.name}}</view>
41
+							</u-col>
42
+							<u-col :span="8">
43
+								<view class="center"><u-input v-model.number="item.price"></u-input></view>
44
+							</u-col>
45
+						</u-row>
46
+					</view>
47
+
48
+					<view class="item-table">
49
+						<view class="center title-1">粮食品类: 储备粮</view>
50
+						<u-row class="row">
51
+							<u-col :span="4">
52
+								<view class="center">品种</view>
53
+							</u-col>
54
+							<u-col :span="4">
55
+								<view class="center">出库价</view>
56
+							</u-col>
57
+							<u-col :span="4">
58
+								<view class="center">入库价</view>
59
+							</u-col>
60
+						</u-row>
61
+						<u-row v-for="(item, index) in price2" :key="index" class="row">
62
+							<u-col :span="4">
63
+								<view class="center">{{item.name}}</view>
64
+							</u-col>
65
+							<u-col :span="4">
66
+								<view class="center m-l-2"><u-input v-model.number="item.price1"></u-input></view>
67
+							</u-col>
68
+							<u-col :span="4">
69
+								<view class="center m-l-2"><u-input v-model.number="item.price2"></u-input></view>
70
+							</u-col>
71
+						</u-row>
72
+					</view>
73
+					
74
+					<view class="item-table">
75
+						<view class="center">粮食品类: 成品粮</view>
76
+						<u-row class="row">
77
+							<u-col :span="4">
78
+								<view class="center">品种</view>
79
+							</u-col>
80
+							<u-col :span="4">
81
+								<view class="center">批发价</view>
82
+							</u-col>
83
+							<u-col :span="4">
84
+								<view class="center">零售价</view>
85
+							</u-col>
86
+						</u-row>
87
+						<u-row v-for="(item, index) in price3" :key="index" class="row">
88
+							<u-col :span="4">
89
+								<view class="center">{{item.name}}</view>
90
+							</u-col>
91
+							<u-col :span="4">
92
+								<view class="center m-l-2"><u-input v-model.number="item.price1"></u-input></view>
93
+							</u-col>
94
+							<u-col :span="4">
95
+								<view class="center m-l-2"><u-input v-model.number="item.price2"></u-input></view>
96
+							</u-col>
97
+						</u-row>
98
+					</view>
99
+					
100
+					<view class="item-table">
101
+						<view class="center">粮食品类: 杂粮</view>
102
+						<u-row class="row">
103
+							<u-col :span="4">
104
+								<view class="center">品种</view>
105
+							</u-col>
106
+							<u-col :span="4">
107
+								<view class="center">批发价</view>
108
+							</u-col>
109
+							<u-col :span="4">
110
+								<view class="center">零售价</view>
111
+							</u-col>
112
+						</u-row>
113
+						<u-row v-for="(item, index) in price4" :key="index" class="row">
114
+							<u-col :span="4">
115
+								<view class="center">{{item.name}}</view>
116
+							</u-col>
117
+							<u-col :span="4">
118
+								<view class="center m-l-2"><u-input v-model.number="item.price1"></u-input></view>
119
+							</u-col>
120
+							<u-col :span="4">
121
+								<view class="center m-l-2"><u-input v-model.number="item.price2"></u-input></view>
122
+							</u-col>
123
+						</u-row>
124
+					</view>
125
+					
126
+					<view class="remark">
127
+						<u--textarea v-model="remark" placeholder="备注:本周/日采集数据与上周/日采集数据作对比价格超出5%,需要填写备注"></u--textarea>
128
+					</view>
129
+				</view>
130
+				<view class="btns">
131
+				<u-button text="上传" type="primary" class="btn-upload" @click="upload"></u-button>
132
+			</view>
133
+		</view>
134
+		</view>
135
+		<u-action-sheet 
136
+			:actions="allMonitor" 
137
+			:closeOnClickOverlay="true" 
138
+			:closeOnClickAction="true"
139
+			title="选择站点"
140
+			:show="show"
141
+			@select="chooseMonitor"
142
+			@close="show = false">
143
+		</u-action-sheet>
144
+	</view>
145
+</template>
146
+
147
+<script>
148
+	
149
+	import { getMonitorInfoByPoint, getMonitorInfo, addCollect } from '@/api/collect'
150
+	import { dateFormat } from '@/utils/dates'
151
+	import { clone } from '@/utils/common'
152
+	
153
+	const DEFAULT_MONITOR = {
154
+		name: '',
155
+		address: '',
156
+		userName: '',
157
+		sysOrgName: '',
158
+		userPhone: '',
159
+		
160
+	}
161
+	
162
+	const PURCHASE_PRICE = 1 // 收购价
163
+	const INBOUND_PRICE = 2// 入库价
164
+	const OUTBOUND_PRICE = 3 // 出库价
165
+	const EX_FACTORY_PRICE = 4 // 出厂价
166
+	const WHOLESALE_PRICE = 5 // 批发价
167
+	const RETAIL_PRICE = 6 // 零售价
168
+	
169
+	export default {
170
+		data() {
171
+			return {
172
+				showTips: false,
173
+				loadingMsg: '',
174
+				position: {
175
+					longitude: null, // 经度
176
+					latitude: null, // 纬度
177
+				},
178
+				price1: [
179
+					{
180
+						name: '小麦',
181
+						firstLevel: 1,
182
+						secondLevel: 11,
183
+						threeLevel: 0,
184
+						price: null,
185
+					},
186
+					{
187
+						name: '青稞',
188
+						firstLevel: 1,
189
+						secondLevel: 12,
190
+						threeLevel: 0,
191
+						price: null,
192
+					},
193
+					{
194
+						name: '油菜籽',
195
+						firstLevel: 1,
196
+						secondLevel: 13,
197
+						threeLevel: 0,
198
+						price: null,
199
+					},
200
+				],
201
+				price2: [
202
+					{
203
+						name: '省储小麦',
204
+						firstLevel: 4,
205
+						secondLevel: 41,
206
+						threeLevel: 0,
207
+						price1: null,
208
+						price2: null,
209
+					},
210
+					{
211
+						name: '省储青稞',
212
+						firstLevel: 4,
213
+						secondLevel: 42,
214
+						threeLevel: 0,
215
+						price1: null,
216
+						price2: null,
217
+					},
218
+					{
219
+						name: '省储菜籽油',
220
+						firstLevel: 4,
221
+						secondLevel: 43,
222
+						threeLevel: 0,
223
+						price1: null,
224
+						price2: null,
225
+					},
226
+				],
227
+				price3: [
228
+					{
229
+						name: '一级菜籽油',
230
+						firstLevel: 3,
231
+						secondLevel: 31,
232
+						threeLevel: 311,
233
+						price1: null,
234
+						price2: null,
235
+					},
236
+					{
237
+						name: '三级菜籽油',
238
+						firstLevel: 3,
239
+						secondLevel: 31,
240
+						threeLevel: 312,
241
+						price1: null,
242
+						price2: null,
243
+					},
244
+					{
245
+						name: '小榨菜籽油',
246
+						firstLevel: 3,
247
+						secondLevel: 31,
248
+						threeLevel: 313,
249
+						price1: null,
250
+						price2: null,
251
+					},
252
+					{
253
+						name: '特一粉',
254
+						firstLevel: 3,
255
+						secondLevel: 32,
256
+						threeLevel: 321,
257
+						price1: null,
258
+						price2: null,
259
+					},
260
+					{
261
+						name: '牛肉面粉',
262
+						firstLevel: 3,
263
+						secondLevel: 32,
264
+						threeLevel: 322,
265
+						price1: null,
266
+						price2: null,
267
+					},
268
+					{
269
+						name: '一级长粒粳米',
270
+						firstLevel: 3,
271
+						secondLevel: 33,
272
+						threeLevel: 331,
273
+						price1: null,
274
+						price2: null,
275
+					},
276
+					{
277
+						name: '一级圆粒粳米',
278
+						firstLevel: 3,
279
+						secondLevel: 33,
280
+						threeLevel: 332,
281
+						price1: null,
282
+						price2: null,
283
+					},
284
+				],
285
+				price4: [
286
+					{
287
+						name: '黄豆',
288
+						firstLevel: 2,
289
+						secondLevel: 21,
290
+						threeLevel: 0,
291
+						price1: null,
292
+						price2: null,
293
+					},
294
+					{
295
+						name: '玉米面',
296
+						firstLevel: 2,
297
+						secondLevel: 22,
298
+						threeLevel: 0,
299
+						price1: null,
300
+						price2: null,
301
+					},
302
+					{
303
+						name: '小米',
304
+						firstLevel: 2,
305
+						secondLevel: 23,
306
+						threeLevel: 0,
307
+						price1: null,
308
+						price2: null,
309
+					},
310
+				],
311
+				monitor: DEFAULT_MONITOR,
312
+				allMonitor: [],
313
+				userId: null,
314
+				nowDate: null,
315
+				isSelfPriceMonitor: false,
316
+				show: false,
317
+				remark: null,
318
+			}
319
+		},
320
+		mounted() {
321
+			uni.showModal({
322
+				content: '上报需要获取当前设备定位信息,是否允许?',
323
+				confirmText: '允许',
324
+				cancelText: '不允许',
325
+				success: (ret) => {
326
+					if(ret.confirm)
327
+						this.getPosition()
328
+					else 
329
+						uni.redirectTo({
330
+							url: '/pages/collectionList/index'
331
+						})
332
+				},
333
+				fail: () => {
334
+					uni.redirectTo({
335
+						url: '/pages/collectionList/index'
336
+					})
337
+				}
338
+			})
339
+		},
340
+		methods: {
341
+			doGetPosition() {
342
+				return new Promise((resolve, reject) => {
343
+					uni.getLocation({
344
+						altitude: true,
345
+						isHighAccuracy: true,
346
+						success: (ret) => {
347
+							resolve(ret)
348
+						},
349
+						fail: (err) => {
350
+							reject(err)
351
+						}
352
+					})
353
+				})
354
+				
355
+				// for debug
356
+				// return Promise.resolve({
357
+				// 	longitude: 40.7124,
358
+				// 	latitude: -74.006,
359
+				// })
360
+			},
361
+			getPosition() {
362
+				this.loadingMsg = '正在获取定位'
363
+				uni.showLoading({
364
+					title: this.loadingMsg,
365
+					mask: true
366
+				})
367
+				this.doGetPosition()
368
+					.then(ret => {
369
+						this.position.latitude = ret.latitude
370
+						this.position.longitude = ret.longitude
371
+					}).then(_ => {
372
+						// 请求所有站点数据
373
+						return getMonitorInfo().then(resp => {
374
+							console.log('所有站点', resp);
375
+							const all = resp.data
376
+						
377
+							this.allMonitor = all.map(d => {
378
+								const ret = {
379
+									... d,
380
+									disabled: d.locationSwitch == 1
381
+								}
382
+								if(ret.disabled) {
383
+									ret.subname = '该站点必须实地采集'
384
+								}
385
+								return ret
386
+							})
387
+						})
388
+					}).then(_ => {
389
+						if(this.allMonitor.length <= 0) {
390
+							return Promise.reject('你没有可用的检测点')
391
+						}else {
392
+							this.userId = this.allMonitor[0].userId
393
+							return Promise.resolve()
394
+						}
395
+					}).then(_ => {
396
+						// 请求检测点
397
+						return getMonitorInfoByPoint({
398
+							userId: this.userId,
399
+							point: `POINT(${this.position.longitude} ${this.position.latitude})`
400
+							// point: `POINT(1 ${this.position.latitude})`
401
+						}).then(resp => {
402
+							console.log('最近站点', resp);
403
+							if(resp.data.status === 'error') {
404
+								uni.showToast({
405
+									icon: 'error',
406
+									title: resp.data.message
407
+								})
408
+								this.monitor = DEFAULT_MONITOR
409
+								this.isSelfPriceMonitor = false
410
+								return 
411
+							}else {
412
+								const data = this.allMonitor.find(d => d.id === resp.data.id)
413
+								if(data) {
414
+									this.monitor = data
415
+									this.isSelfPriceMonitor = true
416
+								}else {
417
+									uni.showToast({
418
+										icon: 'error',
419
+										title: '最近站点数据异常'
420
+									})
421
+									this.monitor = DEFAULT_MONITOR
422
+									this.isSelfPriceMonitor = false
423
+									return 
424
+								}
425
+							}
426
+						})
427
+					}).then(_ => {
428
+						this.nowDate = dateFormat(new Date())
429
+					}).catch(err => {
430
+						console.log(err);
431
+						uni.showToast({
432
+							title: err
433
+						})
434
+					})
435
+			},
436
+			chooseMonitor(m) {
437
+				this.monitor = m
438
+			},
439
+			calPrice(rawData, dataList, priceType1, priceType2) {
440
+				const temp1 = clone(rawData)
441
+				const temp2 = clone(rawData)
442
+				delete temp1.name
443
+				delete temp2.name
444
+				temp1.priceType = priceType1
445
+				temp2.priceType = priceType2
446
+				temp1.price = rawData.price1
447
+				temp2.price = rawData.price2
448
+				delete temp1.price1
449
+				delete temp1.price2
450
+				delete temp2.price1
451
+				delete temp2.price2
452
+				dataList.push(temp1)
453
+				dataList.push(temp2)
454
+			},
455
+			upload() {
456
+				if(this.monitor === DEFAULT_MONITOR) {
457
+					uni.showToast({
458
+						title: '请选择监测点',
459
+						icon: "error"
460
+					})
461
+					return
462
+				}
463
+				const dataList = []
464
+				this.price1.forEach(d => {
465
+					const temp = clone(d)
466
+					delete temp.name
467
+					temp.priceType = PURCHASE_PRICE
468
+					dataList.push(temp)
469
+				})
470
+				this.price2.forEach(d => {
471
+					this.calPrice(d, dataList, OUTBOUND_PRICE, INBOUND_PRICE)
472
+				})
473
+				this.price3.forEach(d => {
474
+					this.calPrice(d, dataList, WHOLESALE_PRICE, RETAIL_PRICE)
475
+				})
476
+				this.price4.forEach(d => {
477
+					this.calPrice(d, dataList, WHOLESALE_PRICE, RETAIL_PRICE)
478
+				})
479
+				const data = {
480
+					type: 0, // 移动端
481
+					priceMonitorId: this.monitor.id,
482
+					userCollectId: this.monitor.userId,
483
+					userId: this.monitor.userId,
484
+					isSelfPriceMonitor: this.isSelfPriceMonitor ? 1 : 0,  // 是否实地采集, 0 否  1 是
485
+					userCollectName: this.monitor.userName,
486
+					userCollectPhone: this.monitor.userPhone,
487
+					userCollectDate: this.nowDate,
488
+					remark: this.remark,
489
+					categoryAddParamList: dataList,
490
+					point: `${this.position.longitude},${this.position.latitude}`
491
+				}
492
+				console.log(data);
493
+				addCollect(data).then(resp => {
494
+					console.log('保存上报', resp);
495
+					if(resp.code == 200) {
496
+						uni.showToast({
497
+							title: '保存成功',
498
+							icon: 'success',
499
+							mask: true,
500
+							duration: 1_500,
501
+						})
502
+						setTimeout(() => {
503
+							uni.redirectTo({
504
+								url: '/pages/collectionList/index'
505
+							})
506
+						}, 1_500)
507
+					}else {
508
+						uni.showToast({
509
+							title: resp.msg,
510
+							icon: 'error',
511
+						})
512
+					}
513
+				})
514
+			},
515
+			getPositionErrMessage(errCode) {
516
+				console.log('定位失败', errCode);
517
+				let message;
518
+				switch (errCode) {
519
+					case '1505004':
520
+						message = '获取定位失败,请开启定位权限';
521
+						break;
522
+					case '1505005':
523
+						message = '获取定位失败,请开启高经度定位权限';
524
+						break;
525
+					case '1505021':
526
+						message = '获取定位失败,请重试';
527
+						break;
528
+					case '1505022':
529
+						message = '获取定位失败,设备不支持当前类型定位';
530
+						break;
531
+					case '1505023':
532
+						message = '获取定位失败,设备不支持逆地理编码';
533
+						break;
534
+					case '1505024':
535
+						message = '获取定位失败,请开启设备的定位功能';
536
+						break;
537
+					case '1505025':
538
+						message = '获取定位失败,逆地理编码捕获失败';
539
+						break;
540
+					case '1505026':
541
+						message = '获取定位失败,捕获定位失败';
542
+						break;
543
+					default:
544
+						message = '获取定位失败'
545
+				}
546
+				return message
547
+			}
548
+		}
549
+	}
550
+</script>
551
+
552
+<style lang="scss" scoped>
553
+	
554
+.container{
555
+	background-color: #fff;
556
+	border-radius: 24rpx;
557
+	
558
+	.info-box{
559
+		padding: 0 30rpx;
560
+	}
561
+}
562
+
563
+.price {
564
+	// margin: 5px;
565
+	// padding-bottom: 70px;
566
+	.title {
567
+		position: relative;
568
+		margin: 10px;
569
+		display: inline-flex;
570
+		justify-content: center;
571
+		align-items: flex-end;
572
+		font-weight: bold;
573
+		z-index: 1;
574
+		
575
+		&::after{
576
+			content: "";
577
+			position: absolute;
578
+			width: 80%;
579
+			height: 20rpx;
580
+			background: url(@/static/bg-item-title.png) top center no-repeat;
581
+			background-size: 100% 100%;
582
+			z-index: -1;
583
+		}
584
+	}
585
+	.title-1 {
586
+		position: relative;
587
+		margin: 10px 0;
588
+		padding: 20rpx 0;
589
+		padding-left: 30rpx;
590
+		display: flex;
591
+		align-items: center;
592
+		background-color: #f4f4f4;
593
+		font-weight: bold;
594
+		z-index: 1;
595
+		
596
+		&::after{
597
+			content: "";
598
+			position: absolute;
599
+			left: 0;
600
+			margin-right: 20rpx;
601
+			width: 12rpx;
602
+			height: 30rpx;
603
+			background: linear-gradient(0deg,#48d9f4 0%,#29a1ff 100%);
604
+			border-radius: 24rpx;
605
+			z-index: -1;
606
+		}
607
+	}
608
+
609
+	.row {
610
+		margin-top: 5px;
611
+	}
612
+
613
+	.center {
614
+		text-align: center;
615
+	}
616
+
617
+	.m-l-2 {
618
+		margin-left: 2px;
619
+	}
620
+	
621
+	.remark{
622
+		margin: 20rpx;
623
+	}
624
+	
625
+}
626
+.btns {
627
+	margin-bottom: 20px;
628
+	width: 100%;
629
+	height: 50px;
630
+	.btn-upload {
631
+		width: 80%;
632
+		margin-bottom: 10px;
633
+	}
634
+}
635
+
636
+::v-deep{
637
+	.u-cell__body{
638
+		padding: 20rpx 0!important;
639
+	}
640
+}
641
+</style>

+ 48 - 0
price-collection/pages/collectionList/components/infoItem.vue

@@ -0,0 +1,48 @@
1
+<template>
2
+	<view class="content">
3
+		<u-cell title="价格监测点名称" :value="name" icon="file-text"></u-cell>
4
+		<u-cell title="价格采集日期" :value="date" icon="calendar"></u-cell>
5
+		<u-cell title="详细地址" :value="address" icon="map"></u-cell>
6
+	</view>
7
+</template>
8
+
9
+<script>
10
+	export default {
11
+		props: {
12
+			name: {
13
+				type: String,
14
+				require: false,
15
+				default: ""
16
+			},
17
+			date: {
18
+				type: String,
19
+				require: false,
20
+				default: ""
21
+			},
22
+			address: {
23
+				type: String,
24
+				require: false,
25
+				default: ""
26
+			}
27
+		},
28
+		data() {
29
+			return {
30
+
31
+			}
32
+		},
33
+		methods: {
34
+
35
+		}
36
+	}
37
+</script>
38
+
39
+<style scoped lang="scss">
40
+.content{
41
+	margin-bottom: 24rpx;
42
+	padding: 30rpx;
43
+	background-color: #fff;
44
+	border-radius: 24rpx;
45
+	
46
+}
47
+
48
+</style>

+ 93 - 0
price-collection/pages/collectionList/index.vue

@@ -0,0 +1,93 @@
1
+<template>
2
+	<view class="content">
3
+		<view class="title-box">
4
+			<view class="title">
5
+				<view class="title">价格采集</view>
6
+				<view class="icon-add" @click="add"/>
7
+			</view>
8
+		</view>
9
+		<view class="container-box">
10
+			<u-list v-if="datas.length > 0">
11
+				<u-list-item v-for="(item, index) in datas" :key="index">
12
+					<info-item :name="item.monitorName" :date="item.userCollectDate" :address="item.address"/>
13
+				</u-list-item>
14
+			</u-list>
15
+			<view v-if="datas.length <= 0" class="center">
16
+				暂无数据
17
+			</view>
18
+		</view>
19
+	</view>
20
+</template>
21
+
22
+<script>
23
+	import infoItem from './components/infoItem.vue'
24
+	import { findAppPage } from '@/api/collect'
25
+	export default {
26
+		components: {
27
+			infoItem
28
+		},
29
+		data() {
30
+			return {
31
+				page: {
32
+					current: 1,
33
+					size: 10,
34
+				},
35
+				datas: [],
36
+			}
37
+		},
38
+		onNavigationBarButtonTap(e) {
39
+			if (e.index === 0) {
40
+				this.add()
41
+			}
42
+		},
43
+		mounted() {
44
+			this.init()
45
+		},
46
+		methods: {
47
+			init() {
48
+				this.getList()
49
+			},
50
+			add() {
51
+				findAppPage({
52
+					current: 1,
53
+					size: 1,
54
+					sortField: 'userCollectDate',
55
+					sortOrder: 'DESCEND',
56
+				}).then(resp => {
57
+					const list = resp?.data?.records || []
58
+					if(list.length > 0) {
59
+						this.gotoAdd()
60
+					}else {
61
+						this.gotoAdd()
62
+					}
63
+				})
64
+				
65
+			},
66
+			gotoAdd() {
67
+				uni.navigateTo({
68
+					url: '/pages/collectionDetail/index'
69
+				})
70
+			},
71
+			getList() {
72
+				return findAppPage({
73
+					... this.page, 
74
+					sortField: 'userCollectDate', 
75
+					sortOrder: 'DESCEND',
76
+					isApp: 1,
77
+				}).then((resp) => {
78
+					console.log('resp', resp);
79
+					this.datas = resp?.data?.records || []
80
+				})
81
+			}
82
+		}
83
+	}
84
+</script>
85
+
86
+<style lang="scss">
87
+	.center {
88
+		text-align: center;
89
+	}
90
+	.bg-w {
91
+		background-color: white;
92
+	}
93
+</style>

+ 52 - 0
price-collection/pages/index/index.vue

@@ -0,0 +1,52 @@
1
+<template>
2
+	<view class="content">
3
+		<image class="logo" src="/static/logo.png"></image>
4
+		<view class="text-area">
5
+			<text class="title">{{title}}</text>
6
+		</view>
7
+	</view>
8
+</template>
9
+
10
+<script>
11
+	export default {
12
+		data() {
13
+			return {
14
+				title: 'Hello'
15
+			}
16
+		},
17
+		onLoad() {
18
+
19
+		},
20
+		methods: {
21
+
22
+		}
23
+	}
24
+</script>
25
+
26
+<style>
27
+	.content {
28
+		display: flex;
29
+		flex-direction: column;
30
+		align-items: center;
31
+		justify-content: center;
32
+	}
33
+
34
+	.logo {
35
+		height: 200rpx;
36
+		width: 200rpx;
37
+		margin-top: 200rpx;
38
+		margin-left: auto;
39
+		margin-right: auto;
40
+		margin-bottom: 50rpx;
41
+	}
42
+
43
+	.text-area {
44
+		display: flex;
45
+		justify-content: center;
46
+	}
47
+
48
+	.title {
49
+		font-size: 36rpx;
50
+		color: #8f8f94;
51
+	}
52
+</style>

+ 168 - 0
price-collection/pages/login/index.vue

@@ -0,0 +1,168 @@
1
+<template>
2
+	<view class="content">
3
+		<view class="welcome">
4
+			<!-- <img :src="require('~/static/login-bg-top.png')" /> -->
5
+			<view class="welcome-text">
6
+				<view class="title">欢迎登录</view>
7
+				<view class="system-name">价格采集系统</view>
8
+			</view>
9
+		</view>
10
+		<view class="login-form-content">
11
+			<view class="login-form">
12
+				<u--form labelPosition="top" :model="userInfo" labelWidth="100px">
13
+					<u-form-item label="登录用户" prop="userInfo.name">
14
+						<u--input v-model="userInfo.name" placeholder="请输入您的账号"></u--input>
15
+					</u-form-item>
16
+					<u-form-item label="登录密码" prop="userInfo.password">
17
+						<u--input v-model="userInfo.password" type="password" placeholder="请输入您的密码"></u--input>
18
+					</u-form-item>
19
+				</u--form>
20
+				
21
+				<view class="btns">
22
+					<view class="login-btn" @click="login">登录</view>
23
+					<!-- <u-button type="primary" text="登录" @tap="login"></u-button> -->
24
+				</view>
25
+			</view>
26
+		</view>
27
+	</view>
28
+</template>
29
+
30
+<script>
31
+	import {
32
+		cryptoPassword,
33
+		login
34
+	} from '@/api/login.js'
35
+	import { setCache } from '../../utils/cache'
36
+	export default {
37
+		data() {
38
+			return {
39
+				userInfo: {
40
+					name: null,
41
+					password: null,
42
+				}
43
+			}
44
+		},
45
+		methods: {
46
+			login() {
47
+				if (
48
+					this.validate(this.userInfo.name, '请输入用户名') &&
49
+					this.validate(this.userInfo.password, '请输入密码')
50
+				) {
51
+					const pwd = cryptoPassword(this.userInfo.password.trim())
52
+					login({
53
+						username: this.userInfo.name.trim(),
54
+						password: pwd
55
+					}).then(resp => {
56
+						const token = resp.data
57
+						console.log(`登录成功 token = ${token}`);
58
+						setCache('token', token).then(_ => {
59
+							return Promise.resolve()
60
+						}).catch(_ => {
61
+							return Promise.reject('系统异常 - 001')
62
+						})
63
+					}).then(_ => {
64
+						console.log('token 保存成功 跳转首页')
65
+						this.goIndex()
66
+					}).catch(err => {
67
+						uni.showToast({
68
+							title: err,
69
+							icon: 'error',
70
+						})
71
+					})
72
+				}
73
+			},
74
+			goIndex() {
75
+				uni.redirectTo({
76
+					url: '/pages/collectionList/index'
77
+				})
78
+			},
79
+			validate(field, message) {
80
+				if (!field || !field.trim()) {
81
+					uni.showToast({
82
+						title: message,
83
+						icon: 'error',
84
+					})
85
+					return false
86
+				}
87
+				return true
88
+			}
89
+		}
90
+	}
91
+</script>
92
+
93
+<style lang="scss" scoped>
94
+	.content {
95
+		width: 100vw;
96
+		height: 100vh;
97
+		display: flex;
98
+		flex-direction: column;
99
+		justify-content: space-between;
100
+		align-items: center;
101
+
102
+		.welcome {
103
+			position: relative;
104
+			padding: 0 80rpx 140rpx 80rpx;
105
+			width: 100%;
106
+			height: 0;
107
+			color: white;
108
+			display: flex;
109
+			flex-direction: column;
110
+			justify-content: flex-end;
111
+			background:url(@/static/login-bg-top.png) top center no-repeat;
112
+			background-size: 100% 100%;
113
+			font-size: 34rpx;
114
+			flex: 1;
115
+			
116
+			.system-name{
117
+				font-size: 68rpx;
118
+			}
119
+		}
120
+	}
121
+
122
+	.login-form-content {
123
+		position: relative;
124
+		margin-top: -80rpx;
125
+		padding-top: 80rpx;
126
+		width: 100%;
127
+		height: 0;
128
+		display: flex;
129
+		flex-direction: column;
130
+		align-items: center;
131
+		background:url(@/static/login/login-bg-bottom.png) bottom center no-repeat;
132
+		background-size: 100% 800rpx;
133
+		// border-radius: 80rpx 80rpx 0 0;
134
+		flex: 1.7;
135
+		z-index: 2;
136
+		
137
+		.login-form{
138
+			width: 80%;
139
+			display: flex;
140
+			flex-direction: column;
141
+			align-items: center;
142
+			
143
+			.btns {
144
+				width: 100%;
145
+			
146
+				.login-btn {
147
+					display: inline-block;
148
+					padding: 10px 20px;
149
+					background-image: url("~@/static/login/login-btn.png");
150
+					background-size: cover;
151
+					background-repeat: no-repeat;
152
+					color: #fff;
153
+					border: none;
154
+					text-decoration: none;
155
+					text-align: center;
156
+					width: 100%;
157
+				}
158
+			}
159
+		}
160
+	}
161
+	
162
+::v-deep{
163
+	.u-form{
164
+		width: 100%!important;
165
+	}
166
+}
167
+
168
+</style>:

BIN
price-collection/static/.DS_Store


BIN
price-collection/static/bg-item-title-1.png


BIN
price-collection/static/bg-item-title.png


BIN
price-collection/static/icon-add.png


BIN
price-collection/static/login-bg-top.png


BIN
price-collection/static/login/login-bg-bottom.png


BIN
price-collection/static/login/login-btn.png


BIN
price-collection/static/logo.png


BIN
price-collection/static/title.png


+ 10 - 0
price-collection/uni.promisify.adaptor.js

@@ -0,0 +1,10 @@
1
+uni.addInterceptor({
2
+  returnValue (res) {
3
+    if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
4
+      return res;
5
+    }
6
+    return new Promise((resolve, reject) => {
7
+      res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
8
+    });
9
+  },
10
+});

+ 83 - 0
price-collection/uni.scss

@@ -0,0 +1,83 @@
1
+/**
2
+ * 这里是uni-app内置的常用样式变量
3
+ *
4
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
5
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
6
+ *
7
+ */
8
+
9
+/**
10
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
11
+ *
12
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
13
+ */
14
+
15
+@import '@/uni_modules/uview-ui/theme.scss';
16
+
17
+/* 颜色变量 */
18
+
19
+/* 行为相关颜色 */
20
+$uni-color-primary: #007aff;
21
+$uni-color-success: #4cd964;
22
+$uni-color-warning: #f0ad4e;
23
+$uni-color-error: #dd524d;
24
+
25
+/* 文字基本颜色 */
26
+$uni-text-color:#333;//基本色
27
+$uni-text-color-inverse:#fff;//反色
28
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
29
+$uni-text-color-placeholder: #808080;
30
+$uni-text-color-disable:#c0c0c0;
31
+
32
+/* 背景颜色 */
33
+$uni-bg-color:#ffffff;
34
+$uni-bg-color-grey:#f8f8f8;
35
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
36
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
37
+
38
+/* 边框颜色 */
39
+$uni-border-color:#c8c7cc;
40
+
41
+/* 尺寸变量 */
42
+
43
+/* 文字尺寸 */
44
+$uni-font-size-sm:12px;
45
+$uni-font-size-base:14px;
46
+$uni-font-size-lg:16px;
47
+
48
+/* 图片尺寸 */
49
+$uni-img-size-sm:20px;
50
+$uni-img-size-base:26px;
51
+$uni-img-size-lg:40px;
52
+
53
+/* Border Radius */
54
+$uni-border-radius-sm: 2px;
55
+$uni-border-radius-base: 3px;
56
+$uni-border-radius-lg: 6px;
57
+$uni-border-radius-circle: 50%;
58
+
59
+/* 水平间距 */
60
+$uni-spacing-row-sm: 5px;
61
+$uni-spacing-row-base: 10px;
62
+$uni-spacing-row-lg: 15px;
63
+
64
+/* 垂直间距 */
65
+$uni-spacing-col-sm: 4px;
66
+$uni-spacing-col-base: 8px;
67
+$uni-spacing-col-lg: 12px;
68
+
69
+/* 透明度 */
70
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
71
+
72
+/* 文章场景相关 */
73
+$uni-color-title: #2C405A; // 文章标题颜色
74
+$uni-font-size-title:20px;
75
+$uni-color-subtitle: #555555; // 二级标题颜色
76
+$uni-font-size-subtitle:26px;
77
+$uni-color-paragraph: #3F536E; // 文章段落颜色
78
+$uni-font-size-paragraph:15px;
79
+
80
+uni-view,div{
81
+	box-sizing: border-box;
82
+}
83
+

+ 40 - 0
price-collection/uni_modules/uni-icons/changelog.md

@@ -0,0 +1,40 @@
1
+## 2.0.9(2024-01-12)
2
+fix: 修复图标大小默认值错误的问题
3
+## 2.0.8(2023-12-14)
4
+- 修复 项目未使用 ts 情况下,打包报错的bug
5
+## 2.0.7(2023-12-14)
6
+- 修复 size 属性为 string 时,不加单位导致尺寸异常的bug
7
+## 2.0.6(2023-12-11)
8
+- 优化 兼容老版本icon类型,如 top ,bottom 等
9
+## 2.0.5(2023-12-11)
10
+- 优化 兼容老版本icon类型,如 top ,bottom 等
11
+## 2.0.4(2023-12-06)
12
+- 优化 uni-app x 下示例项目图标排序
13
+## 2.0.3(2023-12-06)
14
+- 修复 nvue下引入组件报错的bug
15
+## 2.0.2(2023-12-05)
16
+-优化 size 属性支持单位
17
+## 2.0.1(2023-12-05)
18
+- 新增 uni-app x 支持定义图标
19
+## 1.3.5(2022-01-24)
20
+- 优化 size 属性可以传入不带单位的字符串数值
21
+## 1.3.4(2022-01-24)
22
+- 优化 size 支持其他单位
23
+## 1.3.3(2022-01-17)
24
+- 修复 nvue 有些图标不显示的bug,兼容老版本图标
25
+## 1.3.2(2021-12-01)
26
+- 优化 示例可复制图标名称
27
+## 1.3.1(2021-11-23)
28
+- 优化 兼容旧组件 type 值
29
+## 1.3.0(2021-11-19)
30
+- 新增 更多图标
31
+- 优化 自定义图标使用方式
32
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
33
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
34
+## 1.1.7(2021-11-08)
35
+## 1.2.0(2021-07-30)
36
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
37
+## 1.1.5(2021-05-12)
38
+- 新增 组件示例地址
39
+## 1.1.4(2021-02-05)
40
+- 调整为uni_modules目录规范

+ 91 - 0
price-collection/uni_modules/uni-icons/components/uni-icons/uni-icons.uvue

@@ -0,0 +1,91 @@
1
+<template>
2
+	<text class="uni-icons" :style="styleObj">
3
+		<slot>{{unicode}}</slot>
4
+	</text>
5
+</template>
6
+
7
+<script>
8
+	import { fontData, IconsDataItem } from './uniicons_file'
9
+
10
+	/**
11
+	 * Icons 图标
12
+	 * @description 用于展示 icon 图标
13
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
14
+	 * @property {Number} size 图标大小
15
+	 * @property {String} type 图标图案,参考示例
16
+	 * @property {String} color 图标颜色
17
+	 * @property {String} customPrefix 自定义图标
18
+	 * @event {Function} click 点击 Icon 触发事件
19
+	 */
20
+	export default {
21
+		name: "uni-icons",
22
+		props: {
23
+			type: {
24
+				type: String,
25
+				default: ''
26
+			},
27
+			color: {
28
+				type: String,
29
+				default: '#333333'
30
+			},
31
+			size: {
32
+				type: Object,
33
+				default: 16
34
+			},
35
+			fontFamily: {
36
+				type: String,
37
+				default: ''
38
+			}
39
+		},
40
+		data() {
41
+			return {};
42
+		},
43
+		computed: {
44
+			unicode() : string {
45
+				let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
46
+				if (codes !== null) {
47
+					return codes.unicode
48
+				}
49
+				return ''
50
+			},
51
+			iconSize() : string {
52
+				const size = this.size
53
+				if (typeof size == 'string') {
54
+					const reg = /^[0-9]*$/g
55
+					return reg.test(size as string) ? '' + size + 'px' : '' + size;
56
+					// return '' + this.size
57
+				}
58
+				return this.getFontSize(size as number)
59
+			},
60
+			styleObj() : UTSJSONObject {
61
+				if (this.fontFamily !== '') {
62
+					return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
63
+				}
64
+				return { color: this.color, fontSize: this.iconSize }
65
+			}
66
+		},
67
+		created() { },
68
+		methods: {
69
+			/**
70
+			 * 字体大小
71
+			 */
72
+			getFontSize(size : number) : string {
73
+				return size + 'px';
74
+			},
75
+		},
76
+	}
77
+</script>
78
+
79
+<style scoped>
80
+	@font-face {
81
+		font-family: UniIconsFontFamily;
82
+		src: url('./uniicons.ttf');
83
+	}
84
+
85
+	.uni-icons {
86
+		font-family: UniIconsFontFamily;
87
+		font-size: 18px;
88
+		font-style: normal;
89
+		color: #333;
90
+	}
91
+</style>

+ 110 - 0
price-collection/uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@@ -0,0 +1,110 @@
1
+<template>
2
+	<!-- #ifdef APP-NVUE -->
3
+	<text :style="styleObj" class="uni-icons" @click="_onClick">{{unicode}}</text>
4
+	<!-- #endif -->
5
+	<!-- #ifndef APP-NVUE -->
6
+	<text :style="styleObj" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick">
7
+		<slot></slot>
8
+	</text>
9
+	<!-- #endif -->
10
+</template>
11
+
12
+<script>
13
+	import { fontData } from './uniicons_file_vue.js';
14
+
15
+	const getVal = (val) => {
16
+		const reg = /^[0-9]*$/g
17
+		return (typeof val === 'number' || reg.test(val)) ? val + 'px' : val;
18
+	}
19
+
20
+	// #ifdef APP-NVUE
21
+	var domModule = weex.requireModule('dom');
22
+	import iconUrl from './uniicons.ttf'
23
+	domModule.addRule('fontFace', {
24
+		'fontFamily': "uniicons",
25
+		'src': "url('" + iconUrl + "')"
26
+	});
27
+	// #endif
28
+
29
+	/**
30
+	 * Icons 图标
31
+	 * @description 用于展示 icons 图标
32
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
33
+	 * @property {Number} size 图标大小
34
+	 * @property {String} type 图标图案,参考示例
35
+	 * @property {String} color 图标颜色
36
+	 * @property {String} customPrefix 自定义图标
37
+	 * @event {Function} click 点击 Icon 触发事件
38
+	 */
39
+	export default {
40
+		name: 'UniIcons',
41
+		emits: ['click'],
42
+		props: {
43
+			type: {
44
+				type: String,
45
+				default: ''
46
+			},
47
+			color: {
48
+				type: String,
49
+				default: '#333333'
50
+			},
51
+			size: {
52
+				type: [Number, String],
53
+				default: 16
54
+			},
55
+			customPrefix: {
56
+				type: String,
57
+				default: ''
58
+			},
59
+			fontFamily: {
60
+				type: String,
61
+				default: ''
62
+			}
63
+		},
64
+		data() {
65
+			return {
66
+				icons: fontData
67
+			}
68
+		},
69
+		computed: {
70
+			unicode() {
71
+				let code = this.icons.find(v => v.font_class === this.type)
72
+				if (code) {
73
+					return code.unicode
74
+				}
75
+				return ''
76
+			},
77
+			iconSize() {
78
+				return getVal(this.size)
79
+			},
80
+			styleObj() {
81
+				if (this.fontFamily !== '') {
82
+					return `color: ${this.color}; font-size: ${this.iconSize}; font-family: ${this.fontFamily};`
83
+				}
84
+				return `color: ${this.color}; font-size: ${this.iconSize};`
85
+			}
86
+		},
87
+		methods: {
88
+			_onClick() {
89
+				this.$emit('click')
90
+			}
91
+		}
92
+	}
93
+</script>
94
+
95
+<style lang="scss">
96
+	/* #ifndef APP-NVUE */
97
+	@import './uniicons.css';
98
+
99
+	@font-face {
100
+		font-family: uniicons;
101
+		src: url('./uniicons.ttf');
102
+	}
103
+
104
+	/* #endif */
105
+	.uni-icons {
106
+		font-family: uniicons;
107
+		text-decoration: none;
108
+		text-align: center;
109
+	}
110
+</style>

+ 664 - 0
price-collection/uni_modules/uni-icons/components/uni-icons/uniicons.css

@@ -0,0 +1,664 @@
1
+
2
+.uniui-cart-filled:before {
3
+  content: "\e6d0";
4
+}
5
+
6
+.uniui-gift-filled:before {
7
+  content: "\e6c4";
8
+}
9
+
10
+.uniui-color:before {
11
+  content: "\e6cf";
12
+}
13
+
14
+.uniui-wallet:before {
15
+  content: "\e6b1";
16
+}
17
+
18
+.uniui-settings-filled:before {
19
+  content: "\e6ce";
20
+}
21
+
22
+.uniui-auth-filled:before {
23
+  content: "\e6cc";
24
+}
25
+
26
+.uniui-shop-filled:before {
27
+  content: "\e6cd";
28
+}
29
+
30
+.uniui-staff-filled:before {
31
+  content: "\e6cb";
32
+}
33
+
34
+.uniui-vip-filled:before {
35
+  content: "\e6c6";
36
+}
37
+
38
+.uniui-plus-filled:before {
39
+  content: "\e6c7";
40
+}
41
+
42
+.uniui-folder-add-filled:before {
43
+  content: "\e6c8";
44
+}
45
+
46
+.uniui-color-filled:before {
47
+  content: "\e6c9";
48
+}
49
+
50
+.uniui-tune-filled:before {
51
+  content: "\e6ca";
52
+}
53
+
54
+.uniui-calendar-filled:before {
55
+  content: "\e6c0";
56
+}
57
+
58
+.uniui-notification-filled:before {
59
+  content: "\e6c1";
60
+}
61
+
62
+.uniui-wallet-filled:before {
63
+  content: "\e6c2";
64
+}
65
+
66
+.uniui-medal-filled:before {
67
+  content: "\e6c3";
68
+}
69
+
70
+.uniui-fire-filled:before {
71
+  content: "\e6c5";
72
+}
73
+
74
+.uniui-refreshempty:before {
75
+  content: "\e6bf";
76
+}
77
+
78
+.uniui-location-filled:before {
79
+  content: "\e6af";
80
+}
81
+
82
+.uniui-person-filled:before {
83
+  content: "\e69d";
84
+}
85
+
86
+.uniui-personadd-filled:before {
87
+  content: "\e698";
88
+}
89
+
90
+.uniui-arrowthinleft:before {
91
+  content: "\e6d2";
92
+}
93
+
94
+.uniui-arrowthinup:before {
95
+  content: "\e6d3";
96
+}
97
+
98
+.uniui-arrowthindown:before {
99
+  content: "\e6d4";
100
+}
101
+
102
+.uniui-back:before {
103
+  content: "\e6b9";
104
+}
105
+
106
+.uniui-forward:before {
107
+  content: "\e6ba";
108
+}
109
+
110
+.uniui-arrow-right:before {
111
+  content: "\e6bb";
112
+}
113
+
114
+.uniui-arrow-left:before {
115
+  content: "\e6bc";
116
+}
117
+
118
+.uniui-arrow-up:before {
119
+  content: "\e6bd";
120
+}
121
+
122
+.uniui-arrow-down:before {
123
+  content: "\e6be";
124
+}
125
+
126
+.uniui-arrowthinright:before {
127
+  content: "\e6d1";
128
+}
129
+
130
+.uniui-down:before {
131
+  content: "\e6b8";
132
+}
133
+
134
+.uniui-bottom:before {
135
+  content: "\e6b8";
136
+}
137
+
138
+.uniui-arrowright:before {
139
+  content: "\e6d5";
140
+}
141
+
142
+.uniui-right:before {
143
+  content: "\e6b5";
144
+}
145
+
146
+.uniui-up:before {
147
+  content: "\e6b6";
148
+}
149
+
150
+.uniui-top:before {
151
+  content: "\e6b6";
152
+}
153
+
154
+.uniui-left:before {
155
+  content: "\e6b7";
156
+}
157
+
158
+.uniui-arrowup:before {
159
+  content: "\e6d6";
160
+}
161
+
162
+.uniui-eye:before {
163
+  content: "\e651";
164
+}
165
+
166
+.uniui-eye-filled:before {
167
+  content: "\e66a";
168
+}
169
+
170
+.uniui-eye-slash:before {
171
+  content: "\e6b3";
172
+}
173
+
174
+.uniui-eye-slash-filled:before {
175
+  content: "\e6b4";
176
+}
177
+
178
+.uniui-info-filled:before {
179
+  content: "\e649";
180
+}
181
+
182
+.uniui-reload:before {
183
+  content: "\e6b2";
184
+}
185
+
186
+.uniui-micoff-filled:before {
187
+  content: "\e6b0";
188
+}
189
+
190
+.uniui-map-pin-ellipse:before {
191
+  content: "\e6ac";
192
+}
193
+
194
+.uniui-map-pin:before {
195
+  content: "\e6ad";
196
+}
197
+
198
+.uniui-location:before {
199
+  content: "\e6ae";
200
+}
201
+
202
+.uniui-starhalf:before {
203
+  content: "\e683";
204
+}
205
+
206
+.uniui-star:before {
207
+  content: "\e688";
208
+}
209
+
210
+.uniui-star-filled:before {
211
+  content: "\e68f";
212
+}
213
+
214
+.uniui-calendar:before {
215
+  content: "\e6a0";
216
+}
217
+
218
+.uniui-fire:before {
219
+  content: "\e6a1";
220
+}
221
+
222
+.uniui-medal:before {
223
+  content: "\e6a2";
224
+}
225
+
226
+.uniui-font:before {
227
+  content: "\e6a3";
228
+}
229
+
230
+.uniui-gift:before {
231
+  content: "\e6a4";
232
+}
233
+
234
+.uniui-link:before {
235
+  content: "\e6a5";
236
+}
237
+
238
+.uniui-notification:before {
239
+  content: "\e6a6";
240
+}
241
+
242
+.uniui-staff:before {
243
+  content: "\e6a7";
244
+}
245
+
246
+.uniui-vip:before {
247
+  content: "\e6a8";
248
+}
249
+
250
+.uniui-folder-add:before {
251
+  content: "\e6a9";
252
+}
253
+
254
+.uniui-tune:before {
255
+  content: "\e6aa";
256
+}
257
+
258
+.uniui-auth:before {
259
+  content: "\e6ab";
260
+}
261
+
262
+.uniui-person:before {
263
+  content: "\e699";
264
+}
265
+
266
+.uniui-email-filled:before {
267
+  content: "\e69a";
268
+}
269
+
270
+.uniui-phone-filled:before {
271
+  content: "\e69b";
272
+}
273
+
274
+.uniui-phone:before {
275
+  content: "\e69c";
276
+}
277
+
278
+.uniui-email:before {
279
+  content: "\e69e";
280
+}
281
+
282
+.uniui-personadd:before {
283
+  content: "\e69f";
284
+}
285
+
286
+.uniui-chatboxes-filled:before {
287
+  content: "\e692";
288
+}
289
+
290
+.uniui-contact:before {
291
+  content: "\e693";
292
+}
293
+
294
+.uniui-chatbubble-filled:before {
295
+  content: "\e694";
296
+}
297
+
298
+.uniui-contact-filled:before {
299
+  content: "\e695";
300
+}
301
+
302
+.uniui-chatboxes:before {
303
+  content: "\e696";
304
+}
305
+
306
+.uniui-chatbubble:before {
307
+  content: "\e697";
308
+}
309
+
310
+.uniui-upload-filled:before {
311
+  content: "\e68e";
312
+}
313
+
314
+.uniui-upload:before {
315
+  content: "\e690";
316
+}
317
+
318
+.uniui-weixin:before {
319
+  content: "\e691";
320
+}
321
+
322
+.uniui-compose:before {
323
+  content: "\e67f";
324
+}
325
+
326
+.uniui-qq:before {
327
+  content: "\e680";
328
+}
329
+
330
+.uniui-download-filled:before {
331
+  content: "\e681";
332
+}
333
+
334
+.uniui-pyq:before {
335
+  content: "\e682";
336
+}
337
+
338
+.uniui-sound:before {
339
+  content: "\e684";
340
+}
341
+
342
+.uniui-trash-filled:before {
343
+  content: "\e685";
344
+}
345
+
346
+.uniui-sound-filled:before {
347
+  content: "\e686";
348
+}
349
+
350
+.uniui-trash:before {
351
+  content: "\e687";
352
+}
353
+
354
+.uniui-videocam-filled:before {
355
+  content: "\e689";
356
+}
357
+
358
+.uniui-spinner-cycle:before {
359
+  content: "\e68a";
360
+}
361
+
362
+.uniui-weibo:before {
363
+  content: "\e68b";
364
+}
365
+
366
+.uniui-videocam:before {
367
+  content: "\e68c";
368
+}
369
+
370
+.uniui-download:before {
371
+  content: "\e68d";
372
+}
373
+
374
+.uniui-help:before {
375
+  content: "\e679";
376
+}
377
+
378
+.uniui-navigate-filled:before {
379
+  content: "\e67a";
380
+}
381
+
382
+.uniui-plusempty:before {
383
+  content: "\e67b";
384
+}
385
+
386
+.uniui-smallcircle:before {
387
+  content: "\e67c";
388
+}
389
+
390
+.uniui-minus-filled:before {
391
+  content: "\e67d";
392
+}
393
+
394
+.uniui-micoff:before {
395
+  content: "\e67e";
396
+}
397
+
398
+.uniui-closeempty:before {
399
+  content: "\e66c";
400
+}
401
+
402
+.uniui-clear:before {
403
+  content: "\e66d";
404
+}
405
+
406
+.uniui-navigate:before {
407
+  content: "\e66e";
408
+}
409
+
410
+.uniui-minus:before {
411
+  content: "\e66f";
412
+}
413
+
414
+.uniui-image:before {
415
+  content: "\e670";
416
+}
417
+
418
+.uniui-mic:before {
419
+  content: "\e671";
420
+}
421
+
422
+.uniui-paperplane:before {
423
+  content: "\e672";
424
+}
425
+
426
+.uniui-close:before {
427
+  content: "\e673";
428
+}
429
+
430
+.uniui-help-filled:before {
431
+  content: "\e674";
432
+}
433
+
434
+.uniui-paperplane-filled:before {
435
+  content: "\e675";
436
+}
437
+
438
+.uniui-plus:before {
439
+  content: "\e676";
440
+}
441
+
442
+.uniui-mic-filled:before {
443
+  content: "\e677";
444
+}
445
+
446
+.uniui-image-filled:before {
447
+  content: "\e678";
448
+}
449
+
450
+.uniui-locked-filled:before {
451
+  content: "\e668";
452
+}
453
+
454
+.uniui-info:before {
455
+  content: "\e669";
456
+}
457
+
458
+.uniui-locked:before {
459
+  content: "\e66b";
460
+}
461
+
462
+.uniui-camera-filled:before {
463
+  content: "\e658";
464
+}
465
+
466
+.uniui-chat-filled:before {
467
+  content: "\e659";
468
+}
469
+
470
+.uniui-camera:before {
471
+  content: "\e65a";
472
+}
473
+
474
+.uniui-circle:before {
475
+  content: "\e65b";
476
+}
477
+
478
+.uniui-checkmarkempty:before {
479
+  content: "\e65c";
480
+}
481
+
482
+.uniui-chat:before {
483
+  content: "\e65d";
484
+}
485
+
486
+.uniui-circle-filled:before {
487
+  content: "\e65e";
488
+}
489
+
490
+.uniui-flag:before {
491
+  content: "\e65f";
492
+}
493
+
494
+.uniui-flag-filled:before {
495
+  content: "\e660";
496
+}
497
+
498
+.uniui-gear-filled:before {
499
+  content: "\e661";
500
+}
501
+
502
+.uniui-home:before {
503
+  content: "\e662";
504
+}
505
+
506
+.uniui-home-filled:before {
507
+  content: "\e663";
508
+}
509
+
510
+.uniui-gear:before {
511
+  content: "\e664";
512
+}
513
+
514
+.uniui-smallcircle-filled:before {
515
+  content: "\e665";
516
+}
517
+
518
+.uniui-map-filled:before {
519
+  content: "\e666";
520
+}
521
+
522
+.uniui-map:before {
523
+  content: "\e667";
524
+}
525
+
526
+.uniui-refresh-filled:before {
527
+  content: "\e656";
528
+}
529
+
530
+.uniui-refresh:before {
531
+  content: "\e657";
532
+}
533
+
534
+.uniui-cloud-upload:before {
535
+  content: "\e645";
536
+}
537
+
538
+.uniui-cloud-download-filled:before {
539
+  content: "\e646";
540
+}
541
+
542
+.uniui-cloud-download:before {
543
+  content: "\e647";
544
+}
545
+
546
+.uniui-cloud-upload-filled:before {
547
+  content: "\e648";
548
+}
549
+
550
+.uniui-redo:before {
551
+  content: "\e64a";
552
+}
553
+
554
+.uniui-images-filled:before {
555
+  content: "\e64b";
556
+}
557
+
558
+.uniui-undo-filled:before {
559
+  content: "\e64c";
560
+}
561
+
562
+.uniui-more:before {
563
+  content: "\e64d";
564
+}
565
+
566
+.uniui-more-filled:before {
567
+  content: "\e64e";
568
+}
569
+
570
+.uniui-undo:before {
571
+  content: "\e64f";
572
+}
573
+
574
+.uniui-images:before {
575
+  content: "\e650";
576
+}
577
+
578
+.uniui-paperclip:before {
579
+  content: "\e652";
580
+}
581
+
582
+.uniui-settings:before {
583
+  content: "\e653";
584
+}
585
+
586
+.uniui-search:before {
587
+  content: "\e654";
588
+}
589
+
590
+.uniui-redo-filled:before {
591
+  content: "\e655";
592
+}
593
+
594
+.uniui-list:before {
595
+  content: "\e644";
596
+}
597
+
598
+.uniui-mail-open-filled:before {
599
+  content: "\e63a";
600
+}
601
+
602
+.uniui-hand-down-filled:before {
603
+  content: "\e63c";
604
+}
605
+
606
+.uniui-hand-down:before {
607
+  content: "\e63d";
608
+}
609
+
610
+.uniui-hand-up-filled:before {
611
+  content: "\e63e";
612
+}
613
+
614
+.uniui-hand-up:before {
615
+  content: "\e63f";
616
+}
617
+
618
+.uniui-heart-filled:before {
619
+  content: "\e641";
620
+}
621
+
622
+.uniui-mail-open:before {
623
+  content: "\e643";
624
+}
625
+
626
+.uniui-heart:before {
627
+  content: "\e639";
628
+}
629
+
630
+.uniui-loop:before {
631
+  content: "\e633";
632
+}
633
+
634
+.uniui-pulldown:before {
635
+  content: "\e632";
636
+}
637
+
638
+.uniui-scan:before {
639
+  content: "\e62a";
640
+}
641
+
642
+.uniui-bars:before {
643
+  content: "\e627";
644
+}
645
+
646
+.uniui-checkbox:before {
647
+  content: "\e62b";
648
+}
649
+
650
+.uniui-checkbox-filled:before {
651
+  content: "\e62c";
652
+}
653
+
654
+.uniui-shop:before {
655
+  content: "\e62f";
656
+}
657
+
658
+.uniui-headphones:before {
659
+  content: "\e630";
660
+}
661
+
662
+.uniui-cart:before {
663
+  content: "\e631";
664
+}

BIN
price-collection/uni_modules/uni-icons/components/uni-icons/uniicons.ttf


+ 664 - 0
price-collection/uni_modules/uni-icons/components/uni-icons/uniicons_file.ts

@@ -0,0 +1,664 @@
1
+
2
+export type IconsData = {
3
+	id : string
4
+	name : string
5
+	font_family : string
6
+	css_prefix_text : string
7
+	description : string
8
+	glyphs : Array<IconsDataItem>
9
+}
10
+
11
+export type IconsDataItem = {
12
+	font_class : string
13
+	unicode : string
14
+}
15
+
16
+
17
+export const fontData = [
18
+  {
19
+    "font_class": "arrow-down",
20
+    "unicode": "\ue6be"
21
+  },
22
+  {
23
+    "font_class": "arrow-left",
24
+    "unicode": "\ue6bc"
25
+  },
26
+  {
27
+    "font_class": "arrow-right",
28
+    "unicode": "\ue6bb"
29
+  },
30
+  {
31
+    "font_class": "arrow-up",
32
+    "unicode": "\ue6bd"
33
+  },
34
+  {
35
+    "font_class": "auth",
36
+    "unicode": "\ue6ab"
37
+  },
38
+  {
39
+    "font_class": "auth-filled",
40
+    "unicode": "\ue6cc"
41
+  },
42
+  {
43
+    "font_class": "back",
44
+    "unicode": "\ue6b9"
45
+  },
46
+  {
47
+    "font_class": "bars",
48
+    "unicode": "\ue627"
49
+  },
50
+  {
51
+    "font_class": "calendar",
52
+    "unicode": "\ue6a0"
53
+  },
54
+  {
55
+    "font_class": "calendar-filled",
56
+    "unicode": "\ue6c0"
57
+  },
58
+  {
59
+    "font_class": "camera",
60
+    "unicode": "\ue65a"
61
+  },
62
+  {
63
+    "font_class": "camera-filled",
64
+    "unicode": "\ue658"
65
+  },
66
+  {
67
+    "font_class": "cart",
68
+    "unicode": "\ue631"
69
+  },
70
+  {
71
+    "font_class": "cart-filled",
72
+    "unicode": "\ue6d0"
73
+  },
74
+  {
75
+    "font_class": "chat",
76
+    "unicode": "\ue65d"
77
+  },
78
+  {
79
+    "font_class": "chat-filled",
80
+    "unicode": "\ue659"
81
+  },
82
+  {
83
+    "font_class": "chatboxes",
84
+    "unicode": "\ue696"
85
+  },
86
+  {
87
+    "font_class": "chatboxes-filled",
88
+    "unicode": "\ue692"
89
+  },
90
+  {
91
+    "font_class": "chatbubble",
92
+    "unicode": "\ue697"
93
+  },
94
+  {
95
+    "font_class": "chatbubble-filled",
96
+    "unicode": "\ue694"
97
+  },
98
+  {
99
+    "font_class": "checkbox",
100
+    "unicode": "\ue62b"
101
+  },
102
+  {
103
+    "font_class": "checkbox-filled",
104
+    "unicode": "\ue62c"
105
+  },
106
+  {
107
+    "font_class": "checkmarkempty",
108
+    "unicode": "\ue65c"
109
+  },
110
+  {
111
+    "font_class": "circle",
112
+    "unicode": "\ue65b"
113
+  },
114
+  {
115
+    "font_class": "circle-filled",
116
+    "unicode": "\ue65e"
117
+  },
118
+  {
119
+    "font_class": "clear",
120
+    "unicode": "\ue66d"
121
+  },
122
+  {
123
+    "font_class": "close",
124
+    "unicode": "\ue673"
125
+  },
126
+  {
127
+    "font_class": "closeempty",
128
+    "unicode": "\ue66c"
129
+  },
130
+  {
131
+    "font_class": "cloud-download",
132
+    "unicode": "\ue647"
133
+  },
134
+  {
135
+    "font_class": "cloud-download-filled",
136
+    "unicode": "\ue646"
137
+  },
138
+  {
139
+    "font_class": "cloud-upload",
140
+    "unicode": "\ue645"
141
+  },
142
+  {
143
+    "font_class": "cloud-upload-filled",
144
+    "unicode": "\ue648"
145
+  },
146
+  {
147
+    "font_class": "color",
148
+    "unicode": "\ue6cf"
149
+  },
150
+  {
151
+    "font_class": "color-filled",
152
+    "unicode": "\ue6c9"
153
+  },
154
+  {
155
+    "font_class": "compose",
156
+    "unicode": "\ue67f"
157
+  },
158
+  {
159
+    "font_class": "contact",
160
+    "unicode": "\ue693"
161
+  },
162
+  {
163
+    "font_class": "contact-filled",
164
+    "unicode": "\ue695"
165
+  },
166
+  {
167
+    "font_class": "down",
168
+    "unicode": "\ue6b8"
169
+  },
170
+	{
171
+	  "font_class": "bottom",
172
+	  "unicode": "\ue6b8"
173
+	},
174
+  {
175
+    "font_class": "download",
176
+    "unicode": "\ue68d"
177
+  },
178
+  {
179
+    "font_class": "download-filled",
180
+    "unicode": "\ue681"
181
+  },
182
+  {
183
+    "font_class": "email",
184
+    "unicode": "\ue69e"
185
+  },
186
+  {
187
+    "font_class": "email-filled",
188
+    "unicode": "\ue69a"
189
+  },
190
+  {
191
+    "font_class": "eye",
192
+    "unicode": "\ue651"
193
+  },
194
+  {
195
+    "font_class": "eye-filled",
196
+    "unicode": "\ue66a"
197
+  },
198
+  {
199
+    "font_class": "eye-slash",
200
+    "unicode": "\ue6b3"
201
+  },
202
+  {
203
+    "font_class": "eye-slash-filled",
204
+    "unicode": "\ue6b4"
205
+  },
206
+  {
207
+    "font_class": "fire",
208
+    "unicode": "\ue6a1"
209
+  },
210
+  {
211
+    "font_class": "fire-filled",
212
+    "unicode": "\ue6c5"
213
+  },
214
+  {
215
+    "font_class": "flag",
216
+    "unicode": "\ue65f"
217
+  },
218
+  {
219
+    "font_class": "flag-filled",
220
+    "unicode": "\ue660"
221
+  },
222
+  {
223
+    "font_class": "folder-add",
224
+    "unicode": "\ue6a9"
225
+  },
226
+  {
227
+    "font_class": "folder-add-filled",
228
+    "unicode": "\ue6c8"
229
+  },
230
+  {
231
+    "font_class": "font",
232
+    "unicode": "\ue6a3"
233
+  },
234
+  {
235
+    "font_class": "forward",
236
+    "unicode": "\ue6ba"
237
+  },
238
+  {
239
+    "font_class": "gear",
240
+    "unicode": "\ue664"
241
+  },
242
+  {
243
+    "font_class": "gear-filled",
244
+    "unicode": "\ue661"
245
+  },
246
+  {
247
+    "font_class": "gift",
248
+    "unicode": "\ue6a4"
249
+  },
250
+  {
251
+    "font_class": "gift-filled",
252
+    "unicode": "\ue6c4"
253
+  },
254
+  {
255
+    "font_class": "hand-down",
256
+    "unicode": "\ue63d"
257
+  },
258
+  {
259
+    "font_class": "hand-down-filled",
260
+    "unicode": "\ue63c"
261
+  },
262
+  {
263
+    "font_class": "hand-up",
264
+    "unicode": "\ue63f"
265
+  },
266
+  {
267
+    "font_class": "hand-up-filled",
268
+    "unicode": "\ue63e"
269
+  },
270
+  {
271
+    "font_class": "headphones",
272
+    "unicode": "\ue630"
273
+  },
274
+  {
275
+    "font_class": "heart",
276
+    "unicode": "\ue639"
277
+  },
278
+  {
279
+    "font_class": "heart-filled",
280
+    "unicode": "\ue641"
281
+  },
282
+  {
283
+    "font_class": "help",
284
+    "unicode": "\ue679"
285
+  },
286
+  {
287
+    "font_class": "help-filled",
288
+    "unicode": "\ue674"
289
+  },
290
+  {
291
+    "font_class": "home",
292
+    "unicode": "\ue662"
293
+  },
294
+  {
295
+    "font_class": "home-filled",
296
+    "unicode": "\ue663"
297
+  },
298
+  {
299
+    "font_class": "image",
300
+    "unicode": "\ue670"
301
+  },
302
+  {
303
+    "font_class": "image-filled",
304
+    "unicode": "\ue678"
305
+  },
306
+  {
307
+    "font_class": "images",
308
+    "unicode": "\ue650"
309
+  },
310
+  {
311
+    "font_class": "images-filled",
312
+    "unicode": "\ue64b"
313
+  },
314
+  {
315
+    "font_class": "info",
316
+    "unicode": "\ue669"
317
+  },
318
+  {
319
+    "font_class": "info-filled",
320
+    "unicode": "\ue649"
321
+  },
322
+  {
323
+    "font_class": "left",
324
+    "unicode": "\ue6b7"
325
+  },
326
+  {
327
+    "font_class": "link",
328
+    "unicode": "\ue6a5"
329
+  },
330
+  {
331
+    "font_class": "list",
332
+    "unicode": "\ue644"
333
+  },
334
+  {
335
+    "font_class": "location",
336
+    "unicode": "\ue6ae"
337
+  },
338
+  {
339
+    "font_class": "location-filled",
340
+    "unicode": "\ue6af"
341
+  },
342
+  {
343
+    "font_class": "locked",
344
+    "unicode": "\ue66b"
345
+  },
346
+  {
347
+    "font_class": "locked-filled",
348
+    "unicode": "\ue668"
349
+  },
350
+  {
351
+    "font_class": "loop",
352
+    "unicode": "\ue633"
353
+  },
354
+  {
355
+    "font_class": "mail-open",
356
+    "unicode": "\ue643"
357
+  },
358
+  {
359
+    "font_class": "mail-open-filled",
360
+    "unicode": "\ue63a"
361
+  },
362
+  {
363
+    "font_class": "map",
364
+    "unicode": "\ue667"
365
+  },
366
+  {
367
+    "font_class": "map-filled",
368
+    "unicode": "\ue666"
369
+  },
370
+  {
371
+    "font_class": "map-pin",
372
+    "unicode": "\ue6ad"
373
+  },
374
+  {
375
+    "font_class": "map-pin-ellipse",
376
+    "unicode": "\ue6ac"
377
+  },
378
+  {
379
+    "font_class": "medal",
380
+    "unicode": "\ue6a2"
381
+  },
382
+  {
383
+    "font_class": "medal-filled",
384
+    "unicode": "\ue6c3"
385
+  },
386
+  {
387
+    "font_class": "mic",
388
+    "unicode": "\ue671"
389
+  },
390
+  {
391
+    "font_class": "mic-filled",
392
+    "unicode": "\ue677"
393
+  },
394
+  {
395
+    "font_class": "micoff",
396
+    "unicode": "\ue67e"
397
+  },
398
+  {
399
+    "font_class": "micoff-filled",
400
+    "unicode": "\ue6b0"
401
+  },
402
+  {
403
+    "font_class": "minus",
404
+    "unicode": "\ue66f"
405
+  },
406
+  {
407
+    "font_class": "minus-filled",
408
+    "unicode": "\ue67d"
409
+  },
410
+  {
411
+    "font_class": "more",
412
+    "unicode": "\ue64d"
413
+  },
414
+  {
415
+    "font_class": "more-filled",
416
+    "unicode": "\ue64e"
417
+  },
418
+  {
419
+    "font_class": "navigate",
420
+    "unicode": "\ue66e"
421
+  },
422
+  {
423
+    "font_class": "navigate-filled",
424
+    "unicode": "\ue67a"
425
+  },
426
+  {
427
+    "font_class": "notification",
428
+    "unicode": "\ue6a6"
429
+  },
430
+  {
431
+    "font_class": "notification-filled",
432
+    "unicode": "\ue6c1"
433
+  },
434
+  {
435
+    "font_class": "paperclip",
436
+    "unicode": "\ue652"
437
+  },
438
+  {
439
+    "font_class": "paperplane",
440
+    "unicode": "\ue672"
441
+  },
442
+  {
443
+    "font_class": "paperplane-filled",
444
+    "unicode": "\ue675"
445
+  },
446
+  {
447
+    "font_class": "person",
448
+    "unicode": "\ue699"
449
+  },
450
+  {
451
+    "font_class": "person-filled",
452
+    "unicode": "\ue69d"
453
+  },
454
+  {
455
+    "font_class": "personadd",
456
+    "unicode": "\ue69f"
457
+  },
458
+  {
459
+    "font_class": "personadd-filled",
460
+    "unicode": "\ue698"
461
+  },
462
+  {
463
+    "font_class": "personadd-filled-copy",
464
+    "unicode": "\ue6d1"
465
+  },
466
+  {
467
+    "font_class": "phone",
468
+    "unicode": "\ue69c"
469
+  },
470
+  {
471
+    "font_class": "phone-filled",
472
+    "unicode": "\ue69b"
473
+  },
474
+  {
475
+    "font_class": "plus",
476
+    "unicode": "\ue676"
477
+  },
478
+  {
479
+    "font_class": "plus-filled",
480
+    "unicode": "\ue6c7"
481
+  },
482
+  {
483
+    "font_class": "plusempty",
484
+    "unicode": "\ue67b"
485
+  },
486
+  {
487
+    "font_class": "pulldown",
488
+    "unicode": "\ue632"
489
+  },
490
+  {
491
+    "font_class": "pyq",
492
+    "unicode": "\ue682"
493
+  },
494
+  {
495
+    "font_class": "qq",
496
+    "unicode": "\ue680"
497
+  },
498
+  {
499
+    "font_class": "redo",
500
+    "unicode": "\ue64a"
501
+  },
502
+  {
503
+    "font_class": "redo-filled",
504
+    "unicode": "\ue655"
505
+  },
506
+  {
507
+    "font_class": "refresh",
508
+    "unicode": "\ue657"
509
+  },
510
+  {
511
+    "font_class": "refresh-filled",
512
+    "unicode": "\ue656"
513
+  },
514
+  {
515
+    "font_class": "refreshempty",
516
+    "unicode": "\ue6bf"
517
+  },
518
+  {
519
+    "font_class": "reload",
520
+    "unicode": "\ue6b2"
521
+  },
522
+  {
523
+    "font_class": "right",
524
+    "unicode": "\ue6b5"
525
+  },
526
+  {
527
+    "font_class": "scan",
528
+    "unicode": "\ue62a"
529
+  },
530
+  {
531
+    "font_class": "search",
532
+    "unicode": "\ue654"
533
+  },
534
+  {
535
+    "font_class": "settings",
536
+    "unicode": "\ue653"
537
+  },
538
+  {
539
+    "font_class": "settings-filled",
540
+    "unicode": "\ue6ce"
541
+  },
542
+  {
543
+    "font_class": "shop",
544
+    "unicode": "\ue62f"
545
+  },
546
+  {
547
+    "font_class": "shop-filled",
548
+    "unicode": "\ue6cd"
549
+  },
550
+  {
551
+    "font_class": "smallcircle",
552
+    "unicode": "\ue67c"
553
+  },
554
+  {
555
+    "font_class": "smallcircle-filled",
556
+    "unicode": "\ue665"
557
+  },
558
+  {
559
+    "font_class": "sound",
560
+    "unicode": "\ue684"
561
+  },
562
+  {
563
+    "font_class": "sound-filled",
564
+    "unicode": "\ue686"
565
+  },
566
+  {
567
+    "font_class": "spinner-cycle",
568
+    "unicode": "\ue68a"
569
+  },
570
+  {
571
+    "font_class": "staff",
572
+    "unicode": "\ue6a7"
573
+  },
574
+  {
575
+    "font_class": "staff-filled",
576
+    "unicode": "\ue6cb"
577
+  },
578
+  {
579
+    "font_class": "star",
580
+    "unicode": "\ue688"
581
+  },
582
+  {
583
+    "font_class": "star-filled",
584
+    "unicode": "\ue68f"
585
+  },
586
+  {
587
+    "font_class": "starhalf",
588
+    "unicode": "\ue683"
589
+  },
590
+  {
591
+    "font_class": "trash",
592
+    "unicode": "\ue687"
593
+  },
594
+  {
595
+    "font_class": "trash-filled",
596
+    "unicode": "\ue685"
597
+  },
598
+  {
599
+    "font_class": "tune",
600
+    "unicode": "\ue6aa"
601
+  },
602
+  {
603
+    "font_class": "tune-filled",
604
+    "unicode": "\ue6ca"
605
+  },
606
+  {
607
+    "font_class": "undo",
608
+    "unicode": "\ue64f"
609
+  },
610
+  {
611
+    "font_class": "undo-filled",
612
+    "unicode": "\ue64c"
613
+  },
614
+  {
615
+    "font_class": "up",
616
+    "unicode": "\ue6b6"
617
+  },
618
+	{
619
+	  "font_class": "top",
620
+	  "unicode": "\ue6b6"
621
+	},
622
+  {
623
+    "font_class": "upload",
624
+    "unicode": "\ue690"
625
+  },
626
+  {
627
+    "font_class": "upload-filled",
628
+    "unicode": "\ue68e"
629
+  },
630
+  {
631
+    "font_class": "videocam",
632
+    "unicode": "\ue68c"
633
+  },
634
+  {
635
+    "font_class": "videocam-filled",
636
+    "unicode": "\ue689"
637
+  },
638
+  {
639
+    "font_class": "vip",
640
+    "unicode": "\ue6a8"
641
+  },
642
+  {
643
+    "font_class": "vip-filled",
644
+    "unicode": "\ue6c6"
645
+  },
646
+  {
647
+    "font_class": "wallet",
648
+    "unicode": "\ue6b1"
649
+  },
650
+  {
651
+    "font_class": "wallet-filled",
652
+    "unicode": "\ue6c2"
653
+  },
654
+  {
655
+    "font_class": "weibo",
656
+    "unicode": "\ue68b"
657
+  },
658
+  {
659
+    "font_class": "weixin",
660
+    "unicode": "\ue691"
661
+  }
662
+] as IconsDataItem[]
663
+
664
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 649 - 0
price-collection/uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js

@@ -0,0 +1,649 @@
1
+
2
+export const fontData = [
3
+  {
4
+    "font_class": "arrow-down",
5
+    "unicode": "\ue6be"
6
+  },
7
+  {
8
+    "font_class": "arrow-left",
9
+    "unicode": "\ue6bc"
10
+  },
11
+  {
12
+    "font_class": "arrow-right",
13
+    "unicode": "\ue6bb"
14
+  },
15
+  {
16
+    "font_class": "arrow-up",
17
+    "unicode": "\ue6bd"
18
+  },
19
+  {
20
+    "font_class": "auth",
21
+    "unicode": "\ue6ab"
22
+  },
23
+  {
24
+    "font_class": "auth-filled",
25
+    "unicode": "\ue6cc"
26
+  },
27
+  {
28
+    "font_class": "back",
29
+    "unicode": "\ue6b9"
30
+  },
31
+  {
32
+    "font_class": "bars",
33
+    "unicode": "\ue627"
34
+  },
35
+  {
36
+    "font_class": "calendar",
37
+    "unicode": "\ue6a0"
38
+  },
39
+  {
40
+    "font_class": "calendar-filled",
41
+    "unicode": "\ue6c0"
42
+  },
43
+  {
44
+    "font_class": "camera",
45
+    "unicode": "\ue65a"
46
+  },
47
+  {
48
+    "font_class": "camera-filled",
49
+    "unicode": "\ue658"
50
+  },
51
+  {
52
+    "font_class": "cart",
53
+    "unicode": "\ue631"
54
+  },
55
+  {
56
+    "font_class": "cart-filled",
57
+    "unicode": "\ue6d0"
58
+  },
59
+  {
60
+    "font_class": "chat",
61
+    "unicode": "\ue65d"
62
+  },
63
+  {
64
+    "font_class": "chat-filled",
65
+    "unicode": "\ue659"
66
+  },
67
+  {
68
+    "font_class": "chatboxes",
69
+    "unicode": "\ue696"
70
+  },
71
+  {
72
+    "font_class": "chatboxes-filled",
73
+    "unicode": "\ue692"
74
+  },
75
+  {
76
+    "font_class": "chatbubble",
77
+    "unicode": "\ue697"
78
+  },
79
+  {
80
+    "font_class": "chatbubble-filled",
81
+    "unicode": "\ue694"
82
+  },
83
+  {
84
+    "font_class": "checkbox",
85
+    "unicode": "\ue62b"
86
+  },
87
+  {
88
+    "font_class": "checkbox-filled",
89
+    "unicode": "\ue62c"
90
+  },
91
+  {
92
+    "font_class": "checkmarkempty",
93
+    "unicode": "\ue65c"
94
+  },
95
+  {
96
+    "font_class": "circle",
97
+    "unicode": "\ue65b"
98
+  },
99
+  {
100
+    "font_class": "circle-filled",
101
+    "unicode": "\ue65e"
102
+  },
103
+  {
104
+    "font_class": "clear",
105
+    "unicode": "\ue66d"
106
+  },
107
+  {
108
+    "font_class": "close",
109
+    "unicode": "\ue673"
110
+  },
111
+  {
112
+    "font_class": "closeempty",
113
+    "unicode": "\ue66c"
114
+  },
115
+  {
116
+    "font_class": "cloud-download",
117
+    "unicode": "\ue647"
118
+  },
119
+  {
120
+    "font_class": "cloud-download-filled",
121
+    "unicode": "\ue646"
122
+  },
123
+  {
124
+    "font_class": "cloud-upload",
125
+    "unicode": "\ue645"
126
+  },
127
+  {
128
+    "font_class": "cloud-upload-filled",
129
+    "unicode": "\ue648"
130
+  },
131
+  {
132
+    "font_class": "color",
133
+    "unicode": "\ue6cf"
134
+  },
135
+  {
136
+    "font_class": "color-filled",
137
+    "unicode": "\ue6c9"
138
+  },
139
+  {
140
+    "font_class": "compose",
141
+    "unicode": "\ue67f"
142
+  },
143
+  {
144
+    "font_class": "contact",
145
+    "unicode": "\ue693"
146
+  },
147
+  {
148
+    "font_class": "contact-filled",
149
+    "unicode": "\ue695"
150
+  },
151
+  {
152
+    "font_class": "down",
153
+    "unicode": "\ue6b8"
154
+  },
155
+	{
156
+	  "font_class": "bottom",
157
+	  "unicode": "\ue6b8"
158
+	},
159
+  {
160
+    "font_class": "download",
161
+    "unicode": "\ue68d"
162
+  },
163
+  {
164
+    "font_class": "download-filled",
165
+    "unicode": "\ue681"
166
+  },
167
+  {
168
+    "font_class": "email",
169
+    "unicode": "\ue69e"
170
+  },
171
+  {
172
+    "font_class": "email-filled",
173
+    "unicode": "\ue69a"
174
+  },
175
+  {
176
+    "font_class": "eye",
177
+    "unicode": "\ue651"
178
+  },
179
+  {
180
+    "font_class": "eye-filled",
181
+    "unicode": "\ue66a"
182
+  },
183
+  {
184
+    "font_class": "eye-slash",
185
+    "unicode": "\ue6b3"
186
+  },
187
+  {
188
+    "font_class": "eye-slash-filled",
189
+    "unicode": "\ue6b4"
190
+  },
191
+  {
192
+    "font_class": "fire",
193
+    "unicode": "\ue6a1"
194
+  },
195
+  {
196
+    "font_class": "fire-filled",
197
+    "unicode": "\ue6c5"
198
+  },
199
+  {
200
+    "font_class": "flag",
201
+    "unicode": "\ue65f"
202
+  },
203
+  {
204
+    "font_class": "flag-filled",
205
+    "unicode": "\ue660"
206
+  },
207
+  {
208
+    "font_class": "folder-add",
209
+    "unicode": "\ue6a9"
210
+  },
211
+  {
212
+    "font_class": "folder-add-filled",
213
+    "unicode": "\ue6c8"
214
+  },
215
+  {
216
+    "font_class": "font",
217
+    "unicode": "\ue6a3"
218
+  },
219
+  {
220
+    "font_class": "forward",
221
+    "unicode": "\ue6ba"
222
+  },
223
+  {
224
+    "font_class": "gear",
225
+    "unicode": "\ue664"
226
+  },
227
+  {
228
+    "font_class": "gear-filled",
229
+    "unicode": "\ue661"
230
+  },
231
+  {
232
+    "font_class": "gift",
233
+    "unicode": "\ue6a4"
234
+  },
235
+  {
236
+    "font_class": "gift-filled",
237
+    "unicode": "\ue6c4"
238
+  },
239
+  {
240
+    "font_class": "hand-down",
241
+    "unicode": "\ue63d"
242
+  },
243
+  {
244
+    "font_class": "hand-down-filled",
245
+    "unicode": "\ue63c"
246
+  },
247
+  {
248
+    "font_class": "hand-up",
249
+    "unicode": "\ue63f"
250
+  },
251
+  {
252
+    "font_class": "hand-up-filled",
253
+    "unicode": "\ue63e"
254
+  },
255
+  {
256
+    "font_class": "headphones",
257
+    "unicode": "\ue630"
258
+  },
259
+  {
260
+    "font_class": "heart",
261
+    "unicode": "\ue639"
262
+  },
263
+  {
264
+    "font_class": "heart-filled",
265
+    "unicode": "\ue641"
266
+  },
267
+  {
268
+    "font_class": "help",
269
+    "unicode": "\ue679"
270
+  },
271
+  {
272
+    "font_class": "help-filled",
273
+    "unicode": "\ue674"
274
+  },
275
+  {
276
+    "font_class": "home",
277
+    "unicode": "\ue662"
278
+  },
279
+  {
280
+    "font_class": "home-filled",
281
+    "unicode": "\ue663"
282
+  },
283
+  {
284
+    "font_class": "image",
285
+    "unicode": "\ue670"
286
+  },
287
+  {
288
+    "font_class": "image-filled",
289
+    "unicode": "\ue678"
290
+  },
291
+  {
292
+    "font_class": "images",
293
+    "unicode": "\ue650"
294
+  },
295
+  {
296
+    "font_class": "images-filled",
297
+    "unicode": "\ue64b"
298
+  },
299
+  {
300
+    "font_class": "info",
301
+    "unicode": "\ue669"
302
+  },
303
+  {
304
+    "font_class": "info-filled",
305
+    "unicode": "\ue649"
306
+  },
307
+  {
308
+    "font_class": "left",
309
+    "unicode": "\ue6b7"
310
+  },
311
+  {
312
+    "font_class": "link",
313
+    "unicode": "\ue6a5"
314
+  },
315
+  {
316
+    "font_class": "list",
317
+    "unicode": "\ue644"
318
+  },
319
+  {
320
+    "font_class": "location",
321
+    "unicode": "\ue6ae"
322
+  },
323
+  {
324
+    "font_class": "location-filled",
325
+    "unicode": "\ue6af"
326
+  },
327
+  {
328
+    "font_class": "locked",
329
+    "unicode": "\ue66b"
330
+  },
331
+  {
332
+    "font_class": "locked-filled",
333
+    "unicode": "\ue668"
334
+  },
335
+  {
336
+    "font_class": "loop",
337
+    "unicode": "\ue633"
338
+  },
339
+  {
340
+    "font_class": "mail-open",
341
+    "unicode": "\ue643"
342
+  },
343
+  {
344
+    "font_class": "mail-open-filled",
345
+    "unicode": "\ue63a"
346
+  },
347
+  {
348
+    "font_class": "map",
349
+    "unicode": "\ue667"
350
+  },
351
+  {
352
+    "font_class": "map-filled",
353
+    "unicode": "\ue666"
354
+  },
355
+  {
356
+    "font_class": "map-pin",
357
+    "unicode": "\ue6ad"
358
+  },
359
+  {
360
+    "font_class": "map-pin-ellipse",
361
+    "unicode": "\ue6ac"
362
+  },
363
+  {
364
+    "font_class": "medal",
365
+    "unicode": "\ue6a2"
366
+  },
367
+  {
368
+    "font_class": "medal-filled",
369
+    "unicode": "\ue6c3"
370
+  },
371
+  {
372
+    "font_class": "mic",
373
+    "unicode": "\ue671"
374
+  },
375
+  {
376
+    "font_class": "mic-filled",
377
+    "unicode": "\ue677"
378
+  },
379
+  {
380
+    "font_class": "micoff",
381
+    "unicode": "\ue67e"
382
+  },
383
+  {
384
+    "font_class": "micoff-filled",
385
+    "unicode": "\ue6b0"
386
+  },
387
+  {
388
+    "font_class": "minus",
389
+    "unicode": "\ue66f"
390
+  },
391
+  {
392
+    "font_class": "minus-filled",
393
+    "unicode": "\ue67d"
394
+  },
395
+  {
396
+    "font_class": "more",
397
+    "unicode": "\ue64d"
398
+  },
399
+  {
400
+    "font_class": "more-filled",
401
+    "unicode": "\ue64e"
402
+  },
403
+  {
404
+    "font_class": "navigate",
405
+    "unicode": "\ue66e"
406
+  },
407
+  {
408
+    "font_class": "navigate-filled",
409
+    "unicode": "\ue67a"
410
+  },
411
+  {
412
+    "font_class": "notification",
413
+    "unicode": "\ue6a6"
414
+  },
415
+  {
416
+    "font_class": "notification-filled",
417
+    "unicode": "\ue6c1"
418
+  },
419
+  {
420
+    "font_class": "paperclip",
421
+    "unicode": "\ue652"
422
+  },
423
+  {
424
+    "font_class": "paperplane",
425
+    "unicode": "\ue672"
426
+  },
427
+  {
428
+    "font_class": "paperplane-filled",
429
+    "unicode": "\ue675"
430
+  },
431
+  {
432
+    "font_class": "person",
433
+    "unicode": "\ue699"
434
+  },
435
+  {
436
+    "font_class": "person-filled",
437
+    "unicode": "\ue69d"
438
+  },
439
+  {
440
+    "font_class": "personadd",
441
+    "unicode": "\ue69f"
442
+  },
443
+  {
444
+    "font_class": "personadd-filled",
445
+    "unicode": "\ue698"
446
+  },
447
+  {
448
+    "font_class": "personadd-filled-copy",
449
+    "unicode": "\ue6d1"
450
+  },
451
+  {
452
+    "font_class": "phone",
453
+    "unicode": "\ue69c"
454
+  },
455
+  {
456
+    "font_class": "phone-filled",
457
+    "unicode": "\ue69b"
458
+  },
459
+  {
460
+    "font_class": "plus",
461
+    "unicode": "\ue676"
462
+  },
463
+  {
464
+    "font_class": "plus-filled",
465
+    "unicode": "\ue6c7"
466
+  },
467
+  {
468
+    "font_class": "plusempty",
469
+    "unicode": "\ue67b"
470
+  },
471
+  {
472
+    "font_class": "pulldown",
473
+    "unicode": "\ue632"
474
+  },
475
+  {
476
+    "font_class": "pyq",
477
+    "unicode": "\ue682"
478
+  },
479
+  {
480
+    "font_class": "qq",
481
+    "unicode": "\ue680"
482
+  },
483
+  {
484
+    "font_class": "redo",
485
+    "unicode": "\ue64a"
486
+  },
487
+  {
488
+    "font_class": "redo-filled",
489
+    "unicode": "\ue655"
490
+  },
491
+  {
492
+    "font_class": "refresh",
493
+    "unicode": "\ue657"
494
+  },
495
+  {
496
+    "font_class": "refresh-filled",
497
+    "unicode": "\ue656"
498
+  },
499
+  {
500
+    "font_class": "refreshempty",
501
+    "unicode": "\ue6bf"
502
+  },
503
+  {
504
+    "font_class": "reload",
505
+    "unicode": "\ue6b2"
506
+  },
507
+  {
508
+    "font_class": "right",
509
+    "unicode": "\ue6b5"
510
+  },
511
+  {
512
+    "font_class": "scan",
513
+    "unicode": "\ue62a"
514
+  },
515
+  {
516
+    "font_class": "search",
517
+    "unicode": "\ue654"
518
+  },
519
+  {
520
+    "font_class": "settings",
521
+    "unicode": "\ue653"
522
+  },
523
+  {
524
+    "font_class": "settings-filled",
525
+    "unicode": "\ue6ce"
526
+  },
527
+  {
528
+    "font_class": "shop",
529
+    "unicode": "\ue62f"
530
+  },
531
+  {
532
+    "font_class": "shop-filled",
533
+    "unicode": "\ue6cd"
534
+  },
535
+  {
536
+    "font_class": "smallcircle",
537
+    "unicode": "\ue67c"
538
+  },
539
+  {
540
+    "font_class": "smallcircle-filled",
541
+    "unicode": "\ue665"
542
+  },
543
+  {
544
+    "font_class": "sound",
545
+    "unicode": "\ue684"
546
+  },
547
+  {
548
+    "font_class": "sound-filled",
549
+    "unicode": "\ue686"
550
+  },
551
+  {
552
+    "font_class": "spinner-cycle",
553
+    "unicode": "\ue68a"
554
+  },
555
+  {
556
+    "font_class": "staff",
557
+    "unicode": "\ue6a7"
558
+  },
559
+  {
560
+    "font_class": "staff-filled",
561
+    "unicode": "\ue6cb"
562
+  },
563
+  {
564
+    "font_class": "star",
565
+    "unicode": "\ue688"
566
+  },
567
+  {
568
+    "font_class": "star-filled",
569
+    "unicode": "\ue68f"
570
+  },
571
+  {
572
+    "font_class": "starhalf",
573
+    "unicode": "\ue683"
574
+  },
575
+  {
576
+    "font_class": "trash",
577
+    "unicode": "\ue687"
578
+  },
579
+  {
580
+    "font_class": "trash-filled",
581
+    "unicode": "\ue685"
582
+  },
583
+  {
584
+    "font_class": "tune",
585
+    "unicode": "\ue6aa"
586
+  },
587
+  {
588
+    "font_class": "tune-filled",
589
+    "unicode": "\ue6ca"
590
+  },
591
+  {
592
+    "font_class": "undo",
593
+    "unicode": "\ue64f"
594
+  },
595
+  {
596
+    "font_class": "undo-filled",
597
+    "unicode": "\ue64c"
598
+  },
599
+  {
600
+    "font_class": "up",
601
+    "unicode": "\ue6b6"
602
+  },
603
+	{
604
+	  "font_class": "top",
605
+	  "unicode": "\ue6b6"
606
+	},
607
+  {
608
+    "font_class": "upload",
609
+    "unicode": "\ue690"
610
+  },
611
+  {
612
+    "font_class": "upload-filled",
613
+    "unicode": "\ue68e"
614
+  },
615
+  {
616
+    "font_class": "videocam",
617
+    "unicode": "\ue68c"
618
+  },
619
+  {
620
+    "font_class": "videocam-filled",
621
+    "unicode": "\ue689"
622
+  },
623
+  {
624
+    "font_class": "vip",
625
+    "unicode": "\ue6a8"
626
+  },
627
+  {
628
+    "font_class": "vip-filled",
629
+    "unicode": "\ue6c6"
630
+  },
631
+  {
632
+    "font_class": "wallet",
633
+    "unicode": "\ue6b1"
634
+  },
635
+  {
636
+    "font_class": "wallet-filled",
637
+    "unicode": "\ue6c2"
638
+  },
639
+  {
640
+    "font_class": "weibo",
641
+    "unicode": "\ue68b"
642
+  },
643
+  {
644
+    "font_class": "weixin",
645
+    "unicode": "\ue691"
646
+  }
647
+]
648
+
649
+// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)

+ 88 - 0
price-collection/uni_modules/uni-icons/package.json

@@ -0,0 +1,88 @@
1
+{
2
+  "id": "uni-icons",
3
+  "displayName": "uni-icons 图标",
4
+  "version": "2.0.9",
5
+  "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "uniui",
9
+    "icon",
10
+    "图标"
11
+],
12
+  "repository": "https://github.com/dcloudio/uni-ui",
13
+  "engines": {
14
+    "HBuilderX": "^3.2.14"
15
+  },
16
+  "directories": {
17
+    "example": "../../temps/example_temps"
18
+  },
19
+"dcloudext": {
20
+    "sale": {
21
+      "regular": {
22
+        "price": "0.00"
23
+      },
24
+      "sourcecode": {
25
+        "price": "0.00"
26
+      }
27
+    },
28
+    "contact": {
29
+      "qq": ""
30
+    },
31
+    "declaration": {
32
+      "ads": "无",
33
+      "data": "无",
34
+      "permissions": "无"
35
+    },
36
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
37
+    "type": "component-vue"
38
+  },
39
+  "uni_modules": {
40
+    "dependencies": ["uni-scss"],
41
+    "encrypt": [],
42
+    "platforms": {
43
+      "cloud": {
44
+        "tcb": "y",
45
+        "aliyun": "y"
46
+      },
47
+      "client": {
48
+        "App": {
49
+          "app-vue": "y",
50
+          "app-nvue": "y",
51
+          "app-uvue": "y"
52
+        },
53
+        "H5-mobile": {
54
+          "Safari": "y",
55
+          "Android Browser": "y",
56
+          "微信浏览器(Android)": "y",
57
+          "QQ浏览器(Android)": "y"
58
+        },
59
+        "H5-pc": {
60
+          "Chrome": "y",
61
+          "IE": "y",
62
+          "Edge": "y",
63
+          "Firefox": "y",
64
+          "Safari": "y"
65
+        },
66
+        "小程序": {
67
+          "微信": "y",
68
+          "阿里": "y",
69
+          "百度": "y",
70
+          "字节跳动": "y",
71
+          "QQ": "y",
72
+					"钉钉": "y",
73
+					"快手": "y",
74
+					"飞书": "y",
75
+					"京东": "y"
76
+        },
77
+        "快应用": {
78
+          "华为": "y",
79
+          "联盟": "y"
80
+        },
81
+        "Vue": {
82
+            "vue2": "y",
83
+            "vue3": "y"
84
+        }
85
+      }
86
+    }
87
+  }
88
+}

+ 8 - 0
price-collection/uni_modules/uni-icons/readme.md

@@ -0,0 +1,8 @@
1
+## Icons 图标
2
+> **组件名:uni-icons**
3
+> 代码块: `uIcons`
4
+
5
+用于展示 icons 图标 。
6
+
7
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
8
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 51 - 0
price-collection/uni_modules/uni-nav-bar/changelog.md

@@ -0,0 +1,51 @@
1
+## 1.3.11(2023-03-29)
2
+- 修复 自定义状态栏高度闪动BUG
3
+## 1.3.10(2023-03-29)
4
+- 修复 暗黑模式下边线颜色错误的bug
5
+## 1.3.9(2022-10-13)
6
+- 修复 条件编译错误的bug
7
+## 1.3.8(2022-10-12)
8
+- 修复 nvue 环境 fixed 为 true 的情况下,无法置顶的 bug
9
+## 1.3.7(2022-08-11)
10
+- 修复 nvue 环境下 fixed 为 true 的情况下,无法置顶的 bug
11
+## 1.3.6(2022-06-30)
12
+- 修复 组件示例中插槽用法无法显示内容的bug
13
+## 1.3.5(2022-05-24)
14
+- 新增 stat 属性 ,可开启统计title 上报 ,仅使用了title 属性且项目开启了uni统计生效
15
+## 1.3.4(2022-01-24)
16
+- 更新 组件示例
17
+## 1.3.3(2022-01-24)
18
+- 新增 left-width/right-width属性 ,可修改左右两侧的宽度
19
+## 1.3.2(2022-01-18)
20
+- 修复 在vue下,标题不垂直居中的bug
21
+## 1.3.1(2022-01-18)
22
+- 修复 height 属性类型错误
23
+## 1.3.0(2022-01-18)
24
+- 新增 height 属性,可修改组件高度
25
+- 新增 dark 属性可可开启暗黑模式
26
+- 优化 标题字数过多显示省略号
27
+- 优化 插槽,插入内容可完全覆盖
28
+## 1.2.1(2022-01-10)
29
+- 修复 color 属性不生效的bug
30
+## 1.2.0(2021-11-19)
31
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
32
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
33
+## 1.1.0(2021-07-30)
34
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
35
+## 1.0.11(2021-05-12)
36
+- 新增 组件示例地址
37
+## 1.0.10(2021-04-30)
38
+- 修复 在nvue下fixed为true,宽度不能撑满的Bug
39
+## 1.0.9(2021-04-21)
40
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
41
+## 1.0.8(2021-04-14)
42
+- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
43
+
44
+## 1.0.7(2021-02-25)
45
+- 修复 easycom 下,找不到 uni-status-bar 的bug
46
+
47
+## 1.0.6(2021-02-05)
48
+- 优化 组件引用关系,通过uni_modules引用组件
49
+
50
+## 1.0.5(2021-02-05)
51
+- 调整为uni_modules目录规范

+ 357 - 0
price-collection/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue

@@ -0,0 +1,357 @@
1
+<template>
2
+	<view class="uni-navbar" :class="{'uni-dark':dark, 'uni-nvue-fixed': fixed}">
3
+		<view class="uni-navbar__content" :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }"
4
+			:style="{ 'background-color': themeBgColor, 'border-bottom-color':themeColor }" >
5
+			<status-bar v-if="statusBar" />
6
+			<view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight}"
7
+				class="uni-navbar__header">
8
+				<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left"
9
+					:style="{width:leftIconWidth}">
10
+					<slot name="left">
11
+						<view class="uni-navbar__content_view" v-if="leftIcon.length > 0">
12
+							<uni-icons :color="themeColor" :type="leftIcon" size="20" />
13
+						</view>
14
+						<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text"
15
+							v-if="leftText.length">
16
+							<text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text>
17
+						</view>
18
+					</slot>
19
+				</view>
20
+				<view class="uni-navbar__header-container " @tap="onClickTitle">
21
+					<slot>
22
+						<view class="uni-navbar__header-container-inner" v-if="title.length>0">
23
+							<text class="uni-nav-bar-text uni-ellipsis-1"
24
+								:style="{color: themeColor }">{{ title }}</text>
25
+						</view>
26
+					</slot>
27
+				</view>
28
+				<view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right"
29
+					:style="{width:rightIconWidth}">
30
+					<slot name="right">
31
+						<view v-if="rightIcon.length">
32
+							<uni-icons :color="themeColor" :type="rightIcon" size="22" />
33
+						</view>
34
+						<view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length">
35
+							<text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text>
36
+						</view>
37
+					</slot>
38
+				</view>
39
+			</view>
40
+		</view>
41
+		<!-- #ifndef APP-NVUE -->
42
+		<view class="uni-navbar__placeholder" v-if="fixed">
43
+			<status-bar v-if="statusBar" />
44
+			<view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" />
45
+		</view>
46
+		<!-- #endif -->
47
+	</view>
48
+</template>
49
+
50
+<script>
51
+	import statusBar from "./uni-status-bar.vue";
52
+	const getVal = (val) => typeof val === 'number' ? val + 'px' : val;
53
+
54
+	/**
55
+	 * 
56
+	 * 
57
+	 * NavBar 自定义导航栏
58
+	 * @description 导航栏组件,主要用于头部导航
59
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=52
60
+	 * @property {Boolean} dark 开启黑暗模式
61
+	 * @property {String} title 标题文字
62
+	 * @property {String} leftText 左侧按钮文本
63
+	 * @property {String} rightText 右侧按钮文本
64
+	 * @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
65
+	 * @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
66
+	 * @property {String} color 图标和文字颜色
67
+	 * @property {String} backgroundColor 导航栏背景颜色
68
+	 * @property {Boolean} fixed = [true|false] 是否固定顶部
69
+	 * @property {Boolean} statusBar = [true|false] 是否包含状态栏
70
+	 * @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
71
+	 * @property {Boolean} stat 是否开启统计标题上报
72
+	 * @event {Function} clickLeft 左侧按钮点击时触发
73
+	 * @event {Function} clickRight 右侧按钮点击时触发
74
+	 * @event {Function} clickTitle 中间标题点击时触发
75
+	 */
76
+	export default {
77
+		name: "UniNavBar",
78
+		components: {
79
+			statusBar
80
+		},
81
+		emits: ['clickLeft', 'clickRight', 'clickTitle'],
82
+		props: {
83
+			dark: {
84
+				type: Boolean,
85
+				default: false
86
+			},
87
+			title: {
88
+				type: String,
89
+				default: ""
90
+			},
91
+			leftText: {
92
+				type: String,
93
+				default: ""
94
+			},
95
+			rightText: {
96
+				type: String,
97
+				default: ""
98
+			},
99
+			leftIcon: {
100
+				type: String,
101
+				default: ""
102
+			},
103
+			rightIcon: {
104
+				type: String,
105
+				default: ""
106
+			},
107
+			fixed: {
108
+				type: [Boolean, String],
109
+				default: false
110
+			},
111
+			color: {
112
+				type: String,
113
+				default: ""
114
+			},
115
+			backgroundColor: {
116
+				type: String,
117
+				default: ""
118
+			},
119
+			statusBar: {
120
+				type: [Boolean, String],
121
+				default: false
122
+			},
123
+			shadow: {
124
+				type: [Boolean, String],
125
+				default: false
126
+			},
127
+			border: {
128
+				type: [Boolean, String],
129
+				default: true
130
+			},
131
+			height: {
132
+				type: [Number, String],
133
+				default: 44
134
+			},
135
+			leftWidth: {
136
+				type: [Number, String],
137
+				default: 60
138
+			},
139
+			rightWidth: {
140
+				type: [Number, String],
141
+				default: 60
142
+			},
143
+			stat: {
144
+				type: [Boolean, String],
145
+				default: ''
146
+			}
147
+		},
148
+		computed: {
149
+			themeBgColor() {
150
+				if (this.dark) {
151
+					// 默认值
152
+					if (this.backgroundColor) {
153
+						return this.backgroundColor
154
+					} else {
155
+						return this.dark ? '#333' : '#FFF'
156
+					}
157
+				}
158
+				return this.backgroundColor || '#FFF'
159
+			},
160
+			themeColor() {
161
+				if (this.dark) {
162
+					// 默认值
163
+					if (this.color) {
164
+						return this.color
165
+					} else {
166
+						return this.dark ? '#fff' : '#333'
167
+					}
168
+				}
169
+				return this.color || '#333'
170
+			},
171
+			navbarHeight() {
172
+				return getVal(this.height)
173
+			},
174
+			leftIconWidth() {
175
+				return getVal(this.leftWidth)
176
+			},
177
+			rightIconWidth() {
178
+				return getVal(this.rightWidth)
179
+			}
180
+		},
181
+		mounted() {
182
+			if (uni.report && this.stat && this.title !== '') {
183
+				uni.report('title', this.title)
184
+			}
185
+		},
186
+		methods: {
187
+			onClickLeft() {
188
+				this.$emit("clickLeft");
189
+			},
190
+			onClickRight() {
191
+				this.$emit("clickRight");
192
+			},
193
+			onClickTitle() {
194
+				this.$emit("clickTitle");
195
+			}
196
+		}
197
+	};
198
+</script>
199
+
200
+<style lang="scss" scoped>
201
+	$nav-height: 44px;
202
+
203
+	.uni-nvue-fixed {
204
+		/* #ifdef APP-NVUE */
205
+		position: sticky;
206
+		/* #endif */
207
+	}
208
+	.uni-navbar {
209
+		// box-sizing: border-box;
210
+	}
211
+
212
+	.uni-nav-bar-text {
213
+		/* #ifdef APP-PLUS */
214
+		font-size: 34rpx;
215
+		/* #endif */
216
+		/* #ifndef APP-PLUS */
217
+		font-size: 14px;
218
+		/* #endif */
219
+	}
220
+
221
+	.uni-nav-bar-right-text {
222
+		font-size: 12px;
223
+	}
224
+
225
+	.uni-navbar__content {
226
+		position: relative;
227
+		// background-color: #fff;
228
+		// box-sizing: border-box;
229
+		background-color: transparent;
230
+	}
231
+
232
+	.uni-navbar__content_view {
233
+		// box-sizing: border-box;
234
+	}
235
+
236
+	.uni-navbar-btn-text {
237
+		/* #ifndef APP-NVUE */
238
+		display: flex;
239
+		/* #endif */
240
+		flex-direction: column;
241
+		justify-content: flex-start;
242
+		align-items: center;
243
+		line-height: 12px;
244
+	}
245
+
246
+	.uni-navbar__header {
247
+		/* #ifndef APP-NVUE */
248
+		display: flex;
249
+		/* #endif */
250
+		padding: 0 10px;
251
+		flex-direction: row;
252
+		height: $nav-height;
253
+		font-size: 12px;
254
+	}
255
+
256
+	.uni-navbar__header-btns {
257
+		/* #ifndef APP-NVUE */
258
+		overflow: hidden;
259
+		display: flex;
260
+		/* #endif */
261
+		flex-wrap: nowrap;
262
+		flex-direction: row;
263
+		width: 120rpx;
264
+		// padding: 0 6px;
265
+		justify-content: center;
266
+		align-items: center;
267
+		/* #ifdef H5 */
268
+		cursor: pointer;
269
+		/* #endif */
270
+	}
271
+
272
+	.uni-navbar__header-btns-left {
273
+		/* #ifndef APP-NVUE */
274
+		display: flex;
275
+		/* #endif */
276
+		width: 120rpx;
277
+		justify-content: flex-start;
278
+		align-items: center;
279
+	}
280
+
281
+	.uni-navbar__header-btns-right {
282
+		/* #ifndef APP-NVUE */
283
+		display: flex;
284
+		/* #endif */
285
+		flex-direction: row;
286
+		// width: 150rpx;
287
+		// padding-right: 30rpx;
288
+		justify-content: flex-end;
289
+		align-items: center;
290
+	}
291
+
292
+	.uni-navbar__header-container {
293
+		/* #ifndef APP-NVUE */
294
+		display: flex;
295
+		/* #endif */
296
+		flex: 1;
297
+		padding: 0 10px;
298
+		overflow: hidden;
299
+	}
300
+
301
+	.uni-navbar__header-container-inner {
302
+		/* #ifndef APP-NVUE */
303
+		display: flex;
304
+		/* #endif */
305
+		flex: 1;
306
+		flex-direction: row;
307
+		align-items: center;
308
+		justify-content: center;
309
+		font-size: 12px;
310
+		overflow: hidden;
311
+		// box-sizing: border-box;
312
+	}
313
+
314
+
315
+	.uni-navbar__placeholder-view {
316
+		height: $nav-height;
317
+	}
318
+
319
+	.uni-navbar--fixed {
320
+		position: fixed;
321
+		z-index: 998;
322
+		/* #ifdef H5 */
323
+		left: var(--window-left);
324
+		right: var(--window-right);
325
+		/* #endif */
326
+		/* #ifndef H5 */
327
+		left: 0;
328
+		right: 0;
329
+		/* #endif */
330
+
331
+	}
332
+
333
+	.uni-navbar--shadow {
334
+		box-shadow: 0 1px 6px #ccc;
335
+	}
336
+
337
+	.uni-navbar--border {
338
+		border-bottom-width: 1rpx;
339
+		border-bottom-style: solid;
340
+		border-bottom-color: #eee;
341
+	}
342
+
343
+	.uni-ellipsis-1 {
344
+		overflow: hidden;
345
+		/* #ifndef APP-NVUE */
346
+		white-space: nowrap;
347
+		text-overflow: ellipsis;
348
+		/* #endif */
349
+		/* #ifdef APP-NVUE */
350
+		lines: 1;
351
+		text-overflow: ellipsis;
352
+		/* #endif */
353
+	}
354
+
355
+	// 暗主题配置
356
+	.uni-dark {}
357
+</style>

+ 24 - 0
price-collection/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue

@@ -0,0 +1,24 @@
1
+<template>
2
+	<view :style="{ height: statusBarHeight }" class="uni-status-bar">
3
+		<slot />
4
+	</view>
5
+</template>
6
+
7
+<script>
8
+	export default {
9
+		name: 'UniStatusBar',
10
+		data() {
11
+			return {
12
+				statusBarHeight: uni.getSystemInfoSync().statusBarHeight + 'px'
13
+			}
14
+		}
15
+	}
16
+</script>
17
+
18
+<style lang="scss" >
19
+	.uni-status-bar {
20
+		// width: 750rpx;
21
+		height: 20px;
22
+		// height: var(--status-bar-height);
23
+	}
24
+</style>

+ 86 - 0
price-collection/uni_modules/uni-nav-bar/package.json

@@ -0,0 +1,86 @@
1
+{
2
+  "id": "uni-nav-bar",
3
+  "displayName": "uni-nav-bar 自定义导航栏",
4
+  "version": "1.3.11",
5
+  "description": "自定义导航栏组件,主要用于头部导航。",
6
+  "keywords": [
7
+    "uni-ui",
8
+    "导航",
9
+    "导航栏",
10
+    "自定义导航栏"
11
+],
12
+  "repository": "https://github.com/dcloudio/uni-ui",
13
+  "engines": {
14
+    "HBuilderX": ""
15
+  },
16
+  "directories": {
17
+    "example": "../../temps/example_temps"
18
+  },
19
+"dcloudext": {
20
+    "sale": {
21
+      "regular": {
22
+        "price": "0.00"
23
+      },
24
+      "sourcecode": {
25
+        "price": "0.00"
26
+      }
27
+    },
28
+    "contact": {
29
+      "qq": ""
30
+    },
31
+    "declaration": {
32
+      "ads": "无",
33
+      "data": "无",
34
+      "permissions": "无"
35
+    },
36
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
37
+    "type": "component-vue"
38
+  },
39
+  "uni_modules": {
40
+    "dependencies": [
41
+			"uni-scss",
42
+			"uni-icons"
43
+		],
44
+    "encrypt": [],
45
+    "platforms": {
46
+      "cloud": {
47
+        "tcb": "y",
48
+        "aliyun": "y"
49
+      },
50
+      "client": {
51
+        "App": {
52
+          "app-vue": "y",
53
+          "app-nvue": "y"
54
+        },
55
+        "H5-mobile": {
56
+          "Safari": "y",
57
+          "Android Browser": "y",
58
+          "微信浏览器(Android)": "y",
59
+          "QQ浏览器(Android)": "y"
60
+        },
61
+        "H5-pc": {
62
+          "Chrome": "y",
63
+          "IE": "y",
64
+          "Edge": "y",
65
+          "Firefox": "y",
66
+          "Safari": "y"
67
+        },
68
+        "小程序": {
69
+          "微信": "y",
70
+          "阿里": "y",
71
+          "百度": "y",
72
+          "字节跳动": "y",
73
+          "QQ": "y"
74
+        },
75
+        "快应用": {
76
+          "华为": "u",
77
+          "联盟": "u"
78
+        },
79
+        "Vue": {
80
+            "vue2": "y",
81
+            "vue3": "y"
82
+        }
83
+      }
84
+    }
85
+  }
86
+}

+ 15 - 0
price-collection/uni_modules/uni-nav-bar/readme.md

@@ -0,0 +1,15 @@
1
+
2
+
3
+## NavBar 导航栏
4
+> **组件名:uni-nav-bar**
5
+> 代码块: `uNavBar`
6
+
7
+导航栏组件,主要用于头部导航。
8
+
9
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
10
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
11
+
12
+
13
+
14
+
15
+

+ 8 - 0
price-collection/uni_modules/uni-scss/changelog.md

@@ -0,0 +1,8 @@
1
+## 1.0.3(2022-01-21)
2
+- 优化 组件示例
3
+## 1.0.2(2021-11-22)
4
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
5
+## 1.0.1(2021-11-22)
6
+- 修复 vue3中scss语法兼容问题
7
+## 1.0.0(2021-11-18)
8
+- init

+ 1 - 0
price-collection/uni_modules/uni-scss/index.scss

@@ -0,0 +1 @@
1
+@import './styles/index.scss';

+ 82 - 0
price-collection/uni_modules/uni-scss/package.json

@@ -0,0 +1,82 @@
1
+{
2
+  "id": "uni-scss",
3
+  "displayName": "uni-scss 辅助样式",
4
+  "version": "1.0.3",
5
+  "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
6
+  "keywords": [
7
+    "uni-scss",
8
+    "uni-ui",
9
+    "辅助样式"
10
+],
11
+  "repository": "https://github.com/dcloudio/uni-ui",
12
+  "engines": {
13
+    "HBuilderX": "^3.1.0"
14
+  },
15
+  "dcloudext": {
16
+    "category": [
17
+        "JS SDK",
18
+        "通用 SDK"
19
+    ],
20
+    "sale": {
21
+      "regular": {
22
+        "price": "0.00"
23
+      },
24
+      "sourcecode": {
25
+        "price": "0.00"
26
+      }
27
+    },
28
+    "contact": {
29
+      "qq": ""
30
+    },
31
+    "declaration": {
32
+      "ads": "无",
33
+      "data": "无",
34
+      "permissions": "无"
35
+    },
36
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
37
+  },
38
+  "uni_modules": {
39
+    "dependencies": [],
40
+    "encrypt": [],
41
+    "platforms": {
42
+      "cloud": {
43
+        "tcb": "y",
44
+        "aliyun": "y"
45
+      },
46
+      "client": {
47
+        "App": {
48
+          "app-vue": "y",
49
+          "app-nvue": "u"
50
+        },
51
+        "H5-mobile": {
52
+          "Safari": "y",
53
+          "Android Browser": "y",
54
+          "微信浏览器(Android)": "y",
55
+          "QQ浏览器(Android)": "y"
56
+        },
57
+        "H5-pc": {
58
+          "Chrome": "y",
59
+          "IE": "y",
60
+          "Edge": "y",
61
+          "Firefox": "y",
62
+          "Safari": "y"
63
+        },
64
+        "小程序": {
65
+          "微信": "y",
66
+          "阿里": "y",
67
+          "百度": "y",
68
+          "字节跳动": "y",
69
+          "QQ": "y"
70
+        },
71
+        "快应用": {
72
+          "华为": "n",
73
+          "联盟": "n"
74
+        },
75
+        "Vue": {
76
+            "vue2": "y",
77
+            "vue3": "y"
78
+        }
79
+      }
80
+    }
81
+  }
82
+}

+ 4 - 0
price-collection/uni_modules/uni-scss/readme.md

@@ -0,0 +1,4 @@
1
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
2
+
3
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
4
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 7 - 0
price-collection/uni_modules/uni-scss/styles/index.scss

@@ -0,0 +1,7 @@
1
+@import './setting/_variables.scss';
2
+@import './setting/_border.scss';
3
+@import './setting/_color.scss';
4
+@import './setting/_space.scss';
5
+@import './setting/_radius.scss';
6
+@import './setting/_text.scss';
7
+@import './setting/_styles.scss';

+ 3 - 0
price-collection/uni_modules/uni-scss/styles/setting/_border.scss

@@ -0,0 +1,3 @@
1
+.uni-border {
2
+	border: 1px $uni-border-1 solid;
3
+}

+ 66 - 0
price-collection/uni_modules/uni-scss/styles/setting/_color.scss

@@ -0,0 +1,66 @@
1
+
2
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
3
+// @mixin get-styles($k,$c) {
4
+// 	@if $k == size or $k == weight{
5
+// 		font-#{$k}:#{$c}
6
+// 	}@else{
7
+// 		#{$k}:#{$c}
8
+// 	}
9
+// }
10
+$uni-ui-color:(
11
+	// 主色
12
+	primary: $uni-primary,
13
+	primary-disable: $uni-primary-disable,
14
+	primary-light: $uni-primary-light,
15
+	// 辅助色
16
+	success: $uni-success,
17
+	success-disable: $uni-success-disable,
18
+	success-light: $uni-success-light,
19
+	warning: $uni-warning,
20
+	warning-disable: $uni-warning-disable,
21
+	warning-light: $uni-warning-light,
22
+	error: $uni-error,
23
+	error-disable: $uni-error-disable,
24
+	error-light: $uni-error-light,
25
+	info: $uni-info,
26
+	info-disable: $uni-info-disable,
27
+	info-light: $uni-info-light,
28
+	// 中性色
29
+	main-color: $uni-main-color,
30
+	base-color: $uni-base-color,
31
+	secondary-color: $uni-secondary-color,
32
+	extra-color: $uni-extra-color,
33
+	// 背景色
34
+	bg-color: $uni-bg-color,
35
+	// 边框颜色
36
+	border-1: $uni-border-1,
37
+	border-2: $uni-border-2,
38
+	border-3: $uni-border-3,
39
+	border-4: $uni-border-4,
40
+	// 黑色
41
+	black:$uni-black,
42
+	// 白色
43
+	white:$uni-white,
44
+	// 透明
45
+	transparent:$uni-transparent
46
+) !default;
47
+@each $key, $child in $uni-ui-color {
48
+	.uni-#{"" + $key} {
49
+		color: $child;
50
+	}
51
+	.uni-#{"" + $key}-bg {
52
+		background-color: $child;
53
+	}
54
+}
55
+.uni-shadow-sm {
56
+	box-shadow: $uni-shadow-sm;
57
+}
58
+.uni-shadow-base {
59
+	box-shadow: $uni-shadow-base;
60
+}
61
+.uni-shadow-lg {
62
+	box-shadow: $uni-shadow-lg;
63
+}
64
+.uni-mask {
65
+	background-color:$uni-mask;
66
+}

+ 55 - 0
price-collection/uni_modules/uni-scss/styles/setting/_radius.scss

@@ -0,0 +1,55 @@
1
+@mixin radius($r,$d:null ,$important: false){
2
+  $radius-value:map-get($uni-radius, $r) if($important, !important, null);
3
+  // Key exists within the $uni-radius variable
4
+  @if (map-has-key($uni-radius, $r) and  $d){
5
+		@if $d == t {
6
+				border-top-left-radius:$radius-value;
7
+				border-top-right-radius:$radius-value;
8
+		}@else if $d == r {
9
+				border-top-right-radius:$radius-value;
10
+				border-bottom-right-radius:$radius-value;
11
+		}@else if $d == b {
12
+				border-bottom-left-radius:$radius-value;
13
+				border-bottom-right-radius:$radius-value;
14
+		}@else if $d == l {
15
+				border-top-left-radius:$radius-value;
16
+				border-bottom-left-radius:$radius-value;
17
+		}@else if $d == tl {
18
+				border-top-left-radius:$radius-value;
19
+		}@else if $d == tr {
20
+				border-top-right-radius:$radius-value;
21
+		}@else if $d == br {
22
+				border-bottom-right-radius:$radius-value;
23
+		}@else if $d == bl {
24
+				border-bottom-left-radius:$radius-value;
25
+		}
26
+  }@else{
27
+		border-radius:$radius-value;
28
+  }
29
+}
30
+
31
+@each $key, $child in $uni-radius {
32
+	@if($key){
33
+		.uni-radius-#{"" + $key} {
34
+				@include radius($key)
35
+		}
36
+	}@else{
37
+		.uni-radius {
38
+				@include radius($key)
39
+		}
40
+	}
41
+}
42
+
43
+@each $direction in t, r, b, l,tl, tr, br, bl {
44
+	@each $key, $child in $uni-radius {
45
+		@if($key){
46
+			.uni-radius-#{"" + $direction}-#{"" + $key} {
47
+				@include radius($key,$direction,false)
48
+			}
49
+		}@else{
50
+			.uni-radius-#{$direction} {
51
+				@include radius($key,$direction,false)
52
+			}
53
+		}
54
+	}
55
+}

+ 56 - 0
price-collection/uni_modules/uni-scss/styles/setting/_space.scss

@@ -0,0 +1,56 @@
1
+
2
+@mixin fn($space,$direction,$size,$n) {
3
+	@if $n {
4
+		#{$space}-#{$direction}: #{$size*$uni-space-root}px
5
+	} @else {
6
+		 #{$space}-#{$direction}: #{-$size*$uni-space-root}px
7
+	}
8
+}
9
+@mixin get-styles($direction,$i,$space,$n){
10
+	@if $direction == t {
11
+		@include fn($space, top,$i,$n);
12
+	} 
13
+	@if $direction == r {
14
+		@include fn($space, right,$i,$n);
15
+	} 
16
+	@if $direction == b {
17
+		@include fn($space, bottom,$i,$n);
18
+	} 
19
+	@if $direction == l {
20
+	 @include fn($space, left,$i,$n);
21
+	} 
22
+	@if $direction == x {
23
+		@include fn($space, left,$i,$n);
24
+		@include fn($space, right,$i,$n);
25
+	} 
26
+	@if $direction == y {
27
+		@include fn($space, top,$i,$n);
28
+		@include fn($space, bottom,$i,$n);
29
+	} 
30
+	@if $direction == a {
31
+		@if $n {
32
+			#{$space}:#{$i*$uni-space-root}px;
33
+		} @else {
34
+			#{$space}:#{-$i*$uni-space-root}px;
35
+		}
36
+	} 
37
+}
38
+
39
+@each $orientation in m,p {
40
+	$space: margin;
41
+	@if $orientation == m {
42
+		$space: margin;
43
+	} @else {
44
+		$space: padding;
45
+	}
46
+	@for $i from 0 through 16 {
47
+		@each $direction in t, r, b, l, x, y, a {
48
+			.uni-#{$orientation}#{$direction}-#{$i} { 
49
+				@include  get-styles($direction,$i,$space,true);
50
+			} 
51
+			.uni-#{$orientation}#{$direction}-n#{$i} { 
52
+				@include  get-styles($direction,$i,$space,false);
53
+			}
54
+		}
55
+	}
56
+}

+ 167 - 0
price-collection/uni_modules/uni-scss/styles/setting/_styles.scss

@@ -0,0 +1,167 @@
1
+/* #ifndef APP-NVUE */
2
+
3
+$-color-white:#fff;
4
+$-color-black:#000;
5
+@mixin base-style($color) {
6
+	color: #fff;
7
+	background-color: $color;
8
+	border-color: mix($-color-black, $color, 8%);
9
+	&:not([hover-class]):active {
10
+		background: mix($-color-black, $color, 10%);
11
+		border-color: mix($-color-black, $color, 20%);
12
+		color: $-color-white;
13
+		outline: none;
14
+	}
15
+}
16
+@mixin is-color($color) {
17
+	@include base-style($color);
18
+	&[loading] {
19
+		@include base-style($color);
20
+		&::before {
21
+			margin-right:5px;
22
+		}
23
+	}
24
+	&[disabled] {
25
+	  &,
26
+		&[loading],
27
+	  &:not([hover-class]):active {
28
+	    color: $-color-white;
29
+			border-color: mix(darken($color,10%), $-color-white);
30
+	    background-color: mix($color, $-color-white);
31
+	  }
32
+	}
33
+
34
+}
35
+@mixin base-plain-style($color) {
36
+	color:$color;
37
+	background-color: mix($-color-white, $color, 90%);
38
+	border-color: mix($-color-white, $color, 70%);
39
+	&:not([hover-class]):active {
40
+	  background: mix($-color-white, $color, 80%);
41
+	  color: $color;
42
+	  outline: none;
43
+		border-color: mix($-color-white, $color, 50%);
44
+	}
45
+}
46
+@mixin is-plain($color){
47
+	&[plain] {
48
+		@include base-plain-style($color);
49
+		&[loading] {
50
+			@include base-plain-style($color);
51
+			&::before {
52
+				margin-right:5px;
53
+			}
54
+		}
55
+		&[disabled] {
56
+		  &,
57
+		  &:active {
58
+		    color: mix($-color-white, $color, 40%);
59
+		    background-color: mix($-color-white, $color, 90%);
60
+				border-color: mix($-color-white, $color, 80%);
61
+		  }
62
+		}
63
+	}
64
+}
65
+
66
+
67
+.uni-btn {
68
+	margin: 5px;
69
+	color: #393939;
70
+	border:1px solid #ccc;
71
+	font-size: 16px;
72
+	font-weight: 200;
73
+	background-color: #F9F9F9;
74
+	// TODO 暂时处理边框隐藏一边的问题
75
+	overflow: visible;
76
+	&::after{
77
+		border: none;
78
+	}
79
+
80
+	&:not([type]),&[type=default] {
81
+		color: #999;
82
+		&[loading] {
83
+			background: none;
84
+			&::before {
85
+				margin-right:5px;
86
+			}
87
+		}
88
+
89
+
90
+
91
+		&[disabled]{
92
+			color: mix($-color-white, #999, 60%);
93
+		  &,
94
+			&[loading],
95
+		  &:active {
96
+				color: mix($-color-white, #999, 60%);
97
+		    background-color: mix($-color-white,$-color-black , 98%);
98
+				border-color: mix($-color-white,  #999, 85%);
99
+		  }
100
+		}
101
+
102
+		&[plain] {
103
+			color: #999;
104
+			background: none;
105
+			border-color: $uni-border-1;
106
+			&:not([hover-class]):active {
107
+				background: none;
108
+			  color: mix($-color-white, $-color-black, 80%);
109
+				border-color: mix($-color-white, $-color-black, 90%);
110
+			  outline: none;
111
+			}
112
+			&[disabled]{
113
+			  &,
114
+				&[loading],
115
+			  &:active {
116
+			    background: none;
117
+					color: mix($-color-white, #999, 60%);
118
+					border-color: mix($-color-white,  #999, 85%);
119
+			  }
120
+			}
121
+		}
122
+	}
123
+
124
+	&:not([hover-class]):active {
125
+	  color: mix($-color-white, $-color-black, 50%);
126
+	}
127
+
128
+	&[size=mini] {
129
+		font-size: 16px;
130
+		font-weight: 200;
131
+		border-radius: 8px;
132
+	}
133
+
134
+
135
+
136
+	&.uni-btn-small {
137
+		font-size: 14px;
138
+	}
139
+	&.uni-btn-mini {
140
+		font-size: 12px;
141
+	}
142
+
143
+	&.uni-btn-radius {
144
+		border-radius: 999px;
145
+	}
146
+	&[type=primary] {
147
+		@include is-color($uni-primary);
148
+		@include is-plain($uni-primary)
149
+	}
150
+	&[type=success] {
151
+		@include is-color($uni-success);
152
+		@include is-plain($uni-success)
153
+	}
154
+	&[type=error] {
155
+		@include is-color($uni-error);
156
+		@include is-plain($uni-error)
157
+	}
158
+	&[type=warning] {
159
+		@include is-color($uni-warning);
160
+		@include is-plain($uni-warning)
161
+	}
162
+	&[type=info] {
163
+		@include is-color($uni-info);
164
+		@include is-plain($uni-info)
165
+	}
166
+}
167
+/* #endif */

+ 24 - 0
price-collection/uni_modules/uni-scss/styles/setting/_text.scss

@@ -0,0 +1,24 @@
1
+@mixin get-styles($k,$c) {
2
+	@if $k == size or $k == weight{
3
+		font-#{$k}:#{$c}
4
+	}@else{
5
+		#{$k}:#{$c}
6
+	}
7
+}
8
+
9
+@each $key, $child in $uni-headings {
10
+	/* #ifndef APP-NVUE */
11
+	.uni-#{$key} {
12
+		@each $k, $c in $child {
13
+			@include get-styles($k,$c)
14
+		}
15
+	}
16
+	/* #endif */
17
+	/* #ifdef APP-NVUE */
18
+	.container .uni-#{$key} {
19
+		@each $k, $c in $child {
20
+			@include get-styles($k,$c)
21
+		}
22
+	}
23
+	/* #endif */
24
+}

+ 146 - 0
price-collection/uni_modules/uni-scss/styles/setting/_variables.scss

@@ -0,0 +1,146 @@
1
+// @use "sass:math";
2
+@import  '../tools/functions.scss';
3
+// 间距基础倍数
4
+$uni-space-root: 2 !default;
5
+// 边框半径默认值
6
+$uni-radius-root:5px !default;
7
+$uni-radius: () !default;
8
+// 边框半径断点
9
+$uni-radius: map-deep-merge(
10
+  (
11
+    0: 0,
12
+		// TODO 当前版本暂时不支持 sm 属性
13
+    // 'sm': math.div($uni-radius-root, 2),
14
+    null: $uni-radius-root,
15
+    'lg': $uni-radius-root * 2,
16
+    'xl': $uni-radius-root * 6,
17
+    'pill': 9999px,
18
+    'circle': 50%
19
+  ),
20
+  $uni-radius
21
+);
22
+// 字体家族
23
+$body-font-family: 'Roboto', sans-serif !default;
24
+// 文本
25
+$heading-font-family: $body-font-family !default;
26
+$uni-headings: () !default;
27
+$letterSpacing: -0.01562em;
28
+$uni-headings: map-deep-merge(
29
+  (
30
+    'h1': (
31
+      size: 32px,
32
+			weight: 300,
33
+			line-height: 50px,
34
+			// letter-spacing:-0.01562em
35
+    ),
36
+    'h2': (
37
+      size: 28px,
38
+      weight: 300,
39
+      line-height: 40px,
40
+      // letter-spacing: -0.00833em
41
+    ),
42
+    'h3': (
43
+      size: 24px,
44
+      weight: 400,
45
+      line-height: 32px,
46
+      // letter-spacing: normal
47
+    ),
48
+    'h4': (
49
+      size: 20px,
50
+      weight: 400,
51
+      line-height: 30px,
52
+      // letter-spacing: 0.00735em
53
+    ),
54
+    'h5': (
55
+      size: 16px,
56
+      weight: 400,
57
+      line-height: 24px,
58
+      // letter-spacing: normal
59
+    ),
60
+    'h6': (
61
+      size: 14px,
62
+      weight: 500,
63
+      line-height: 18px,
64
+      // letter-spacing: 0.0125em
65
+    ),
66
+    'subtitle': (
67
+      size: 12px,
68
+      weight: 400,
69
+      line-height: 20px,
70
+      // letter-spacing: 0.00937em
71
+    ),
72
+    'body': (
73
+      font-size: 14px,
74
+			font-weight: 400,
75
+			line-height: 22px,
76
+			// letter-spacing: 0.03125em
77
+    ),
78
+    'caption': (
79
+      'size': 12px,
80
+      'weight': 400,
81
+      'line-height': 20px,
82
+      // 'letter-spacing': 0.03333em,
83
+      // 'text-transform': false
84
+    )
85
+  ),
86
+  $uni-headings
87
+);
88
+
89
+
90
+
91
+// 主色
92
+$uni-primary: #2979ff !default;
93
+$uni-primary-disable:lighten($uni-primary,20%) !default;
94
+$uni-primary-light: lighten($uni-primary,25%) !default;
95
+
96
+// 辅助色
97
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
98
+$uni-success: #18bc37 !default;
99
+$uni-success-disable:lighten($uni-success,20%) !default;
100
+$uni-success-light: lighten($uni-success,25%) !default;
101
+
102
+$uni-warning: #f3a73f !default;
103
+$uni-warning-disable:lighten($uni-warning,20%) !default;
104
+$uni-warning-light: lighten($uni-warning,25%) !default;
105
+
106
+$uni-error: #e43d33 !default;
107
+$uni-error-disable:lighten($uni-error,20%) !default;
108
+$uni-error-light: lighten($uni-error,25%) !default;
109
+
110
+$uni-info: #8f939c !default;
111
+$uni-info-disable:lighten($uni-info,20%) !default;
112
+$uni-info-light: lighten($uni-info,25%) !default;
113
+
114
+// 中性色
115
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
116
+$uni-main-color: #3a3a3a !default; 			// 主要文字
117
+$uni-base-color: #6a6a6a !default;			// 常规文字
118
+$uni-secondary-color: #909399 !default;	// 次要文字
119
+$uni-extra-color: #c7c7c7 !default;			// 辅助说明
120
+
121
+// 边框颜色
122
+$uni-border-1: #F0F0F0 !default;
123
+$uni-border-2: #EDEDED !default;
124
+$uni-border-3: #DCDCDC !default;
125
+$uni-border-4: #B9B9B9 !default;
126
+
127
+// 常规色
128
+$uni-black: #000000 !default;
129
+$uni-white: #ffffff !default;
130
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
131
+
132
+// 背景色
133
+$uni-bg-color: #f7f7f7 !default;
134
+
135
+/* 水平间距 */
136
+$uni-spacing-sm: 8px !default;
137
+$uni-spacing-base: 15px !default;
138
+$uni-spacing-lg: 30px !default;
139
+
140
+// 阴影
141
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
142
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
143
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
144
+
145
+// 蒙版
146
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;

+ 19 - 0
price-collection/uni_modules/uni-scss/styles/tools/functions.scss

@@ -0,0 +1,19 @@
1
+// 合并 map
2
+@function map-deep-merge($parent-map, $child-map){
3
+	$result: $parent-map;
4
+	@each $key, $child in $child-map {
5
+		$parent-has-key: map-has-key($result, $key);
6
+		$parent-value: map-get($result, $key);
7
+		$parent-type: type-of($parent-value);
8
+		$child-type: type-of($child);
9
+		$parent-is-map: $parent-type == map;
10
+		$child-is-map: $child-type == map;
11
+			
12
+		@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
13
+			$result: map-merge($result, ( $key: $child ));
14
+		}@else {
15
+			$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
16
+		}
17
+	}
18
+	@return $result;
19
+};

+ 31 - 0
price-collection/uni_modules/uni-scss/theme.scss

@@ -0,0 +1,31 @@
1
+// 间距基础倍数
2
+$uni-space-root: 2;
3
+// 边框半径默认值
4
+$uni-radius-root:5px;
5
+// 主色
6
+$uni-primary: #2979ff;
7
+// 辅助色
8
+$uni-success: #4cd964;
9
+// 警告色
10
+$uni-warning: #f0ad4e;
11
+// 错误色
12
+$uni-error: #dd524d;
13
+// 描述色
14
+$uni-info: #909399;
15
+// 中性色
16
+$uni-main-color: #303133;
17
+$uni-base-color: #606266;
18
+$uni-secondary-color: #909399;
19
+$uni-extra-color: #C0C4CC;
20
+// 背景色
21
+$uni-bg-color: #f5f5f5;
22
+// 边框颜色
23
+$uni-border-1: #DCDFE6;
24
+$uni-border-2: #E4E7ED;
25
+$uni-border-3: #EBEEF5;
26
+$uni-border-4: #F2F6FC;
27
+
28
+// 常规色
29
+$uni-black: #000000;
30
+$uni-white: #ffffff;
31
+$uni-transparent: rgba($color: #000000, $alpha: 0);

+ 62 - 0
price-collection/uni_modules/uni-scss/variables.scss

@@ -0,0 +1,62 @@
1
+@import './styles/setting/_variables.scss';
2
+// 间距基础倍数
3
+$uni-space-root: 2;
4
+// 边框半径默认值
5
+$uni-radius-root:5px;
6
+
7
+// 主色
8
+$uni-primary: #2979ff;
9
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
10
+$uni-primary-light: mix(#fff,$uni-primary,80%);
11
+
12
+// 辅助色
13
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
14
+$uni-success: #18bc37;
15
+$uni-success-disable:mix(#fff,$uni-success,50%);
16
+$uni-success-light: mix(#fff,$uni-success,80%);
17
+
18
+$uni-warning: #f3a73f;
19
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
20
+$uni-warning-light: mix(#fff,$uni-warning,80%);
21
+
22
+$uni-error: #e43d33;
23
+$uni-error-disable:mix(#fff,$uni-error,50%);
24
+$uni-error-light: mix(#fff,$uni-error,80%);
25
+
26
+$uni-info: #8f939c;
27
+$uni-info-disable:mix(#fff,$uni-info,50%);
28
+$uni-info-light: mix(#fff,$uni-info,80%);
29
+
30
+// 中性色
31
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
32
+$uni-main-color: #3a3a3a; 			// 主要文字
33
+$uni-base-color: #6a6a6a;			// 常规文字
34
+$uni-secondary-color: #909399;	// 次要文字
35
+$uni-extra-color: #c7c7c7;			// 辅助说明
36
+
37
+// 边框颜色
38
+$uni-border-1: #F0F0F0;
39
+$uni-border-2: #EDEDED;
40
+$uni-border-3: #DCDCDC;
41
+$uni-border-4: #B9B9B9;
42
+
43
+// 常规色
44
+$uni-black: #000000;
45
+$uni-white: #ffffff;
46
+$uni-transparent: rgba($color: #000000, $alpha: 0);
47
+
48
+// 背景色
49
+$uni-bg-color: #f7f7f7;
50
+
51
+/* 水平间距 */
52
+$uni-spacing-sm: 8px;
53
+$uni-spacing-base: 15px;
54
+$uni-spacing-lg: 30px;
55
+
56
+// 阴影
57
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
58
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
59
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
60
+
61
+// 蒙版
62
+$uni-mask: rgba($color: #000000, $alpha: 0.4);

+ 21 - 0
price-collection/uni_modules/uview-ui/LICENSE

@@ -0,0 +1,21 @@
1
+MIT License
2
+
3
+Copyright (c) 2023 www.uviewui.com
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.

+ 66 - 0
price-collection/uni_modules/uview-ui/README.md

@@ -0,0 +1,66 @@
1
+<p align="center">
2
+    <img alt="logo" src="https://uviewui.com/common/logo.png" width="120" height="120" style="margin-bottom: 10px;">
3
+</p>
4
+<h3 align="center" style="margin: 30px 0 30px;font-weight: bold;font-size:40px;">uView 2.0</h3>
5
+<h3 align="center">多平台快速开发的UI框架</h3>
6
+
7
+[![stars](https://img.shields.io/github/stars/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
8
+[![forks](https://img.shields.io/github/forks/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0)
9
+[![issues](https://img.shields.io/github/issues/umicro/uView2.0?style=flat-square&logo=GitHub)](https://github.com/umicro/uView2.0/issues)
10
+[![Website](https://img.shields.io/badge/uView-up-blue?style=flat-square)](https://uviewui.com)
11
+[![release](https://img.shields.io/github/v/release/umicro/uView2.0?style=flat-square)](https://gitee.com/umicro/uView2.0/releases)
12
+[![license](https://img.shields.io/github/license/umicro/uView2.0?style=flat-square)](https://en.wikipedia.org/wiki/MIT_License)
13
+
14
+## 说明
15
+
16
+uView UI,是[uni-app](https://uniapp.dcloud.io/)全面兼容nvue的uni-app生态框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水
17
+
18
+## [官方文档:https://uviewui.com](https://uviewui.com)
19
+
20
+
21
+## 预览
22
+
23
+您可以通过**微信**扫码,查看最佳的演示效果。
24
+<br>
25
+<br>
26
+<img src="https://uviewui.com/common/weixin_mini_qrcode.png" width="220" height="220" >
27
+
28
+
29
+## 链接
30
+
31
+- [官方文档](https://www.uviewui.com/)
32
+- [更新日志](https://www.uviewui.com/components/changelog.html)
33
+- [升级指南](https://www.uviewui.com/components/changeGuide.html)
34
+- [关于我们](https://www.uviewui.com/cooperation/about.html)
35
+
36
+## 交流反馈
37
+
38
+欢迎加入我们的QQ群交流反馈:[点此跳转](https://www.uviewui.com/components/addQQGroup.html)
39
+
40
+## 关于PR
41
+
42
+> 我们非常乐意接受各位的优质PR,但在此之前我希望您了解uView2.0是一个需要兼容多个平台的(小程序、h5、ios app、android app)包括nvue页面、vue页面。
43
+> 所以希望在您修复bug并提交之前尽可能的去这些平台测试一下兼容性。最好能携带测试截图以方便审核。非常感谢!
44
+
45
+## 安装
46
+
47
+#### **uni-app插件市场链接** —— [https://ext.dcloud.net.cn/plugin?id=1593](https://ext.dcloud.net.cn/plugin?id=1593)
48
+
49
+请通过[官网安装文档](https://www.uviewui.com/components/install.html)了解更详细的内容
50
+
51
+## 快速上手
52
+
53
+请通过[快速上手](https://uviewui.com/components/quickstart.html)了解更详细的内容
54
+
55
+## 使用方法
56
+配置easycom规则后,自动按需引入,无需`import`组件,直接引用即可。
57
+
58
+```html
59
+<template>
60
+	<u-button text="按钮"></u-button>
61
+</template>
62
+```
63
+
64
+## 版权信息
65
+uView遵循[MIT](https://en.wikipedia.org/wiki/MIT_License)开源协议,意味着您无需支付任何费用,也无需授权,即可将uView应用到您的产品中。
66
+

+ 374 - 0
price-collection/uni_modules/uview-ui/changelog.md

@@ -0,0 +1,374 @@
1
+## 2.0.37(2024-03-17)
2
+# uView2.0重磅发布,利剑出鞘,一统江湖
3
+
4
+1. 修复表单校验`trigger`触发器参数无效问题
5
+2. 修复`u-input`组件的`password`属性在动态切换为`false`时失效的问题
6
+3. 添加微信小程序用户同意隐私协议事件回调
7
+4. 修复支付宝小程序picker样式问题
8
+5. `u-modal`添加`duration`字段控制动画过度时间
9
+6. 修复`picker` `lastIndex`异常导致的`column`异常问题
10
+7. `tabs`增加长按事件支持
11
+8. 修复`u-avatar` `square`属性在小程序`open-data`下无效问题
12
+9. 其他一些修复
13
+## 2.0.36(2023-03-27)
14
+# uView2.0重磅发布,利剑出鞘,一统江湖
15
+
16
+1. 重构`deepClone` & `deepMerge`方法
17
+2. 其他优化
18
+## 2.0.34(2022-09-24)
19
+# uView2.0重磅发布,利剑出鞘,一统江湖
20
+
21
+1. `u-input`、`u-textarea`增加`ignoreCompositionEvent`属性
22
+2. 修复`route`方法调用可能报错的问题
23
+3. 修复`u-no-network`组件`z-index`无效的问题
24
+4. 修复`textarea`组件在h5上confirmType=""报错的问题
25
+5. `u-rate`适配`nvue`
26
+6. 优化验证手机号码的正则表达式(根据工信部发布的《电信网编号计划(2017年版)》进行修改。)
27
+7. `form-item`添加`labelPosition`属性
28
+8. `u-calendar`修复`maxDate`设置为当前日期,并且当前时间大于08:00时无法显示日期列表的问题 (#724)
29
+9. `u-radio`增加一个默认插槽用于自定义修改label内容 (#680)
30
+10. 修复`timeFormat`函数在safari重的兼容性问题 (#664)
31
+## 2.0.33(2022-06-17)
32
+# uView2.0重磅发布,利剑出鞘,一统江湖
33
+
34
+1. 修复`loadmore`组件`lineColor`类型错误问题
35
+2. 修复`u-parse`组件`imgtap`、`linktap`不生效问题
36
+## 2.0.32(2022-06-16)
37
+# uView2.0重磅发布,利剑出鞘,一统江湖
38
+1. `u-loadmore`新增自定义颜色、虚/实线
39
+2. 修复`u-swiper-action`组件部分平台不能上下滑动的问题
40
+3. 修复`u-list`回弹问题
41
+4. 修复`notice-bar`组件动画在低端安卓机可能会抖动的问题
42
+5. `u-loading-page`添加控制图标大小的属性`iconSize`
43
+6. 修复`u-tooltip`组件`color`参数不生效的问题
44
+7. 修复`u--input`组件使用`blur`事件输出为`undefined`的bug
45
+8. `u-code-input`组件新增键盘弹起时,是否自动上推页面参数`adjustPosition`
46
+9. 修复`image`组件`load`事件无回调对象问题
47
+10. 修复`button`组件`loadingSize`设置无效问题
48
+10. 其他修复
49
+## 2.0.31(2022-04-19)
50
+# uView2.0重磅发布,利剑出鞘,一统江湖
51
+
52
+1. 修复`upload`在`vue`页面上传成功后没有成功标志的问题
53
+2. 解决演示项目中微信小程序模拟上传图片一直出于上传中问题
54
+3. 修复`u-code-input`组件在`nvue`页面编译到`app`平台上光标异常问题(`app`去除此功能)
55
+4. 修复`actionSheet`组件标题关闭按钮点击事件名称错误的问题
56
+5. 其他修复
57
+## 2.0.30(2022-04-04)
58
+# uView2.0重磅发布,利剑出鞘,一统江湖
59
+
60
+1. `u-rate`增加`readonly`属性
61
+2. `tabs`滑块支持设置背景图片
62
+3. 修复`u-subsection` `mode`为`subsection`时,滑块样式不正确的问题
63
+4. `u-code-input`添加光标效果动画
64
+5. 修复`popup`的`open`事件不触发
65
+6. 修复`u-flex-column`无效的问题
66
+7. 修复`u-datetime-picker`索引在特定场合异常问题
67
+8. 修复`u-datetime-picker`最小时间字符串模板错误问题
68
+9. `u-swiper`添加`m3u8`验证
69
+10. `u-swiper`修改判断image和video逻辑
70
+11. 修复`swiper`无法使用本地图片问题,增加`type`参数
71
+12. 修复`u-row-notice`格式错误问题
72
+13. 修复`u-switch`组件当`unit`为`rpx`时,`nodeStyle`消失的问题
73
+14. 修复`datetime-picker`组件`showToolbar`与`visibleItemCount`属性无效的问题
74
+15. 修复`upload`组件条件编译位置判断错误,导致`previewImage`属性设置为`false`时,整个组件都会被隐藏的问题
75
+16. 修复`u-checkbox-group`设置`shape`属性无效的问题
76
+17. 修复`u-upload`的`capture`传入字符串的时候不生效的问题
77
+18. 修复`u-action-sheet`组件,关闭事件逻辑错误的问题
78
+19. 修复`u-list`触顶事件的触发错误的问题
79
+20. 修复`u-text`只有手机号可拨打的问题
80
+21. 修复`u-textarea`不能换行的问题
81
+22. 其他修复
82
+## 2.0.29(2022-03-13)
83
+# uView2.0重磅发布,利剑出鞘,一统江湖
84
+
85
+1. 修复`u--text`组件设置`decoration`属性未生效的问题
86
+2. 修复`u-datetime-picker`使用`formatter`后返回值不正确
87
+3. 修复`u-datetime-picker` `intercept` 可能为undefined
88
+4. 修复已设置单位 uni..config.unit = 'rpx'时,线型指示器 `transform` 的位置翻倍,导致指示器超出宽度
89
+5. 修复mixin中bem方法生成的类名在支付宝和字节小程序中失效
90
+6. 修复默认值传值为空的时候,打开`u-datetime-picker`报错,不能选中第一列时间的bug
91
+7. 修复`u-datetime-picker`使用`formatter`后返回值不正确
92
+8. 修复`u-image`组件`loading`无效果的问题
93
+9. 修复`config.unit`属性设为`rpx`时,导航栏占用高度不足导致塌陷的问题
94
+10. 修复`u-datetime-picker`组件`itemHeight`无效问题
95
+11. 其他修复
96
+## 2.0.28(2022-02-22)
97
+# uView2.0重磅发布,利剑出鞘,一统江湖
98
+
99
+1. search组件新增searchIconSize属性
100
+2. 兼容Safari/Webkit中传入时间格式如2022-02-17 12:00:56
101
+3. 修复text value.js 判断日期出format错误问题
102
+4. priceFormat格式化金额出现精度错误
103
+5. priceFormat在部分情况下出现精度损失问题
104
+6. 优化表单rules提示
105
+7. 修复avatar组件src为空时,展示状态不对
106
+8. 其他修复
107
+## 2.0.27(2022-01-28)
108
+# uView2.0重磅发布,利剑出鞘,一统江湖
109
+
110
+1.样式修复
111
+## 2.0.26(2022-01-28)
112
+# uView2.0重磅发布,利剑出鞘,一统江湖
113
+
114
+1.样式修复
115
+## 2.0.25(2022-01-27)
116
+# uView2.0重磅发布,利剑出鞘,一统江湖
117
+
118
+1. 修复text组件mode=price时,可能会导致精度错误的问题
119
+2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
120
+3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题
121
+4. 修复$u.addUnit()对配置默认单位可能无效的问题
122
+## 2.0.24(2022-01-25)
123
+# uView2.0重磅发布,利剑出鞘,一统江湖
124
+
125
+1. 修复swiper在current指定非0时缩放有误
126
+2. 修复u-icon添加stop属性的时候报错
127
+3. 优化遗留的通过正则判断rpx单位的问题
128
+4. 优化Layout布局 vue使用gutter时,会超出固定区域
129
+5. 优化search组件高度单位问题(rpx -> px)
130
+6. 修复u-image slot 加载和错误的图片失去了高度
131
+7. 修复u-index-list中footer插槽与header插槽存在性判断错误
132
+8. 修复部分机型下u-popup关闭时会闪烁
133
+9. 修复u-image在nvue-app下失去宽高
134
+10. 修复u-popup运行报错
135
+11. 修复u-tooltip报错
136
+12. 修复box-sizing在app下的警告
137
+13. 修复u-navbar在小程序中报运行时错误
138
+14. 其他修复
139
+## 2.0.23(2022-01-24)
140
+# uView2.0重磅发布,利剑出鞘,一统江湖
141
+
142
+1. 修复image组件在hx3.3.9的nvue下可能会显示异常的问题
143
+2. 修复col组件gutter参数带rpx单位处理不正确的问题
144
+3. 修复text组件单行时无法显示省略号的问题
145
+4. navbar添加titleStyle参数
146
+5. 升级到hx3.3.9可消除nvue下控制台样式警告的问题
147
+## 2.0.22(2022-01-19)
148
+# uView2.0重磅发布,利剑出鞘,一统江湖
149
+
150
+1. $u.page()方法优化,避免在特殊场景可能报错的问题
151
+2. picker组件添加immediateChange参数
152
+3. 新增$u.pages()方法
153
+## 2.0.21(2022-01-19)
154
+# uView2.0重磅发布,利剑出鞘,一统江湖
155
+
156
+1. 优化:form组件在用户设置rules的时候提示用户model必传
157
+2. 优化遗留的通过正则判断rpx单位的问题
158
+3. 修复微信小程序环境中tabbar组件开启safeAreaInsetBottom属性后,placeholder高度填充不正确
159
+4. 修复swiper在current指定非0时缩放有误
160
+5. 修复u-icon添加stop属性的时候报错
161
+6. 修复upload组件在accept=all的时候没有作用
162
+7. 修复在text组件mode为phone时call属性无效的问题
163
+8. 处理u-form clearValidate方法
164
+9. 其他修复
165
+## 2.0.20(2022-01-14)
166
+# uView2.0重磅发布,利剑出鞘,一统江湖
167
+
168
+1. 修复calendar默认会选择一个日期,如果直接点确定的话,无法取到值的问题
169
+2. 修复Slider缺少disabled props 还有注释
170
+3. 修复u-notice-bar点击事件无法拿到index索引值的问题
171
+4. 修复u-collapse-item在vue文件下,app端自定义插槽不生效的问题
172
+5. 优化头像为空时显示默认头像 
173
+6. 修复图片地址赋值后判断加载状态为完成问题
174
+7. 修复日历滚动到默认日期月份区域
175
+8. search组件暴露点击左边icon事件
176
+9. 修复u-form clearValidate方法不生效
177
+10. upload h5端增加返回文件参数(文件的name参数)
178
+11. 处理upload选择文件后url为blob类型无法预览的问题
179
+12. u-code-input 修复输入框没有往左移出一半屏幕
180
+13. 修复Upload上传 disabled为true时,控制台报hoverClass类型错误
181
+14. 临时处理ios app下grid点击坍塌问题
182
+15. 其他修复
183
+## 2.0.19(2021-12-29)
184
+# uView2.0重磅发布,利剑出鞘,一统江湖
185
+
186
+1. 优化微信小程序包体积可在微信中预览,请升级HbuilderX3.3.4,同时在“运行->运行到小程序模拟器”中勾选“运行时是否压缩代码”
187
+2. 优化微信小程序setData性能,处理某些方法如$u.route()无法在模板中使用的问题
188
+3. navbar添加autoBack参数
189
+4. 允许avatar组件的事件冒泡
190
+5. 修复cell组件报错问题
191
+6. 其他修复
192
+## 2.0.18(2021-12-28)
193
+# uView2.0重磅发布,利剑出鞘,一统江湖
194
+
195
+1. 修复app端编译报错问题
196
+2. 重新处理微信小程序端setData过大的性能问题
197
+3. 修复边框问题
198
+4. 修复最大最小月份不大于0则没有数据出现的问题
199
+5. 修复SwipeAction微信小程序端无法上下滑动问题
200
+6. 修复input的placeholder在小程序端默认显示为true问题
201
+7. 修复divider组件click事件无效问题
202
+8. 修复u-code-input maxlength 属性值为 String 类型时显示异常
203
+9. 修复当 grid只有 1到2时 在小程序端algin设置无效的问题
204
+10. 处理form-item的label为top时,取消错误提示的左边距
205
+11. 其他修复
206
+## 2.0.17(2021-12-26)
207
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
208
+
209
+# uView2.0重磅发布,利剑出鞘,一统江湖
210
+
211
+1. 解决HBuilderX3.3.3.20211225版本导致的样式问题
212
+2. calendar日历添加monthNum参数
213
+3. navbar添加center slot
214
+## 2.0.16(2021-12-25)
215
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
216
+
217
+# uView2.0重磅发布,利剑出鞘,一统江湖
218
+
219
+1. 解决微信小程序setData性能问题
220
+2. 修复count-down组件change事件不触发问题
221
+## 2.0.15(2021-12-21)
222
+## uView正在参与开源中国的“年度最佳项目”评选,之前投过票的现在也可以投票,恳请同学们投一票,[点此帮助uView](https://www.oschina.net/project/top_cn_2021/?id=583)
223
+
224
+# uView2.0重磅发布,利剑出鞘,一统江湖
225
+
226
+1. 修复Cell单元格titleWidth无效
227
+2. 修复cheakbox组件ischecked不更新
228
+3. 修复keyboard是否显示"."按键默认值问题
229
+4. 修复number-keyboard是否显示键盘的"."符号问题
230
+5. 修复Input输入框 readonly无效
231
+6. 修复u-avatar 导致打包app、H5时候报错问题
232
+7. 修复Upload上传deletable无效
233
+8. 修复upload当设置maxSize时无效的问题
234
+9. 修复tabs lineWidth传入带单位的字符串的时候偏移量计算错误问题
235
+10. 修复rate组件在有padding的view内,显示的星星位置和可触摸区域不匹配,无法正常选中星星
236
+## 2.0.13(2021-12-14)
237
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
238
+
239
+# uView2.0重磅发布,利剑出鞘,一统江湖
240
+
241
+1. 修复配置默认单位为rpx可能会导致自定义导航栏高度异常的问题
242
+## 2.0.12(2021-12-14)
243
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
244
+
245
+# uView2.0重磅发布,利剑出鞘,一统江湖
246
+
247
+1. 修复tabs组件在vue环境下划线消失的问题
248
+2. 修复upload组件在安卓小程序无法选择视频的问题
249
+3. 添加uni.$u.config.unit配置,用于配置参数默认单位,详见:[默认单位配置](https://www.uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE)
250
+4. 修复textarea组件在没绑定v-model时,字符统计不生效问题
251
+5. 修复nvue下控制是否出现滚动条失效问题
252
+## 2.0.11(2021-12-13)
253
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
254
+
255
+# uView2.0重磅发布,利剑出鞘,一统江湖
256
+
257
+1. text组件align参数无效的问题
258
+2. subsection组件添加keyName参数
259
+3. upload组件无法判断[Object file]类型的问题
260
+4. 处理notify层级过低问题
261
+5. codeInput组件添加disabledDot参数
262
+6. 处理actionSheet组件round参数无效的问题
263
+7. calendar组件添加round参数用于控制圆角值
264
+8. 处理swipeAction组件在vue环境下默认被打开的问题
265
+9. button组件的throttleTime节流参数无效的问题
266
+10. 解决u-notify手动关闭方法close()无效的问题
267
+11. input组件readonly不生效问题
268
+12. tag组件type参数为info不生效问题
269
+## 2.0.10(2021-12-08)
270
+## [点击加群交流反馈:364463526](https://jq.qq.com/?_chanwv=1027&k=mCxS3TGY)
271
+
272
+# uView2.0重磅发布,利剑出鞘,一统江湖
273
+
274
+1. 修复button sendMessagePath属性不生效
275
+2. 修复DatetimePicker选择器title无效
276
+3. 修复u-toast设置loading=true不生效
277
+4. 修复u-text金额模式传0报错
278
+5. 修复u-toast组件的icon属性配置不生效
279
+6. button的icon在特殊场景下的颜色优化
280
+7. IndexList优化,增加#
281
+## 2.0.9(2021-12-01)
282
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
283
+
284
+# uView2.0重磅发布,利剑出鞘,一统江湖
285
+
286
+1. 优化swiper的height支持100%值(仅vue有效),修复嵌入视频时click事件无法触发的问题
287
+2. 优化tabs组件对list值为空的判断,或者动态变化list时重新计算相关尺寸的问题
288
+3. 优化datetime-picker组件逻辑,让其后续打开的默认值为上一次的选中值,需要通过v-model绑定值才有效
289
+4. 修复upload内嵌在其他组件中,选择图片可能不会换行的问题
290
+## 2.0.8(2021-12-01)
291
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
292
+
293
+# uView2.0重磅发布,利剑出鞘,一统江湖
294
+
295
+1. 修复toast的position参数无效问题
296
+2. 处理input在ios nvue上无法获得焦点的问题
297
+3. avatar-group组件添加extraValue参数,让剩余展示数量可手动控制
298
+4. tabs组件添加keyName参数用于配置从对象中读取的键名
299
+5. 处理text组件名字脱敏默认配置无效的问题
300
+6. 处理picker组件item文本太长换行问题
301
+## 2.0.7(2021-11-30)
302
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
303
+
304
+# uView2.0重磅发布,利剑出鞘,一统江湖
305
+
306
+1. 修复radio和checkbox动态改变v-model无效的问题。
307
+2. 优化form规则validator在微信小程序用法
308
+3. 修复backtop组件mode参数在微信小程序无效的问题
309
+4. 处理Album的previewFullImage属性无效的问题
310
+5. 处理u-datetime-picker组件mode='time'在选择改变时间时,控制台报错的问题
311
+## 2.0.6(2021-11-27)
312
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
313
+
314
+# uView2.0重磅发布,利剑出鞘,一统江湖
315
+
316
+1. 处理tag组件在vue下边框无效的问题。
317
+2. 处理popup组件圆角参数可能无效的问题。
318
+3. 处理tabs组件lineColor参数可能无效的问题。
319
+4. propgress组件在值很小时,显示异常的问题。
320
+## 2.0.5(2021-11-25)
321
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
322
+
323
+# uView2.0重磅发布,利剑出鞘,一统江湖
324
+
325
+1. calendar在vue下显示异常问题。 
326
+2. form组件labelPosition和errorType参数无效的问题
327
+3. input组件inputAlign无效的问题
328
+4. 其他一些修复
329
+## 2.0.4(2021-11-23)
330
+## [点击加群交流反馈:232041042](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
331
+
332
+# uView2.0重磅发布,利剑出鞘,一统江湖
333
+
334
+0. input组件缺失@confirm事件,以及subfix和prefix无效问题
335
+1. component.scss文件样式在vue下干扰全局布局问题
336
+2. 修复subsection在vue环境下表现异常的问题
337
+3. tag组件的bgColor等参数无效的问题
338
+4. upload组件不换行的问题
339
+5. 其他的一些修复处理
340
+## 2.0.3(2021-11-16)
341
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
342
+
343
+# uView2.0重磅发布,利剑出鞘,一统江湖
344
+
345
+1. uView2.0已实现全面兼容nvue
346
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
347
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
348
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
349
+5. 处理modal的confirm回调事件拼写错误问题
350
+6. 处理input组件@input事件参数错误问题
351
+7. 其他一些修复
352
+## 2.0.2(2021-11-16)
353
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
354
+
355
+# uView2.0重磅发布,利剑出鞘,一统江湖
356
+
357
+1. uView2.0已实现全面兼容nvue
358
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
359
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
360
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
361
+5. 修复input组件formatter参数缺失问题
362
+6. 优化loading-icon组件的scss写法问题,防止不兼容新版本scss
363
+## 2.0.0(2020-11-15)
364
+## [点击加群交流反馈:1129077272](https://jq.qq.com/?_wv=1027&k=KnbeceDU)
365
+
366
+# uView2.0重磅发布,利剑出鞘,一统江湖
367
+
368
+1. uView2.0已实现全面兼容nvue
369
+2. uView2.0对1.x进行了架构重构,细节和性能都有极大提升
370
+3. 目前uView2.0为公测阶段,相关细节可能会有变动
371
+4. 我们写了一份与1.x的对比指南,详见[对比1.x](https://www.uviewui.com/components/diff1.x.html)
372
+5. 修复input组件formatter参数缺失问题
373
+
374
+

+ 78 - 0
price-collection/uni_modules/uview-ui/components/u--form/u--form.vue

@@ -0,0 +1,78 @@
1
+<template>
2
+	<uvForm
3
+		ref="uForm"
4
+		:model="model"
5
+		:rules="rules"
6
+		:errorType="errorType"
7
+		:borderBottom="borderBottom"
8
+		:labelPosition="labelPosition"
9
+		:labelWidth="labelWidth"
10
+		:labelAlign="labelAlign"
11
+		:labelStyle="labelStyle"
12
+		:customStyle="customStyle"
13
+	>
14
+		<slot />
15
+	</uvForm>
16
+</template>
17
+
18
+<script>
19
+	/**
20
+	 * 此组件存在的理由是,在nvue下,u-form被uni-app官方占用了,u-form在nvue中相当于form组件
21
+	 * 所以在nvue下,取名为u--form,内部其实还是u-form.vue,只不过做一层中转
22
+	 */
23
+	import uvForm from '../u-form/u-form.vue';
24
+	import props from '../u-form/props.js'
25
+	export default {
26
+		// #ifdef MP-WEIXIN
27
+		name: 'u-form',
28
+		// #endif
29
+		// #ifndef MP-WEIXIN
30
+		name: 'u--form',
31
+		// #endif
32
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
33
+		components: {
34
+			uvForm
35
+		},
36
+		created() {
37
+			this.children = []
38
+		},
39
+		methods: {
40
+			// 手动设置校验的规则,如果规则中有函数的话,微信小程序中会过滤掉,所以只能手动调用设置规则
41
+			setRules(rules) {
42
+				this.$refs.uForm.setRules(rules)
43
+			},
44
+			validate() {
45
+				/**
46
+				 * 在微信小程序中,通过this.$parent拿到的父组件是u--form,而不是其内嵌的u-form
47
+				 * 导致在u-form组件中,拿不到对应的children数组,从而校验无效,所以这里每次调用u-form组件中的
48
+				 * 对应方法的时候,在小程序中都先将u--form的children赋值给u-form中的children
49
+				 */
50
+				// #ifdef MP-WEIXIN
51
+				this.setMpData()
52
+				// #endif
53
+				return this.$refs.uForm.validate()
54
+			},
55
+			validateField(value, callback, event) {
56
+				// #ifdef MP-WEIXIN
57
+				this.setMpData()
58
+				// #endif
59
+				return this.$refs.uForm.validateField(value, callback, event)
60
+			},
61
+			resetFields() {
62
+				// #ifdef MP-WEIXIN
63
+				this.setMpData()
64
+				// #endif
65
+				return this.$refs.uForm.resetFields()
66
+			},
67
+			clearValidate(props) {
68
+				// #ifdef MP-WEIXIN
69
+				this.setMpData()
70
+				// #endif
71
+				return this.$refs.uForm.clearValidate(props)
72
+			},
73
+			setMpData() {
74
+				this.$refs.uForm.children = this.children
75
+			}
76
+		},
77
+	}
78
+</script>

+ 47 - 0
price-collection/uni_modules/uview-ui/components/u--image/u--image.vue

@@ -0,0 +1,47 @@
1
+<template>
2
+	<uvImage 
3
+		:src="src"
4
+		:mode="mode"
5
+		:width="width"
6
+		:height="height"
7
+		:shape="shape"
8
+		:radius="radius"
9
+		:lazyLoad="lazyLoad"
10
+		:showMenuByLongpress="showMenuByLongpress"
11
+		:loadingIcon="loadingIcon"
12
+		:errorIcon="errorIcon"
13
+		:showLoading="showLoading"
14
+		:showError="showError"
15
+		:fade="fade"
16
+		:webp="webp"
17
+		:duration="duration"
18
+		:bgColor="bgColor"
19
+		:customStyle="customStyle"
20
+		@click="$emit('click')"
21
+		@error="$emit('error')"
22
+		@load="$emit('load')"
23
+	>
24
+		<template v-slot:loading>
25
+			<slot name="loading"></slot>
26
+		</template>
27
+		<template v-slot:error>
28
+			<slot name="error"></slot>
29
+		</template>
30
+	</uvImage>
31
+</template>
32
+
33
+<script>
34
+	/**
35
+	 * 此组件存在的理由是,在nvue下,u-image被uni-app官方占用了,u-image在nvue中相当于image组件
36
+	 * 所以在nvue下,取名为u--image,内部其实还是u-iamge.vue,只不过做一层中转
37
+	 */
38
+	import uvImage from '../u-image/u-image.vue';
39
+	import props from '../u-image/props.js';
40
+	export default {
41
+		name: 'u--image',
42
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
43
+		components: {
44
+			uvImage
45
+		},
46
+	}
47
+</script>

+ 73 - 0
price-collection/uni_modules/uview-ui/components/u--input/u--input.vue

@@ -0,0 +1,73 @@
1
+<template>
2
+	<uvInput 
3
+		:value="value"
4
+		:type="type"
5
+		:fixed="fixed"
6
+		:disabled="disabled"
7
+		:disabledColor="disabledColor"
8
+		:clearable="clearable"
9
+		:password="password"
10
+		:maxlength="maxlength"
11
+		:placeholder="placeholder"
12
+		:placeholderClass="placeholderClass"
13
+		:placeholderStyle="placeholderStyle"
14
+		:showWordLimit="showWordLimit"
15
+		:confirmType="confirmType"
16
+		:confirmHold="confirmHold"
17
+		:holdKeyboard="holdKeyboard"
18
+		:focus="focus"
19
+		:autoBlur="autoBlur"
20
+		:disableDefaultPadding="disableDefaultPadding"
21
+		:cursor="cursor"
22
+		:cursorSpacing="cursorSpacing"
23
+		:selectionStart="selectionStart"
24
+		:selectionEnd="selectionEnd"
25
+		:adjustPosition="adjustPosition"
26
+		:inputAlign="inputAlign"
27
+		:fontSize="fontSize"
28
+		:color="color"
29
+		:prefixIcon="prefixIcon"
30
+		:suffixIcon="suffixIcon"
31
+		:suffixIconStyle="suffixIconStyle"
32
+		:prefixIconStyle="prefixIconStyle"
33
+		:border="border"
34
+		:readonly="readonly"
35
+		:shape="shape"
36
+		:customStyle="customStyle"
37
+		:formatter="formatter"
38
+		:ignoreCompositionEvent="ignoreCompositionEvent"
39
+		@focus="$emit('focus')"
40
+		@blur="e => $emit('blur', e)"
41
+		@keyboardheightchange="$emit('keyboardheightchange')"
42
+		@change="e => $emit('change', e)"
43
+		@input="e => $emit('input', e)"
44
+		@confirm="e => $emit('confirm', e)"
45
+		@clear="$emit('clear')"
46
+		@click="$emit('click')"
47
+	>
48
+		<!-- #ifdef MP -->
49
+		<slot name="prefix"></slot>
50
+		<slot name="suffix"></slot>
51
+		<!-- #endif -->
52
+		<!-- #ifndef MP -->
53
+		<slot name="prefix" slot="prefix"></slot>
54
+		<slot name="suffix" slot="suffix"></slot>
55
+		<!-- #endif -->
56
+	</uvInput>
57
+</template>
58
+
59
+<script>
60
+	/**
61
+	 * 此组件存在的理由是,在nvue下,u-input被uni-app官方占用了,u-input在nvue中相当于input组件
62
+	 * 所以在nvue下,取名为u--input,内部其实还是u-input.vue,只不过做一层中转
63
+	 */
64
+	import uvInput from '../u-input/u-input.vue';
65
+	import props from '../u-input/props.js'
66
+	export default {
67
+		name: 'u--input',
68
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
69
+		components: {
70
+			uvInput
71
+		},
72
+	}
73
+</script>

+ 44 - 0
price-collection/uni_modules/uview-ui/components/u--text/u--text.vue

@@ -0,0 +1,44 @@
1
+<template>
2
+    <uvText
3
+        :type="type"
4
+        :show="show"
5
+        :text="text"
6
+        :prefixIcon="prefixIcon"
7
+        :suffixIcon="suffixIcon"
8
+        :mode="mode"
9
+        :href="href"
10
+        :format="format"
11
+        :call="call"
12
+        :openType="openType"
13
+        :bold="bold"
14
+        :block="block"
15
+        :lines="lines"
16
+        :color="color"
17
+		:decoration="decoration"
18
+        :size="size"
19
+        :iconStyle="iconStyle"
20
+        :margin="margin"
21
+        :lineHeight="lineHeight"
22
+        :align="align"
23
+        :wordWrap="wordWrap"
24
+        :customStyle="customStyle"
25
+        @click="$emit('click')"
26
+    ></uvText>
27
+</template>
28
+
29
+<script>
30
+/**
31
+ * 此组件存在的理由是,在nvue下,u-text被uni-app官方占用了,u-text在nvue中相当于input组件
32
+ * 所以在nvue下,取名为u--input,内部其实还是u-text.vue,只不过做一层中转
33
+ * 不使用v-bind="$attrs",而是分开独立写传参,是因为微信小程序不支持此写法
34
+ */
35
+import uvText from "../u-text/u-text.vue";
36
+import props from "../u-text/props.js";
37
+export default {
38
+    name: "u--text",
39
+    mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
40
+    components: {
41
+        uvText,
42
+    },
43
+};
44
+</script>

+ 48 - 0
price-collection/uni_modules/uview-ui/components/u--textarea/u--textarea.vue

@@ -0,0 +1,48 @@
1
+<template>
2
+	<uvTextarea
3
+		:value="value"
4
+		:placeholder="placeholder"
5
+		:height="height"
6
+		:confirmType="confirmType"
7
+		:disabled="disabled"
8
+		:count="count"
9
+		:focus="focus"
10
+		:autoHeight="autoHeight"
11
+		:fixed="fixed"
12
+		:cursorSpacing="cursorSpacing"
13
+		:cursor="cursor"
14
+		:showConfirmBar="showConfirmBar"
15
+		:selectionStart="selectionStart"
16
+		:selectionEnd="selectionEnd"
17
+		:adjustPosition="adjustPosition"
18
+		:disableDefaultPadding="disableDefaultPadding"
19
+		:holdKeyboard="holdKeyboard"
20
+		:maxlength="maxlength"
21
+		:border="border"
22
+		:customStyle="customStyle"
23
+		:formatter="formatter"
24
+		:ignoreCompositionEvent="ignoreCompositionEvent"
25
+		@focus="e => $emit('focus')"
26
+		@blur="e => $emit('blur')"
27
+		@linechange="e => $emit('linechange', e)"
28
+		@confirm="e => $emit('confirm')"
29
+		@input="e => $emit('input', e)"
30
+		@keyboardheightchange="e => $emit('keyboardheightchange')"
31
+	></uvTextarea>
32
+</template>
33
+
34
+<script>
35
+	/**
36
+	 * 此组件存在的理由是,在nvue下,u--textarea被uni-app官方占用了,u-textarea在nvue中相当于textarea组件
37
+	 * 所以在nvue下,取名为u--textarea,内部其实还是u-textarea.vue,只不过做一层中转
38
+	 */
39
+	import uvTextarea from '../u-textarea/u-textarea.vue';
40
+	import props from '../u-textarea/props.js'
41
+	export default {
42
+		name: 'u--textarea',
43
+		mixins: [uni.$u.mpMixin, props, uni.$u.mixin],
44
+		components: {
45
+			uvTextarea
46
+		},
47
+	}
48
+</script>

+ 54 - 0
price-collection/uni_modules/uview-ui/components/u-action-sheet/props.js

@@ -0,0 +1,54 @@
1
+export default {
2
+    props: {
3
+        // 操作菜单是否展示 (默认false)
4
+        show: {
5
+            type: Boolean,
6
+            default: uni.$u.props.actionSheet.show
7
+        },
8
+        // 标题
9
+        title: {
10
+            type: String,
11
+            default: uni.$u.props.actionSheet.title
12
+        },
13
+        // 选项上方的描述信息
14
+        description: {
15
+            type: String,
16
+            default: uni.$u.props.actionSheet.description
17
+        },
18
+        // 数据
19
+        actions: {
20
+            type: Array,
21
+            default: uni.$u.props.actionSheet.actions
22
+        },
23
+        // 取消按钮的文字,不为空时显示按钮
24
+        cancelText: {
25
+            type: String,
26
+            default: uni.$u.props.actionSheet.cancelText
27
+        },
28
+        // 点击某个菜单项时是否关闭弹窗
29
+        closeOnClickAction: {
30
+            type: Boolean,
31
+            default: uni.$u.props.actionSheet.closeOnClickAction
32
+        },
33
+        // 处理底部安全区(默认true)
34
+        safeAreaInsetBottom: {
35
+            type: Boolean,
36
+            default: uni.$u.props.actionSheet.safeAreaInsetBottom
37
+        },
38
+        // 小程序的打开方式
39
+        openType: {
40
+            type: String,
41
+            default: uni.$u.props.actionSheet.openType
42
+        },
43
+        // 点击遮罩是否允许关闭 (默认true)
44
+        closeOnClickOverlay: {
45
+            type: Boolean,
46
+            default: uni.$u.props.actionSheet.closeOnClickOverlay
47
+        },
48
+        // 圆角值
49
+        round: {
50
+            type: [Boolean, String, Number],
51
+            default: uni.$u.props.actionSheet.round
52
+        }
53
+    }
54
+}

+ 278 - 0
price-collection/uni_modules/uview-ui/components/u-action-sheet/u-action-sheet.vue

@@ -0,0 +1,278 @@
1
+
2
+<template>
3
+	<u-popup
4
+	    :show="show"
5
+	    mode="bottom"
6
+	    @close="closeHandler"
7
+	    :safeAreaInsetBottom="safeAreaInsetBottom"
8
+	    :round="round"
9
+	>
10
+		<view class="u-action-sheet">
11
+			<view
12
+			    class="u-action-sheet__header"
13
+			    v-if="title"
14
+			>
15
+				<text class="u-action-sheet__header__title u-line-1">{{title}}</text>
16
+				<view
17
+				    class="u-action-sheet__header__icon-wrap"
18
+				    @tap.stop="cancel"
19
+				>
20
+					<u-icon
21
+					    name="close"
22
+					    size="17"
23
+					    color="#c8c9cc"
24
+					    bold
25
+					></u-icon>
26
+				</view>
27
+			</view>
28
+			<text
29
+			    class="u-action-sheet__description"
30
+				:style="[{
31
+					marginTop: `${title && description ? 0 : '18px'}`
32
+				}]"
33
+			    v-if="description"
34
+			>{{description}}</text>
35
+			<slot>
36
+				<u-line v-if="description"></u-line>
37
+				<view class="u-action-sheet__item-wrap">
38
+					<template v-for="(item, index) in actions">
39
+						<!-- #ifdef MP -->
40
+						<button
41
+						    :key="index"
42
+						    class="u-reset-button"
43
+						    :openType="item.openType"
44
+						    @getuserinfo="onGetUserInfo"
45
+						    @contact="onContact"
46
+						    @getphonenumber="onGetPhoneNumber"
47
+						    @error="onError"
48
+						    @launchapp="onLaunchApp"
49
+						    @opensetting="onOpenSetting"
50
+						    :lang="lang"
51
+						    :session-from="sessionFrom"
52
+						    :send-message-title="sendMessageTitle"
53
+						    :send-message-path="sendMessagePath"
54
+						    :send-message-img="sendMessageImg"
55
+						    :show-message-card="showMessageCard"
56
+						    :app-parameter="appParameter"
57
+						    @tap="selectHandler(index)"
58
+						    :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
59
+						>
60
+							<!-- #endif -->
61
+							<view
62
+							    class="u-action-sheet__item-wrap__item"
63
+							    @tap.stop="selectHandler(index)"
64
+							    :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"
65
+							    :hover-stay-time="150"
66
+							>
67
+								<template v-if="!item.loading">
68
+									<text
69
+									    class="u-action-sheet__item-wrap__item__name"
70
+									    :style="[itemStyle(index)]"
71
+									>{{ item.name }}</text>
72
+									<text
73
+									    v-if="item.subname"
74
+									    class="u-action-sheet__item-wrap__item__subname"
75
+									>{{ item.subname }}</text>
76
+								</template>
77
+								<u-loading-icon
78
+								    v-else
79
+								    custom-class="van-action-sheet__loading"
80
+								    size="18"
81
+								    mode="circle"
82
+								/>
83
+							</view>
84
+							<!-- #ifdef MP -->
85
+						</button>
86
+						<!-- #endif -->
87
+						<u-line v-if="index !== actions.length - 1"></u-line>
88
+					</template>
89
+				</view>
90
+			</slot>
91
+			<u-gap
92
+			    bgColor="#eaeaec"
93
+			    height="6"
94
+			    v-if="cancelText"
95
+			></u-gap>
96
+			<view hover-class="u-action-sheet--hover">
97
+				<text
98
+				    @touchmove.stop.prevent
99
+				    :hover-stay-time="150"
100
+				    v-if="cancelText"
101
+				    class="u-action-sheet__cancel-text"
102
+				    @tap="cancel"
103
+				>{{cancelText}}</text>
104
+			</view>
105
+		</view>
106
+	</u-popup>
107
+</template>
108
+
109
+<script>
110
+	import openType from '../../libs/mixin/openType'
111
+	import button from '../../libs/mixin/button'
112
+	import props from './props.js';
113
+	/**
114
+	 * ActionSheet 操作菜单
115
+	 * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
116
+	 * @tutorial https://www.uviewui.com/components/actionSheet.html
117
+	 * 
118
+	 * @property {Boolean}			show				操作菜单是否展示 (默认 false )
119
+	 * @property {String}			title				操作菜单标题
120
+	 * @property {String}			description			选项上方的描述信息
121
+	 * @property {Array<Object>}	actions				按钮的文字数组,见官方文档示例
122
+	 * @property {String}			cancelText			取消按钮的提示文字,不为空时显示按钮
123
+	 * @property {Boolean}			closeOnClickAction	点击某个菜单项时是否关闭弹窗 (默认 true )
124
+	 * @property {Boolean}			safeAreaInsetBottom	处理底部安全区 (默认 true )
125
+	 * @property {String}			openType			小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
126
+	 * @property {Boolean}			closeOnClickOverlay	点击遮罩是否允许关闭  (默认 true )
127
+	 * @property {Number|String}	round				圆角值,默认无圆角  (默认 0 )
128
+	 * @property {String}			lang				指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
129
+	 * @property {String}			sessionFrom			会话来源,openType="contact"时有效
130
+	 * @property {String}			sendMessageTitle	会话内消息卡片标题,openType="contact"时有效
131
+	 * @property {String}			sendMessagePath		会话内消息卡片点击跳转小程序路径,openType="contact"时有效
132
+	 * @property {String}			sendMessageImg		会话内消息卡片图片,openType="contact"时有效
133
+	 * @property {Boolean}			showMessageCard		是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
134
+	 * @property {String}			appParameter		打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
135
+	 * 
136
+	 * @event {Function} select			点击ActionSheet列表项时触发 
137
+	 * @event {Function} close			点击取消按钮时触发
138
+	 * @event {Function} getuserinfo	用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
139
+	 * @event {Function} contact		客服消息回调,openType="contact"时有效
140
+	 * @event {Function} getphonenumber	获取用户手机号回调,openType="getPhoneNumber"时有效
141
+	 * @event {Function} error			当使用开放能力时,发生错误的回调,openType="error"时有效
142
+	 * @event {Function} launchapp		打开 APP 成功的回调,openType="launchApp"时有效
143
+	 * @event {Function} opensetting	在打开授权设置页后回调,openType="openSetting"时有效
144
+	 * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
145
+	 */
146
+	export default {
147
+		name: "u-action-sheet",
148
+		// 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
149
+		mixins: [openType, button, uni.$u.mixin, props],
150
+		data() {
151
+			return {
152
+
153
+			}
154
+		},
155
+		computed: {
156
+			// 操作项目的样式
157
+			itemStyle() {
158
+				return (index) => {
159
+					let style = {};
160
+					if (this.actions[index].color) style.color = this.actions[index].color
161
+					if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
162
+					// 选项被禁用的样式
163
+					if (this.actions[index].disabled) style.color = '#c0c4cc'
164
+					return style;
165
+				}
166
+			},
167
+		},
168
+		methods: {
169
+			closeHandler() {
170
+				// 允许点击遮罩关闭时,才发出close事件
171
+				if(this.closeOnClickOverlay) {
172
+					this.$emit('close')
173
+				}
174
+			},
175
+			// 点击取消按钮
176
+			cancel() {
177
+				this.$emit('close')
178
+			},
179
+			selectHandler(index) {
180
+				const item = this.actions[index]
181
+				if (item && !item.disabled && !item.loading) {
182
+					this.$emit('select', item)
183
+					if (this.closeOnClickAction) {
184
+						this.$emit('close')
185
+					}
186
+				}
187
+			},
188
+		}
189
+	}
190
+</script>
191
+
192
+<style lang="scss" scoped>
193
+	@import "../../libs/css/components.scss";
194
+	$u-action-sheet-reset-button-width:100% !default;
195
+	$u-action-sheet-title-font-size: 16px !default;
196
+	$u-action-sheet-title-padding: 12px 30px !default;
197
+	$u-action-sheet-title-color: $u-main-color !default;
198
+	$u-action-sheet-header-icon-wrap-right:15px !default;
199
+	$u-action-sheet-header-icon-wrap-top:15px !default;
200
+	$u-action-sheet-description-font-size:13px !default;
201
+	$u-action-sheet-description-color:14px !default;
202
+	$u-action-sheet-description-margin: 18px 15px !default;
203
+	$u-action-sheet-item-wrap-item-padding:15px !default;
204
+	$u-action-sheet-item-wrap-name-font-size:16px !default;
205
+	$u-action-sheet-item-wrap-subname-font-size:13px !default;
206
+	$u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
207
+	$u-action-sheet-item-wrap-subname-margin-top:10px !default;
208
+	$u-action-sheet-cancel-text-font-size:16px !default;
209
+	$u-action-sheet-cancel-text-color:$u-content-color !default;
210
+	$u-action-sheet-cancel-text-font-size:15px !default;
211
+	$u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default;
212
+
213
+	.u-reset-button {
214
+		width: $u-action-sheet-reset-button-width;
215
+	}
216
+
217
+	.u-action-sheet {
218
+		text-align: center;
219
+		&__header {
220
+			position: relative;
221
+			padding: $u-action-sheet-title-padding;
222
+			&__title {
223
+				font-size: $u-action-sheet-title-font-size;
224
+				color: $u-action-sheet-title-color;
225
+				font-weight: bold;
226
+				text-align: center;
227
+			}
228
+
229
+			&__icon-wrap {
230
+				position: absolute;
231
+				right: $u-action-sheet-header-icon-wrap-right;
232
+				top: $u-action-sheet-header-icon-wrap-top;
233
+			}
234
+		}
235
+
236
+		&__description {
237
+			font-size: $u-action-sheet-description-font-size;
238
+			color: $u-tips-color;
239
+			margin: $u-action-sheet-description-margin;
240
+			text-align: center;
241
+		}
242
+
243
+		&__item-wrap {
244
+
245
+			&__item {
246
+				padding: $u-action-sheet-item-wrap-item-padding;
247
+				@include flex;
248
+				align-items: center;
249
+				justify-content: center;
250
+				flex-direction: column;
251
+
252
+				&__name {
253
+					font-size: $u-action-sheet-item-wrap-name-font-size;
254
+					color: $u-main-color;
255
+					text-align: center;
256
+				}
257
+
258
+				&__subname {
259
+					font-size: $u-action-sheet-item-wrap-subname-font-size;
260
+					color: $u-action-sheet-item-wrap-subname-color;
261
+					margin-top: $u-action-sheet-item-wrap-subname-margin-top;
262
+					text-align: center;
263
+				}
264
+			}
265
+		}
266
+
267
+		&__cancel-text {
268
+			font-size: $u-action-sheet-cancel-text-font-size;
269
+			color: $u-action-sheet-cancel-text-color;
270
+			text-align: center;
271
+			padding: $u-action-sheet-cancel-text-font-size;
272
+		}
273
+
274
+		&--hover {
275
+			background-color: $u-action-sheet-cancel-text-hover-background-color;
276
+		}
277
+	}
278
+</style>

+ 59 - 0
price-collection/uni_modules/uview-ui/components/u-album/props.js

@@ -0,0 +1,59 @@
1
+export default {
2
+    props: {
3
+        // 图片地址,Array<String>|Array<Object>形式
4
+        urls: {
5
+            type: Array,
6
+            default: uni.$u.props.album.urls
7
+        },
8
+        // 指定从数组的对象元素中读取哪个属性作为图片地址
9
+        keyName: {
10
+            type: String,
11
+            default: uni.$u.props.album.keyName
12
+        },
13
+        // 单图时,图片长边的长度
14
+        singleSize: {
15
+            type: [String, Number],
16
+            default: uni.$u.props.album.singleSize
17
+        },
18
+        // 多图时,图片边长
19
+        multipleSize: {
20
+            type: [String, Number],
21
+            default: uni.$u.props.album.multipleSize
22
+        },
23
+        // 多图时,图片水平和垂直之间的间隔
24
+        space: {
25
+            type: [String, Number],
26
+            default: uni.$u.props.album.space
27
+        },
28
+        // 单图时,图片缩放裁剪的模式
29
+        singleMode: {
30
+            type: String,
31
+            default: uni.$u.props.album.singleMode
32
+        },
33
+        // 多图时,图片缩放裁剪的模式
34
+        multipleMode: {
35
+            type: String,
36
+            default: uni.$u.props.album.multipleMode
37
+        },
38
+        // 最多展示的图片数量,超出时最后一个位置将会显示剩余图片数量
39
+        maxCount: {
40
+            type: [String, Number],
41
+            default: uni.$u.props.album.maxCount
42
+        },
43
+        // 是否可以预览图片
44
+        previewFullImage: {
45
+            type: Boolean,
46
+            default: uni.$u.props.album.previewFullImage
47
+        },
48
+        // 每行展示图片数量,如设置,singleSize和multipleSize将会无效
49
+        rowCount: {
50
+            type: [String, Number],
51
+            default: uni.$u.props.album.rowCount
52
+        },
53
+        // 超出maxCount时是否显示查看更多的提示
54
+        showMore: {
55
+            type: Boolean,
56
+            default: uni.$u.props.album.showMore
57
+        }
58
+    }
59
+}

+ 259 - 0
price-collection/uni_modules/uview-ui/components/u-album/u-album.vue

@@ -0,0 +1,259 @@
1
+<template>
2
+    <view class="u-album">
3
+        <view
4
+            class="u-album__row"
5
+            ref="u-album__row"
6
+            v-for="(arr, index) in showUrls"
7
+            :forComputedUse="albumWidth"
8
+            :key="index"
9
+        >
10
+            <view
11
+                class="u-album__row__wrapper"
12
+                v-for="(item, index1) in arr"
13
+                :key="index1"
14
+                :style="[imageStyle(index + 1, index1 + 1)]"
15
+                @tap="previewFullImage ? onPreviewTap(getSrc(item)) : ''"
16
+            >
17
+                <image
18
+                    :src="getSrc(item)"
19
+                    :mode="
20
+                        urls.length === 1
21
+                            ? imageHeight > 0
22
+                                ? singleMode
23
+                                : 'widthFix'
24
+                            : multipleMode
25
+                    "
26
+                    :style="[
27
+                        {
28
+                            width: imageWidth,
29
+                            height: imageHeight
30
+                        }
31
+                    ]"
32
+                ></image>
33
+                <view
34
+                    v-if="
35
+                        showMore &&
36
+                        urls.length > rowCount * showUrls.length &&
37
+                        index === showUrls.length - 1 &&
38
+                        index1 === showUrls[showUrls.length - 1].length - 1
39
+                    "
40
+                    class="u-album__row__wrapper__text"
41
+                >
42
+                    <u--text
43
+                        :text="`+${urls.length - maxCount}`"
44
+                        color="#fff"
45
+                        :size="multipleSize * 0.3"
46
+                        align="center"
47
+                        customStyle="justify-content: center"
48
+                    ></u--text>
49
+                </view>
50
+            </view>
51
+        </view>
52
+    </view>
53
+</template>
54
+
55
+<script>
56
+import props from './props.js'
57
+// #ifdef APP-NVUE
58
+// 由于weex为阿里的KPI业绩考核的产物,所以不支持百分比单位,这里需要通过dom查询组件的宽度
59
+const dom = uni.requireNativePlugin('dom')
60
+// #endif
61
+
62
+/**
63
+ * Album 相册
64
+ * @description 本组件提供一个类似相册的功能,让开发者开发起来更加得心应手。减少重复的模板代码
65
+ * @tutorial https://www.uviewui.com/components/album.html
66
+ *
67
+ * @property {Array}           urls             图片地址列表 Array<String>|Array<Object>形式
68
+ * @property {String}          keyName          指定从数组的对象元素中读取哪个属性作为图片地址
69
+ * @property {String | Number} singleSize       单图时,图片长边的长度  (默认 180 )
70
+ * @property {String | Number} multipleSize     多图时,图片边长 (默认 70 )
71
+ * @property {String | Number} space            多图时,图片水平和垂直之间的间隔 (默认 6 )
72
+ * @property {String}          singleMode       单图时,图片缩放裁剪的模式 (默认 'scaleToFill' )
73
+ * @property {String}          multipleMode     多图时,图片缩放裁剪的模式 (默认 'aspectFill' )
74
+ * @property {String | Number} maxCount         取消按钮的提示文字 (默认 9 )
75
+ * @property {Boolean}         previewFullImage 是否可以预览图片 (默认 true )
76
+ * @property {String | Number} rowCount         每行展示图片数量,如设置,singleSize和multipleSize将会无效	(默认 3 )
77
+ * @property {Boolean}         showMore         超出maxCount时是否显示查看更多的提示 (默认 true )
78
+ *
79
+ * @event    {Function}        albumWidth       某些特殊的情况下,需要让文字与相册的宽度相等,这里事件的形式对外发送  (回调参数 width )
80
+ * @example <u-album :urls="urls2" @albumWidth="width => albumWidth = width" multipleSize="68" ></u-album>
81
+ */
82
+export default {
83
+    name: 'u-album',
84
+    mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
85
+    data() {
86
+        return {
87
+            // 单图的宽度
88
+            singleWidth: 0,
89
+            // 单图的高度
90
+            singleHeight: 0,
91
+            // 单图时,如果无法获取图片的尺寸信息,让图片宽度默认为容器的一定百分比
92
+            singlePercent: 0.6
93
+        }
94
+    },
95
+    watch: {
96
+        urls: {
97
+            immediate: true,
98
+            handler(newVal) {
99
+                if (newVal.length === 1) {
100
+                    this.getImageRect()
101
+                }
102
+            }
103
+        }
104
+    },
105
+    computed: {
106
+        imageStyle() {
107
+            return (index1, index2) => {
108
+                const { space, rowCount, multipleSize, urls } = this,
109
+                    { addUnit, addStyle } = uni.$u,
110
+                    rowLen = this.showUrls.length,
111
+                    allLen = this.urls.length
112
+                const style = {
113
+                    marginRight: addUnit(space),
114
+                    marginBottom: addUnit(space)
115
+                }
116
+                // 如果为最后一行,则每个图片都无需下边框
117
+                if (index1 === rowLen) style.marginBottom = 0
118
+                // 每行的最右边一张和总长度的最后一张无需右边框
119
+                if (
120
+                    index2 === rowCount ||
121
+                    (index1 === rowLen &&
122
+                        index2 === this.showUrls[index1 - 1].length)
123
+                )
124
+                    style.marginRight = 0
125
+                return style
126
+            }
127
+        },
128
+        // 将数组划分为二维数组
129
+        showUrls() {
130
+            const arr = []
131
+            this.urls.map((item, index) => {
132
+                // 限制最大展示数量
133
+                if (index + 1 <= this.maxCount) {
134
+                    // 计算该元素为第几个素组内
135
+                    const itemIndex = Math.floor(index / this.rowCount)
136
+                    // 判断对应的索引是否存在
137
+                    if (!arr[itemIndex]) {
138
+                        arr[itemIndex] = []
139
+                    }
140
+                    arr[itemIndex].push(item)
141
+                }
142
+            })
143
+            return arr
144
+        },
145
+        imageWidth() {
146
+            return uni.$u.addUnit(
147
+                this.urls.length === 1 ? this.singleWidth : this.multipleSize
148
+            )
149
+        },
150
+        imageHeight() {
151
+            return uni.$u.addUnit(
152
+                this.urls.length === 1 ? this.singleHeight : this.multipleSize
153
+            )
154
+        },
155
+        // 此变量无实际用途,仅仅是为了利用computed特性,让其在urls长度等变化时,重新计算图片的宽度
156
+        // 因为用户在某些特殊的情况下,需要让文字与相册的宽度相等,所以这里事件的形式对外发送
157
+        albumWidth() {
158
+            let width = 0
159
+            if (this.urls.length === 1) {
160
+                width = this.singleWidth
161
+            } else {
162
+                width =
163
+                    this.showUrls[0].length * this.multipleSize +
164
+                    this.space * (this.showUrls[0].length - 1)
165
+            }
166
+            this.$emit('albumWidth', width)
167
+            return width
168
+        }
169
+    },
170
+    methods: {
171
+        // 预览图片
172
+        onPreviewTap(url) {
173
+            const urls = this.urls.map((item) => {
174
+                return this.getSrc(item)
175
+            })
176
+            uni.previewImage({
177
+                current: url,
178
+                urls
179
+            })
180
+        },
181
+        // 获取图片的路径
182
+        getSrc(item) {
183
+            return uni.$u.test.object(item)
184
+                ? (this.keyName && item[this.keyName]) || item.src
185
+                : item
186
+        },
187
+        // 单图时,获取图片的尺寸
188
+        // 在小程序中,需要将网络图片的的域名添加到小程序的download域名才可能获取尺寸
189
+        // 在没有添加的情况下,让单图宽度默认为盒子的一定宽度(singlePercent)
190
+        getImageRect() {
191
+            const src = this.getSrc(this.urls[0])
192
+            uni.getImageInfo({
193
+                src,
194
+                success: (res) => {
195
+                    // 判断图片横向还是竖向展示方式
196
+                    const isHorizotal = res.width >= res.height
197
+                    this.singleWidth = isHorizotal
198
+                        ? this.singleSize
199
+                        : (res.width / res.height) * this.singleSize
200
+                    this.singleHeight = !isHorizotal
201
+                        ? this.singleSize
202
+                        : (res.height / res.width) * this.singleWidth
203
+                },
204
+                fail: () => {
205
+                    this.getComponentWidth()
206
+                }
207
+            })
208
+        },
209
+        // 获取组件的宽度
210
+        async getComponentWidth() {
211
+            // 延时一定时间,以获取dom尺寸
212
+            await uni.$u.sleep(30)
213
+            // #ifndef APP-NVUE
214
+            this.$uGetRect('.u-album__row').then((size) => {
215
+                this.singleWidth = size.width * this.singlePercent
216
+            })
217
+            // #endif
218
+
219
+            // #ifdef APP-NVUE
220
+            // 这里ref="u-album__row"所在的标签为通过for循环出来,导致this.$refs['u-album__row']是一个数组
221
+            const ref = this.$refs['u-album__row'][0]
222
+            ref &&
223
+                dom.getComponentRect(ref, (res) => {
224
+                    this.singleWidth = res.size.width * this.singlePercent
225
+                })
226
+            // #endif
227
+        }
228
+    }
229
+}
230
+</script>
231
+
232
+<style lang="scss" scoped>
233
+@import '../../libs/css/components.scss';
234
+
235
+.u-album {
236
+    @include flex(column);
237
+
238
+    &__row {
239
+        @include flex(row);
240
+        flex-wrap: wrap;
241
+
242
+        &__wrapper {
243
+            position: relative;
244
+
245
+            &__text {
246
+                position: absolute;
247
+                top: 0;
248
+                left: 0;
249
+                right: 0;
250
+                bottom: 0;
251
+                background-color: rgba(0, 0, 0, 0.3);
252
+                @include flex(row);
253
+                justify-content: center;
254
+                align-items: center;
255
+            }
256
+        }
257
+    }
258
+}
259
+</style>

+ 44 - 0
price-collection/uni_modules/uview-ui/components/u-alert/props.js

@@ -0,0 +1,44 @@
1
+export default {
2
+    props: {
3
+        // 显示文字
4
+        title: {
5
+            type: String,
6
+            default: uni.$u.props.alert.title
7
+        },
8
+        // 主题,success/warning/info/error
9
+        type: {
10
+            type: String,
11
+            default: uni.$u.props.alert.type
12
+        },
13
+        // 辅助性文字
14
+        description: {
15
+            type: String,
16
+            default: uni.$u.props.alert.description
17
+        },
18
+        // 是否可关闭
19
+        closable: {
20
+            type: Boolean,
21
+            default: uni.$u.props.alert.closable
22
+        },
23
+        // 是否显示图标
24
+        showIcon: {
25
+            type: Boolean,
26
+            default: uni.$u.props.alert.showIcon
27
+        },
28
+        // 浅或深色调,light-浅色,dark-深色
29
+        effect: {
30
+            type: String,
31
+            default: uni.$u.props.alert.effect
32
+        },
33
+        // 文字是否居中
34
+        center: {
35
+            type: Boolean,
36
+            default: uni.$u.props.alert.center
37
+        },
38
+        // 字体大小
39
+        fontSize: {
40
+            type: [String, Number],
41
+            default: uni.$u.props.alert.fontSize
42
+        }
43
+    }
44
+}

+ 0 - 0
price-collection/uni_modules/uview-ui/components/u-alert/u-alert.vue


Some files were not shown because too many files changed in this diff