af-mobile-client-vue3 1.3.41 → 1.3.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChKsPmzaqY3iw4
3
+ nugwJIdl/Xf4HA33hxiNs1u5VnL/DceCz/6uOfj/pi1w3N4Zzn8j58aY5Oh2HTDJ
4
+ laaDEHQmq7suBgeAVIJoplr4SDQEyecehqH5bHt4MnJ5ize1ldNxzXgO5a2XwfPz
5
+ YxWw90jZk1QEQIgS1Ip90amJk7al+M/+dIb61uoET/xLIrcVXtc9lzglPyZpNYQd
6
+ LB0hkjd+Ed8c5Hx90/gc/JJh3Ur1YfWREr4SJwfz1+KbUGbADEFwaLX6G5Hma6qi
7
+ gC3OZ13M1+bxpxT01+TGtPzUhFADFF+ychj8v4U4UbypgsiW9Wya7LHRNUfODmXc
8
+ UT2M5O/pAgMBAAECggEAUtmDH3D2k+MSZID751O/7uQf+gGiBG8EZkOfkWUpdIgG
9
+ 2e5GhBX1NKaekXhZDHck0LZjV1HFVoKnA9nUYWfh7cc2T/B1hrjq2RU7iorDgvqv
10
+ vveC6I+l4SI9ytGQb953dfckErRrSqo/2AxFqFVWs9KSzCTITrXIA+n1921h5Wtz
11
+ 2UGsiyt7SR9ASOQ9o16QlDBNan7SulQyIam/NHaiDuyoB8bBxrewPGIx12vESbeK
12
+ NlpZhWd9jzcdkfLudIiCkp2XQ3lQsQHHNIgTij2GsYEE6hb4jLIfRsuUz6IHdFcE
13
+ gnqnXtUJPUMMmaoz6sFG3yLjHrsMUfSShDzMp19ViQKBgQDJzZ1fL+ZhQd7kTR4N
14
+ zDexXHcuHFXhXJ8VuXKcCgc5K4wt88yVQTNWwWRw27RFIh75DHQhm3FQiGydf+HM
15
+ 8k7riKA0ab3/AO5u9JYNf+Pbz0k/+rthWk/qA4N/New2eJaJMZcguwCRtg7h1Ecr
16
+ JvcVxKkxwdCvPNwq8IKeyOyS1wKBgQDMc1Uok5sPhn/LSjqnUCRlyzv1tbgJPRsZ
17
+ 1RU2wouRJc5b0usPJi9bX4642O2eTfd4mwQpPS4WcYnXVA2+qVG+rs6WAvMN10LI
18
+ SIICIzFrah1GyXs8baILE9bfJamB+YFAOF7DPK6dDHLlEg/ZhUqKr/PwoU1Cjro6
19
+ Xiwy7Gz7PwKBgQC44TgBAbg1eAyE6iXTjDmlssm5I9qGGb3hQEHAtOtDNCM74jSW
20
+ tOIc5BZp0s6H26e2kPM/6tHYbvPbI1Kx2Xf2Dvh+rDWVjrviSQ/DlFwjf/ditwm+
21
+ Oegmw0tQWw1qJfX8AMOtB8WQuNNPj5QX853AgqhjXmYadU5bxHZWlEswhwKBgCMP
22
+ uE/wGExuTWYogayFwuguFUdK9ZeoAgjJEQ1GCbdHm38FycfcTYzG82vhz8YxKrpl
23
+ Iy6LTmcM642g3YaP9PPVeJojQVljTBGa1ajWLjh0hzbHgLnZN0vdCCFWjR48Ep1X
24
+ zXB/7JYEN4PvOAaepCzqhdQDZYN/hJJT6hKFlx7zAoGAC2wxKt0MdQCX8f9B8Lhj
25
+ 3zl6ehRrfM0Ah/4Bf8845AQcS1K8FeDgU7glacz8EAKX2XUx+y2KqOb2Wiw+LwVi
26
+ kAl60oJBZxpuK/upjlOykWP9wOrpWtEYgqlu3ilOFLNQUb0h/7oL9fvfinUzij/V
27
+ PkQrsv2j4+R8OHWD5VN1IiA=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIEkTCCAvmgAwIBAgIQcMK+bOM3fXEWrBMEL3//XDANBgkqhkiG9w0BAQsFADCB
3
+ pTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMT0wOwYDVQQLDDRMQVBU
4
+ T1AtOUxOR0xKQktc5ZSQ5qKT54OoQExBUFRPUC05TE5HTEpCSyAodGFuZ3ppeWUp
5
+ MUQwQgYDVQQDDDtta2NlcnQgTEFQVE9QLTlMTkdMSkJLXOWUkOaik+eDqEBMQVBU
6
+ T1AtOUxOR0xKQksgKHRhbmd6aXllKTAeFw0yNDA5MDQwNjI4MThaFw0yNjEyMDQw
7
+ NjI4MThaMGgxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0
8
+ ZTE9MDsGA1UECww0TEFQVE9QLTlMTkdMSkJLXOWUkOaik+eDqEBMQVBUT1AtOUxO
9
+ R0xKQksgKHRhbmd6aXllKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
10
+ AKEqw+bNqpjeLDie6DAkh2X9d/gcDfeHGI2zW7lWcv8Nx4LP/q45+P+mLXDc3hnO
11
+ fyPnxpjk6HYdMMmVpoMQdCaruy4GB4BUgmimWvhINATJ5x6Goflse3gycnmLN7WV
12
+ 03HNeA7lrZfB8/NjFbD3SNmTVARAiBLUin3RqYmTtqX4z/50hvrW6gRP/EsitxVe
13
+ 1z2XOCU/Jmk1hB0sHSGSN34R3xzkfH3T+Bz8kmHdSvVh9ZESvhInB/PX4ptQZsAM
14
+ QXBotfobkeZrqqKALc5nXczX5vGnFPTX5Ma0/NSEUAMUX7JyGPy/hThRvKmCyJb1
15
+ bJrssdE1R84OZdxRPYzk7+kCAwEAAaN5MHcwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud
16
+ JQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFChzYGTua1EmLuS4rXqUekjNK40r
17
+ MC8GA1UdEQQoMCaCCWxvY2FsaG9zdIITd3d3LmFvZmVuZ2Nsb3VkLmNvbYcEfwAA
18
+ ATANBgkqhkiG9w0BAQsFAAOCAYEAhVvhN3eEEw2jmJ+ey2h7eLoZkuTIlJpJymPj
19
+ pXea4LBj+q3MHNXO5SRjc5QzB6As5GOLld++JDLOUkL/4IA+E6IFNWyDS7pS2EdP
20
+ G61nc3v7Os4g/ZElXA3xePYEfHewTURe5NagEHx+jdXEwK4nEChrJxmlbNgk6VEL
21
+ TYDLhA0bWWm7/CMv1oPOXWPLI5BDi56HnjJVXem6JpOwiHRmiZcj1DvP9m52+8f9
22
+ g94Q9zMBvwpNneaNAcUgATxykMjZoLJBCe1EdqmO0xXEJI6Cz8nJEp6CJBl5Vi/t
23
+ deKITXWe7ZP2/temIHG3Tv62l3/XQqdCvztgk50aW8YGyci243k7YDgWuULPvDf1
24
+ N0cUEC3PYKnkhhSWyy91aMyrsorWGpsjrb6xgla+0SpHNb+ZAl1SEY5VqTOsWxE/
25
+ qAQ+5xHN1EnrIqtNX7Lzp/7ekq0OQTP/U9D2soLpX7jlnWgQPnoBrNmOYr26UpzB
26
+ os3c4GV0Cr9AChbLjbWPn7D9+cA1
27
+ -----END CERTIFICATE-----
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "af-mobile-client-vue3",
3
3
  "type": "module",
4
- "version": "1.3.41",
4
+ "version": "1.3.42",
5
5
  "packageManager": "pnpm@10.13.1",
6
6
  "description": "Vue + Vite component lib",
7
7
  "engines": {
@@ -43,7 +43,8 @@
43
43
  "vue": "^3.5.17",
44
44
  "vue-i18n": "^11.1.10",
45
45
  "vue-router": "^4.5.1",
46
- "vue3-hash-calendar": "^1.1.3"
46
+ "vue3-hash-calendar": "^1.1.3",
47
+ "weixin-js-sdk": "^1.6.5"
47
48
  },
48
49
  "devDependencies": {
49
50
  "@antfu/eslint-config": "4.17.0",
@@ -1,40 +1,40 @@
1
- import { loginApi } from '@af-mobile-client-vue3/services/api/Login'
2
-
3
- import { get, post } from '@af-mobile-client-vue3/services/restTools'
4
- import { http } from '@af-mobile-client-vue3/utils/http'
5
-
6
- export interface BasicResponseModel<T = any> {
7
- code: number
8
- msg: string
9
- data: T
10
- }
11
-
12
- export function login(data: any) {
13
- return post(
14
- loginApi.Login,
15
- data,
16
- )
17
- }
18
-
19
- export function OALogin(data: any) {
20
- return get(`/af-system/user/${data.username}/${data.password}/智慧OA`)
21
- }
22
-
23
- /**
24
- * @description: 获取用户信息
25
- */
26
- export function getUserInfo() {
27
- return get(
28
- '/getUserInfo',
29
- )
30
- }
31
-
32
- /**
33
- * @description: 用户登出
34
- */
35
- export function doLogout() {
36
- return http.request({
37
- url: loginApi.Logout,
38
- method: 'DELETE',
39
- })
40
- }
1
+ import { loginApi } from '@af-mobile-client-vue3/services/api/Login'
2
+
3
+ import { get, post } from '@af-mobile-client-vue3/services/restTools'
4
+ import { http } from '@af-mobile-client-vue3/utils/http'
5
+
6
+ export interface BasicResponseModel<T = any> {
7
+ code: number
8
+ msg: string
9
+ data: T
10
+ }
11
+
12
+ export function login(data: any) {
13
+ return post(
14
+ loginApi.Login,
15
+ data,
16
+ )
17
+ }
18
+
19
+ export function OALogin(data: any) {
20
+ return get(`/af-system/user/${data.username}/${data.password}/智慧OA`)
21
+ }
22
+
23
+ /**
24
+ * @description: 获取用户信息
25
+ */
26
+ export function getUserInfo() {
27
+ return get(
28
+ '/getUserInfo',
29
+ )
30
+ }
31
+
32
+ /**
33
+ * @description: 用户登出
34
+ */
35
+ export function doLogout() {
36
+ return http.request({
37
+ url: loginApi.Logout,
38
+ method: 'DELETE',
39
+ })
40
+ }
@@ -155,7 +155,7 @@ const routes: Array<RouteRecordRaw> = [
155
155
  component: XFormAppraiseView,
156
156
  },
157
157
  {
158
- path: '/Component/XFormView',
158
+ path: '/Component/XFormView/:id/:openid',
159
159
  name: 'XFormView',
160
160
  component: XFormView,
161
161
  },
@@ -1,6 +1,6 @@
1
- const loginApi = {
2
- Login: '/af-auth/login',
3
- Logout: '/af-auth/logout',
4
- }
5
-
6
- export { loginApi }
1
+ const loginApi = {
2
+ Login: '/af-auth/login',
3
+ Logout: '/af-auth/logout',
4
+ }
5
+
6
+ export { loginApi }
@@ -250,6 +250,21 @@ export const useUserStore = defineStore('app-user', () => {
250
250
  return Promise.reject(error)
251
251
  }
252
252
  }
253
+ const loginExternalMini = async (data: any) => {
254
+ try {
255
+ // 设置Token
256
+ setToken(data.access_token)
257
+
258
+ // 加密存储登录票据
259
+ const LoginTicket = crypto.AESEncrypt(JSON.stringify(data), '3KMKqvgwR8ULbR8Z')
260
+ Storage.set('LoginTicket', LoginTicket)
261
+
262
+ return Promise.resolve(data)
263
+ }
264
+ catch (error) {
265
+ return Promise.reject(error)
266
+ }
267
+ }
253
268
 
254
269
  const logout = async () => {
255
270
  if (getToken()) {
@@ -294,6 +309,7 @@ export const useUserStore = defineStore('app-user', () => {
294
309
  Login,
295
310
  loginUnified,
296
311
  loginExternal,
312
+ loginExternalMini,
297
313
  getToken,
298
314
  getLastUpdateTime,
299
315
  logout,
@@ -1,109 +1,109 @@
1
- html:not(.dark) {
2
- .form {
3
- .form_field {
4
- :deep(.van-field__label) {
5
- color: rgb(88, 88, 88);
6
- }
7
- :deep(.van-field__body) {
8
- background: rgb(251, 251, 251);
9
- box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.1);
10
- color: rgb(71, 71, 71);
11
- }
12
- :deep(.van-cell) {
13
- background: #ffffff;
14
- }
15
- }
16
- .extra_setting {
17
- .extra_setting_for_remember_password {
18
- color: rgb(88, 88, 88);
19
- }
20
- }
21
- }
22
- }
23
- .form {
24
- width: 100%;
25
- padding: 0 40px;
26
- .form_field {
27
- padding-right: 0;
28
- padding-left: 0;
29
- :deep(.van-field__label) {
30
- opacity: 0.7;
31
- font-size: 16px;
32
- font-weight: 400;
33
- line-height: 23px;
34
- text-transform: uppercase;
35
- text-indent: 10px;
36
- }
37
- :deep(.van-field__body) {
38
- height: 40px;
39
- border-radius: 5px;
40
- font-size: 16px;
41
- font-weight: 400;
42
- padding: 8px 10px;
43
- opacity: 0.6;
44
- }
45
- }
46
- .extra_setting {
47
- font-size: 12px;
48
- font-weight: 400;
49
- line-height: 12px;
50
- .extra_setting_for_remember_password {
51
- opacity: 0.7;
52
- span {
53
- position: relative;
54
- bottom: 3px;
55
- left: 5px;
56
- }
57
- }
58
- .extra_setting_for_reset_password {
59
- position: relative;
60
- top: 2px;
61
- opacity: 0.7;
62
- color: rgb(56, 149, 250);
63
- }
64
- }
65
- .btn {
66
- height: 50px;
67
- :deep(.van-button__text) {
68
- color: rgb(255, 255, 255);
69
- font-size: 16px;
70
- font-weight: 700;
71
- line-height: 23px;
72
- }
73
- }
74
- .login_btn {
75
- background: rgb(56, 149, 250);
76
- margin-top: 104px;
77
- }
78
- .reset_btn {
79
- margin: 24px 0;
80
- }
81
- .back_btn {
82
- :deep(.van-button__text) {
83
- color: rgb(56, 149, 250);
84
- }
85
- }
86
- :deep(.van-cell:after) {
87
- border-bottom: none;
88
- }
89
- }
90
- .login_form {
91
- margin-top: 65px;
92
- }
93
- .forget_password_form {
94
- margin-top: 15px;
95
- }
96
- /* 使图标垂直居中 */
97
- .wechat-login-btn .van-icon {
98
- vertical-align: middle;
99
- }
100
- /* 悬停效果 */
101
- .wechat-login-btn:hover {
102
- background-color: #06ad56 !important;
103
- border-color: #06ad56 !important;
104
- }
105
- /* 点击效果 */
106
- .wechat-login-btn:active {
107
- background-color: #05994c !important;
108
- border-color: #05994c !important;
109
- }
1
+ html:not(.dark) {
2
+ .form {
3
+ .form_field {
4
+ :deep(.van-field__label) {
5
+ color: rgb(88, 88, 88);
6
+ }
7
+ :deep(.van-field__body) {
8
+ background: rgb(251, 251, 251);
9
+ box-shadow: inset 0 0 1px 0 rgba(0, 0, 0, 0.1);
10
+ color: rgb(71, 71, 71);
11
+ }
12
+ :deep(.van-cell) {
13
+ background: #ffffff;
14
+ }
15
+ }
16
+ .extra_setting {
17
+ .extra_setting_for_remember_password {
18
+ color: rgb(88, 88, 88);
19
+ }
20
+ }
21
+ }
22
+ }
23
+ .form {
24
+ width: 100%;
25
+ padding: 0 40px;
26
+ .form_field {
27
+ padding-right: 0;
28
+ padding-left: 0;
29
+ :deep(.van-field__label) {
30
+ opacity: 0.7;
31
+ font-size: 16px;
32
+ font-weight: 400;
33
+ line-height: 23px;
34
+ text-transform: uppercase;
35
+ text-indent: 10px;
36
+ }
37
+ :deep(.van-field__body) {
38
+ height: 40px;
39
+ border-radius: 5px;
40
+ font-size: 16px;
41
+ font-weight: 400;
42
+ padding: 8px 10px;
43
+ opacity: 0.6;
44
+ }
45
+ }
46
+ .extra_setting {
47
+ font-size: 12px;
48
+ font-weight: 400;
49
+ line-height: 12px;
50
+ .extra_setting_for_remember_password {
51
+ opacity: 0.7;
52
+ span {
53
+ position: relative;
54
+ bottom: 3px;
55
+ left: 5px;
56
+ }
57
+ }
58
+ .extra_setting_for_reset_password {
59
+ position: relative;
60
+ top: 2px;
61
+ opacity: 0.7;
62
+ color: rgb(56, 149, 250);
63
+ }
64
+ }
65
+ .btn {
66
+ height: 50px;
67
+ :deep(.van-button__text) {
68
+ color: rgb(255, 255, 255);
69
+ font-size: 16px;
70
+ font-weight: 700;
71
+ line-height: 23px;
72
+ }
73
+ }
74
+ .login_btn {
75
+ background: rgb(56, 149, 250);
76
+ margin-top: 104px;
77
+ }
78
+ .reset_btn {
79
+ margin: 24px 0;
80
+ }
81
+ .back_btn {
82
+ :deep(.van-button__text) {
83
+ color: rgb(56, 149, 250);
84
+ }
85
+ }
86
+ :deep(.van-cell:after) {
87
+ border-bottom: none;
88
+ }
89
+ }
90
+ .login_form {
91
+ margin-top: 65px;
92
+ }
93
+ .forget_password_form {
94
+ margin-top: 15px;
95
+ }
96
+ /* 使图标垂直居中 */
97
+ .wechat-login-btn .van-icon {
98
+ vertical-align: middle;
99
+ }
100
+ /* 悬停效果 */
101
+ .wechat-login-btn:hover {
102
+ background-color: #06ad56 !important;
103
+ border-color: #06ad56 !important;
104
+ }
105
+ /* 点击效果 */
106
+ .wechat-login-btn:active {
107
+ background-color: #05994c !important;
108
+ border-color: #05994c !important;
109
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * 环境检测工具类
3
+ * 用于检测当前运行环境:微信服务号、浏览器、小程序、App等
4
+ */
5
+
6
+ export interface EnvironmentInfo {
7
+ isWechat: boolean
8
+ isMiniprogram: boolean
9
+ isApp: boolean
10
+ isBrowser: boolean
11
+ userAgent: string
12
+ platform: string
13
+ isAlipayClient: boolean
14
+ isDingTalk: boolean
15
+ }
16
+
17
+ /**
18
+ * 从 UA-CH 或 UA 推断平台,避免使用已弃用的 navigator.platform
19
+ */
20
+ function getPlatformFromClient(): string {
21
+ // 优先使用 UA-CH(Chromium 等支持)
22
+ const navAny = navigator as any
23
+ const uaData = navAny && navAny.userAgentData
24
+ const uaDataPlatform = typeof uaData?.platform === 'string' ? uaData.platform : ''
25
+
26
+ const platform = uaDataPlatform || inferPlatformFromUserAgent(navigator.userAgent)
27
+ return (platform || 'unknown').toLowerCase()
28
+ }
29
+
30
+ function inferPlatformFromUserAgent(userAgent: string): string {
31
+ const ua = (userAgent || '').toLowerCase()
32
+ if (ua.includes('windows'))
33
+ return 'windows'
34
+ if (ua.includes('mac os x') || ua.includes('macintosh') || ua.includes('mac os'))
35
+ return 'macos'
36
+ if (ua.includes('android'))
37
+ return 'android'
38
+ if (ua.includes('iphone') || ua.includes('ipad') || ua.includes('ipod') || ua.includes('ios'))
39
+ return 'ios'
40
+ if (ua.includes('cros'))
41
+ return 'chrome os'
42
+ if (ua.includes('linux'))
43
+ return 'linux'
44
+ return 'unknown'
45
+ }
46
+
47
+ /**
48
+ * 检测当前运行环境
49
+ */
50
+ export function detectEnvironment(): EnvironmentInfo {
51
+ const userAgent = navigator.userAgent.toLowerCase()
52
+ const platform = getPlatformFromClient()
53
+
54
+ // 检测微信环境
55
+ const isWechat = /micromessenger/i.test(userAgent)
56
+
57
+ // 检测支付宝环境
58
+ const isAlipayClient = /alipayclient/i.test(userAgent)
59
+
60
+ // 检测抖音环境
61
+ const isDingTalk = /dingtalk/i.test(userAgent)
62
+
63
+ // 检测微信小程序环境
64
+ const isMiniprogram = isWechat && /miniprogram/i.test(userAgent)
65
+
66
+ // 检测App环境 - 使用括号明确优先级
67
+ const isApp = (
68
+ /myapp|customapp|nativeapp/.test(userAgent)
69
+ || (Object.prototype.hasOwnProperty.call(window, 'webkit') && !!(window as any).webkit?.messageHandlers)
70
+ )
71
+
72
+ // 检测浏览器环境
73
+ const isBrowser = !isWechat && !isApp
74
+
75
+ return {
76
+ isWechat,
77
+ isMiniprogram,
78
+ isApp,
79
+ isBrowser,
80
+ userAgent,
81
+ platform,
82
+ isAlipayClient,
83
+ isDingTalk,
84
+ }
85
+ }
86
+ /**
87
+ * 获取当前场景类型
88
+ */
89
+ export function getCurrentScene(): 'wechat' | 'browser' | 'miniprogram' | 'app' | 'unknown' {
90
+ const env = detectEnvironment()
91
+
92
+ if (env.isMiniprogram)
93
+ return 'miniprogram'
94
+ if (env.isWechat)
95
+ return 'wechat'
96
+ if (env.isApp)
97
+ return 'app'
98
+ if (env.isBrowser)
99
+ return 'browser'
100
+
101
+ return 'unknown'
102
+ }
103
+
104
+ /**
105
+ * 检查是否支持特定功能
106
+ */
107
+ export function checkFeatureSupport() {
108
+ const env = detectEnvironment()
109
+
110
+ return {
111
+ // 摄像头支持
112
+ camera: 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices,
113
+
114
+ // NFC支持
115
+ nfc: 'NDEFReader' in window || 'nfc' in navigator,
116
+
117
+ // 文件系统支持
118
+ fileSystem: 'showOpenFilePicker' in window,
119
+
120
+ // 振动支持
121
+ vibration: 'vibrate' in navigator,
122
+
123
+ // 地理位置支持
124
+ geolocation: 'geolocation' in navigator,
125
+
126
+ // 微信JS-SDK支持
127
+ wechatJSSDK: env.isWechat && typeof window !== 'undefined' && 'WeixinJSBridge' in window,
128
+ }
129
+ }
@@ -5,7 +5,7 @@
5
5
 
6
6
  import type { RouteLocationNormalized } from 'vue-router'
7
7
  import { PLATFORM_ROUTE_MAP, PlatformType } from '@af-mobile-client-vue3/types/platform'
8
-
8
+ import { detectEnvironment } from '@af-mobile-client-vue3/utils/environment'
9
9
  /**
10
10
  * 认证参数接口
11
11
  */
@@ -58,7 +58,7 @@ export function isExternalUser(to: RouteLocationNormalized): ExternalUserResult
58
58
 
59
59
  // 第一层检测:URL参数检测(最高优先级)判断公众号登录逻辑
60
60
  // 检查路由查询参数中是否有授权参数(code + state)
61
- const { code, state } = to.query
61
+ const { code, state, appData } = to.query
62
62
  if (code && state) {
63
63
  // 解析认证参数
64
64
  const authParams = {
@@ -77,10 +77,21 @@ export function isExternalUser(to: RouteLocationNormalized): ExternalUserResult
77
77
 
78
78
  // 第二层检测:User-Agent环境检测
79
79
  // 检查浏览器环境是否为第三方平台
80
- const ua = navigator.userAgent.toLowerCase()
81
-
80
+ const env = detectEnvironment()
81
+ // 微信小程序
82
+ if (env.isMiniprogram && appData) {
83
+ const authParams = {
84
+ platformType: PlatformType.WECHAT_MINI,
85
+ appData,
86
+ }
87
+ // 暂未实现 后续需要增加登陆参数
88
+ return {
89
+ isExternal: true,
90
+ authParams,
91
+ }
92
+ }
82
93
  // 微信环境检测
83
- if (/micromessenger/i.test(ua)) {
94
+ if (env.isWechat) {
84
95
  console.log('[Platform Detection] 检测到微信环境,判定为外部用户(无授权参数)')
85
96
  return {
86
97
  isExternal: true,
@@ -92,7 +103,7 @@ export function isExternalUser(to: RouteLocationNormalized): ExternalUserResult
92
103
  }
93
104
 
94
105
  // 支付宝环境检测
95
- if (/alipayclient/i.test(ua)) {
106
+ if (env.isAlipayClient) {
96
107
  // 暂未实现 后续需要增加登陆参数
97
108
  return {
98
109
  isExternal: true,
@@ -103,9 +114,14 @@ export function isExternalUser(to: RouteLocationNormalized): ExternalUserResult
103
114
  }
104
115
 
105
116
  // 钉钉环境检测
106
- if (/dingtalk/i.test(ua)) {
117
+ if (env.isDingTalk) {
107
118
  // 暂未实现 后续需要增加登陆参数
108
- return { isExternal: true }
119
+ return {
120
+ isExternal: true,
121
+ authParams: {
122
+ platformType: PlatformType.DINGTALK,
123
+ },
124
+ }
109
125
  }
110
126
 
111
127
  // 第三层检测:路由前缀检测
@@ -1,57 +1,57 @@
1
- /**
2
- * 根据类型获取日期区间字符串
3
- * @param type '当年' | 'curMonth' | '当日'
4
- * @param show 区分实际值还是显示值, true为实际值, false为显示值
5
- * @returns [start, end] 例:['2024-01-01 00:00:00', '2024-12-31 23:59:59']
6
- */
7
- export function getRangeByType(type: string, show: boolean): [string, string] {
8
- const now = new Date()
9
- const year = now.getFullYear()
10
- const month = (now.getMonth() + 1).toString().padStart(2, '0')
11
- const day = now.getDate().toString().padStart(2, '0')
12
-
13
- if (!show) {
14
- if (type === 'curYear') {
15
- return [
16
- `${year}-01-01 00:00:00`,
17
- `${year}-12-31 23:59:59`,
18
- ]
19
- }
20
- if (type === 'curMonth') {
21
- const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
22
- return [
23
- `${year}-${month}-01 00:00:00`,
24
- `${year}-${month}-${lastDay.toString().padStart(2, '0')} 23:59:59`,
25
- ]
26
- }
27
- if (type === 'curDay') {
28
- return [
29
- `${year}-${month}-${day} 00:00:00`,
30
- `${year}-${month}-${day} 23:59:59`,
31
- ]
32
- }
33
- }
34
- if (show) {
35
- if (type === 'curYear') {
36
- return [
37
- `${year}-01-01`,
38
- `${year}-12-31`,
39
- ]
40
- }
41
- if (type === 'curMonth') {
42
- const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
43
- return [
44
- `${year}-${month}-01`,
45
- `${year}-${month}-${lastDay.toString().padStart(2, '0')}`,
46
- ]
47
- }
48
- if (type === 'curDay') {
49
- return [
50
- `${year}-${month}-${day}`,
51
- `${year}-${month}-${day}`,
52
- ]
53
- }
54
- }
55
- // 兜底返回空字符串数组
56
- return ['', '']
57
- }
1
+ /**
2
+ * 根据类型获取日期区间字符串
3
+ * @param type '当年' | 'curMonth' | '当日'
4
+ * @param show 区分实际值还是显示值, true为实际值, false为显示值
5
+ * @returns [start, end] 例:['2024-01-01 00:00:00', '2024-12-31 23:59:59']
6
+ */
7
+ export function getRangeByType(type: string, show: boolean): [string, string] {
8
+ const now = new Date()
9
+ const year = now.getFullYear()
10
+ const month = (now.getMonth() + 1).toString().padStart(2, '0')
11
+ const day = now.getDate().toString().padStart(2, '0')
12
+
13
+ if (!show) {
14
+ if (type === 'curYear') {
15
+ return [
16
+ `${year}-01-01 00:00:00`,
17
+ `${year}-12-31 23:59:59`,
18
+ ]
19
+ }
20
+ if (type === 'curMonth') {
21
+ const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
22
+ return [
23
+ `${year}-${month}-01 00:00:00`,
24
+ `${year}-${month}-${lastDay.toString().padStart(2, '0')} 23:59:59`,
25
+ ]
26
+ }
27
+ if (type === 'curDay') {
28
+ return [
29
+ `${year}-${month}-${day} 00:00:00`,
30
+ `${year}-${month}-${day} 23:59:59`,
31
+ ]
32
+ }
33
+ }
34
+ if (show) {
35
+ if (type === 'curYear') {
36
+ return [
37
+ `${year}-01-01`,
38
+ `${year}-12-31`,
39
+ ]
40
+ }
41
+ if (type === 'curMonth') {
42
+ const lastDay = new Date(year, now.getMonth() + 1, 0).getDate()
43
+ return [
44
+ `${year}-${month}-01`,
45
+ `${year}-${month}-${lastDay.toString().padStart(2, '0')}`,
46
+ ]
47
+ }
48
+ if (type === 'curDay') {
49
+ return [
50
+ `${year}-${month}-${day}`,
51
+ `${year}-${month}-${day}`,
52
+ ]
53
+ }
54
+ }
55
+ // 兜底返回空字符串数组
56
+ return ['', '']
57
+ }
@@ -0,0 +1,297 @@
1
+ import { get } from '@af-mobile-client-vue3/services/restTools'
2
+ import { detectEnvironment } from '@af-mobile-client-vue3/utils/environment'
3
+ import wx from 'weixin-js-sdk'
4
+ // 微信JS-SDK配置接口
5
+ export interface WechatConfig {
6
+ debug: boolean
7
+ appId: string
8
+ timestamp: string
9
+ nonceStr: string
10
+ signature: string
11
+ jsApiList: string[]
12
+ }
13
+
14
+ // 微信扫码配置
15
+ export interface WechatScanConfig {
16
+ needResult: 0 | 1
17
+ scanType: string[]
18
+ }
19
+
20
+ // 微信扫码结果
21
+ export interface WechatScanResult {
22
+ resultStr: string
23
+ }
24
+
25
+ // 检查是否在微信环境中
26
+ export function isWechatBrowser(): boolean {
27
+ const env = detectEnvironment()
28
+ return env.isWechat
29
+ }
30
+
31
+ // 检查是否在小程序环境中
32
+ export function isMiniprogram(): boolean {
33
+ const env = detectEnvironment()
34
+ return env.isMiniprogram
35
+ }
36
+
37
+ // 配置微信JS-SDK
38
+ export function configWechatSDK(config: WechatConfig): Promise<void> {
39
+ return new Promise((resolve, reject) => {
40
+ if (!isWechatBrowser()) {
41
+ reject(new Error('非微信环境,无法使用微信JS-SDK'))
42
+ return
43
+ }
44
+
45
+ wx.config({
46
+ debug: config.debug,
47
+ appId: config.appId,
48
+ timestamp: config.timestamp,
49
+ nonceStr: config.nonceStr,
50
+ signature: config.signature,
51
+ jsApiList: config.jsApiList,
52
+ })
53
+
54
+ wx.ready(() => {
55
+ console.log('微信JS-SDK配置成功')
56
+ resolve()
57
+ })
58
+
59
+ wx.error((res: any) => {
60
+ console.error('微信JS-SDK配置失败:', res)
61
+ reject(new Error(`微信JS-SDK配置失败: ${res.errMsg}`))
62
+ })
63
+ })
64
+ }
65
+
66
+ // 微信扫码
67
+ export function scanQRCode(config: WechatScanConfig): Promise<WechatScanResult> {
68
+ return new Promise((resolve, reject) => {
69
+ if (!isWechatBrowser()) {
70
+ reject(new Error('非微信环境,无法使用微信扫码'))
71
+ return
72
+ }
73
+
74
+ wx.scanQRCode({
75
+ needResult: config.needResult,
76
+ scanType: config.scanType,
77
+ success: (res: WechatScanResult) => {
78
+ console.log('微信扫码成功:', res)
79
+ resolve(res)
80
+ },
81
+ fail: (res: any) => {
82
+ console.error('微信扫码失败:', res)
83
+ reject(new Error(`微信扫码失败: ${res.errMsg}`))
84
+ },
85
+ cancel: () => {
86
+ reject(new Error('用户取消扫码'))
87
+ },
88
+ })
89
+ })
90
+ }
91
+
92
+ // 获取微信签名(模拟)
93
+ export async function getWechatSignature(url: string): Promise<{
94
+ appId: string
95
+ timestamp: string
96
+ nonceStr: string
97
+ signature: string
98
+ }> {
99
+ // 这里应该调用后端接口获取微信签名
100
+ // 现在使用模拟数据
101
+ return new Promise((resolve) => {
102
+ get(`/af-wechat/weixin/getJsSdk?path=${url}`).then((res) => {
103
+ resolve({
104
+ appId: res.appId,
105
+ timestamp: res.timeStamp,
106
+ nonceStr: res.nonceStr,
107
+ signature: res.sign,
108
+ })
109
+ })
110
+ })
111
+ }
112
+
113
+ // 初始化微信环境
114
+ export async function initWechatEnvironment(): Promise<void> {
115
+ if (!isWechatBrowser()) {
116
+ console.log('非微信环境,跳过微信初始化')
117
+ return
118
+ }
119
+
120
+ try {
121
+ const currentUrl = window.location.href.split('#')[0]
122
+ const signatureData = await getWechatSignature(currentUrl)
123
+
124
+ await configWechatSDK({
125
+ debug: false,
126
+ appId: signatureData.appId,
127
+ timestamp: signatureData.timestamp,
128
+ nonceStr: signatureData.nonceStr,
129
+ signature: signatureData.signature,
130
+ jsApiList: [
131
+ 'onMenuShareTimeline',
132
+ 'onMenuShareAppMessage',
133
+ 'onMenuShareQQ',
134
+ 'onMenuShareWeibo',
135
+ 'onMenuShareQZone',
136
+ 'startRecord',
137
+ 'stopRecord',
138
+ 'onVoiceRecordEnd',
139
+ 'playVoice',
140
+ 'pauseVoice',
141
+ 'stopVoice',
142
+ 'onVoicePlayEnd',
143
+ 'uploadVoice',
144
+ 'downloadVoice',
145
+ 'chooseImage',
146
+ 'previewImage',
147
+ 'uploadImage',
148
+ 'downloadImage',
149
+ 'translateVoice',
150
+ 'getNetworkType',
151
+ 'openLocation',
152
+ 'getLocation',
153
+ 'hideOptionMenu',
154
+ 'showOptionMenu',
155
+ 'hideMenuItems',
156
+ 'showMenuItems',
157
+ 'hideAllNonBaseMenuItem',
158
+ 'showAllNonBaseMenuItem',
159
+ 'closeWindow',
160
+ 'scanQRCode',
161
+ 'chooseWXPay',
162
+ 'openProductSpecificView',
163
+ 'addCard',
164
+ 'chooseCard',
165
+ 'openCard',
166
+ ],
167
+ })
168
+
169
+ console.log('微信环境初始化成功')
170
+ }
171
+ catch (error) {
172
+ console.error('微信环境初始化失败:', error)
173
+ }
174
+ }
175
+
176
+ // 小程序扫码(在小程序环境中)
177
+ export function miniprogramScanCode(): Promise<string> {
178
+ return new Promise((resolve, reject) => {
179
+ if (!isMiniprogram()) {
180
+ reject(new Error('非小程序环境,无法使用小程序扫码'))
181
+ return
182
+ }
183
+
184
+ // 在小程序环境中,通过 postMessage 与小程序通信
185
+ const mp = (window as any).wx && (window as any).wx.miniProgram
186
+ const sendMessage = (payload: any) => {
187
+ if (mp && typeof mp.postMessage === 'function') {
188
+ mp.postMessage({ data: payload })
189
+ }
190
+ else if (window.parent && window.parent !== window) {
191
+ window.parent.postMessage(payload, '*')
192
+ }
193
+ else {
194
+ throw new Error('无法与小程序通信')
195
+ }
196
+ }
197
+
198
+ try {
199
+ sendMessage({ type: 'scanCode', data: {} })
200
+
201
+ // 监听小程序返回的扫码结果
202
+ const handleMessage = (event: MessageEvent) => {
203
+ const raw = (event as any).data
204
+ const msg = raw && typeof raw === 'object' && 'data' in raw ? (raw as any).data : raw
205
+ if (msg && msg.type === 'scanCodeResult') {
206
+ window.removeEventListener('message', handleMessage)
207
+ if (msg.success) {
208
+ resolve(msg.result)
209
+ }
210
+ else {
211
+ reject(new Error(msg.error || '扫码失败'))
212
+ }
213
+ }
214
+ }
215
+
216
+ window.addEventListener('message', handleMessage)
217
+
218
+ // 设置超时
219
+ setTimeout(() => {
220
+ window.removeEventListener('message', handleMessage)
221
+ reject(new Error('扫码超时'))
222
+ }, 30000)
223
+ }
224
+ catch (err) {
225
+ reject(err)
226
+ }
227
+ })
228
+ }
229
+
230
+ // 小程序NFC读取(在小程序环境中)
231
+ export function miniprogramNfcRead(): Promise<string> {
232
+ return new Promise((resolve, reject) => {
233
+ if (!isMiniprogram()) {
234
+ reject(new Error('非小程序环境,无法使用小程序NFC'))
235
+ return
236
+ }
237
+
238
+ const mp = (window as any).wx && (window as any).wx.miniProgram
239
+ const sendMessage = (payload: any) => {
240
+ if (mp && typeof mp.postMessage === 'function') {
241
+ mp.postMessage({ data: payload })
242
+ }
243
+ else if (window.parent && window.parent !== window) {
244
+ window.parent.postMessage(payload, '*')
245
+ }
246
+ else {
247
+ throw new Error('无法与小程序通信')
248
+ }
249
+ }
250
+
251
+ try {
252
+ sendMessage({ type: 'nfcRead', data: {} })
253
+
254
+ const handleMessage = (event: MessageEvent) => {
255
+ const raw = (event as any).data
256
+ const msg = raw && typeof raw === 'object' && 'data' in raw ? (raw as any).data : raw
257
+ if (msg && msg.type === 'nfcResult') {
258
+ window.removeEventListener('message', handleMessage)
259
+ if (msg.success) {
260
+ resolve(msg.result || '')
261
+ }
262
+ else {
263
+ reject(new Error(msg.error || 'NFC读取失败'))
264
+ }
265
+ }
266
+ }
267
+
268
+ window.addEventListener('message', handleMessage)
269
+
270
+ setTimeout(() => {
271
+ window.removeEventListener('message', handleMessage)
272
+ reject(new Error('NFC读取超时'))
273
+ }, 30000)
274
+ }
275
+ catch (err) {
276
+ reject(err)
277
+ }
278
+ })
279
+ }
280
+ // H5:仅监听小程序主动回传
281
+ export function waitAuthFromMiniProgram(timeout = 15000) {
282
+ return new Promise<{ token: string, resources?: any, expireTime?: number }>((resolve, reject) => {
283
+ const handle = (event: MessageEvent) => {
284
+ const raw = (event as any).data
285
+ const msg = raw && typeof raw === 'object' && 'data' in raw ? (raw as any).data : raw
286
+ if (msg && msg.type === 'auth') {
287
+ window.removeEventListener('message', handle)
288
+ return msg ? resolve(msg) : reject(new Error('未获取到授权信息'))
289
+ }
290
+ }
291
+ window.addEventListener('message', handle)
292
+ setTimeout(() => {
293
+ window.removeEventListener('message', handle)
294
+ reject(new Error('获取授权信息超时'))
295
+ }, timeout)
296
+ })
297
+ }
@@ -1,19 +1,11 @@
1
1
  <script setup lang="ts">
2
2
  import XCellList from '@af-mobile-client-vue3/components/data/XCellList/index.vue'
3
3
  import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
- import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
5
4
  import { defineEmits, ref } from 'vue'
6
5
  import { useRouter } from 'vue-router'
7
6
 
8
7
  // 定义事件
9
8
  const emit = defineEmits(['deleteRow'])
10
-
11
- // 多选操作配置
12
- const multiSelectActions = ref([
13
- { name: '批量审核', key: 'batchAudit', color: '#000000', icon: 'passed' },
14
- ])
15
-
16
- const userInfo = useUserStore().getUserInfo()
17
9
  // 访问路由
18
10
  const router = useRouter()
19
11
  // 获取默认值
@@ -56,7 +48,7 @@ const serviceName = ref('af-gaslink')
56
48
  // 跳转到表单——以表单组来渲染纯表单
57
49
  function toDetail(item) {
58
50
  router.push({
59
- name: 'XFormView',
51
+ name: 'XFormGroupView',
60
52
  query: {
61
53
  id: item[idKey.value],
62
54
  // id: item.rr_id,
@@ -95,31 +87,18 @@ function toDetail(item) {
95
87
  function deleteRow(result) {
96
88
  emit('deleteRow', result.o_id)
97
89
  }
98
-
99
- // 多选操作处理
100
- function handleMultiSelectAction(action: string, selectedItems: any[], selectedItemsArray: any[]) {
101
- console.log('多选操作:', action, selectedItems, selectedItemsArray)
102
- }
103
-
104
- // 选择变化处理
105
- function handleSelectionChange(selectedItems: any[]) {
106
- console.log('选择变化,当前选中:', selectedItems.length, '个项目')
107
- // 可以在这里更新UI状态,比如显示选中数量等
108
- }
109
90
  </script>
110
91
 
111
92
  <template>
112
93
  <NormalDataLayout id="XCellListView" title="工作计划">
113
94
  <template #layout_content>
114
95
  <XCellList
115
- config-name="lngChargeAuditMobileCRUD"
116
- service-name="af-gaslink"
117
- :enable-multi-select="true"
118
- id-key="rr_id"
119
- :multi-select-actions="multiSelectActions"
96
+ :config-name="configName"
97
+ :service-name="serviceName"
98
+ :fix-query-form="{ o_f_oper_name: 'edu_test' }"
99
+ :id-key="idKey"
120
100
  @to-detail="toDetail"
121
- @multi-select-action="handleMultiSelectAction"
122
- @selection-change="handleSelectionChange"
101
+ @delete-row="deleteRow"
123
102
  />
124
103
  </template>
125
104
  </NormalDataLayout>
@@ -5,19 +5,16 @@ import { showDialog } from 'vant'
5
5
  import { ref } from 'vue'
6
6
  import { useRoute } from 'vue-router'
7
7
 
8
- // const configName = ref('reviewFormGroup')
9
- // const serviceName = ref('af-revenue')
10
-
11
8
  // 纯表单
12
- // const configName = ref('form_check_test')
13
- // const serviceName = ref('af-system')
9
+ const configName = ref('form_check_test')
10
+ const serviceName = ref('af-system')
14
11
 
15
12
  // const configName = ref("计划下发Form")
16
13
  // const serviceName = ref("af-linepatrol")
17
14
 
18
15
  // 表单组
19
- const configName = ref('lngChargeAuditMobileFormGroup')
20
- const serviceName = ref('af-gaslink')
16
+ // const configName = ref('lngChargeAuditMobileFormGroup')
17
+ // const serviceName = ref('af-gaslink')
21
18
 
22
19
  const formData = ref({})
23
20
  const formGroup = ref(null)
@@ -25,8 +22,7 @@ const route = useRoute()
25
22
  const isInit = ref(false)
26
23
  function submit(_result) {
27
24
  showDialog({ message: '提交成功' }).then(() => {
28
- console.log('12121')
29
- // history.back()
25
+ history.back()
30
26
  })
31
27
  }
32
28
 
@@ -67,8 +63,8 @@ function submit(_result) {
67
63
  <!-- v-if="isInit" -->
68
64
  <XFormGroup
69
65
  ref="formGroup"
70
- config-name="ApplyAddContractFormGroup"
71
- service-name="af-apply"
66
+ :config-name="configName"
67
+ :service-name="serviceName"
72
68
  :group-form-data="formData"
73
69
  mode="新增"
74
70
  @submit="submit"
@@ -3,8 +3,8 @@ import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
3
  import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
4
  import { ref } from 'vue'
5
5
 
6
- const configName = ref('lngSecurityChecktestForm')
7
- const serviceName = ref('af-safecheck')
6
+ const configName = ref('AddConstructionForm')
7
+ const serviceName = ref('af-linepatrol')
8
8
 
9
9
  const formGroupAddConstruction = ref(null)
10
10
  </script>
@@ -24,8 +24,16 @@ async function handleAuth() {
24
24
  const authParam = route.query as Record<string, string>
25
25
 
26
26
  if (authParam.platformType) {
27
- // 微信公众号授权登录参数
28
- await handleExternalLogin(authParam)
27
+ switch (authParam.platformType) {
28
+ case PlatformType.WECHAT_OFFICIAL:
29
+ case PlatformType.WECHAT_MINI:
30
+ // 微信公众号,微信小程序授权登录参数
31
+ await handleExternalLogin(authParam)
32
+ break
33
+ default:
34
+ // 其他环境使用原生扫码(需要页面跳转或调用原生API)
35
+ throw new Error('当前环境不支持授权登录')
36
+ }
29
37
  }
30
38
  else {
31
39
  // 无授权参数,检查是否已登录或等待授权
@@ -49,9 +57,16 @@ async function handleAuth() {
49
57
 
50
58
  // 处理外部用户登录
51
59
  async function handleExternalLogin(loginParams: any) {
52
- const data = await userStore.loginExternal(Object.assign(loginParams, {
53
- isMobile: true,
54
- }))
60
+ let data: any
61
+ if (loginParams.platformType === PlatformType.WECHAT_OFFICIAL) {
62
+ data = await userStore.loginExternal(Object.assign(loginParams, {
63
+ isMobile: true,
64
+ }))
65
+ }
66
+ else {
67
+ data = await userStore.loginExternalMini(JSON.parse(loginParams.appData))
68
+ }
69
+
55
70
  const loginInfo = {
56
71
  f: data,
57
72
  jwt: data.id,
@@ -310,10 +310,14 @@ async function submitRegistration(): Promise<void> {
310
310
  try {
311
311
  console.log('formData', formData.value)
312
312
  const response = await openApiLogic(formData.value, 'registrationUser', 'af-system')
313
- console.log('response', response)
313
+ if (response.success) {
314
+ showSuccess.value = true
315
+ showSuccessToast('注册成功')
316
+ }
317
+ else {
318
+ showSuccessToast(`注册失败,${response.msg}!`)
319
+ }
314
320
  isSubmitting.value = false
315
- showSuccess.value = true
316
- showSuccessToast('注册成功')
317
321
  }
318
322
  catch (error) {
319
323
  isSubmitting.value = false
@@ -705,12 +709,12 @@ onMounted(async () => {
705
709
  <p><strong>手机号码:</strong>{{ formData.phone }}</p>
706
710
  </div>
707
711
  <div class="success-actions">
708
- <VanButton type="default" @click="resetForm">
709
- 继续注册
710
- </VanButton>
711
- <VanButton type="primary" @click="goBack">
712
- 去登录
713
- </VanButton>
712
+ <!-- <VanButton type="default" @click="resetForm"> -->
713
+ <!-- 继续注册 -->
714
+ <!-- </VanButton> -->
715
+ <!-- <VanButton type="primary" @click="goBack"> -->
716
+ <!-- 去登录 -->
717
+ <!-- </VanButton> -->
714
718
  </div>
715
719
  </div>
716
720
  </VanPopup>