mali-applet-ui 0.2.93 → 0.2.95

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.
@@ -4,16 +4,16 @@
4
4
  <view class="ml-approval-record-header-title">审批记录</view>
5
5
  </view>
6
6
  <view class="ml-approval-record-body">
7
- <view class="ml-approval-record-list" v-for="(group, gIndex) in flowOptions" :key="gIndex">
7
+ <view class="ml-approval-record-list" v-for="(group, gIndex) in flowItems" :key="gIndex">
8
8
  <view class="ml-approval-record-flow-line"></view>
9
9
  <view class="ml-approval-record-item">
10
10
  <view class="ml-approval-record-item-title">{{ group.name }}</view>
11
11
  </view>
12
12
  <view class="ml-approval-record-users">
13
- <view class="ml-approval-record-user-item" v-for="(item, uIndex) in group.users" :key="uIndex">
13
+ <view class="ml-approval-record-user-item" v-for="(item, uIndex) in group.userList" :key="uIndex">
14
14
  <view class="ml-approval-record-user-item-info">
15
15
  <view class="ml-approval-record-user-item-left">
16
- <image class="ml-approval-record-user-picture" :src="item.picture" mode="scaleToFill"></image>
16
+ <image class="ml-approval-record-user-picture" src="https://csgc.saas.ddqrcode.com/applet/business/image/portrait2.png" mode="scaleToFill"></image>
17
17
  </view>
18
18
  <view class="ml-approval-record-user-item-content">
19
19
  <view class="ml-approval-record-user-item-top">
@@ -48,31 +48,53 @@ export default {
48
48
  },
49
49
  data () {
50
50
  return {
51
+ flowItems: [],
52
+ approvalData: {
53
+ flowHandlers: [],
54
+ module: null,
55
+ flowSettingCode: null,
56
+ enableFlag: false
57
+ },
51
58
  flowOptions: []
52
59
  }
53
60
  },
54
61
  watch: {
55
62
  code () {
56
- this.load()
63
+ this.loadFlow()
57
64
  }
58
65
  },
59
66
  created () {
60
- this.flowOptions = this.options || []
61
- this.load()
67
+ this.approvalData.module = this.code
68
+ this.approvalData.flowSettingCode = this.code
69
+ this.updateFlowItems(this.options)
70
+ this.loadFlow()
62
71
  },
63
72
  methods: {
64
- load () {
73
+ updateModel () {
74
+ this.$emit('input', this.approvalData)
75
+ },
76
+ updateFlowItems (list) {
77
+ this.flowItems = (list || []).map(item => {
78
+ item.f = []
79
+ return item
80
+ })
81
+ },
82
+ async loadFlow () {
83
+ await this.$nextTick()
65
84
  if (!this.code) {
66
85
  return
67
86
  }
68
- if (globalStore.approval && globalStore.approval.record) {
69
- const loadOptionMethod = globalStore.approval.record.loadOption
70
- if (loadOptionMethod) {
71
- Promise.resolve(loadOptionMethod({
72
- value: this.value,
87
+ if (globalStore.approval && globalStore.approval.select) {
88
+ const loadFlowMethod = globalStore.approval.select.loadFlow
89
+ if (loadFlowMethod) {
90
+ Promise.resolve(loadFlowMethod({
73
91
  code: this.code
74
- })).then(options => {
75
- this.flowOptions = options
92
+ })).then(res => {
93
+ this.approvalData.enableFlag = res.enableFlag
94
+ this.approvalData.flowSettingCode = res.flowSettingCode
95
+ this.approvalData.module = res.module
96
+ this.updateFlowItems(res.flowItems)
97
+ this.updateModel()
76
98
  })
77
99
  }
78
100
  }
@@ -5,8 +5,8 @@
5
5
  <view v-else class="ml-cascader-picker" :class="[className || '', {'is-border': border, 'is-clear': value.length}]">
6
6
  <view class="ml-cascader-picker-warpper" @click="openPopup()">
7
7
  <view class="ml-cascader-picker-text">
8
- <text v-if="value.length">{{ selectLabel }}</text>
9
- <text v-else class="picker-placeholder">{{ placeholder }}</text>
8
+ <view v-if="value.length" class="ml-cascader-picker-label">{{ selectLabel }}</view>
9
+ <view v-else class="ml-cascader-picker-placeholder">{{ placeholder }}</view>
10
10
  </view>
11
11
  <view v-if="clearable && value.length" class="ml-cascader-picker-clear-icon" @click.stop="clearEvent">
12
12
  <ml-icon name="delete-filling"></ml-icon>
@@ -211,8 +211,12 @@ export default {
211
211
  flex-grow: 1;
212
212
  padding-right: 10rpx;
213
213
  overflow: hidden;
214
- text-overflow: ellipsis;
215
- white-space: nowrap;
214
+ .ml-cascader-picker-label,
215
+ .ml-cascader-picker-placeholder {
216
+ overflow: hidden;
217
+ text-overflow: ellipsis;
218
+ white-space: nowrap;
219
+ }
216
220
  }
217
221
  .ml-cascader-picker-clear-icon {
218
222
  width: 60rpx;
@@ -1,7 +1,18 @@
1
1
  <template>
2
- <view class="ml-load-more" :class="[className]">
3
- <slot></slot>
4
- <view v-if="showPage" class="ml-load-more-warpper">
2
+ <view class="ml-load-more" :class="[className || '', {'not-data': showNotData}]">
3
+ <view class="ml-load-more-content">
4
+ <slot></slot>
5
+ </view>
6
+ <view v-if="showNotData && !loading" class="ml-load-more-empty">
7
+ <slot name="empty">
8
+ <ml-not-data :emptyUrl="emptyUrl" :emptyText="emptyText" :emptyHint="emptyHint">
9
+ <template #content>
10
+ <slot name="emptycontent"></slot>
11
+ </template>
12
+ </ml-not-data>
13
+ </slot>
14
+ </view>
15
+ <view v-else-if="showPage" class="ml-load-more-warpper">
5
16
  <view v-if="loadStatus === 'more'" class="ml-load-more-status-more">上拉显示更多</view>
6
17
  <view v-if="loadStatus === 'noMore'" class="ml-load-more-status-no-more">没有更多数据了</view>
7
18
  </view>
@@ -19,6 +30,8 @@ export default {
19
30
  showPage: Boolean,
20
31
  pageProps: Object,
21
32
  requestMethod: Function,
33
+ filterForm: Object,
34
+ emptyConfig: Object,
22
35
  className: String
23
36
  },
24
37
  inject: {
@@ -34,7 +47,10 @@ export default {
34
47
  pageSize: globalStore.loadMore.pageSize,
35
48
  currPage: 1,
36
49
  total: 0
37
- }
50
+ },
51
+ emptyUrl: '',
52
+ emptyText: '',
53
+ emptyHint: ''
38
54
  }
39
55
  },
40
56
  computed: {
@@ -44,8 +60,23 @@ export default {
44
60
  }
45
61
  return this.pageVO.pageSize * this.pageVO.currPage < Number(this.pageVO.total) ? 'more' : 'noMore'
46
62
  },
63
+ showNotData () {
64
+ return !this.value || !this.value.length
65
+ },
47
66
  pagePropOpts () {
48
67
  return { ...globalStore.loadMore.pageProp, ...this.pageProps }
68
+ },
69
+ hasFilters () {
70
+ console.log(this.filterForm)
71
+ for (let key in this.filterForm) {
72
+ if (this.filterForm[key]) {
73
+ return true
74
+ }
75
+ }
76
+ return false
77
+ },
78
+ emptyOpts () {
79
+ return Object.assign({}, this.emptyConfig)
49
80
  }
50
81
  },
51
82
  created () {
@@ -119,6 +150,7 @@ export default {
119
150
  uni.stopPullDownRefresh()
120
151
  console.error(e)
121
152
  }
153
+ this.updateEmptyStatus()
122
154
  },
123
155
  async loadMore() {
124
156
  if (this.showPage && !this.loading && this.loadStatus === 'more') {
@@ -131,12 +163,30 @@ export default {
131
163
  console.error(e)
132
164
  }
133
165
  }
166
+ },
167
+ updateEmptyStatus () {
168
+ if (this.hasFilters) {
169
+ this.emptyUrl = this.emptyOpts.resultUrl || globalStore.loadMore.notData.resultUrl
170
+ this.emptyText = XEUtils.template(this.emptyOpts.resultText || globalStore.loadMore.notData.resultText, this.filterForm)
171
+ this.emptyHint = XEUtils.template(this.emptyOpts.resultHint || globalStore.loadMore.notData.resultHint, this.filterForm)
172
+ } else {
173
+ this.emptyUrl = this.emptyOpts.emptyUrl || globalStore.loadMore.notData.emptyUrl
174
+ this.emptyText = this.emptyOpts.emptyText || globalStore.loadMore.notData.emptyText
175
+ this.emptyHint = this.emptyOpts.emptyHint || globalStore.loadMore.notData.emptyHint
176
+ }
134
177
  }
135
178
  }
136
179
  }
137
180
  </script>
138
181
 
139
182
  <style lang="scss">
183
+ .ml-load-more {
184
+ &.not-data {
185
+ .ml-load-more-content {
186
+ display: none;
187
+ }
188
+ }
189
+ }
140
190
  .ml-load-more-warpper {
141
191
  text-align: center;
142
192
  .ml-load-more-status-more,
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <view class="ml-not-data">
3
+ <slot>
4
+ <view v-if="emptyUrl || $slots.icon" class="ml-not-data-image">
5
+ <slot name="icon">
6
+ <image class="ml-not-data-image-icon" :src="emptyUrl" mode="aspectFit"></image>
7
+ </slot>
8
+ </view>
9
+ <view v-if="emptyText || $slots.text" class="ml-not-data-text">
10
+ <slot name="text">
11
+ <text>{{ emptyText || '暂无数据!' }}</text>
12
+ </slot>
13
+ </view>
14
+ <view v-if="emptyHint || $slots.hint" class="ml-not-data-hint">
15
+ <slot name="hint">
16
+ <text>{{ emptyHint }}</text>
17
+ </slot>
18
+ </view>
19
+ <view class="ml-not-data-contnet">
20
+ <slot name="contnet"></slot>
21
+ </view>
22
+ </slot>
23
+ </view>
24
+ </template>
25
+
26
+ <script>
27
+ export default {
28
+ name: 'MlNotData',
29
+ props: {
30
+ emptyUrl: String,
31
+ emptyText: String,
32
+ emptyHint: String
33
+ }
34
+ }
35
+ </script>
36
+
37
+ <style lang="scss">
38
+ .ml-not-data {
39
+ text-align: center;
40
+ padding-top: 100rpx;
41
+ .ml-not-data-image-icon {
42
+ width: 400rpx;
43
+ }
44
+ .ml-not-data-text {
45
+ font-size: 32rpx;
46
+ font-weight: 700;
47
+ }
48
+ .ml-not-data-hint {
49
+ font-size: 26rpx;
50
+ padding: 0 60rpx;
51
+ line-height: 40rpx;
52
+ color: rgba(0, 0, 0, 0.45);
53
+ }
54
+ .ml-not-data-text,
55
+ .ml-not-data-hint {
56
+ margin-bottom: 20rpx;
57
+ }
58
+ }
59
+ </style>
@@ -5,8 +5,8 @@
5
5
  <view v-else class="ml-province-city-picker" :class="[className || '', {'is-border': border, 'is-clear': (value ? (value.length || province) : province)}]">
6
6
  <view class="ml-province-city-picker-warpper" @click="openPopup()">
7
7
  <view class="ml-province-city-picker-text">
8
- <text v-if="(value ? (value.length || province) : province)">{{ selectLabel }}</text>
9
- <text v-else class="picker-placeholder">{{ placeholder }}</text>
8
+ <view v-if="(value ? (value.length || province) : province)" class="ml-province-city-picker-label">{{ selectLabel }}</view>
9
+ <view v-else class="ml-province-city-picker-placeholder">{{ placeholder }}</view>
10
10
  </view>
11
11
  <view v-if="clearable && (value ? (value.length || province) : province)" class="ml-province-city-picker-clear-icon" @click.stop="clearEvent">
12
12
  <ml-icon name="delete-filling"></ml-icon>
@@ -174,8 +174,12 @@ export default {
174
174
  flex-grow: 1;
175
175
  padding-right: 10rpx;
176
176
  overflow: hidden;
177
- text-overflow: ellipsis;
178
- white-space: nowrap;
177
+ .ml-province-city-picker-label,
178
+ .ml-province-city-picker-placeholder {
179
+ overflow: hidden;
180
+ text-overflow: ellipsis;
181
+ white-space: nowrap;
182
+ }
179
183
  }
180
184
  .ml-province-city-picker-clear-icon {
181
185
  width: 60rpx;
@@ -5,8 +5,8 @@
5
5
  <picker v-else class="ml-select-picker" mode="selector" :value="selectIndex" :style="{width: width || '100%'}" :range="optionList" :range-key="optLabelField" @change="changeEvent">
6
6
  <view class="ml-select-picker-warpper" :class="[className || '', {'is-border': border, 'is-clear': value !== null}]">
7
7
  <view class="ml-select-picker-text">
8
- <text v-if="value !== null">{{ selectLabel }}</text>
9
- <text v-else class="picker-placeholder">{{ placeholder }}</text>
8
+ <view v-if="value !== null" class="ml-select-picker-label">{{ selectLabel }}</view>
9
+ <view v-else class="ml-select-picker-placeholder">{{ placeholder }}</view>
10
10
  </view>
11
11
  <view v-if="clearable && value !== null" class="ml-select-picker-clear-icon" @click.stop="clearEvent">
12
12
  <ml-icon name="delete-filling"></ml-icon>
@@ -155,8 +155,12 @@ export default {
155
155
  .ml-select-picker-text {
156
156
  flex-grow: 1;
157
157
  overflow: hidden;
158
- text-overflow: ellipsis;
159
- white-space: nowrap;
158
+ .ml-select-picker-label,
159
+ .ml-select-picker-placeholder {
160
+ overflow: hidden;
161
+ text-overflow: ellipsis;
162
+ white-space: nowrap;
163
+ }
160
164
  }
161
165
  .ml-select-picker-clear-icon {
162
166
  width: 34rpx;
@@ -74,6 +74,7 @@ export default {
74
74
  }
75
75
  .ml-tabs-header {
76
76
  background: #fff;
77
+ padding-bottom: 10rpx;
77
78
  margin-bottom: 20rpx;
78
79
  }
79
80
  .ml-tabs-content {
@@ -85,7 +86,7 @@ export default {
85
86
  .ml-tabs-nav-item {
86
87
  position: relative;
87
88
  display: inline-block;
88
- padding: 10rpx 20rpx 0 20rpx;
89
+ padding: 10rpx 10rpx 0 10rpx;
89
90
  text-align: center;
90
91
  .ml-tabs-nav-title {
91
92
  position: relative;
@@ -39,7 +39,7 @@
39
39
  <view class="ml-upload-file-info">
40
40
  <view class="ml-upload-file-name">{{ item[nameField] }}</view>
41
41
  <view class="ml-upload-file-desc">
42
- <ml-button v-if="previewTypes.includes(item[typeField])" status="primary" type="text" @click="previewDocs(item)">预览</ml-button>
42
+ <ml-button v-if="preview && previewTypes.includes(item[typeField])" status="primary" type="text" @click="previewDocs(item)">预览</ml-button>
43
43
  <ml-button status="primary" type="text" @click="downloadEvent(item)">下载</ml-button>
44
44
  </view>
45
45
  </view>
@@ -54,9 +54,8 @@
54
54
  </template>
55
55
 
56
56
  <script>
57
- import XEUtils from 'xe-utils'
58
57
  import globalStore from '../../config/store'
59
- import { getFileSuffix } from '../../utils/file'
58
+ import { getFileSuffix, getFileName } from '../../utils/file'
60
59
  import { uploadAllFiles, uploadImageFiles } from './file-handle'
61
60
 
62
61
  export default {
@@ -70,6 +69,10 @@ export default {
70
69
  type: Array,
71
70
  default: () => ([])
72
71
  },
72
+ preview: {
73
+ type: Boolean,
74
+ default: true
75
+ },
73
76
  simpleValue: {
74
77
  type: Boolean,
75
78
  default: false
@@ -180,7 +183,7 @@ export default {
180
183
  loadList () {
181
184
  if (this.simpleValue) {
182
185
  this.fileList = (this.urlList && this.urlList.length ? this.urlList : (this.value || [])).map(url => {
183
- const name = this.getUrlName(url)
186
+ const name = getFileName(url)
184
187
  const obj = {
185
188
  id: null,
186
189
  [this.nameField]: name,
@@ -195,9 +198,9 @@ export default {
195
198
  tempPath: this.getUrl(obj)
196
199
  }
197
200
  })
198
- this.isUpdate = true
199
201
  if (this.urlList && this.urlList.length) {
200
- this.$emit('input', this.fileList)
202
+ this.isUpdate = true
203
+ this.$emit('input', [...this.fileList])
201
204
  }
202
205
  } else {
203
206
  this.fileList = (this.value || []).map(item => {
@@ -242,12 +245,11 @@ export default {
242
245
  })
243
246
  }
244
247
  return item[this.urlField]
245
- },
246
- getUrlName (url) {
247
- const urlRest = XEUtils.parseUrl(url)
248
- return urlRest.pathname.split('/').slice(-1)[0] || ''
249
248
  },
250
249
  previewImageEvent (item, index) {
250
+ if (!this.preview) {
251
+ return
252
+ }
251
253
  if (this.previewStatus) {
252
254
  return
253
255
  }
@@ -354,7 +356,7 @@ export default {
354
356
  }
355
357
  })
356
358
  },
357
- chooseEvent () {
359
+ choose () {
358
360
  if (this.loading) {
359
361
  return
360
362
  }
@@ -394,7 +396,7 @@ export default {
394
396
  }
395
397
  })
396
398
  ).then(list => {
397
- this.fileList.push(...list)
399
+ this.fileList = [...this.fileList, ...list].slice(-this.limit)
398
400
  this.isUpdate = true
399
401
  this.updateModel()
400
402
  this.loading = false
@@ -405,6 +407,9 @@ export default {
405
407
  }).catch(e => {
406
408
  console.log(e)
407
409
  })
410
+ },
411
+ chooseEvent () {
412
+ this.choose()
408
413
  }
409
414
  }
410
415
  }
package/config/store.js CHANGED
@@ -47,6 +47,13 @@ const globalStore = {
47
47
  resProps: {
48
48
  result: 'datas',
49
49
  total: 'total'
50
+ },
51
+ notData: {
52
+ emptyUrl: '',
53
+ emptyText: '暂无记录',
54
+ resultUrl: '',
55
+ resultText: '暂无相关结果',
56
+ resultHint: '请检查输入是否正确'
50
57
  }
51
58
  }
52
59
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mali-applet-ui",
3
- "version": "0.2.93",
3
+ "version": "0.2.95",
4
4
  "description": "码里云小程序组件库",
5
5
  "scripts": {
6
6
  "release": "node script/release.js && npm publish"
@@ -18,7 +18,8 @@
18
18
  "main": "index.js",
19
19
  "devDependencies": {
20
20
  "vuex": "^4.0.2",
21
- "xe-utils": "3.5.7"
21
+ "xe-utils": "3.5.7",
22
+ "dingtalk-design-miniapp": "^1.9.1"
22
23
  },
23
24
  "uni-app": {
24
25
  "scripts": {
package/utils/file.js CHANGED
@@ -1,3 +1,5 @@
1
+ import XEUtils from 'xe-utils'
2
+
1
3
  export function getFileSuffix (filename) {
2
4
  const pos = filename.lastIndexOf('.')
3
5
  let suffix = ''
@@ -7,6 +9,11 @@ export function getFileSuffix (filename) {
7
9
  return suffix
8
10
  }
9
11
 
12
+ export function getFileName (url) {
13
+ const urlRest = XEUtils.parseUrl(url)
14
+ return urlRest.pathname.split('/').slice(-1)[0] || ''
15
+ }
16
+
10
17
  /**
11
18
  * 下载文件
12
19
  * @param {*} url