t20-common-lib 0.15.3 → 0.15.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "t20-common-lib",
3
- "version": "0.15.3",
3
+ "version": "0.15.5",
4
4
  "description": "T20",
5
5
  "private": false,
6
6
  "main": "dist/index.js",
@@ -0,0 +1,204 @@
1
+ <template>
2
+ <T20-Scroll-Load-Select
3
+ ref="scrollLoadSelect"
4
+ class="input-w"
5
+ v-model="_value"
6
+ v-bind="passThroughProps"
7
+ v-on="innerListeners"
8
+ @canGetData="handleCanGetData"
9
+ />
10
+ </template>
11
+
12
+ <script>
13
+ import { getDataForGet, getDataForPost } from '../utils/request'
14
+
15
+ export default {
16
+ name: 'ScrollLoadSelect',
17
+ props: {
18
+ value: {
19
+ type: [String, Number, Array, Object],
20
+ default: undefined
21
+ },
22
+ items: {
23
+ type: Object,
24
+ default: () => ({})
25
+ },
26
+ label: {
27
+ type: String,
28
+ default: ''
29
+ }
30
+ },
31
+ computed: {
32
+ _value: {
33
+ get() {
34
+ return this.value
35
+ },
36
+ set(val) {
37
+ this.$emit('input', val)
38
+ }
39
+ },
40
+ innerListeners() {
41
+ const listeners = { ...this.$listeners }
42
+ delete listeners.canGetData
43
+ return listeners
44
+ },
45
+ runtimeLabelKey() {
46
+ return this.items?.api?.labelKey || this.items?.props?.labelKey || this.$attrs.labelKey || 'label'
47
+ },
48
+ runtimeValueKey() {
49
+ return this.items?.api?.valueKey || this.items?.props?.valueKey || this.$attrs.valueKey || 'value'
50
+ },
51
+ runtimeSearchKeyName() {
52
+ return this.items?.api?.searchKeyName || this.items?.props?.searchKeyName || this.$attrs.searchKeyName || 'searchKey'
53
+ },
54
+ runtimePageSize() {
55
+ return this.items?.api?.pageSize || this.items?.props?.pageSize || this.$attrs.pageSize || 20
56
+ },
57
+ runtimeSelectedLabel() {
58
+ return this.items?.props?.selectedLabel || this.$attrs.selectedLabel || this.label || ''
59
+ },
60
+ runtimeRequestFn() {
61
+ if (this.items?.api?.apiUrl && this.items?.api?.requestMethod) {
62
+ return this.fetchByApiConfig
63
+ }
64
+ return this.$attrs.requestFn || this.$attrs['request-fn'] || this.fetchByStaticOptions
65
+ },
66
+ shouldAutoLoad() {
67
+ const autoLoad = this.items?.props?.autoLoad ?? this.$attrs.autoLoad
68
+ return autoLoad !== false
69
+ },
70
+ passThroughProps() {
71
+ return {
72
+ ...this.$attrs,
73
+ ...(this.items?.props || {}),
74
+ requestFn: this.runtimeRequestFn,
75
+ labelKey: this.runtimeLabelKey,
76
+ valueKey: this.runtimeValueKey,
77
+ searchKeyName: this.runtimeSearchKeyName,
78
+ pageSize: this.runtimePageSize,
79
+ selectedLabel: this.runtimeSelectedLabel
80
+ }
81
+ }
82
+ },
83
+ mounted() {
84
+ this.triggerInitialRequest()
85
+ },
86
+ methods: {
87
+ triggerInitialRequest() {
88
+ if (!this.shouldAutoLoad) return
89
+ this.$nextTick(() => {
90
+ const instance = this.$refs.scrollLoadSelect
91
+ if (instance && typeof instance.handleFilter === 'function') {
92
+ instance.handleFilter('')
93
+ }
94
+ })
95
+ },
96
+ resolvePath(data, path) {
97
+ if (!path) return data
98
+ return String(path)
99
+ .split('.')
100
+ .reduce((acc, key) => (acc == null ? acc : acc[key]), data)
101
+ },
102
+ normalizeList(rawList) {
103
+ if (!Array.isArray(rawList)) return []
104
+ return rawList.map(item => {
105
+ if (!item || typeof item !== 'object') {
106
+ return {
107
+ [this.runtimeLabelKey]: String(item),
108
+ [this.runtimeValueKey]: item
109
+ }
110
+ }
111
+ return item
112
+ })
113
+ },
114
+ setDeepValue(target, path, value) {
115
+ const keys = String(path || '').split('.').filter(Boolean)
116
+ if (keys.length === 0) return
117
+ let cur = target
118
+ for (let i = 0; i < keys.length - 1; i += 1) {
119
+ const key = keys[i]
120
+ if (!cur[key] || typeof cur[key] !== 'object' || Array.isArray(cur[key])) {
121
+ cur[key] = {}
122
+ }
123
+ cur = cur[key]
124
+ }
125
+ cur[keys[keys.length - 1]] = value
126
+ },
127
+ buildPagingParams(params, apiConfig) {
128
+ const pageConfig = apiConfig?.page || {}
129
+ const currentKey = pageConfig.current || 'current'
130
+ const sizeKey = pageConfig.size || 'size'
131
+ const currentVal = params.current
132
+ const sizeVal = params.size
133
+
134
+ // 场景1:page: { current, size }
135
+ if (pageConfig.reqKey) {
136
+ return {
137
+ [pageConfig.reqKey]: {
138
+ [currentKey]: currentVal,
139
+ [sizeKey]: sizeVal
140
+ }
141
+ }
142
+ }
143
+
144
+ // 场景2:page.current=xx&page.size=xx(支持点路径)
145
+ const pageParams = {}
146
+ this.setDeepValue(pageParams, currentKey, currentVal)
147
+ this.setDeepValue(pageParams, sizeKey, sizeVal)
148
+ return pageParams
149
+ },
150
+ async fetchByApiConfig(params = {}) {
151
+ const apiConfig = this.items?.api || {}
152
+ const method = String(apiConfig.requestMethod || '').toUpperCase()
153
+ const reqKeys = apiConfig.reqKeys || {}
154
+ const headerConfig = apiConfig.headerConfig || {}
155
+ const searchValue = params[this.runtimeSearchKeyName]
156
+ const pagingParams = this.buildPagingParams(params, apiConfig)
157
+ const requestData = {
158
+ ...reqKeys,
159
+ ...pagingParams
160
+ }
161
+ if (searchValue !== undefined) {
162
+ requestData[this.runtimeSearchKeyName] = searchValue
163
+ }
164
+ let res = null
165
+ if (method === 'GET') {
166
+ res = await getDataForGet(apiConfig.apiUrl, requestData, headerConfig)
167
+ } else if (method === 'POST') {
168
+ res = await getDataForPost(apiConfig.apiUrl, requestData, headerConfig)
169
+ } else {
170
+ return []
171
+ }
172
+ const list = apiConfig.dataProp ? this.resolvePath(res, apiConfig.dataProp) : (res && res.data)
173
+ return this.normalizeList(list)
174
+ },
175
+ async fetchByStaticOptions(params = {}) {
176
+ const sourceOptions = Array.isArray(this.items?.options) ? this.items.options : []
177
+ const current = Number(params.current || 1)
178
+ const size = Number(params.size || this.runtimePageSize || 20)
179
+ const searchValue = params[this.runtimeSearchKeyName]
180
+ const normalizedKeyword = searchValue == null ? '' : String(searchValue).toLowerCase()
181
+ const filtered = sourceOptions.filter(item => {
182
+ if (!normalizedKeyword) return true
183
+ const label = item && item[this.runtimeLabelKey]
184
+ return String(label == null ? '' : label).toLowerCase().includes(normalizedKeyword)
185
+ })
186
+ const start = (current - 1) * size
187
+ return filtered.slice(start, start + size)
188
+ },
189
+ handleCanGetData(val, option) {
190
+ if (Array.isArray(option)) {
191
+ const labels = option
192
+ .map(item => item && item[this.runtimeLabelKey])
193
+ .filter(label => label !== undefined && label !== null)
194
+ this.$emit('update:label', labels.join(','))
195
+ } else if (option && typeof option === 'object') {
196
+ this.$emit('update:label', option[this.runtimeLabelKey] || '')
197
+ } else if (val === '' || val === null || val === undefined) {
198
+ this.$emit('update:label', '')
199
+ }
200
+ this.$emit('canGetData', val, option)
201
+ }
202
+ }
203
+ }
204
+ </script>
@@ -118,6 +118,7 @@ export default {
118
118
  elementTypeChange: {
119
119
  SELECT: 'Select',
120
120
  SELECT_LAZY: 'LazySelect',
121
+ SELECT_SCROLL_LOAD: 'ScrollLoadSelect',
121
122
  DIALOG: 'Dialog',
122
123
  INPUT: 'Input',
123
124
  AMOUNT: 'Amount',