mali-applet-ui 0.0.43 → 0.0.47

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.
@@ -1,5 +1,9 @@
1
1
  <template>
2
+ <view v-if="isFromReadonly" class="ml-amount-input is-readonly">
3
+ <view class="ml-amount-input-readonly-content">¥{{ amountLabel }}</view>
4
+ </view>
2
5
  <input
6
+ v-else
3
7
  class="ml-amount-input"
4
8
  v-model="inpVal"
5
9
  type="digit"
@@ -14,7 +18,7 @@
14
18
 
15
19
  <script>
16
20
  import XEUtils from 'xe-utils'
17
- import { toNumMoneyToChinese } from '../../utils'
21
+ import { toAmountString, toWanAmountString } from '../../utils'
18
22
 
19
23
  export default {
20
24
  name: 'MlAmountInput',
@@ -47,17 +51,29 @@ export default {
47
51
  },
48
52
  className: String
49
53
  },
54
+ inject: {
55
+ form: {
56
+ from: 'mlForm',
57
+ default: null
58
+ }
59
+ },
50
60
  data () {
51
61
  return {
52
62
  inpVal: ''
53
63
  }
54
64
  },
55
65
  computed: {
66
+ isFromReadonly () {
67
+ return this.form ? this.form.readonly : false
68
+ },
56
69
  currAmountNum () {
57
70
  return this.value === '' ? '' : Number(this.value || 0)
58
71
  },
59
- currAmountLabel () {
60
- return this.currAmountNum === '' ? '无' : toNumMoneyToChinese(this.currAmountNum)
72
+ amountLabel () {
73
+ if (this.simplify) {
74
+ return toWanAmountString(this.value)
75
+ }
76
+ return toAmountString(this.value)
61
77
  },
62
78
  minNum () {
63
79
  if (XEUtils.isNumber(this.min) || this.min) {
@@ -108,8 +124,9 @@ export default {
108
124
  this.$emit('blur')
109
125
  },
110
126
  inputEvent () {
111
- this.$emit('input', this.inpVal)
112
- this.$emit('change', this.inpVal)
127
+ const value = this.inpVal
128
+ this.$emit('input', value)
129
+ this.$emit('change', { value })
113
130
  }
114
131
  }
115
132
  }
@@ -128,4 +145,7 @@ export default {
128
145
  border-radius: 10rpx;
129
146
  }
130
147
  }
148
+ .ml-amount-input-readonly-content {
149
+ padding: 20rpx 4rpx;
150
+ }
131
151
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="ml-amount-text" :class="className">
2
+ <view class="ml-amount-text" :class="[className || '', status ? `status-${status}` : '', {'is-underline': underline}]">
3
3
  <slot name="symbol">
4
4
  <view v-if="symbol" class="amount-flag">¥</view>
5
5
  </slot>
@@ -23,6 +23,7 @@ export default {
23
23
  props: {
24
24
  value: [String, Number],
25
25
  simplify: Boolean,
26
+ status: String,
26
27
  symbol: {
27
28
  type: Boolean,
28
29
  default: true
@@ -31,6 +32,7 @@ export default {
31
32
  type: Boolean,
32
33
  default: false
33
34
  },
35
+ underline: Boolean,
34
36
  className: String
35
37
  },
36
38
  computed: {
@@ -53,6 +55,10 @@ export default {
53
55
  <style lang="scss">
54
56
  .ml-amount-text {
55
57
  display: inline;
58
+ padding: 0 4rpx;
59
+ &.is-underline {
60
+ text-decoration: underline;
61
+ }
56
62
  .amount-flag,
57
63
  .amount-num,
58
64
  .amount-unit {
@@ -62,5 +68,20 @@ export default {
62
68
  font-size: 0.65em;
63
69
  color: rgba(39, 42, 48, 0.45);
64
70
  }
71
+ &.status-primary {
72
+ color: $uni-color-primary;
73
+ }
74
+ &.status-success {
75
+ color: $uni-color-success;
76
+ }
77
+ &.status-info {
78
+ color: #909399;
79
+ }
80
+ &.status-warning {
81
+ color: $uni-color-warning;
82
+ }
83
+ &.status-danger {
84
+ color: $uni-color-error;
85
+ }
65
86
  }
66
87
  </style>
@@ -0,0 +1,155 @@
1
+ <template>
2
+ <view class="ml-approval-record">
3
+ <view class="ml-approval-record-header">
4
+ <view class="ml-approval-record-header-title">审批记录</view>
5
+ </view>
6
+ <view class="ml-approval-record-body">
7
+ <view class="ml-approval-record-list" v-for="(group, gIndex) in options" :key="gIndex">
8
+ <view class="ml-approval-record-flow-line"></view>
9
+ <view class="ml-approval-record-item">
10
+ <view class="ml-approval-record-item-title">{{ group.name }}</view>
11
+ </view>
12
+ <view class="ml-approval-record-users">
13
+ <view class="ml-approval-record-user-item" v-for="(item, uIndex) in group.users" :key="uIndex">
14
+ <view class="ml-approval-record-user-item-info">
15
+ <view class="ml-approval-record-user-item-left">
16
+ <image class="ml-approval-record-user-picture" :src="item.picture" mode="scaleToFill"></image>
17
+ </view>
18
+ <view class="ml-approval-record-user-item-content">
19
+ <view class="ml-approval-record-user-item-top">
20
+ <view class="ml-approval-record-user-name">{{ item.name }}</view>
21
+ <ml-approval-type :value="item.status"></ml-approval-type>
22
+ </view>
23
+ <view class="ml-approval-record-user-role">{{ item.role }}</view>
24
+ </view>
25
+ <view class="ml-approval-record-user-item-right">
26
+ <view class="ml-approval-record-user-date">{{ item.date }}</view>
27
+ </view>
28
+ </view>
29
+ <view class="ml-approval-record-user-item-comment">
30
+ <text>{{ item.comment }}</text>
31
+ </view>
32
+ </view>
33
+ </view>
34
+ </view>
35
+ </view>
36
+ </view>
37
+ </template>
38
+
39
+ <script>
40
+ export default {
41
+ name: 'MlApprovalRecord',
42
+ props: {
43
+ value: Array,
44
+ options: Array
45
+ }
46
+ }
47
+ </script>
48
+
49
+ <style lang="scss">
50
+ .ml-approval-record {
51
+ background: #ffffff;
52
+ padding: 20rpx;
53
+ border-radius: 10rpx;
54
+ font-size: 30rpx;
55
+ }
56
+ .ml-approval-record-header-title {
57
+ font-weight: 700;
58
+ line-height: 60rpx;
59
+ }
60
+ .ml-approval-record-list {
61
+ position: relative;
62
+ padding-bottom: 10rpx;
63
+ .ml-approval-record-flow-line {
64
+ position: absolute;
65
+ top: 0;
66
+ left: 0;
67
+ height: 100%;
68
+ width: 4rpx;
69
+ background: #D9D9D9;
70
+ &::before {
71
+ content: "";
72
+ position: absolute;
73
+ top: 12rpx;
74
+ left: -10rpx;
75
+ width: 24rpx;
76
+ height: 24rpx;
77
+ border-radius: 50%;
78
+ background: #D9D9D9;
79
+ }
80
+ }
81
+ &:first-child {
82
+ .ml-approval-record-flow-line {
83
+ top: 12rpx;
84
+ &::before {
85
+ top: 0;
86
+ }
87
+ }
88
+ }
89
+ &:last-child {
90
+ .ml-approval-record-flow-line {
91
+ height: 30rpx;
92
+ }
93
+ }
94
+ }
95
+ .ml-approval-record-item-title {
96
+ padding-left: 40rpx;
97
+ line-height: 50rpx;
98
+ }
99
+ .ml-approval-record-users {
100
+ display: flex;
101
+ flex-direction: column;
102
+ padding-left: 40rpx;
103
+ }
104
+ .ml-approval-record-user-item {
105
+ display: flex;
106
+ flex-direction: column;
107
+ padding: 10rpx;
108
+ .ml-approval-record-user-item-info {
109
+ display: flex;
110
+ flex-direction: row;
111
+ }
112
+ .ml-approval-record-user-item-left {
113
+ flex-shrink: 0;
114
+ }
115
+ .ml-approval-record-user-item-content {
116
+ flex-grow: 1;
117
+ padding: 0 10rpx;
118
+ }
119
+ .ml-approval-record-user-item-right {
120
+ flex-shrink: 0;
121
+ }
122
+ .ml-approval-record-user-item-top {
123
+ line-height: 40rpx;
124
+ }
125
+ .ml-approval-record-user-picture {
126
+ width: 100rpx;
127
+ height: 100rpx;
128
+ border-radius: 50%;
129
+ }
130
+ .ml-approval-record-user-name {
131
+ display: inline-block;
132
+ vertical-align: middle;
133
+ max-width: 150rpx;
134
+ overflow: hidden;
135
+ text-overflow: ellipsis;
136
+ white-space: nowrap;
137
+ margin-right: 10rpx;
138
+ color: rgba(0, 0, 0, 0.85);
139
+ }
140
+ .ml-approval-record-user-role {
141
+ font-size: 24rpx;
142
+ color: rgba(0, 0, 0, 0.86);
143
+ }
144
+ .ml-approval-record-user-date {
145
+ font-size: 24rpx;
146
+ }
147
+ .ml-approval-record-user-item-comment{
148
+ padding: 20rpx;
149
+ background: #F0F2F5;
150
+ height: 160rpx;
151
+ border-radius: 10rpx;
152
+ overflow: auto;
153
+ }
154
+ }
155
+ </style>
@@ -0,0 +1,117 @@
1
+ <template>
2
+ <view class="ml-approval-select">
3
+ <view class="ml-approval-select-header">
4
+ <view class="ml-approval-select-header-title">审批流程</view>
5
+ </view>
6
+ <view class="ml-approval-select-body">
7
+ <view class="ml-approval-select-list" v-for="(group, gIndex) in options" :key="gIndex">
8
+ <view class="ml-approval-select-item">
9
+ <view class="ml-approval-select-item-title">{{ group.name }}</view>
10
+ </view>
11
+ <view class="ml-approval-select-users">
12
+ <view class="ml-approval-select-user-item" v-for="(item, uIndex) in group.users" :key="uIndex">
13
+ <image class="ml-approval-select-user-picture" :src="item.picture" mode="scaleToFill"></image>
14
+ <view class="ml-approval-select-user-name">{{ item.name }}</view>
15
+ <view class="ml-approval-select-user-remove">
16
+ <ml-icon name="close"></ml-icon>
17
+ </view>
18
+ </view>
19
+ <view class="ml-approval-select-user-add" @click="openAddUser">
20
+ <view class="ml-approval-select-user-add-icon">
21
+ <ml-icon name="add"></ml-icon>
22
+ </view>
23
+ </view>
24
+ </view>
25
+ </view>
26
+ </view>
27
+
28
+ <uni-popup ref="popup" type="bottom">
29
+ <text>Popup</text>
30
+ <button @click="close">关闭</button>
31
+ </uni-popup>
32
+ </view>
33
+ </template>
34
+
35
+ <script>
36
+ export default {
37
+ name: 'MlApprovalSelect',
38
+ props: {
39
+ value: Array,
40
+ options: Array
41
+ },
42
+ methods: {
43
+ openAddUser () {
44
+ this.$refs.popup.open()
45
+ }
46
+ }
47
+ }
48
+ </script>
49
+
50
+ <style lang="scss">
51
+ .ml-approval-select {
52
+ background: #ffffff;
53
+ padding: 20rpx;
54
+ border-radius: 10rpx;
55
+ font-size: 30rpx;
56
+ }
57
+ .ml-approval-select-header-title {
58
+ font-weight: 700;
59
+ line-height: 60rpx;
60
+ }
61
+ .ml-approval-select-list {
62
+ padding-bottom: 10rpx;
63
+ }
64
+ .ml-approval-select-item-title {
65
+ padding-left: 20rpx;
66
+ line-height: 50rpx;
67
+ }
68
+ .ml-approval-select-users {
69
+ display: flex;
70
+ flex-direction: row;
71
+ flex-wrap: wrap;
72
+ }
73
+ .ml-approval-select-user-item {
74
+ position: relative;
75
+ padding: 10rpx;
76
+ width: 150rpx;
77
+ text-align: center;
78
+ .ml-approval-select-user-picture {
79
+ width: 100rpx;
80
+ height: 100rpx;
81
+ border-radius: 50%;
82
+ }
83
+ .ml-approval-select-user-name {
84
+ overflow: hidden;
85
+ text-overflow: ellipsis;
86
+ white-space: nowrap;
87
+ font-size: 24rpx;
88
+ }
89
+ .ml-approval-select-user-remove {
90
+ position: absolute;
91
+ top: 0;
92
+ right: 10rpx;
93
+ width: 40rpx;
94
+ height: 40rpx;
95
+ line-height: 40rpx;
96
+ border-radius: 50%;
97
+ text-align: center;
98
+ color: #ffffff;
99
+ background: rgba(0, 0, 0, 0.45);
100
+ }
101
+ }
102
+ .ml-approval-select-user-add {
103
+ padding: 10rpx;
104
+ width: 160rpx;
105
+ text-align: center;
106
+ .ml-approval-select-user-add-icon {
107
+ width: 100rpx;
108
+ height: 100rpx;
109
+ line-height: 100rpx;
110
+ border-radius: 50%;
111
+ font-size: 50rpx;
112
+ color: $uni-color-primary;
113
+ background: #DAE6FF;
114
+ overflow: hidden;
115
+ }
116
+ }
117
+ </style>
@@ -43,7 +43,7 @@ export default {
43
43
  .ml-approval-type {
44
44
  display: inline-block;
45
45
  color: #ffffff;
46
- padding: 6rpx 18rpx;
46
+ padding: 4rpx 16rpx;
47
47
  border-radius: 10rpx;
48
48
  font-size: 24rpx;
49
49
  }
@@ -61,8 +61,13 @@ export default {
61
61
  .ml-checkbox-icon {
62
62
  display: inline-block;
63
63
  width: 40rpx;
64
- margin-right: 5rpx;
64
+ margin-right: 10rpx;
65
65
  text-align: center;
66
+ font-size: 1.3em;
67
+ }
68
+ .ml-checkbox-icon,
69
+ .ml-checkbox-content {
70
+ vertical-align: middle;
66
71
  }
67
72
  }
68
73
  </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <view class="ml-col" :class="[className || '', span && !width ? `span-${span}` : '', align ? `align-${align}` : '', {'is-flex': flex,'is-fixed': width || shrink}]" :style="styles">
2
+ <view class="ml-col" :class="[className || '', span && !width ? `span-${span}` : '', align ? `align-${align}` : '', verticalAling ? `vertical-${verticalAling}` : '', {'is-light': light, 'is-flex': verticalAling || flex,'is-fixed': width || shrink}]" :style="styles">
3
3
  <slot></slot>
4
4
  </view>
5
5
  </template>
@@ -12,15 +12,17 @@ export default {
12
12
  },
13
13
  props: {
14
14
  span: [String, Number],
15
+ light: Boolean,
15
16
  flex: Boolean,
16
17
  shrink: Boolean,
17
18
  align: String,
19
+ verticalAling: String,
18
20
  width: String,
19
21
  className: String
20
22
  },
21
23
  computed: {
22
24
  styles () {
23
- return this.width ? `width: ${this.width};` : ''
25
+ return this.width ? `width: ${this.width};` : ''
24
26
  }
25
27
  }
26
28
  }
@@ -31,6 +33,9 @@ export default {
31
33
  $spans: 4.16667%, 8.33333%, 12.5%, 16.66667%, 20.83333%, 25%, 29.16667%, 33.33333%,
32
34
  37.5%, 41.66667%, 45.83333%, 50%, 54.16667%, 58.33333%, 62.5%, 66.66667%,
33
35
  70.83333%, 75%, 79.16667%, 83.33333%, 87.5%, 91.66667%, 95.83333%, 100%;
36
+ &.is-light {
37
+ color: rgba(0, 0, 0, 0.45);
38
+ }
34
39
  &.is-flex {
35
40
  display: flex;
36
41
  flex-direction: row;
@@ -43,6 +48,9 @@ export default {
43
48
  &.align-right {
44
49
  justify-content: right;
45
50
  }
51
+ &.vertical-center {
52
+ align-items: center;
53
+ }
46
54
  }
47
55
  &.align-left {
48
56
  text-align: left;
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <uni-datetime-picker :class="className" v-model="selectVal" type="date" :start="start" :end="end" @change="changeEvent" :border="border"/>
2
+ <view v-if="isFromReadonly" class="ml-date-picker is-readonly">
3
+ <view class="ml-date-picker-readonly-content">{{ value }}</view>
4
+ </view>
5
+ <uni-datetime-picker v-else :class="className" v-model="selectVal" type="date" :start="minDate" :end="maxDate" @change="changeEvent" :border="border"/>
3
6
  </template>
4
7
 
5
8
  <script>
@@ -11,15 +14,26 @@ export default {
11
14
  props: {
12
15
  value: String,
13
16
  border: Boolean,
14
- start: [String, Number],
15
- end: [String, Number],
17
+ minDate: [String, Number],
18
+ maxDate: [String, Number],
16
19
  className: String
17
20
  },
21
+ inject: {
22
+ form: {
23
+ from: 'mlForm',
24
+ default: null
25
+ }
26
+ },
18
27
  data () {
19
28
  return {
20
29
  selectVal: ''
21
30
  }
22
31
  },
32
+ computed: {
33
+ isFromReadonly () {
34
+ return this.form ? this.form.readonly : false
35
+ }
36
+ },
23
37
  watch: {
24
38
  value (value) {
25
39
  this.selectVal = value
@@ -37,4 +51,10 @@ export default {
37
51
  }
38
52
  }
39
53
  }
40
- </script>
54
+ </script>
55
+
56
+ <style lang="scss">
57
+ .ml-date-picker-readonly-content {
58
+ padding: 20rpx 4rpx;
59
+ }
60
+ </style>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <uni-datetime-picker :class="className" v-model="selectDates" type="daterange" :start="start" :end="end" @change="changeEvent" :border="border" :clear-icon="clear"/>
2
+ <uni-datetime-picker :class="className" v-model="selectDates" type="daterange" :start="minDate" :end="maxDate" @change="changeEvent" :border="border" :clear-icon="clear"/>
3
3
  </template>
4
4
 
5
5
  <script>
@@ -12,8 +12,8 @@ export default {
12
12
  border: Boolean,
13
13
  startDate: String,
14
14
  endDate: String,
15
- start: [String, Number],
16
- end: [String, Number],
15
+ minDate: [String, Number],
16
+ maxDate: [String, Number],
17
17
  clear: {
18
18
  type: Boolean,
19
19
  default: true
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <uni-datetime-picker :class="className" v-model="selectVal" type="datetime" :start="start" :end="end" @change="changeEvent" :border="border"/>
2
+ <uni-datetime-picker :class="className" v-model="selectVal" type="datetime" :start="minDate" :end="maxDate" @change="changeEvent" :border="border"/>
3
3
  </template>
4
4
 
5
5
  <script>
@@ -11,8 +11,8 @@ export default {
11
11
  props: {
12
12
  value: String,
13
13
  border: Boolean,
14
- start: [String, Number],
15
- end: [String, Number],
14
+ minDate: [String, Number],
15
+ maxDate: [String, Number],
16
16
  className: String
17
17
  },
18
18
  data () {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <uni-datetime-picker :class="className" v-model="selectDates" type="datetimerange" :start="start" :end="end" @change="changeEvent" :border="border"/>
2
+ <uni-datetime-picker :class="className" v-model="selectDates" type="datetimerange" :start="minDate" :end="maxDate" @change="changeEvent" :border="border"/>
3
3
  </template>
4
4
 
5
5
  <script>
@@ -9,11 +9,12 @@ export default {
9
9
  virtualHost: true
10
10
  },
11
11
  props: {
12
+ value: Array,
12
13
  border: Boolean,
13
14
  startDate: String,
14
15
  endDate: String,
15
- start: [String, Number],
16
- end: [String, Number],
16
+ minDate: [String, Number],
17
+ maxDate: [String, Number],
17
18
  className: String
18
19
  },
19
20
  data () {
@@ -29,11 +30,14 @@ export default {
29
30
  created () {
30
31
  if (this.startDate) {
31
32
  this.selectDates = this.startDate && this.endDate ? [this.startDate, this.endDate] : []
33
+ } else if (this.value && this.value.length) {
34
+ this.selectDates = this.value
32
35
  }
33
36
  },
34
37
  methods: {
35
38
  changeEvent (value) {
36
39
  const [startDate, endDate] = value
40
+ this.$emit('input', value)
37
41
  this.$emit('update:startDate', startDate)
38
42
  this.$emit('update:endDate', endDate)
39
43
  this.$emit('change', { startDate, endDate })
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <text class="ml-dict-type" :class="[className || '', status ? `status-${status}` : '', {'is-underline': underline}]">{{ selectLabel }}</text>
3
+ </template>
4
+
5
+ <script>
6
+ export default {
7
+ name: 'MlDictType',
8
+ options: {
9
+ virtualHost: true
10
+ },
11
+ props: {
12
+ value: [Number, String],
13
+ options: Array,
14
+ status: String,
15
+ underline: Boolean,
16
+ optionProps: Object,
17
+ className: String
18
+ },
19
+ computed: {
20
+ selectLabel () {
21
+ const item = this.options ? this.options.find(item => item[this.optValueField] === this.value) : null
22
+ return item ? item[this.optLabelField] : this.value
23
+ },
24
+ optOptions () {
25
+ return Object.assign({}, this.optionProps)
26
+ },
27
+ optLabelField () {
28
+ return this.optOptions.label || 'label'
29
+ },
30
+ optValueField () {
31
+ return this.optOptions.value || 'value'
32
+ }
33
+ }
34
+ }
35
+ </script>
36
+
37
+ <style lang="scss">
38
+ .ml-dict-type {
39
+ padding: 0 4rpx;
40
+ &.is-underline {
41
+ text-decoration: underline;
42
+ }
43
+ &.status-primary {
44
+ color: $uni-color-primary;
45
+ }
46
+ &.status-success {
47
+ color: $uni-color-success;
48
+ }
49
+ &.status-info {
50
+ color: #909399;
51
+ }
52
+ &.status-warning {
53
+ color: $uni-color-warning;
54
+ }
55
+ &.status-danger {
56
+ color: $uni-color-error;
57
+ }
58
+ }
59
+ </style>
@@ -1,21 +1,17 @@
1
1
  <template>
2
- <view class="ml-form" :class="[className || '']">
3
- <uni-forms :key="fKey" ref="uniForm" :modelValue="data" :rules="formRules" :label-position="vertical ? 'top' : 'left'">
4
- <slot>
5
- <view v-for="(item, index) in items" :key="index">
6
- <ml-form-group v-if="item.children && item.children.length">
7
- <ml-form-item v-for="(cItem, cIndex) in item.children" :key="cIndex" :title="cItem.title" :field="cItem.field" :itemRender="cItem.itemRender" @modelvalue="updateModel"></ml-form-item>
8
- </ml-form-group>
9
- <ml-form-item v-else :title="item.title" :field="item.field" :itemRender="item.itemRender" @modelvalue="updateModel"></ml-form-item>
10
- </view>
11
- </slot>
12
- </uni-forms>
2
+ <view class="ml-form" :class="[className || '', {'is-border': border}]">
3
+ <slot>
4
+ <view v-for="(item, index) in items" :key="index">
5
+ <ml-form-group v-if="item.children && item.children.length" :title="item.title">
6
+ <ml-form-item v-for="(cItem, cIndex) in item.children" :key="cIndex" :title="cItem.title" :field="cItem.field" :itemRender="cItem.itemRender" @modelvalue="updateModel"></ml-form-item>
7
+ </ml-form-group>
8
+ <ml-form-item v-else :title="item.title" :field="item.field" :itemRender="item.itemRender" @modelvalue="updateModel"></ml-form-item>
9
+ </view>
10
+ </slot>
13
11
  </view>
14
12
  </template>
15
13
 
16
14
  <script>
17
- import XEUtils from 'xe-utils'
18
-
19
15
  export default {
20
16
  name: 'MlForm',
21
17
  options: {
@@ -26,6 +22,9 @@ export default {
26
22
  data: Object,
27
23
  items: Array,
28
24
  rules: Object,
25
+ align: String,
26
+ titleAlign: String,
27
+ border: Boolean,
29
28
  readonly: Boolean,
30
29
  vertical: Boolean,
31
30
  labelWidth: String,
@@ -38,46 +37,20 @@ export default {
38
37
  },
39
38
  data () {
40
39
  return {
41
- fKey: 1
42
- }
43
- },
44
- computed: {
45
- formRules () {
46
- const rest = {}
47
- XEUtils.each(this.rules, (rules, field) => {
48
- rest[field] = {
49
- rules: rules.map(item => {
50
- return { ...item, errorMessage: item.message }
51
- })
52
- }
53
- })
54
- return rest
55
40
  }
56
41
  },
57
- created () {
58
- this.$nextTick(() => {
59
- this.fKey++
60
- })
61
- },
62
42
  methods: {
63
- getProp (item, prop, defultValue) {
64
- return (item.itemRender.props ? item.itemRender.props[prop] : null) || defultValue
65
- },
66
43
  validate () {
67
- return this.$refs.uniForm.validate().then(() => {
68
- return null
69
- }).catch(() => {
70
- return {}
44
+ return new Promise(resolve => {
45
+ resolve()
71
46
  })
72
47
  },
73
48
  validateField (fields) {
74
- return this.$refs.uniForm.validateField(fields).then(() => {
75
- return null
76
- }).catch(() => {
77
- return {}
49
+ return new Promise(resolve => {
50
+ resolve()
78
51
  })
79
52
  },
80
- updateModel ({ field, value}) {
53
+ updateModel ({ field, value }) {
81
54
  this.$emit('input', { ...this.value, [field]: value })
82
55
  }
83
56
  }
@@ -87,5 +60,6 @@ export default {
87
60
  <style lang="scss">
88
61
  .ml-form {
89
62
  display: block;
63
+ font-size: $uni-font-size-base;
90
64
  }
91
65
  </style>
@@ -1,6 +1,13 @@
1
1
  <template>
2
2
  <view class="ml-form-group" :class="className">
3
- <slot></slot>
3
+ <view v-if="title || $slots.title" class="ml-form-group-title">
4
+ <slot name="title">
5
+ <text>{{ title }}</text>
6
+ </slot>
7
+ </view>
8
+ <view class="ml-form-group-content">
9
+ <slot></slot>
10
+ </view>
4
11
  </view>
5
12
  </template>
6
13
 
@@ -11,6 +18,7 @@ export default {
11
18
  virtualHost: true
12
19
  },
13
20
  props: {
21
+ title: String,
14
22
  className: String
15
23
  }
16
24
  }
@@ -18,9 +26,15 @@ export default {
18
26
 
19
27
  <style lang="scss">
20
28
  .ml-form-group {
21
- margin: 10rpx 0;
22
- padding: 20rpx;
29
+ margin: 20rpx 0;
23
30
  border-radius: 10rpx;
24
31
  background: #ffffff;
32
+ .ml-form-group-title {
33
+ display: flex;
34
+ align-items: center;
35
+ min-height: 80rpx;
36
+ padding: 0 20rpx;
37
+ border-bottom: 1px solid #e5e5e5;
38
+ }
25
39
  }
26
40
  </style>
@@ -1,21 +1,24 @@
1
1
  <template>
2
- <view class="ml-form-item">
3
- <uni-forms-item
4
- ref="uniFormItem"
5
- :class="className"
6
- :label="title"
7
- :name="field"
8
- :label-width="itemLabelWidth"
9
- :label-position="itemVertical">
10
- <slot>
11
- <ml-input v-if="matchComponent('MlInput')" :value="itemValue" border @change="modelEvent"></ml-input>
12
- <ml-date-picker v-else-if="matchComponent('MlDatePicker')" :value="itemValue" border @change="modelEvent"></ml-date-picker>
13
- <ml-select-picker v-else-if="matchComponent('MlSelectPicker')" :value="itemValue" :options="renderOpts.options" border @change="modelEvent"></ml-select-picker>
14
- <ml-textarea v-else-if="matchComponent('MlTextarea')" :value="itemValue" :rows="renderOpts.rows || 3" border @change="modelEvent"></ml-textarea>
15
- <ml-upload v-else-if="matchComponent('MlUpload')" :value="itemValue" :mediatype="renderOpts.mediatype || 'image'" @change="modelEvent"></ml-upload>
16
- <view v-else>{{ itemValue }}</view>
2
+ <view class="ml-form-item" :class="[className, '', itemTitleAlign ? `title-align-${itemTitleAlign}` : '', itemAlign ? `align-${itemAlign}` : '', {'is-border': isFormBorder, 'is-vertical': itemVertical}]">
3
+ <view class="ml-form-item-title" :style="titleStyle">
4
+ <slot name="title">
5
+ <text>{{ title }}</text>
17
6
  </slot>
18
- </uni-forms-item>
7
+ </view>
8
+ <view class="ml-form-item-content">
9
+ <view class="ml-form-item-content-warpper">
10
+ <slot>
11
+ <ml-input v-if="matchComponent('MlInput')" :value="itemValue" border @change="modelEvent"></ml-input>
12
+ <ml-date-picker v-else-if="matchComponent('MlDatePicker')" :value="itemValue" border @change="modelEvent"></ml-date-picker>
13
+ <ml-select-picker v-else-if="matchComponent('MlSelectPicker')" :value="itemValue" :options="renderOpts.options" border @change="modelEvent"></ml-select-picker>
14
+ <ml-textarea v-else-if="matchComponent('MlTextarea')" :value="itemValue" :rows="renderOpts.rows || 3" border @change="modelEvent"></ml-textarea>
15
+ <ml-upload v-else-if="matchComponent('MlUpload')" :value="itemValue" :mediatype="renderOpts.mediatype || 'image'" @change="modelEvent"></ml-upload>
16
+ <ml-amount-input v-else-if="matchComponent('MlAmountInput')" :value="itemValue" @change="modelEvent"></ml-amount-input>
17
+ <ml-amount-text v-else-if="matchComponent('MlAmountText')" :value="itemValue" @change="modelEvent"></ml-amount-text>
18
+ <text v-else style="color:red">{{ itemValue }}</text>
19
+ </slot>
20
+ </view>
21
+ </view>
19
22
  </view>
20
23
  </template>
21
24
 
@@ -28,10 +31,9 @@ export default {
28
31
  props: {
29
32
  title: String,
30
33
  field: String,
31
- vertical: {
32
- type: Boolean,
33
- default: null
34
- },
34
+ align: String,
35
+ titleAlign: String,
36
+ vertical: Boolean,
35
37
  labelWidth: String,
36
38
  itemRender: Object,
37
39
  className: String
@@ -43,6 +45,21 @@ export default {
43
45
  }
44
46
  },
45
47
  computed: {
48
+ titleStyle () {
49
+ return this.itemLabelWidth ? `width:${this.itemLabelWidth};` : ''
50
+ },
51
+ isFormBorder () {
52
+ return this.form ? this.form.border : false
53
+ },
54
+ isRequired () {
55
+ if (this.form && this.form.rules) {
56
+ const currRules = this.form.rules[this.field]
57
+ if (currRules && currRules.some(item => item.required)) {
58
+ return true
59
+ }
60
+ }
61
+ return false
62
+ },
46
63
  itemValue () {
47
64
  return this.formData[this.field]
48
65
  },
@@ -52,12 +69,23 @@ export default {
52
69
  renderOpts () {
53
70
  return this.itemRender || {}
54
71
  },
72
+ itemAlign () {
73
+ if (this.align) {
74
+ return this.align
75
+ }
76
+ return this.form ? this.form.align : ''
77
+ },
78
+ itemTitleAlign () {
79
+ if (this.titleAlign) {
80
+ return this.titleAlign
81
+ }
82
+ return this.form ? this.form.titleAlign : ''
83
+ },
55
84
  itemVertical () {
56
- let vertical = this.vertical
57
- if (!vertical) {
58
- vertical = this.form ? this.form.vertical : ''
85
+ if (this.vertical) {
86
+ return true
59
87
  }
60
- return vertical ? 'top' : 'left'
88
+ return this.form ? this.form.vertical : false
61
89
  },
62
90
  itemLabelWidth () {
63
91
  let labelWidth = this.labelWidth
@@ -73,18 +101,8 @@ export default {
73
101
  created () {
74
102
  this.init()
75
103
  },
76
- watch: {
77
- itemVertical () {
78
- this.init()
79
- }
80
- },
81
104
  methods: {
82
105
  init () {
83
- this.$nextTick(() => {
84
- if (this.$refs.uniFormItem) {
85
- this.$refs.uniFormItem.localLabelPos = this.itemVertical
86
- }
87
- })
88
106
  },
89
107
  matchComponent (name) {
90
108
  return this.renderOpts.name === name
@@ -95,3 +113,75 @@ export default {
95
113
  }
96
114
  }
97
115
  </script>
116
+
117
+ <style lang="scss">
118
+ .ml-form-item {
119
+ position: relative;
120
+ display: flex;
121
+ flex-direction: row;
122
+ font-size: $uni-font-size-base;
123
+ padding: 10rpx 20rpx;
124
+ &.is-border {
125
+ border-bottom: 1px solid #e5e5e5;
126
+ &:last-child {
127
+ border: 0;
128
+ }
129
+ }
130
+ .ml-form-item-title {
131
+ min-height: 70rpx;
132
+ color: rgba(0, 0, 0, 0.65);
133
+ }
134
+ &.is-vertical {
135
+ flex-direction: column;
136
+ }
137
+ &:not(.is-vertical) {
138
+ .ml-form-item-title {
139
+ flex-shrink: 0;
140
+ }
141
+ }
142
+ &.title-align-left {
143
+ .ml-form-item-title {
144
+ text-align: left;
145
+ }
146
+ }
147
+ &.title-align-center {
148
+ .ml-form-item-title {
149
+ text-align: center;
150
+ }
151
+ }
152
+ &.title-align-right {
153
+ .ml-form-item-title {
154
+ text-align: right;
155
+ }
156
+ }
157
+ &.align-left {
158
+ .ml-form-item-content {
159
+ text-align: left;
160
+ }
161
+ }
162
+ &.align-center {
163
+ .ml-form-item-content {
164
+ text-align: center;
165
+ }
166
+ }
167
+ &.align-right {
168
+ .ml-form-item-content {
169
+ text-align: right;
170
+ }
171
+ }
172
+ .ml-form-item-title {
173
+ display: flex;
174
+ align-items: center;
175
+ padding-right: 20rpx;
176
+ }
177
+ }
178
+ .ml-form-item-content {
179
+ display: flex;
180
+ align-items: center;
181
+ flex-grow: 1;
182
+ }
183
+ .ml-form-item-content-warpper {
184
+ flex-grow: 1;
185
+ width: 100%;
186
+ }
187
+ </style>
@@ -28,7 +28,7 @@ export default {
28
28
  .ml-full-watermark-text{
29
29
  float: left;
30
30
  padding: 0 50rpx;
31
- color: rgba(169,169,169,0.2);
31
+ color: rgba(169,169,169,0.15);
32
32
  text-align: center;
33
33
  font-size: 22rpx;
34
34
  margin: 80rpx 0;
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <view class="ml-input" :class="[className || '', {'is-right': align === 'right', 'is-border': border, 'is-prefix': prefixIcon || type === 'search', 'is-suffix': suffixIcon, 'is-disabled': disabled}]">
2
+ <view v-if="isFromReadonly" class="ml-input is-readonly">
3
+ <view class="ml-input-readonly-content">{{ inpVal }}</view>
4
+ </view>
5
+ <view v-else class="ml-input" :class="[className || '', {'is-right': align === 'right', 'is-border': border, 'is-prefix': prefixIcon || type === 'search', 'is-suffix': suffixIcon, 'is-disabled': disabled}]">
3
6
  <view v-if="prefixIcon || type === 'search'" class="ml-input-prefix-icon">
4
7
  <ml-icon v-if="prefixIcon" :className="prefixIcon"></ml-icon>
5
8
  <ml-icon v-else name="search"></ml-icon>
@@ -38,11 +41,22 @@ export default {
38
41
  },
39
42
  className: String
40
43
  },
44
+ inject: {
45
+ form: {
46
+ from: 'mlForm',
47
+ default: null
48
+ }
49
+ },
41
50
  data () {
42
51
  return {
43
52
  inpVal: ''
44
53
  }
45
54
  },
55
+ computed: {
56
+ isFromReadonly () {
57
+ return this.form ? this.form.readonly : false
58
+ }
59
+ },
46
60
  watch: {
47
61
  value (val) {
48
62
  this.inpVal = val
@@ -67,8 +81,12 @@ export default {
67
81
 
68
82
  <style lang="scss">
69
83
  .ml-input {
84
+ flex-grow: 1;
70
85
  display: flex;
71
86
  flex-direction: row;
87
+ .ml-input-readonly-content {
88
+ padding: 20rpx 4rpx;
89
+ }
72
90
  .ml-input-inp {
73
91
  padding: 0 20rpx;
74
92
  height: 70rpx;
@@ -64,7 +64,7 @@ export default {
64
64
  background: #ffffff;
65
65
  .ml-list-item-content {
66
66
  display: flex;
67
- flex-direction: row;
67
+ flex-direction: column;
68
68
  flex-grow: 1;
69
69
  overflow: hidden;
70
70
  text-overflow: ellipsis;
@@ -50,8 +50,12 @@ export default {
50
50
  color: $uni-color-primary;
51
51
  }
52
52
  .ml-radio-icon {
53
- font-size: 1.1em;
54
53
  margin-right: 10rpx;
54
+ font-size: 1.4em;
55
+ }
56
+ .ml-radio-icon,
57
+ .ml-radio-content {
58
+ vertical-align: middle;
55
59
  }
56
60
  }
57
61
  </style>
@@ -1,8 +1,11 @@
1
1
  <template>
2
- <picker class="ml-select-picker" :style="{width: width || '100%'}" :range="optionList" :range-key="optLabelField" @change="changeEvent">
2
+ <view v-if="isFromReadonly" class="ml-select-picker is-readonly">
3
+ <view class="ml-select-picker-readonly-content">{{ selectLabel }}</view>
4
+ </view>
5
+ <picker v-else class="ml-select-picker" :style="{width: width || '100%'}" :range="optionList" :range-key="optLabelField" @change="changeEvent">
3
6
  <view class="ml-select-picker-warpper" :class="[className || '', {'is-border': border}]">
4
7
  <view class="ml-select-picker-text">
5
- <text v-if="value !== null">{{ selectName }}</text>
8
+ <text v-if="value !== null">{{ selectLabel }}</text>
6
9
  <text v-else class="picker-placeholder">{{ placeholder }}</text>
7
10
  </view>
8
11
  <view class="ml-select-picker-icon">
@@ -31,11 +34,20 @@ export default {
31
34
  isAll: Boolean,
32
35
  className: String
33
36
  },
37
+ inject: {
38
+ form: {
39
+ from: 'mlForm',
40
+ default: null
41
+ }
42
+ },
34
43
  data () {
35
44
  return {
36
45
  }
37
46
  },
38
47
  computed: {
48
+ isFromReadonly () {
49
+ return this.form ? this.form.readonly : false
50
+ },
39
51
  optionList () {
40
52
  if (this.isAll) {
41
53
  return [
@@ -45,9 +57,9 @@ export default {
45
57
  }
46
58
  ].concat(this.options)
47
59
  }
48
- return this.options
60
+ return this.options || []
49
61
  },
50
- selectName () {
62
+ selectLabel () {
51
63
  const item = this.optionList.find(item => item[this.optValueField] === this.value)
52
64
  return item ? item[this.optLabelField] : this.value
53
65
  },
@@ -70,7 +82,7 @@ export default {
70
82
  value = item[this.optValueField]
71
83
  }
72
84
  this.$emit('input', value)
73
- this.$emit('change', value)
85
+ this.$emit('change', { value })
74
86
  }
75
87
  }
76
88
  }
@@ -89,6 +101,9 @@ export default {
89
101
  width: 100%;
90
102
  color: #6a6a6a;
91
103
  }
104
+ .ml-select-picker-readonly-content {
105
+ padding: 20rpx;
106
+ }
92
107
  .ml-select-picker-warpper {
93
108
  position: relative;
94
109
  display: flex;
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <text class="ml-text" :class="[className || '', status ? `status-${status}` : '', {'is-underline': underline}]">
3
+ <slot>{{ content }}</slot>
4
+ </text>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'MlText',
10
+ props: {
11
+ status: String,
12
+ content: String,
13
+ underline: Boolean,
14
+ className: String
15
+ }
16
+ }
17
+ </script>
18
+
19
+ <style lang="scss">
20
+ .ml-text {
21
+ padding: 0 4rpx;
22
+ &.is-underline {
23
+ text-decoration: underline;
24
+ }
25
+ &.status-primary {
26
+ color: $uni-color-primary;
27
+ }
28
+ &.status-success {
29
+ color: $uni-color-success;
30
+ }
31
+ &.status-info {
32
+ color: #909399;
33
+ }
34
+ &.status-warning {
35
+ color: $uni-color-warning;
36
+ }
37
+ &.status-danger {
38
+ color: $uni-color-error;
39
+ }
40
+ }
41
+ </style>
@@ -1,5 +1,8 @@
1
1
  <template>
2
- <view class="ml-textarea" :class="[className || '', {'is-border': border}]">
2
+ <view v-if="isFromReadonly" class="ml-textarea is-readonly">
3
+ <view class="ml-textarea-readonly-content">{{ inpVal }}</view>
4
+ </view>
5
+ <view v-else class="ml-textarea" :class="[className || '', {'is-border': border}]">
3
6
  <view v-if="readonly" class="ml-textarea-content">{{ inpVal }}</view>
4
7
  <view v-else>
5
8
  <textarea class="ml-textarea-inp" v-model="inpVal" :rows="rows" :maxlength="maxLength" :placeholder="placeholder" @input="inputEvent" :style="{color: fontColor, height: `${rows * 30}rpx`}"></textarea>
@@ -52,11 +55,22 @@ export default {
52
55
  fontColor: String,
53
56
  className: String
54
57
  },
58
+ inject: {
59
+ form: {
60
+ from: 'mlForm',
61
+ default: null
62
+ }
63
+ },
55
64
  data () {
56
65
  return {
57
66
  inpVal: ''
58
67
  }
59
68
  },
69
+ computed: {
70
+ isFromReadonly () {
71
+ return this.form ? this.form.readonly : false
72
+ }
73
+ },
60
74
  watch: {
61
75
  value (val) {
62
76
  this.inpVal = val
@@ -80,12 +94,17 @@ export default {
80
94
 
81
95
  <style lang="scss">
82
96
  .ml-textarea {
97
+ display: block;
98
+ width: 100%;
83
99
  font-size: $uni-font-size-base;
84
100
  padding: 20rpx 10rpx 10rpx 20rpx;
85
101
  &.is-border {
86
102
  border: 1px solid #e5e5e5;
87
103
  border-radius: 10rpx;
88
104
  }
105
+ .ml-textarea-readonly-content {
106
+ padding: 0;
107
+ }
89
108
  .ml-textarea-content {
90
109
  width: 100%;
91
110
  overflow: auto;
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <view class="ml-upload" :class="className">
3
- <view v-if="readonly">
3
+ <view v-if="isFromReadonly">
4
4
  <view v-if="mediatype === 'image'" class="ml-upload-image-list">
5
5
  <view class="ml-upload-file-item" v-for="(item, index) in value" :key="index">
6
6
  <image class="ml-upload-file-img" mode="aspectFill" :src="getUrl(item)" @click="previewEvent(item, index)"></image>
@@ -72,6 +72,12 @@ export default {
72
72
  uploadFile: Function,
73
73
  removeFile: Function
74
74
  },
75
+ inject: {
76
+ form: {
77
+ from: 'mlForm',
78
+ default: null
79
+ }
80
+ },
75
81
  data () {
76
82
  return {
77
83
  fileList: [],
@@ -89,6 +95,12 @@ export default {
89
95
  }
90
96
  },
91
97
  computed: {
98
+ isFromReadonly () {
99
+ if (this.readonly) {
100
+ return true
101
+ }
102
+ return this.form ? this.form.readonly : false
103
+ },
92
104
  imageList () {
93
105
  return this.value ? this.value.filter(item => this.imgTypes.includes(item[this.typeField])) : []
94
106
  },
@@ -157,8 +169,10 @@ export default {
157
169
  }
158
170
  },
159
171
  updateModel () {
160
- this.$emit('update:urlList', this.fileList.map(item => item[this.urlField]))
172
+ const urlList = this.fileList.map(item => item[this.urlField])
173
+ this.$emit('update:urlList', urlList)
161
174
  this.$emit('input', this.fileList)
175
+ this.$emit('change', { value: this.simpleValue ? urlList : this.fileList })
162
176
  },
163
177
  async selectFile (e) {
164
178
  const { tempFiles } = e
@@ -202,7 +216,7 @@ export default {
202
216
  })
203
217
  ).then(res => {
204
218
  uni.hideLoading();
205
- }).catch(() => {
219
+ }).catch((e) => {
206
220
  console.error(e)
207
221
  uni.hideLoading();
208
222
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mali-applet-ui",
3
- "version": "0.0.43",
3
+ "version": "0.0.47",
4
4
  "description": "码里云小程序组件库",
5
5
  "files": [
6
6
  "components",