jmash-core-mp 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +14 -3
  2. package/package.json +3 -1
  3. package/src/api/auth/index.ts +58 -15
  4. package/src/api/auth/types.ts +52 -1
  5. package/src/api/files/index.ts +37 -45
  6. package/src/app.mpx +12 -7
  7. package/src/components/auth-user/jmash-logout.mpx +91 -0
  8. package/src/components/auth-user/jmash-update-user.mpx +58 -21
  9. package/src/components/auth-user/jmash-update-user.web.mpx +365 -0
  10. package/src/components/auth-user/jmash-user.mpx +168 -48
  11. package/src/components/common/jmash-menu.mpx +129 -0
  12. package/src/components/common/jmash-tab-bar.mpx +2 -2
  13. package/src/components/core/jmash-login.ali.mpx +284 -0
  14. package/src/components/core/jmash-login.mpx +20 -15
  15. package/src/components/core/jmash-login.web.mpx +421 -0
  16. package/src/components/core/jmash-popup-login.ali.mpx +311 -0
  17. package/src/components/core/jmash-popup-login.mpx +6 -4
  18. package/src/components/core/jmash-popup-login.web.mpx +389 -0
  19. package/src/custom-tab-bar/index.mpx +0 -1
  20. package/src/global.d.ts +10 -3
  21. package/src/index.ts +2 -1
  22. package/src/packages/pages/auth/cms-protocol.mpx +1 -1
  23. package/src/packages/pages/auth/login.mpx +10 -14
  24. package/src/packages/pages/auth/update-user.mpx +4 -4
  25. package/src/pages/half-home.mpx +3 -2
  26. package/src/pages/home.mpx +14 -11
  27. package/src/pages/index.mpx +0 -1
  28. package/src/pages/tabbar/home.mpx +6 -2
  29. package/src/pages/tabbar/my.mpx +52 -11
  30. package/src/store/user.ts +268 -0
  31. package/src/styles/index.scss +24 -5
  32. package/src/utils/config.ts +1 -1
  33. package/src/utils/db.ts +1 -1
  34. package/src/utils/net.ts +18 -0
  35. package/src/utils/request.ts +11 -5
  36. package/src/stores/setup.js +0 -15
  37. package/src/utils/auth.ts +0 -272
package/README.md CHANGED
@@ -34,10 +34,21 @@ npm run build -- --targets=wx,ali,web
34
34
 
35
35
  登录
36
36
  minidev login
37
- 预览
38
- minidev preview --app-id 2021006137629651
39
37
 
40
- rm -rf .cache
38
+ 调试开发
39
+ minidev dev
40
+
41
+ 本地 IP 调试
42
+ minidev dev --host 192.168.1.154
43
+
44
+ 真机调试
45
+ minidev remote-debug -a 2021006137629651
46
+
47
+ Web 端调试
48
+ minidev dev
49
+ web -a 2021006137629651
50
+ 真机预览
51
+ minidev preview -a 2021006137629651
41
52
 
42
53
  # pnpm publish --no-git-checks
43
54
 
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "jmash-core-mp",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "dependencies": {
6
+ "sm-crypto": "^0.4.0",
6
7
  "@mpxjs/api-proxy": "^2.10.19",
7
8
  "@mpxjs/core": "^2.10.19",
8
9
  "@mpxjs/fetch": "^2.10.19",
@@ -22,6 +23,7 @@
22
23
  "@babel/plugin-transform-runtime": "^7.10.4",
23
24
  "@babel/preset-env": "^7.10.4",
24
25
  "@babel/runtime-corejs3": "^7.10.4",
26
+ "@mini-types/global": "^1.0.33",
25
27
  "@mpxjs/babel-plugin-inject-page-events": "^2.9.0",
26
28
  "@mpxjs/eslint-config": "^2.0.3",
27
29
  "@mpxjs/miniprogram-simulate": "^1.4.17",
@@ -1,10 +1,13 @@
1
1
  import { ResponseData } from "../../types/core";
2
+ import { OpensType } from "./types";
2
3
  import type {
3
4
  LoginReq,
4
5
  LoginRes,
5
6
  RolesPerms,
7
+ WebLoginReq,
6
8
  TokenModel,
7
- PhoneNumberReq,
9
+ PhoneRegisterReq,
10
+ PhoneReplaceReq,
8
11
  UpdateUserReq,
9
12
  UserInfoReq,
10
13
  UserInfo,
@@ -15,8 +18,14 @@ import { config } from "../../utils/config";
15
18
  import mpx from "@mpxjs/core";
16
19
 
17
20
  class AuthApi {
18
- // 登录
19
- miniappLogin(data: LoginReq): Promise<ResponseData<LoginRes>> {
21
+ // 小程序静默登录
22
+ mpLogin(data: LoginReq): Promise<ResponseData<LoginRes>> {
23
+ if (__mpx_mode__ === "wx") {
24
+ data.opensType = OpensType.wechat;
25
+ }
26
+ if (__mpx_mode__ === "ali") {
27
+ data.opensType = OpensType.ali_pay;
28
+ }
20
29
  return mpx.xfetch.fetch({
21
30
  url: "/v1/front/rbac/miniapp_login/" + config.tenant,
22
31
  method: "POST",
@@ -27,14 +36,59 @@ class AuthApi {
27
36
  },
28
37
  });
29
38
  }
39
+
30
40
  // 手机号注册登录
31
- miniappPhoneNumber(data: PhoneNumberReq): Promise<ResponseData<LoginRes>> {
41
+ mpPhoneRegister(data: PhoneRegisterReq): Promise<ResponseData<LoginRes>> {
42
+ if (__mpx_mode__ === "wx") {
43
+ data.opensType = OpensType.wechat;
44
+ }
45
+ if (__mpx_mode__ === "ali") {
46
+ data.opensType = OpensType.ali_pay;
47
+ }
32
48
  return mpx.xfetch.fetch({
33
49
  url: "/v1/front/rbac/miniapp_phonenumber/" + config.tenant,
34
50
  method: "POST",
35
51
  data: data,
52
+ header: {
53
+ Authorization: false,
54
+ },
55
+ });
56
+ }
57
+
58
+ // 已登陆状态小程序更换绑定手机号
59
+ replaceBindphone(data: PhoneReplaceReq): Promise<ResponseData<string>> {
60
+ data.tenant = config.tenant;
61
+ if (__mpx_mode__ === "wx") {
62
+ data.opensType = OpensType.wechat;
63
+ }
64
+ if (__mpx_mode__ === "ali") {
65
+ data.opensType = OpensType.ali_pay;
66
+ }
67
+ grpc.clearEmpty(data);
68
+ return mpx.xfetch.fetch({
69
+ url: "/v1/front/rbac/miniapp_bindphone",
70
+ method: "POST",
71
+ data: data,
36
72
  });
37
73
  }
74
+
75
+ //web登录.
76
+ webLogin(data: WebLoginReq): Promise<ResponseData<TokenModel>> {
77
+ data.tenant = config.tenant;
78
+ data.directoryId = "user";
79
+ data.clientId = config.appId ? config.appId : "h5";
80
+ data.captchaId = "1";
81
+ data.captchaCode = "1";
82
+ return mpx.xfetch.fetch({
83
+ url: "/v1/rbac/auth/login",
84
+ method: "POST",
85
+ data: data,
86
+ header: {
87
+ Authorization: false,
88
+ },
89
+ });
90
+ }
91
+
38
92
  // 刷新token
39
93
  refreshToken(): Promise<ResponseData<TokenModel>> {
40
94
  return mpx.xfetch.fetch({
@@ -144,17 +198,6 @@ class AuthApi {
144
198
  });
145
199
  }
146
200
 
147
- // 已登陆状态小程序更换绑定手机号
148
- replaceBindphone(data: PhoneNumberReq): Promise<ResponseData<string>> {
149
- data.tenant = config.tenant;
150
- grpc.clearEmpty(data);
151
- return mpx.xfetch.fetch({
152
- url: "/v1/front/rbac/miniapp_bindphone",
153
- method: "POST",
154
- data: data,
155
- });
156
- }
157
-
158
201
  // 获取当前会话用户的信息
159
202
  findUserInfo(data: UserInfoReq): Promise<ResponseData<UserInfo>> {
160
203
  data.tenant = config.tenant;
@@ -10,6 +10,15 @@ export interface TokenModel {
10
10
  tokenType: string;
11
11
  }
12
12
 
13
+ export enum OpensType {
14
+ //微信
15
+ wechat,
16
+ //支付宝
17
+ ali_pay,
18
+ //云闪付
19
+ union_pay,
20
+ }
21
+
13
22
  // 登录接口传参定义
14
23
  export interface LoginReq {
15
24
  // 小程序APPID
@@ -18,6 +27,30 @@ export interface LoginReq {
18
27
  loginCode: string;
19
28
  // 小程序托管微信第三方平台(可选)
20
29
  componentAppid?: string;
30
+ //登录类型
31
+ opensType?: OpensType;
32
+ }
33
+
34
+ /**
35
+ * 登录请求参数
36
+ */
37
+ export interface WebLoginReq {
38
+ // 租户
39
+ tenant?: string;
40
+ // 目录ID
41
+ directoryId?: string;
42
+ //互斥角色
43
+ scope?: string;
44
+ //用户名
45
+ userName: string;
46
+ //加密密钥
47
+ encodePwd: string;
48
+ //验证码缓存key
49
+ captchaId?: string;
50
+ //验证码
51
+ captchaCode?: string;
52
+ // 客户ID
53
+ clientId?: string;
21
54
  }
22
55
 
23
56
  // 登录接口接收参数定义
@@ -33,7 +66,7 @@ export interface LoginRes {
33
66
  }
34
67
 
35
68
  // 获取手机号定义
36
- export interface PhoneNumberReq {
69
+ export interface PhoneRegisterReq {
37
70
  // 租户
38
71
  tenant?: string;
39
72
  // 小程序APPID
@@ -44,8 +77,26 @@ export interface PhoneNumberReq {
44
77
  phoneCode: string;
45
78
  // 昵称
46
79
  nickName?: string;
80
+ // 头像
81
+ avatar?: string;
82
+ // 小程序托管微信第三方平台(可选)
83
+ componentAppid?: string;
84
+ //登录类型
85
+ opensType?: OpensType;
86
+ }
87
+
88
+ // 手机号绑定接口
89
+ export interface PhoneReplaceReq {
90
+ // 租户
91
+ tenant?: string;
92
+ // 小程序APPID
93
+ appId: string;
94
+ // 获取手机号码
95
+ phoneCode: string;
47
96
  // 小程序托管微信第三方平台(可选)
48
97
  componentAppid?: string;
98
+ //登录类型
99
+ opensType?: OpensType;
49
100
  }
50
101
 
51
102
  // 刷新token
@@ -88,56 +88,48 @@ class FileApi {
88
88
 
89
89
  // 上传文件
90
90
  uploadFile(file: string): Promise<FileInfo> {
91
- const that = this;
92
- return new Promise((resolve, reject) => {
93
- const p = mpx.uploadFile({
94
- url: that.uploadUrl(),
95
- filePath: file,
96
- name: "file",
97
- header: {
98
- "Content-Type": "multipart/form-data",
99
- Authorization: db.getBearerToken(),
100
- },
101
- } as WechatMiniprogram.UploadFileOption) as any;
102
- p.then((res: any) => {
103
- console.log("uploadFile", res);
104
- if (res.statusCode === 200) {
105
- resolve(JSON.parse(res.data) as FileInfo);
106
- } else if (res.statusCode === 401) {
107
- // 清理登录信息
108
- mpx.clearStorage();
109
- } else {
110
- mpx.showToast({
111
- title: res.errMsg,
112
- icon: "none",
113
- duration: 2000,
114
- });
115
- resolve(JSON.parse(res.data) as FileInfo);
116
- }
117
- }).catch((err: any) => {
118
- reject(err);
119
- });
91
+ const p = mpx.uploadFile({
92
+ url: this.uploadUrl(),
93
+ filePath: file,
94
+ name: "file",
95
+ header: {
96
+ "Content-Type": "multipart/form-data",
97
+ Authorization: db.getBearerToken(),
98
+ },
99
+ } as WechatMiniprogram.UploadFileOption) as any;
100
+ return p.then((res: any) => {
101
+ console.log("uploadFile", res);
102
+ if (res.statusCode === 200) {
103
+ return JSON.parse(res.data) as FileInfo;
104
+ } else if (res.statusCode === 401) {
105
+ // 清理登录信息
106
+ mpx.clearStorage();
107
+ throw new Error("登录过期,请重新登录");
108
+ } else {
109
+ mpx.showToast({
110
+ title: res.errMsg,
111
+ icon: "none",
112
+ duration: 2000,
113
+ });
114
+ return JSON.parse(res.data) as FileInfo;
115
+ }
120
116
  });
121
117
  }
122
118
 
123
119
  // 上传文件
124
120
  downloadFile(url: string): Promise<FileDownInfo> {
125
- return new Promise((resolve, reject) => {
126
- const p = mpx.downloadFile({
127
- url: url,
128
- header: {
129
- Authorization: db.getBearerToken(),
130
- },
131
- }) as any;
132
- p.then((res: any) => {
133
- resolve({
134
- statusCode: res.statusCode,
135
- tempFilePath: res.tempFilePath,
136
- filePath: res.tempFilePath,
137
- } as FileDownInfo);
138
- }).catch((err: any) => {
139
- reject(err);
140
- });
121
+ const p = mpx.downloadFile({
122
+ url: url,
123
+ header: {
124
+ Authorization: db.getBearerToken(),
125
+ },
126
+ }) as any;
127
+ return p.then((res: any) => {
128
+ return {
129
+ statusCode: res.statusCode,
130
+ tempFilePath: res.tempFilePath,
131
+ filePath: res.tempFilePath,
132
+ } as FileDownInfo;
141
133
  });
142
134
  }
143
135
 
package/src/app.mpx CHANGED
@@ -15,10 +15,12 @@ createApp({
15
15
  config: config
16
16
  }
17
17
  })
18
- // 只有运行时才能调用
19
- const accountInfo = mpx.getAccountInfoSync();
20
- // 微信
21
- config.appId = accountInfo.miniProgram.appId;
18
+ if (__mpx_mode__ !== "web") {
19
+ // 只有运行时才能调用
20
+ const accountInfo = mpx.getAccountInfoSync();
21
+ // 微信
22
+ config.appId = accountInfo.miniProgram.appId;
23
+ }
22
24
  </script>
23
25
 
24
26
  <style></style>
@@ -40,15 +42,18 @@ config.appId = accountInfo.miniProgram.appId;
40
42
  "custom": true,
41
43
  "color": "#86909C",
42
44
  "selectedColor": "#EA4C3B",
43
- "borderStyle": "white",
44
45
  "list": [
45
46
  {
46
47
  "pagePath": "pages/tabbar/home",
47
- "text": "首页"
48
+ "text": "首页",
49
+ "activeIcon": "",
50
+ "icon": ""
48
51
  },
49
52
  {
50
53
  "pagePath": "pages/tabbar/my",
51
- "text": "我的"
54
+ "text": "我的",
55
+ "activeIcon": "",
56
+ "icon": ""
52
57
  }
53
58
  ]
54
59
  }
@@ -0,0 +1,91 @@
1
+ <template>
2
+ <view class="logout-section">
3
+ <!-- 登录状态才显示退出按钮 -->
4
+ <button class="logout-btn" bind:tap="handleLogout" wx:if="{{ isLogin }}">退出登录</button>
5
+ <text class="version-text">当前版本 V{{ version }}</text>
6
+ </view>
7
+ </template>
8
+
9
+ <script>
10
+ import mpx, { createComponent, computed } from '@mpxjs/core'
11
+ import { useUserStore } from '../../store/user'
12
+
13
+ createComponent({
14
+ properties: {
15
+ // 自定义版本号,默认读配置
16
+ version: {
17
+ type: String,
18
+ value: '1.0.0'
19
+ }
20
+ },
21
+ setup() {
22
+ let userStore = useUserStore();
23
+ const isLogin = computed(() => userStore.accessToken !== '');
24
+ return {
25
+ isLogin, userStore
26
+ };
27
+ },
28
+ methods: {
29
+ // 退出登录逻辑
30
+ handleLogout() {
31
+ mpx.showModal({
32
+ title: '提示',
33
+ content: '确定要退出登录吗?',
34
+ success: (res) => {
35
+ if (res.confirm) {
36
+ this.userStore.logout() // 调用退出接口
37
+ mpx.showToast({ title: '已退出登录', icon: 'success' })
38
+ // 通知父组件退出成功
39
+ this.triggerEvent('logoutSuccess');
40
+ }
41
+ }
42
+ })
43
+ }
44
+ }
45
+ })
46
+ </script>
47
+
48
+ <style lang="scss">
49
+ $primary: #07c160;
50
+ $text-3: #999999;
51
+
52
+ .logout-section {
53
+ padding: 40rpx 16rpx 80rpx; // 底部留空适配tabbar
54
+ display: flex;
55
+ flex-direction: column;
56
+ align-items: center;
57
+
58
+ .logout-btn {
59
+ width: 300rpx;
60
+ height: 72rpx;
61
+ border-radius: 36rpx;
62
+ border: 2rpx solid #ff4d4f;
63
+ background: #fff;
64
+ color: #ff4d4f;
65
+ font-size: 28rpx;
66
+ font-weight: 500;
67
+ display: flex;
68
+ align-items: center;
69
+ justify-content: center;
70
+ margin-bottom: 24rpx;
71
+ transition: all 0.2s;
72
+
73
+ &:active {
74
+ background: #fff1f0;
75
+ transform: scale(0.98);
76
+ }
77
+ }
78
+
79
+ .version-text {
80
+ font-size: 24rpx;
81
+ color: $text-3;
82
+ }
83
+ }
84
+ </style>
85
+
86
+ <script type="application/json">
87
+ {
88
+ "component": true,
89
+ "usingComponents": {}
90
+ }
91
+ </script>
@@ -6,7 +6,8 @@
6
6
  <view class="main-profile" wx:if="{{ isUserAvatar }}">
7
7
  <view class="profile-left">头像</view>
8
8
  <view class="profile-right">
9
- <button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
9
+ <button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar@wx="onChooseAvatar"
10
+ onChooseAvatar@ali="onChooseAvatar">
10
11
  <image class="avatar-img" src="{{ resourceUrl + '/components/gray_head2x.png' }}" mode="aspectFill"
11
12
  wx:if="{{ !userInfo.avatar }}" />
12
13
  <image class="avatar-img" src="{{ imageUrl + userInfo.avatar }}" mode="aspectFill" wx:else />
@@ -40,8 +41,13 @@
40
41
  <view class="phone-left">手机号</view>
41
42
  <view class="phone-right">
42
43
  <view class="phone-number">{{ userInfo.mobilePhone }}</view>
43
- <button open-type="getPhoneNumber" class="phone-right-btn" bindgetphonenumber="getPhoneNumber"
44
- wx:if="{{ isChangePhone }}">更换手机号</button>
44
+ <!-- 微信 -->
45
+ <button open-type="getPhoneNumber" class="phone-right-btn" bindgetphonenumber="getPhoneNumberWechat"
46
+ wx:if="{{ isChangePhone && __mpx_mode__ === 'wx' }}">更换手机号</button>
47
+ <!-- 支付宝 -->
48
+ <button open-type="getAuthorize" scope="phoneNumber" class="phone-right-btn"
49
+ wx:if="{{ isChangePhone && __mpx_mode__ === 'ali' }}" onGetAuthorize="getPhoneNumberAli"
50
+ onError="onPhoneAuthFail">更换手机号</button>
45
51
  </view>
46
52
  </view>
47
53
  </view>
@@ -59,9 +65,8 @@ import { config } from '../../utils/config'
59
65
  import { UpdateUserReq, UserInfo } from '../../api/auth/types'
60
66
  import { authApi } from '../../api/auth/index'
61
67
  import { fileApi } from '../../api/files/index';
62
- import { db } from '../../utils/db';
63
68
  import { FileInfo } from '../../api/files/types';
64
- import { auth } from '../../utils/auth';
69
+ import { useUserStore } from '../../store/user';
65
70
 
66
71
  createComponent({
67
72
  properties: {
@@ -94,9 +99,11 @@ createComponent({
94
99
  data: {
95
100
  resourceUrl: config.resourceUrl + "/images",
96
101
  imageUrl: config.baseUrl + "/v1/file/path/",
97
- userInfo: {} as UserInfo
102
+ userInfo: {} as UserInfo,
103
+ userStore: {} as any
98
104
  },
99
105
  ready() {
106
+ this.userStore = useUserStore();
100
107
  this.getUserInfo();
101
108
  },
102
109
  /**
@@ -104,19 +111,17 @@ createComponent({
104
111
  */
105
112
  methods: {
106
113
  // 获取用户信息
107
- getUserInfo() {
114
+ getUserInfo(cache: boolean = true) {
108
115
  console.log("getUserInfo");
109
- auth.getUserInfo().then((resp: UserInfo) => {
110
- console.log("getUserInfo", resp);
116
+ this.userStore.getUserInfo(cache).then((resp: UserInfo) => {
111
117
  this.userInfo = resp;
112
- })
118
+ });
113
119
  },
114
120
 
115
121
  // 获取微信头像
116
122
  onChooseAvatar(e: any) {
117
123
  console.log("onChooseAvatar", e);
118
124
  const { avatarUrl } = e.detail;
119
-
120
125
  fileApi.uploadFile(avatarUrl).then((res: FileInfo) => {
121
126
  console.log("uploadFile1", res);
122
127
  this.userInfo.avatar = res.fileSrc;
@@ -124,7 +129,8 @@ createComponent({
124
129
  },
125
130
 
126
131
  // 更换手机号
127
- getPhoneNumber(e: any) {
132
+ getPhoneNumberWechat(e: any) {
133
+ console.log("getPhoneNumber", e);
128
134
  if (e.detail.errMsg === "getPhoneNumber:ok") {
129
135
  // 授权成功后,调用rbac模块接口 已登陆状态小程序更换绑定手机号
130
136
  authApi.replaceBindphone({
@@ -133,13 +139,37 @@ createComponent({
133
139
  componentAppid: config.componentAppid
134
140
  }).then((res) => {
135
141
  if (res.data) {
136
- auth.getUserInfo(false).then((res) => {
137
- this.userInfo = res as UserInfo;
138
- });
142
+ this.getUserInfo(false);
139
143
  }
140
144
  })
141
145
  }
142
146
  },
147
+ getPhoneNumberAli(e: any) {
148
+ console.log("getPhoneNumber", e);
149
+ // 支付宝小程序获取手机号
150
+ my.getPhoneNumber({
151
+ success: (res: any) => {
152
+ console.log("手机号授权", res);
153
+ const { response } = res;
154
+ authApi.replaceBindphone({
155
+ appId: config.appId,
156
+ phoneCode: response,
157
+ componentAppid: config.componentAppid
158
+ }).then((res) => {
159
+ if (res.data) {
160
+ this.getUserInfo(false);
161
+ }
162
+ })
163
+ },
164
+ fail: () => {
165
+ mpx.showToast({
166
+ title: "您已取消授权",
167
+ icon: "none",
168
+ duration: 2000,
169
+ });
170
+ }
171
+ });
172
+ },
143
173
  // 更新用户信息
144
174
  handleUpdateUser() {
145
175
  let updateReq: UpdateUserReq = { ...this.userInfo } as UpdateUserReq;
@@ -148,12 +178,20 @@ createComponent({
148
178
  authApi.updateUserInfo(updateReq).then((res) => {
149
179
  // 保存成功后重新设置本地缓存信息,并跳转到我的页面
150
180
  if (res.statusCode === 200) {
151
- db.setUserInfo(res.data)
181
+ this.userStore.setUserInfo(res.data);
152
182
  mpx.navigateBack({
153
183
  delta: 1
154
- })
155
- }
156
- })
184
+ });
185
+ };
186
+ });
187
+ },
188
+ // 手机号授权失败回调
189
+ onPhoneAuthFail() {
190
+ mpx.showToast({
191
+ title: "手机号授权失败",
192
+ icon: "none",
193
+ duration: 2000,
194
+ });
157
195
  }
158
196
  }
159
197
  }
@@ -338,7 +376,6 @@ $bg-card: #ffffff;
338
376
 
339
377
  <script type="application/json">
340
378
  {
341
- "component": true,
342
- "usingComponents": {}
379
+ "component": true
343
380
  }
344
381
  </script>