jmash-core-mp 0.1.0

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 (58) hide show
  1. package/.editorconfig +9 -0
  2. package/README.md +49 -0
  3. package/babel.config.json +34 -0
  4. package/eslint.config.mjs +7 -0
  5. package/mpx.config.js +27 -0
  6. package/package.json +69 -0
  7. package/postcss.config.js +11 -0
  8. package/project.config.json +25 -0
  9. package/project.private.config.json +14 -0
  10. package/public/index.html +15 -0
  11. package/src/api/auth/index.ts +166 -0
  12. package/src/api/auth/types.ts +115 -0
  13. package/src/api/cms/index.ts +58 -0
  14. package/src/api/cms/types.ts +137 -0
  15. package/src/api/constant.ts +6 -0
  16. package/src/api/dict/index.ts +44 -0
  17. package/src/api/dict/types.ts +50 -0
  18. package/src/api/dicts.ts +72 -0
  19. package/src/api/files/index.ts +177 -0
  20. package/src/api/files/types.ts +68 -0
  21. package/src/api/index.ts +11 -0
  22. package/src/api/myorgan/index.ts +0 -0
  23. package/src/api/myorgan/types.ts +43 -0
  24. package/src/app.mpx +62 -0
  25. package/src/components/auth-user/jmash-update-user/index.mpx +31 -0
  26. package/src/components/auth-user/jmash-user.mpx +119 -0
  27. package/src/components/common/auth-avatar/avatar-edit/index.mpx +31 -0
  28. package/src/components/common/auth-search/index.mpx +31 -0
  29. package/src/components/common/jmash-tab-bar.mpx +50 -0
  30. package/src/components/core/jmash-cms-protocol.mpx +67 -0
  31. package/src/components/core/jmash-login.mpx +343 -0
  32. package/src/components/core/jmash-popup-login.mpx +414 -0
  33. package/src/custom-tab-bar/index.mpx +11 -0
  34. package/src/global.d.ts +4 -0
  35. package/src/index.ts +9 -0
  36. package/src/packages/index.mpx +8 -0
  37. package/src/packages/pages/auth/cms-protocol.mpx +31 -0
  38. package/src/packages/pages/auth/login.mpx +53 -0
  39. package/src/pages/basic-component.mpx +31 -0
  40. package/src/pages/half-home.mpx +58 -0
  41. package/src/pages/home.mpx +38 -0
  42. package/src/pages/index.mpx +45 -0
  43. package/src/pages/tabbar/home.mpx +69 -0
  44. package/src/pages/tabbar/my.mpx +40 -0
  45. package/src/stores/setup.js +15 -0
  46. package/src/styles/index.scss +27 -0
  47. package/src/types/core.ts +41 -0
  48. package/src/utils/auth.ts +270 -0
  49. package/src/utils/config.ts +31 -0
  50. package/src/utils/db.ts +100 -0
  51. package/src/utils/grpc.ts +21 -0
  52. package/src/utils/request.ts +123 -0
  53. package/static/ali/mini.project.json +4 -0
  54. package/static/dd/project.config.json +15 -0
  55. package/static/swan/project.swan.json +14 -0
  56. package/static/tt/project.config.json +11 -0
  57. package/static/wx/project.config.json +41 -0
  58. package/uno.config.js +9 -0
@@ -0,0 +1,119 @@
1
+ <template>
2
+ <view class="auth-user-box">
3
+ <block wx:if="{{ token }}">
4
+ <view class="auth-user-l">
5
+ <image src="{{ baseUrl+'/v1/file/image/clip/200/200/' + userInfo.avatar }}" class="avatar-img"
6
+ wx:if="{{ userInfo.avatar }}"></image>
7
+ <image src="{{ resourceUrl + '/images/mall/' + defaultAvatar }}" class="avatar-img" style="border-radius:50%"
8
+ wx:elif="{{ defaultAvatar }}"></image>
9
+ <image src="{{ resourceUrl }}/images/mall/tswk.png" class="avatar-img" wx:else></image>
10
+ <view class="auth-user-r">
11
+ <view class="user-edit">{{ userInfo.realName }}
12
+ <image src="{{ resourceUrl }}/images/mall/book/icon/user_edit_icon.png" class="edit_icon"
13
+ bind:tap="handleUpdateUser">
14
+ </image>
15
+ </view>
16
+ <text class="user-mobile">{{ userInfo.mobilePhoneIns }}</text>
17
+ </view>
18
+ </view>
19
+ </block>
20
+ <view class="auth-user-l" wx:else>
21
+ <image src="{{ resourceUrl }}/images/mall/tswk.png" class="avatar-img"></image>
22
+ <text bind:tap="handleLogin">登录</text>
23
+ </view>
24
+ </view>
25
+ </template>
26
+
27
+ <script>
28
+ import mpx, { createComponent, ref, onShow } from '@mpxjs/core'
29
+ import { db } from '../../utils/db';
30
+ import { authApi } from '../../api/auth/index';
31
+
32
+ createComponent({
33
+ properties: {
34
+ defaultAvatar: {
35
+ type: String,
36
+ value: ''
37
+ },
38
+ },
39
+ setup(props, context) {
40
+ let config = getApp().globalData.config;
41
+ let resourceUrl = ref(config.resourceUrl);
42
+ let baseUrl = ref(config.baseUrl);
43
+ let token = ref('');
44
+ let userInfo = ref({});
45
+
46
+ onShow(() => {
47
+ token.value = db.getToken();
48
+ authApi.userInfo().then((resp) => {
49
+ userInfo.value = resp.data;
50
+ })
51
+ })
52
+ console.log(resourceUrl);
53
+ return { resourceUrl, baseUrl, token, userInfo };
54
+ },
55
+ methods: {
56
+ handleLogin() {
57
+ mpx.navigateTo({
58
+ url: '/jmash/pages/auth/login'
59
+ })
60
+ },
61
+ handleUpdateUser() {
62
+ mpx.navigateTo({
63
+ url: '/pages/user/index'
64
+ })
65
+ },
66
+ }
67
+
68
+ })
69
+ </script>
70
+
71
+ <style lang="scss">
72
+ @use "../../styles/index.scss" as *;
73
+
74
+ .auth-user-box {
75
+ display: flex;
76
+ align-items: center;
77
+ padding: 30rpx 0 30rpx 30rpx;
78
+
79
+ .auth-user-l {
80
+ display: flex;
81
+ align-items: center;
82
+ font-size: 30rpx;
83
+ font-weight: bold;
84
+
85
+ .avatar-img {
86
+ width: 120rpx;
87
+ height: 120rpx;
88
+ border-radius: $border-max-radius;
89
+ margin-right: 20rpx;
90
+ }
91
+ }
92
+
93
+ .auth-user-r {
94
+ .user-edit {
95
+ display: flex;
96
+ align-items: center;
97
+
98
+ .edit_icon {
99
+ width: 34rpx;
100
+ height: 34rpx;
101
+ margin-left: 10rpx;
102
+ }
103
+ }
104
+
105
+ .user-mobile {
106
+ font-size: $font-size;
107
+ color: $font-color-grey;
108
+ font-weight: 500;
109
+ }
110
+ }
111
+ }
112
+ </style>
113
+
114
+ <script type="application/json">
115
+ {
116
+ "component": true,
117
+ "usingComponents": {}
118
+ }
119
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <view class="avatar-edit-component">
3
+ <text>头像编辑组件</text>
4
+ </view>
5
+ </template>
6
+
7
+ <script>
8
+ import { createComponent } from '@mpxjs/core'
9
+
10
+ createComponent({
11
+ data: {
12
+ title: '头像编辑'
13
+ }
14
+ })
15
+ </script>
16
+
17
+ <style lang="scss">
18
+ .avatar-edit-component {
19
+ padding: 40rpx;
20
+ text-align: center;
21
+ font-size: 32rpx;
22
+ color: #333;
23
+ }
24
+ </style>
25
+
26
+ <script type="application/json">
27
+ {
28
+ "component": true,
29
+ "usingComponents": {}
30
+ }
31
+ </script>
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <view class="search-component">
3
+ <text>搜索组件</text>
4
+ </view>
5
+ </template>
6
+
7
+ <script>
8
+ import { createComponent } from '@mpxjs/core'
9
+
10
+ createComponent({
11
+ data: {
12
+ title: '搜索'
13
+ }
14
+ })
15
+ </script>
16
+
17
+ <style lang="scss">
18
+ .search-component {
19
+ padding: 40rpx;
20
+ text-align: center;
21
+ font-size: 32rpx;
22
+ color: #333;
23
+ }
24
+ </style>
25
+
26
+ <script type="application/json">
27
+ {
28
+ "component": true,
29
+ "usingComponents": {}
30
+ }
31
+ </script>
@@ -0,0 +1,50 @@
1
+ <template>
2
+ <cube-tab-bar wx:model="{{ selectedLabelDefault }}" wx:model-prop="value" tabs="{{ tabs }}"
3
+ bindclick="clickHandler">
4
+ </cube-tab-bar>
5
+ </template>
6
+
7
+ <script>
8
+ import mpx, { createComponent } from '@mpxjs/core'
9
+ createComponent({
10
+ data: {
11
+ selectedLabelDefault: 'Home',
12
+ tabs: [{
13
+ label: '首页',
14
+ value: 'Home',
15
+ pagePath: '/pages/tabbar/home',
16
+ icon: 'home'
17
+ },
18
+ {
19
+ label: '我的',
20
+ value: 'My',
21
+ pagePath: '/pages/tabbar/my',
22
+ icon: 'user'
23
+ },]
24
+ },
25
+ methods: {
26
+ clickHandler(tab) {
27
+ console.log('tab was clicked', tab)
28
+ const target = this.tabs.find(item => item.value === tab.detail.value)
29
+ if (target) {
30
+ mpx.switchTab({
31
+ url: target.pagePath
32
+ });
33
+ }
34
+ },
35
+ activeTab(value) {
36
+ console.log('activeTab set value:', value)
37
+ this.selectedLabelDefault = value;
38
+ }
39
+ }
40
+ })
41
+ </script>
42
+ <script type="application/json">
43
+ {
44
+ "usingComponents": {
45
+ "cube-tab-bar": "@mpxjs/mpx-cube-ui/lib/components/tab-bar/index.mpx",
46
+ // "cube-tab": "@mpxjs/mpx-cube-ui/lib/components/tab-bar/tab.mpx",
47
+ // "cube-icon": "@mpxjs/mpx-cube-ui/lib/components/icon/index.mpx"
48
+ }
49
+ }
50
+ </script>
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <view class="cms_box" wx:for="{{ contents }}" wx:key="*this">
3
+ <view class="cms_title">{{ title }}</view>
4
+ <rich-text nodes="{{ item.infoContent }}"></rich-text>
5
+ </view>
6
+ </template>
7
+
8
+ <script>
9
+ import { createComponent, ref, toRefs, watch } from '@mpxjs/core'
10
+ import { cmsApi } from '../../api/cms/index'
11
+
12
+ createComponent({
13
+ properties: {
14
+ // 站点ID
15
+ siteId: {
16
+ type: String,
17
+ value: ""
18
+ },
19
+ // 租户
20
+ tenant: {
21
+ type: String,
22
+ value: ""
23
+ },
24
+ // 别名
25
+ channelAlias: {
26
+ type: String,
27
+ value: ""
28
+ }
29
+ },
30
+ setup(props) {
31
+ let contents = ref([{ contentId: "123" }]);
32
+ let title = ref("");
33
+ const { channelAlias } = toRefs(props)
34
+ watch(channelAlias, (newVal) => {
35
+ cmsApi.findCmsContentInfo({ siteId: props.siteId, channelAlias: newVal, tenant: props.tenant }).then(({ data }) => {
36
+ console.log(data)
37
+ title.value = data.cmsInfo.infoTitle;
38
+ contents.value = data.infoContentResults;
39
+ console.log(contents)
40
+ })
41
+ })
42
+ return {
43
+ title,
44
+ contents
45
+ };
46
+ },
47
+ })
48
+ </script>
49
+
50
+ <style lang="scss">
51
+ .cms_box {
52
+ padding: 15px 3%;
53
+ font-size: 28rpx;
54
+ line-height: 25px;
55
+ }
56
+
57
+ .cms_title {
58
+ text-align: center;
59
+ }
60
+ </style>
61
+
62
+ <script type="application/json">
63
+ {
64
+ "component": true,
65
+ "usingComponents": {}
66
+ }
67
+ </script>
@@ -0,0 +1,343 @@
1
+ <template>
2
+ <slot name="before"></slot>
3
+ <view class="login_box">
4
+ <!-- 头像区域 -->
5
+ <view class="avatar-section">
6
+ <button class="avatar-wrapper" open-type="chooseAvatar" bind:chooseavatar="onChooseAvatar">
7
+ <image class="avatar-img" src="{{ avatarUrl || avatar }}" mode="aspectFill" />
8
+ <view class="avatar-badge">
9
+ <text class="badge-icon">✎</text>
10
+ </view>
11
+ </button>
12
+ <text class="avatar-tip">点击更换头像</text>
13
+ </view>
14
+
15
+ <!-- 姓名输入 -->
16
+ <view class="name-section">
17
+ <view class="name-field">
18
+ <text class="field-icon">👤</text>
19
+ <input type="nickname" class="weui-input name-input" bind:input="validate" placeholder="请输入您的姓名"
20
+ wx:model="{{ nameValue }}" wx:model-prop="value" />
21
+ </view>
22
+ </view>
23
+
24
+ <button open-type="getPhoneNumber" style="{{ loginStyle }}" bindgetphonenumber="wxPhoneLogin"
25
+ wx:if="{{ agreeStatus && isValidate }}">手机号授权登录</button>
26
+ <button bind:tap="onLogin" style="{{ loginStyle }}" wx:else>手机号授权登录</button>
27
+ <radio-group bindchange="agreeChange" class="protocol_agree" wx:if="{{ showPrivacyPolicy }}">
28
+ <label>
29
+ <radio value="{{ agreeStatus }}" checked="{{ agreeStatus }}" color="{{ checkedColor }}" />
30
+ 已阅读<text id="user" style="{{ agreementStyle }}" catch:tap="goPolicyInfo">《用户使用协议》</text> <text id="privacy"
31
+ style="{{ agreementStyle }}" catch:tap="goPolicyInfo">《隐私权政策》</text>
32
+ </label>
33
+ </radio-group>
34
+ <slot name="after"></slot>
35
+ </view>
36
+ </template>
37
+
38
+ <script>
39
+ import { auth } from '../../utils/auth'
40
+ import mpx, { createComponent, ref } from '@mpxjs/core'
41
+
42
+ createComponent({
43
+ options: {
44
+ multipleSlots: true,
45
+ },
46
+ properties: {
47
+ // 登录按钮样式
48
+ loginStyle: {
49
+ type: String,
50
+ value:
51
+ "width: 100%;background-color: #2563EB;color: #fff;font-size: 15px;",
52
+ },
53
+ // 单选框选中的颜色
54
+ checkedColor: {
55
+ type: String,
56
+ value: "#0551ff",
57
+ },
58
+
59
+ // 协议样式
60
+ agreementStyle: {
61
+ type: String,
62
+ value: "color: #0551ff",
63
+ },
64
+
65
+ //登录后跳转页面
66
+ backurl: {
67
+ type: String,
68
+ value: "/pages/home",
69
+ },
70
+ // 登录后跳转方式 "redirectTo switchTab reLaunch navigateTo"
71
+ linkType: {
72
+ type: String,
73
+ value: "redirectTo",
74
+ },
75
+ //遮罩层效果
76
+ isShowModel: {
77
+ type: Boolean,
78
+ value: false,
79
+ },
80
+ // 是否显示隐私协议和政策
81
+ showPrivacyPolicy: {
82
+ type: Boolean,
83
+ value: true
84
+ }
85
+ },
86
+ setup(props) {
87
+ let config = getApp().globalData.config || { resourceUrl: '', name: '应用' };
88
+ let agreeStatus = ref(false);
89
+ let nameValue = ref('');
90
+ let avatarUrl = ref('');
91
+ let isValidate = ref(false);
92
+ let avatar = ref(config.resourceUrl + "/images/components/gray_head2x.png");
93
+ console.log(avatar);
94
+ return {
95
+ agreeStatus,
96
+ nameValue,
97
+ avatarUrl,
98
+ isValidate,
99
+ avatar,
100
+ };
101
+ },
102
+ methods: {
103
+ // 协议勾选事件
104
+ agreeChange() {
105
+ this.agreeStatus = !this.agreeStatus;
106
+ this.validate();
107
+ },
108
+ // 跳转隐私协议
109
+ goPolicyInfo(e) {
110
+ const id = e.currentTarget.id
111
+ this.triggerEvent("policy", id);
112
+ mpx.navigateTo({
113
+ url: '/jmash/pages/auth/cms-protocol?channelAlias=' + id
114
+ });
115
+ },
116
+ // 头像选择
117
+ onChooseAvatar(e) {
118
+ this.avatarUrl = e.detail.avatarUrl;
119
+ this.validate();
120
+ },
121
+ // 验证
122
+ validate() {
123
+ if (!this.nameValue) {
124
+ this.isValidate = false;
125
+ return;
126
+ }
127
+ this.isValidate = true;
128
+ },
129
+ // 登录前验证
130
+ onLogin() {
131
+ if (!this.agreeStatus && this.showPrivacyPolicy) {
132
+ mpx.showModal({
133
+ title: "提示",
134
+ content: "您是否已阅读《用户使用协议》《隐私权政策》?",
135
+ success: (res) => {
136
+ if (res.confirm) {
137
+ this.agreeStatus = true;
138
+ }
139
+ },
140
+ });
141
+ }
142
+ if (!this.nameValue) {
143
+ mpx.showToast({
144
+ title: "请输入姓名",
145
+ icon: "none",
146
+ duration: 2000,
147
+ });
148
+ }
149
+ },
150
+ wxPhoneLogin(event) {
151
+ let that = this;
152
+ if (!this.agreeStatus && this.showPrivacyPolicy) {
153
+ mpx.showModal({
154
+ title: "提示",
155
+ content: "您是否已阅读《用户使用协议》《隐私权政策》?",
156
+ success(res) {
157
+ if (res.confirm) {
158
+ that.agreeStatus = true;
159
+ }
160
+ },
161
+ });
162
+ return;
163
+ }
164
+ if (!this.nameValue) {
165
+ mpx.showToast({
166
+ title: "请输入姓名",
167
+ icon: "none",
168
+ duration: 2000,
169
+ });
170
+ return;
171
+ }
172
+ if (event.detail.errMsg === "getPhoneNumber:ok") {
173
+ console.log(event.detail.code);
174
+ auth.phoneCodeLogin(event.detail.code, this.nameValue).then((resp) => {
175
+ if (resp.status === false) {
176
+ mpx.showToast({
177
+ title: resp.message ? resp.message : "登录失败联系管理员",
178
+ icon: "none",
179
+ duration: 2000,
180
+ });
181
+ return;
182
+ }
183
+ const backurl = decodeURIComponent(this.backurl);
184
+ if (this.linkType === "switchTab") {
185
+ mpx.switchTab({ url: backurl });
186
+ } else if (this.linkType === "navigateTo") {
187
+ mpx.navigateTo({ url: backurl });
188
+ } else if (this.linkType === "redirectTo") {
189
+ mpx.redirectTo({ url: backurl });
190
+ } else {
191
+ mpx.reLaunch({ url: backurl });
192
+ }
193
+ });
194
+ } else {
195
+ mpx.showToast({
196
+ title: "您已取消授权",
197
+ icon: "none",
198
+ duration: 2000,
199
+ });
200
+ }
201
+ }
202
+ }
203
+ })
204
+ </script>
205
+
206
+ <style lang="scss">
207
+ @use "../../styles/index.scss" as *;
208
+
209
+ $primary: #07c160;
210
+ $primary-dark: #06ad56;
211
+ $text-1: #111111;
212
+ $text-2: #555555;
213
+ $text-3: #888888;
214
+ $border: #d0d0d0;
215
+ $bg-page: #f2f2f2;
216
+ $bg-card: #ffffff;
217
+
218
+ .login_box {
219
+ padding: 13% 3% 4%;
220
+ display: flex;
221
+ flex-direction: column;
222
+ align-items: center;
223
+
224
+ .login_btn {
225
+ background-color: $blue-color;
226
+ color: $white-color;
227
+ padding: 16px 0;
228
+ width: $width;
229
+ font-size: $font-size;
230
+ }
231
+
232
+ .protocol_agree {
233
+ color: $font-color-grey-opacity;
234
+ font-size: $font-size;
235
+ margin-top: 20px;
236
+
237
+ text {
238
+ color: $blue-color;
239
+ }
240
+ }
241
+
242
+ .avatar-section {
243
+ display: flex;
244
+ flex-direction: column;
245
+ align-items: center;
246
+ margin-bottom: 32rpx;
247
+
248
+ .avatar-wrapper {
249
+ position: relative;
250
+ margin: 0;
251
+ padding: 0;
252
+ background: none;
253
+ border: none;
254
+ line-height: 1;
255
+
256
+ .avatar-img {
257
+ width: 120rpx;
258
+ height: 120rpx;
259
+ border-radius: 50%;
260
+ border: 4rpx solid $border;
261
+ display: block;
262
+ }
263
+
264
+ .avatar-badge {
265
+ position: absolute;
266
+ right: 0;
267
+ bottom: 0;
268
+ width: 36rpx;
269
+ height: 36rpx;
270
+ background: $primary;
271
+ border-radius: 50%;
272
+ border: 3rpx solid $bg-card;
273
+ display: flex;
274
+ align-items: center;
275
+ justify-content: center;
276
+
277
+ .badge-icon {
278
+ font-size: 16rpx;
279
+ color: #fff;
280
+ }
281
+ }
282
+ }
283
+
284
+ .avatar-tip {
285
+ margin-top: 16rpx;
286
+ font-size: 20rpx;
287
+ color: $text-3;
288
+ }
289
+ }
290
+
291
+ .name-section {
292
+ width: 100%;
293
+ margin-bottom: 32rpx;
294
+
295
+ .name-field {
296
+ display: flex;
297
+ align-items: center;
298
+ background: $bg-page;
299
+ border-radius: 20rpx;
300
+ padding: 0 28rpx;
301
+ height: 88rpx;
302
+ border: 2rpx solid transparent;
303
+ transition: border-color 0.25s, background-color 0.25s;
304
+
305
+ .field-icon {
306
+ font-size: 32rpx;
307
+ margin-right: 16rpx;
308
+ flex-shrink: 0;
309
+ }
310
+
311
+ .name-input {
312
+ flex: 1;
313
+ min-width: 0;
314
+ font-size: 28rpx;
315
+ color: $text-1;
316
+ background: transparent;
317
+ border: none;
318
+ outline: none;
319
+ height: 80rpx;
320
+ line-height: 80rpx;
321
+ padding: 0;
322
+ }
323
+
324
+ .name-input::placeholder {
325
+ font-size: 28rpx;
326
+ color: $text-3;
327
+ }
328
+ }
329
+
330
+ .name-field:focus-within {
331
+ border-color: $primary;
332
+ background: $bg-card;
333
+ }
334
+ }
335
+ }
336
+ </style>
337
+
338
+ <script type="application/json">
339
+ {
340
+ "component": true,
341
+ "usingComponents": {}
342
+ }
343
+ </script>