@tplc/business 0.4.26 → 0.4.28
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/CHANGELOG.md +21 -0
- package/components/lcb-calendar-search/lcb-calendar-search.vue +0 -22
- package/components/lcb-city-select/lcb-city-select.vue +20 -2
- package/components/lcb-home-search/lcb-home-search.vue +9 -11
- package/components/lcb-list/api.ts +6 -0
- package/components/lcb-list/components/ComponentGroup/index.vue +8 -1
- package/components/lcb-list/components/FilterSelect/index.vue +7 -0
- package/components/lcb-list/components/FilterSlider/index.vue +12 -0
- package/components/lcb-list/components/FilterTabs/index.vue +11 -1
- package/components/lcb-list/components/FilterView/index.vue +5 -0
- package/components/lcb-list/components/TagSelect/index.vue +12 -1
- package/components/lcb-list/components/UnCondiLayout/index.vue +84 -0
- package/components/lcb-list/hooks/useSyncValues.ts +16 -0
- package/components/lcb-list/lcb-list.vue +5 -4
- package/components/lcb-list/types.ts +5 -2
- package/components/lcb-search/lcb-search.vue +15 -8
- package/components/lcb-search/types.ts +2 -0
- package/constants.ts +2 -0
- package/package.json +2 -2
- package/types/components/lcb-list/api.d.ts +6 -0
- package/types/components/lcb-list/components/UnCondiLayout/index.vue.d.ts +36 -0
- package/types/components/lcb-list/hooks/useSelect.d.ts +1 -1
- package/types/components/lcb-list/hooks/useSyncValues.d.ts +5 -0
- package/types/components/lcb-list/types.d.ts +4 -2
- package/types/components/lcb-search/lcb-search.vue.d.ts +16 -0
- package/types/components/lcb-search/types.d.ts +1 -0
- package/types/constants.d.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.4.28](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.1.75...v0.4.28) (2025-03-27)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### ✨ Features | 新功能
|
|
9
|
+
|
|
10
|
+
* backup ([5934345](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/59343452497456c698c7c6e0d9cafb4cc18ea842))
|
|
11
|
+
|
|
12
|
+
### [0.4.27](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.4.24...v0.4.27) (2025-03-27)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### 🚀 Chore | 构建/工程依赖/工具
|
|
16
|
+
|
|
17
|
+
* **release:** 0.4.25 ([2ad40e5](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/2ad40e5abc837b15a5cc2a9ece27d8c30e4db150))
|
|
18
|
+
* **release:** 0.4.26 ([2057c24](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/2057c245e4692eecd64f8ec1f0850792ba6672ca))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### ✨ Features | 新功能
|
|
22
|
+
|
|
23
|
+
* 修改数据 ([e068701](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/e0687014bb0d3fef33658acc50f742326d60a783))
|
|
24
|
+
* 支持过滤 ([7fd93ce](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/commit/7fd93ce323e2276b4a8e837340eeda1fe1926981))
|
|
25
|
+
|
|
5
26
|
### [0.4.26](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.4.25...v0.4.26) (2025-03-26)
|
|
6
27
|
|
|
7
28
|
### [0.4.25](http://gitlab888.30jia.com.cn/bhBank/zero-code-pro/compare/v0.4.18...v0.4.25) (2025-03-26)
|
|
@@ -108,28 +108,6 @@ const urlParams = computed(() => {
|
|
|
108
108
|
const { translate } = useTranslate()
|
|
109
109
|
const { getLocation, userLocation } = useLocation()
|
|
110
110
|
|
|
111
|
-
watch(
|
|
112
|
-
() => addressCity.value,
|
|
113
|
-
(val) => {
|
|
114
|
-
if (val) {
|
|
115
|
-
const params: Record<string, any> = {
|
|
116
|
-
cityId: val?.cityId,
|
|
117
|
-
areaId: val?.areaId,
|
|
118
|
-
provinceId: val?.provinceId,
|
|
119
|
-
addressName: val?.addressName,
|
|
120
|
-
}
|
|
121
|
-
if (val.keywords) {
|
|
122
|
-
params.keywords = val.keywords
|
|
123
|
-
}
|
|
124
|
-
const datas = cleanOutSizeKeys(form.value, Object.keys(getCurrentPage().options))
|
|
125
|
-
form.value = {
|
|
126
|
-
...datas,
|
|
127
|
-
...params,
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
)
|
|
132
|
-
|
|
133
111
|
getLocation()
|
|
134
112
|
const onSearch = (e) => {
|
|
135
113
|
form.value.keywords = e.target.value
|
|
@@ -59,13 +59,16 @@
|
|
|
59
59
|
</template>
|
|
60
60
|
|
|
61
61
|
<script setup lang="ts">
|
|
62
|
-
import { ref, watch, provide, onMounted, onUnmounted } from 'vue'
|
|
62
|
+
import { ref, watch, provide, onMounted, onUnmounted, inject, Ref } from 'vue'
|
|
63
63
|
import { ChildHotAddress, getAddressList, LcbAddress } from './api'
|
|
64
64
|
import LcbCityLetter from './components/lcb-city-letter/index.vue'
|
|
65
65
|
import LcbCityList from './components/lcb-city-list/index.vue'
|
|
66
66
|
import { LcbCitySelectProps } from './types'
|
|
67
67
|
import { debounce } from '@tplc/wot/components/common/util'
|
|
68
68
|
import { setHistoryCity } from '../../utils/history'
|
|
69
|
+
import { cleanOutSizeKeys } from '../../utils/transform'
|
|
70
|
+
import { getCurrentPage } from '../../utils/utils'
|
|
71
|
+
import { FORM_KEY } from '../../constants'
|
|
69
72
|
defineOptions({
|
|
70
73
|
name: 'LcbCitySelect',
|
|
71
74
|
options: {
|
|
@@ -78,6 +81,7 @@ const props = withDefaults(defineProps<LcbCitySelectProps>(), {
|
|
|
78
81
|
placeholder: '搜索城市/区域/景点',
|
|
79
82
|
})
|
|
80
83
|
const historyList = ref<LcbAddress[]>(uni.getStorageSync('historyAddress') || [])
|
|
84
|
+
const form = inject(FORM_KEY) as Ref<Record<string, any>>
|
|
81
85
|
provide('lcb-city-history', historyList)
|
|
82
86
|
const modelValue = defineModel<ChildHotAddress>()
|
|
83
87
|
const isOver = ref(false)
|
|
@@ -121,7 +125,21 @@ watch(
|
|
|
121
125
|
|
|
122
126
|
watch(
|
|
123
127
|
() => modelValue.value,
|
|
124
|
-
() => {
|
|
128
|
+
(val) => {
|
|
129
|
+
const params: Record<string, any> = {
|
|
130
|
+
cityId: val?.cityId,
|
|
131
|
+
areaId: val?.areaId,
|
|
132
|
+
provinceId: val?.provinceId,
|
|
133
|
+
addressName: val?.addressName,
|
|
134
|
+
}
|
|
135
|
+
// if (val.keywords) {
|
|
136
|
+
// params.keywords = val.keywords
|
|
137
|
+
// }
|
|
138
|
+
const datas = cleanOutSizeKeys(form.value, Object.keys(getCurrentPage().options))
|
|
139
|
+
form.value = {
|
|
140
|
+
...datas,
|
|
141
|
+
...params,
|
|
142
|
+
}
|
|
125
143
|
setHistoryCity(modelValue.value)
|
|
126
144
|
show.value = false
|
|
127
145
|
},
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
</template>
|
|
112
112
|
|
|
113
113
|
<script setup lang="ts">
|
|
114
|
-
import { computed, ref, watchEffect, inject, Ref } from 'vue'
|
|
114
|
+
import { computed, ref, watchEffect, inject, Ref, onMounted } from 'vue'
|
|
115
115
|
import { LcbHomeSearch } from './types'
|
|
116
116
|
import dayjs from 'dayjs/esm'
|
|
117
117
|
import useLocation from '../../hooks/useLocation'
|
|
@@ -169,16 +169,14 @@ watchEffect(() => {
|
|
|
169
169
|
form.value.startDate = dayjs(dayRange.value[0]).format('YYYY-MM-DD')
|
|
170
170
|
form.value.endDate = dayjs(dayRange.value[1]).format('YYYY-MM-DD')
|
|
171
171
|
})
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
form.value
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
form.value.keywords = addressCity.value.keywords
|
|
181
|
-
}
|
|
172
|
+
onMounted(() => {
|
|
173
|
+
const { addressName, cityId, provinceId, areaId } = getHistoryCity() || {}
|
|
174
|
+
form.value = {
|
|
175
|
+
...form.value,
|
|
176
|
+
addressName,
|
|
177
|
+
cityId,
|
|
178
|
+
provinceId,
|
|
179
|
+
areaId,
|
|
182
180
|
}
|
|
183
181
|
})
|
|
184
182
|
</script>
|
|
@@ -12,6 +12,7 @@ export interface LcbFilterResult {
|
|
|
12
12
|
filterTabs?: {
|
|
13
13
|
componentProps: FilterTabsProps
|
|
14
14
|
valueName: string
|
|
15
|
+
sortType?: boolean
|
|
15
16
|
defaultValue?: string
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -22,6 +23,7 @@ export interface FilterComponent {
|
|
|
22
23
|
defaultValue?: string
|
|
23
24
|
defaultName?: string
|
|
24
25
|
valueName: string
|
|
26
|
+
sortType?: boolean
|
|
25
27
|
componentProps: FilterComponentProps
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -36,6 +38,7 @@ export interface ComponentList {
|
|
|
36
38
|
filterName: string
|
|
37
39
|
component: string
|
|
38
40
|
valueName: string
|
|
41
|
+
sortType?: boolean
|
|
39
42
|
defaultValue?: string | string[] | number[]
|
|
40
43
|
componentProps: FilterTagsProps
|
|
41
44
|
}
|
|
@@ -43,6 +46,7 @@ export interface ComponentList {
|
|
|
43
46
|
export interface FilterTags {
|
|
44
47
|
component: string
|
|
45
48
|
valueName: string
|
|
49
|
+
sortType?: boolean
|
|
46
50
|
defaultValue?: string
|
|
47
51
|
defaultName?: string
|
|
48
52
|
componentProps: FilterTagsProps
|
|
@@ -56,6 +60,8 @@ export interface FilterTagsProps {
|
|
|
56
60
|
options: Option[]
|
|
57
61
|
unit?: string
|
|
58
62
|
step?: number
|
|
63
|
+
valueName: string
|
|
64
|
+
sortType?: boolean
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
interface BtnComponent {
|
|
@@ -15,12 +15,19 @@
|
|
|
15
15
|
</view>
|
|
16
16
|
</view>
|
|
17
17
|
<view class="grid grid-cols-4 gap-22rpx" v-if="child.component === 'tagSelect'">
|
|
18
|
-
<TagSelect
|
|
18
|
+
<TagSelect
|
|
19
|
+
v-bind="child.componentProps"
|
|
20
|
+
v-model="innerFilter[child.valueName]"
|
|
21
|
+
:value-name="child.valueName"
|
|
22
|
+
:sort-type="child.sortType"
|
|
23
|
+
/>
|
|
19
24
|
</view>
|
|
20
25
|
<FilterSlider
|
|
21
26
|
v-if="child.component === 'slider'"
|
|
22
27
|
v-bind="child.componentProps"
|
|
23
28
|
v-model="innerFilter[child.valueName]"
|
|
29
|
+
:value-name="child.valueName"
|
|
30
|
+
:sort-type="child.sortType"
|
|
24
31
|
/>
|
|
25
32
|
</view>
|
|
26
33
|
</view>
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { FilterSelectProps } from './type'
|
|
18
18
|
import useSelect from '../../hooks/useSelect'
|
|
19
19
|
import { watch, watchEffect } from 'vue'
|
|
20
|
+
import useSyncValues from '../../hooks/useSyncValues'
|
|
20
21
|
defineOptions({
|
|
21
22
|
name: 'FilterSelect',
|
|
22
23
|
options: {
|
|
@@ -27,11 +28,17 @@ defineOptions({
|
|
|
27
28
|
})
|
|
28
29
|
const props = defineProps<FilterSelectProps>()
|
|
29
30
|
const model = defineModel<string | string[]>()
|
|
31
|
+
const { syncValues } = useSyncValues()
|
|
30
32
|
const modelTitle = defineModel<string>('title')
|
|
31
33
|
const { onItemClick, options, getChecked } = useSelect(props, { model })
|
|
32
34
|
const emits = defineEmits(['submit'])
|
|
33
35
|
watchEffect(() => {
|
|
34
36
|
modelTitle.value = options.value?.find((v) => v.value === model.value)?.label
|
|
37
|
+
syncValues(
|
|
38
|
+
props.valueName,
|
|
39
|
+
options.value?.filter((v) => v.value === model.value),
|
|
40
|
+
props.sortType,
|
|
41
|
+
)
|
|
35
42
|
})
|
|
36
43
|
watch(
|
|
37
44
|
() => model.value,
|
|
@@ -35,6 +35,7 @@ import { FilterSliderProps } from './types'
|
|
|
35
35
|
import SelectTagView from '../SelectTagView/index.vue'
|
|
36
36
|
import { onMounted, onUnmounted, ref, watch, inject } from 'vue'
|
|
37
37
|
import type { SliderInstance } from '@tplc/wot/components/wd-slider/types'
|
|
38
|
+
import useSyncValues from '../../hooks/useSyncValues'
|
|
38
39
|
defineOptions({
|
|
39
40
|
name: 'FilterSlider',
|
|
40
41
|
options: {
|
|
@@ -51,6 +52,7 @@ const props = withDefaults(defineProps<FilterSliderProps>(), {
|
|
|
51
52
|
})
|
|
52
53
|
const model = defineModel<number[]>()
|
|
53
54
|
const innerValue = ref<number[]>()
|
|
55
|
+
const { syncValues } = useSyncValues()
|
|
54
56
|
const onItemClick = (value) => {
|
|
55
57
|
if (Array.isArray(value)) {
|
|
56
58
|
if (value[1]) {
|
|
@@ -85,6 +87,16 @@ watch(
|
|
|
85
87
|
? val.map((v) => (typeof v === 'string' ? parseInt(v) : v))
|
|
86
88
|
: [props.min, props.max]
|
|
87
89
|
}
|
|
90
|
+
syncValues(
|
|
91
|
+
props.valueName,
|
|
92
|
+
[
|
|
93
|
+
{
|
|
94
|
+
label: `${innerValue.value?.[0]}${props.unit} - ${innerValue.value?.[1]}${props.unit}`,
|
|
95
|
+
value: `${innerValue.value}`,
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
props.sortType,
|
|
99
|
+
)
|
|
88
100
|
},
|
|
89
101
|
{ immediate: true },
|
|
90
102
|
)
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
<script setup lang="ts">
|
|
15
15
|
import { FilterTabsProps } from './type'
|
|
16
|
+
import useSyncValues from '../../hooks/useSyncValues'
|
|
17
|
+
import { watchEffect } from 'vue'
|
|
16
18
|
defineOptions({
|
|
17
19
|
name: 'FilterTabs',
|
|
18
20
|
options: {
|
|
@@ -21,7 +23,15 @@ defineOptions({
|
|
|
21
23
|
styleIsolation: 'shared',
|
|
22
24
|
},
|
|
23
25
|
})
|
|
24
|
-
defineProps<FilterTabsProps>()
|
|
26
|
+
const props = defineProps<FilterTabsProps>()
|
|
25
27
|
const modelValue = defineModel<string>()
|
|
28
|
+
const { syncValues } = useSyncValues()
|
|
29
|
+
watchEffect(() => {
|
|
30
|
+
syncValues(
|
|
31
|
+
props.valueName,
|
|
32
|
+
props.options?.filter((v) => v.value === modelValue.value),
|
|
33
|
+
props.sortType,
|
|
34
|
+
)
|
|
35
|
+
})
|
|
26
36
|
</script>
|
|
27
37
|
<style lang="scss" scoped></style>
|
|
@@ -30,6 +30,8 @@
|
|
|
30
30
|
v-if="item.component === 'select'"
|
|
31
31
|
v-bind="item.componentProps"
|
|
32
32
|
v-model="filter[item.valueName]"
|
|
33
|
+
:value-name="item.valueName"
|
|
34
|
+
:sort-type="item.sortType"
|
|
33
35
|
v-model:title="titleObj[item.valueName]"
|
|
34
36
|
@submit="onSubmit(index)"
|
|
35
37
|
/>
|
|
@@ -38,6 +40,7 @@
|
|
|
38
40
|
v-bind="item.componentProps"
|
|
39
41
|
:value="filter[item.valueName]"
|
|
40
42
|
:value-name="item.valueName"
|
|
43
|
+
:sort-type="item.sortType"
|
|
41
44
|
:filter-value="filter"
|
|
42
45
|
v-model:keys="dynamicKeys[index]"
|
|
43
46
|
@submit="onSubmit(index, $event)"
|
|
@@ -64,6 +67,8 @@
|
|
|
64
67
|
size="small"
|
|
65
68
|
v-bind="info.filterTags.componentProps"
|
|
66
69
|
v-model="filter[info.filterTags.valueName]"
|
|
70
|
+
:value-name="info.filterTags.valueName"
|
|
71
|
+
:sort-type="info.filterTags.sortType"
|
|
67
72
|
/>
|
|
68
73
|
</view>
|
|
69
74
|
<wd-button v-if="info?.btnComponent" custom-class="!h-60rpx opacity-primary">
|
|
@@ -44,6 +44,7 @@ import useSelect from '../../hooks/useSelect'
|
|
|
44
44
|
import { ref, watchEffect, nextTick } from 'vue'
|
|
45
45
|
import SelectTagView from '../SelectTagView/index.vue'
|
|
46
46
|
import { Option } from '../../types'
|
|
47
|
+
import useSyncValues from '../../hooks/useSyncValues'
|
|
47
48
|
defineOptions({
|
|
48
49
|
name: 'TagSelect',
|
|
49
50
|
options: {
|
|
@@ -58,8 +59,18 @@ const modelTitle = defineModel<string>('title')
|
|
|
58
59
|
const showInput = ref(false)
|
|
59
60
|
const inputValue = ref('')
|
|
60
61
|
const { options, onItemClick, getChecked } = useSelect(props, { model })
|
|
62
|
+
const { syncValues } = useSyncValues()
|
|
61
63
|
watchEffect(() => {
|
|
62
|
-
|
|
64
|
+
if (typeof model.value === 'string') {
|
|
65
|
+
modelTitle.value = options.value?.find((v) => v.value === model.value)?.label
|
|
66
|
+
}
|
|
67
|
+
syncValues(
|
|
68
|
+
props.valueName,
|
|
69
|
+
options.value?.filter((v) =>
|
|
70
|
+
Array.isArray(model.value) ? model.value.includes(v.value) : v.value === model.value,
|
|
71
|
+
),
|
|
72
|
+
props.sortType,
|
|
73
|
+
)
|
|
63
74
|
})
|
|
64
75
|
const onCustomClick = (item: Option, edit = false) => {
|
|
65
76
|
if (item.value && !edit) {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="un-condi-layout p-3">
|
|
3
|
+
<view class="un-condi-tags">
|
|
4
|
+
<view v-for="(tag, index) in tags" :key="index" class="un-condi-tag radius-12rpx m-1">
|
|
5
|
+
<text class="tag-text text-3">{{ tag.label }}</text>
|
|
6
|
+
<text class="tag-close" @click="handleRemoveTag(tag, index)">×</text>
|
|
7
|
+
</view>
|
|
8
|
+
</view>
|
|
9
|
+
<view class="un-condi-clear" @click="handleClearAll">
|
|
10
|
+
<wd-img src="/static/icons/clear.png" width="40rpx" height="40rpx" />
|
|
11
|
+
<text class="clear-text text-3 text-#969696 m-1">清空</text>
|
|
12
|
+
</view>
|
|
13
|
+
</view>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script lang="ts" setup>
|
|
17
|
+
import type { PropType } from 'vue'
|
|
18
|
+
|
|
19
|
+
interface TagItem {
|
|
20
|
+
label: string
|
|
21
|
+
value: string | number
|
|
22
|
+
type?: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const props = defineProps({
|
|
26
|
+
tags: {
|
|
27
|
+
type: Array as PropType<TagItem[]>,
|
|
28
|
+
default: () => [],
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 移除单个标签
|
|
34
|
+
*/
|
|
35
|
+
const handleRemoveTag = (tag: TagItem, index: number) => {}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* 清空所有标签
|
|
39
|
+
*/
|
|
40
|
+
const handleClearAll = () => {}
|
|
41
|
+
</script>
|
|
42
|
+
|
|
43
|
+
<style lang="scss" scoped>
|
|
44
|
+
.un-condi-layout {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: row;
|
|
47
|
+
justify-content: space-between;
|
|
48
|
+
align-items: center;
|
|
49
|
+
width: 100%;
|
|
50
|
+
background-color: #fff;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.un-condi-tags {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: row;
|
|
56
|
+
flex-wrap: wrap;
|
|
57
|
+
flex: 1;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.un-condi-tag {
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: row;
|
|
63
|
+
align-items: center;
|
|
64
|
+
padding: 10rpx 20rpx;
|
|
65
|
+
background-color: #f5f5f5;
|
|
66
|
+
|
|
67
|
+
.tag-text {
|
|
68
|
+
color: #333;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.tag-close {
|
|
72
|
+
margin-left: 10rpx;
|
|
73
|
+
font-size: 32rpx;
|
|
74
|
+
color: #969696;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.un-condi-clear {
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: row;
|
|
81
|
+
align-items: center;
|
|
82
|
+
padding-left: 20rpx;
|
|
83
|
+
}
|
|
84
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Ref, inject } from 'vue'
|
|
2
|
+
import { LIST_FORM_CHOOSER_VALUES } from '../../../constants'
|
|
3
|
+
import { ListFormChooserValues, Option } from '../types'
|
|
4
|
+
|
|
5
|
+
const useSyncValues = () => {
|
|
6
|
+
const listFormChooserValues = inject(LIST_FORM_CHOOSER_VALUES) as Ref<ListFormChooserValues>
|
|
7
|
+
const syncValues = (valueName: string, options?: Option[], sortType?: boolean) => {
|
|
8
|
+
if (!sortType) {
|
|
9
|
+
listFormChooserValues.value[valueName] = options
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
syncValues,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export default useSyncValues
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
</template>
|
|
61
61
|
|
|
62
62
|
<script setup lang="ts">
|
|
63
|
-
import { inject, Ref, ref, watch, useAttrs } from 'vue'
|
|
63
|
+
import { inject, Ref, ref, watch, useAttrs, provide } from 'vue'
|
|
64
64
|
import { getFilterDetail, LcbFilterResult } from './api'
|
|
65
65
|
import FilterList from './components/FilterList/index.vue'
|
|
66
66
|
import FilterView from './components/FilterView/index.vue'
|
|
67
|
-
import { LcbListProps } from './types'
|
|
68
|
-
import { FORM_KEY } from '../../constants'
|
|
67
|
+
import { LcbListProps, ListFormChooserValues } from './types'
|
|
68
|
+
import { FORM_KEY, LIST_FORM_CHOOSER_VALUES } from '../../constants'
|
|
69
69
|
import './index.scss'
|
|
70
70
|
const attrs = useAttrs()
|
|
71
71
|
/** 是否悬停 */
|
|
@@ -82,7 +82,8 @@ defineOptions({
|
|
|
82
82
|
})
|
|
83
83
|
const titleObj = ref<Record<string, any>>({})
|
|
84
84
|
const titleCount = ref<Record<string, number>>({})
|
|
85
|
-
const form = inject
|
|
85
|
+
const form = inject(FORM_KEY) as Ref<Record<string, any>>
|
|
86
|
+
provide<Ref<Record<string, any>>>(LIST_FORM_CHOOSER_VALUES, ref<ListFormChooserValues>({}))
|
|
86
87
|
const props = withDefaults(defineProps<LcbListProps>(), {
|
|
87
88
|
borderRadius: 12,
|
|
88
89
|
styleMode: 'default',
|
|
@@ -20,7 +20,7 @@ export interface LcbListProps extends LcbBlockProps {
|
|
|
20
20
|
}
|
|
21
21
|
export interface Option {
|
|
22
22
|
label: string
|
|
23
|
-
value: string
|
|
23
|
+
value: string
|
|
24
24
|
custom?: boolean
|
|
25
25
|
max?: number
|
|
26
26
|
min?: number
|
|
@@ -34,5 +34,8 @@ export interface FilterItemProps {
|
|
|
34
34
|
apiPath?: string
|
|
35
35
|
apiParams?: Record<string, any>
|
|
36
36
|
options?: Option[]
|
|
37
|
-
|
|
37
|
+
valueName: string
|
|
38
|
+
sortType?: boolean
|
|
38
39
|
}
|
|
40
|
+
|
|
41
|
+
export type ListFormChooserValues = Record<string, Option[] | undefined>
|
|
@@ -64,14 +64,15 @@
|
|
|
64
64
|
:placeholder="placeholder"
|
|
65
65
|
v-model="form.keywords"
|
|
66
66
|
@confirm="onSearch"
|
|
67
|
-
focus
|
|
67
|
+
@blur="focus = false"
|
|
68
|
+
:focus="focus"
|
|
68
69
|
/>
|
|
69
70
|
<wd-icon
|
|
70
71
|
name="close-circle"
|
|
71
72
|
:size="iconSize"
|
|
72
73
|
:color="iconColor"
|
|
73
74
|
v-if="form.keywords"
|
|
74
|
-
@click="
|
|
75
|
+
@click="onClear"
|
|
75
76
|
/>
|
|
76
77
|
</view>
|
|
77
78
|
<lcb-action-view v-bind="link" :urlParams="stringify(addressCity)" v-else>
|
|
@@ -156,10 +157,12 @@ const props = withDefaults(defineProps<LcbSearchProps>(), {
|
|
|
156
157
|
iconType: 'icon',
|
|
157
158
|
mode: 'link',
|
|
158
159
|
fontSize: 24,
|
|
160
|
+
initFocus: true,
|
|
159
161
|
})
|
|
160
162
|
const searchHistoryRef = ref<InstanceType<typeof LcbSearchHistory>>()
|
|
161
163
|
const searchListRef = ref<InstanceType<typeof LcbSearchList>>()
|
|
162
164
|
const { height, top } = useAutoHeight('searchPagingTop')
|
|
165
|
+
const focus = ref(props.initFocus)
|
|
163
166
|
const { getLocation, userLocation } = useLocation()
|
|
164
167
|
const addressCity = ref<ChildHotAddress | undefined>(getHistoryCity())
|
|
165
168
|
const popupProvide = inject('wd-popup', {
|
|
@@ -168,12 +171,10 @@ const popupProvide = inject('wd-popup', {
|
|
|
168
171
|
getLocation()
|
|
169
172
|
const form = inject(FORM_KEY) as Ref<Record<string, any>>
|
|
170
173
|
const onSearch = async (e: { detail: { value: string } }) => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
uni.navigateBack()
|
|
176
|
-
}
|
|
174
|
+
uni.$emit(`${getPreviousPageId()}_filter_change`, {
|
|
175
|
+
keywords: form?.value?.keywords,
|
|
176
|
+
})
|
|
177
|
+
uni.navigateBack()
|
|
177
178
|
}
|
|
178
179
|
const onSelect = (keyword: ProductInfo) => {
|
|
179
180
|
searchHistoryRef.value?.saveHistory(keyword)
|
|
@@ -213,6 +214,12 @@ const onCancel = () => {
|
|
|
213
214
|
watchEffect(() => {
|
|
214
215
|
popupProvide.value = form.value?.keywords && props.productTypeList && top
|
|
215
216
|
})
|
|
217
|
+
const onClear = () => {
|
|
218
|
+
form.value.keywords = ''
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
focus.value = true
|
|
221
|
+
}, 100)
|
|
222
|
+
}
|
|
216
223
|
</script>
|
|
217
224
|
|
|
218
225
|
<style lang="scss" scoped>
|
package/constants.ts
CHANGED
|
@@ -7,3 +7,5 @@ export const PAGE_TYPE_PROVIDE_KEY = 'page_type_provide'
|
|
|
7
7
|
export const PAGE_ANCHOR_PROVIDE_KEY = 'page_anchor_provide'
|
|
8
8
|
/** 用户基本信息 */
|
|
9
9
|
export const USER_BASIC_INFO = 'user_basic_info'
|
|
10
|
+
/** 列表页表单选择项 */
|
|
11
|
+
export const LIST_FORM_CHOOSER_VALUES = 'list_form_chooser_values'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tplc/business",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.28",
|
|
4
4
|
"keywords": [
|
|
5
5
|
"业务组件"
|
|
6
6
|
],
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"vue": ">=3.2.47",
|
|
14
|
-
"@tplc/wot": "0.1.
|
|
14
|
+
"@tplc/wot": "0.1.75"
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
17
|
"node": ">=18",
|
|
@@ -12,6 +12,7 @@ export interface LcbFilterResult {
|
|
|
12
12
|
filterTabs?: {
|
|
13
13
|
componentProps: FilterTabsProps
|
|
14
14
|
valueName: string
|
|
15
|
+
sortType?: boolean
|
|
15
16
|
defaultValue?: string
|
|
16
17
|
}
|
|
17
18
|
}
|
|
@@ -21,6 +22,7 @@ export interface FilterComponent {
|
|
|
21
22
|
defaultValue?: string
|
|
22
23
|
defaultName?: string
|
|
23
24
|
valueName: string
|
|
25
|
+
sortType?: boolean
|
|
24
26
|
componentProps: FilterComponentProps
|
|
25
27
|
}
|
|
26
28
|
interface FilterComponentProps {
|
|
@@ -33,12 +35,14 @@ export interface ComponentList {
|
|
|
33
35
|
filterName: string
|
|
34
36
|
component: string
|
|
35
37
|
valueName: string
|
|
38
|
+
sortType?: boolean
|
|
36
39
|
defaultValue?: string | string[] | number[]
|
|
37
40
|
componentProps: FilterTagsProps
|
|
38
41
|
}
|
|
39
42
|
export interface FilterTags {
|
|
40
43
|
component: string
|
|
41
44
|
valueName: string
|
|
45
|
+
sortType?: boolean
|
|
42
46
|
defaultValue?: string
|
|
43
47
|
defaultName?: string
|
|
44
48
|
componentProps: FilterTagsProps
|
|
@@ -51,6 +55,8 @@ export interface FilterTagsProps {
|
|
|
51
55
|
options: Option[]
|
|
52
56
|
unit?: string
|
|
53
57
|
step?: number
|
|
58
|
+
valueName: string
|
|
59
|
+
sortType?: boolean
|
|
54
60
|
}
|
|
55
61
|
interface BtnComponent {
|
|
56
62
|
postRequest: string
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { PropType } from 'vue'
|
|
2
|
+
interface TagItem {
|
|
3
|
+
label: string
|
|
4
|
+
value: string | number
|
|
5
|
+
type?: string
|
|
6
|
+
}
|
|
7
|
+
declare const _default: import('vue').DefineComponent<
|
|
8
|
+
{
|
|
9
|
+
tags: {
|
|
10
|
+
type: PropType<TagItem[]>
|
|
11
|
+
default: () => never[]
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
{},
|
|
15
|
+
unknown,
|
|
16
|
+
{},
|
|
17
|
+
{},
|
|
18
|
+
import('vue').ComponentOptionsMixin,
|
|
19
|
+
import('vue').ComponentOptionsMixin,
|
|
20
|
+
{},
|
|
21
|
+
string,
|
|
22
|
+
import('vue').PublicProps,
|
|
23
|
+
Readonly<
|
|
24
|
+
import('vue').ExtractPropTypes<{
|
|
25
|
+
tags: {
|
|
26
|
+
type: PropType<TagItem[]>
|
|
27
|
+
default: () => never[]
|
|
28
|
+
}
|
|
29
|
+
}>
|
|
30
|
+
>,
|
|
31
|
+
{
|
|
32
|
+
tags: TagItem[]
|
|
33
|
+
},
|
|
34
|
+
{}
|
|
35
|
+
>
|
|
36
|
+
export default _default
|
|
@@ -19,7 +19,7 @@ export interface LcbListProps extends LcbBlockProps {
|
|
|
19
19
|
}
|
|
20
20
|
export interface Option {
|
|
21
21
|
label: string
|
|
22
|
-
value: string
|
|
22
|
+
value: string
|
|
23
23
|
custom?: boolean
|
|
24
24
|
max?: number
|
|
25
25
|
min?: number
|
|
@@ -32,5 +32,7 @@ export interface FilterItemProps {
|
|
|
32
32
|
apiPath?: string
|
|
33
33
|
apiParams?: Record<string, any>
|
|
34
34
|
options?: Option[]
|
|
35
|
-
|
|
35
|
+
valueName: string
|
|
36
|
+
sortType?: boolean
|
|
36
37
|
}
|
|
38
|
+
export type ListFormChooserValues = Record<string, Option[] | undefined>
|
|
@@ -25,6 +25,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
25
25
|
iconType: string
|
|
26
26
|
mode: string
|
|
27
27
|
fontSize: number
|
|
28
|
+
initFocus: boolean
|
|
28
29
|
}
|
|
29
30
|
>,
|
|
30
31
|
{},
|
|
@@ -62,6 +63,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
62
63
|
linePadding?: number
|
|
63
64
|
lineHeight?: number
|
|
64
65
|
historyKey?: string
|
|
66
|
+
initFocus?: boolean
|
|
65
67
|
} & {
|
|
66
68
|
jumpUrl?: string
|
|
67
69
|
urlParams?: string
|
|
@@ -120,6 +122,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
120
122
|
iconType: string
|
|
121
123
|
mode: string
|
|
122
124
|
fontSize: number
|
|
125
|
+
initFocus: boolean
|
|
123
126
|
}
|
|
124
127
|
>
|
|
125
128
|
>
|
|
@@ -150,6 +153,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
150
153
|
linePadding?: number
|
|
151
154
|
lineHeight?: number
|
|
152
155
|
historyKey?: string
|
|
156
|
+
initFocus?: boolean
|
|
153
157
|
} & {
|
|
154
158
|
jumpUrl?: string
|
|
155
159
|
urlParams?: string
|
|
@@ -186,6 +190,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
186
190
|
iconType: string
|
|
187
191
|
mode: string
|
|
188
192
|
fontSize: number
|
|
193
|
+
initFocus: boolean
|
|
189
194
|
}
|
|
190
195
|
>
|
|
191
196
|
>
|
|
@@ -216,6 +221,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
216
221
|
linePadding?: number
|
|
217
222
|
lineHeight?: number
|
|
218
223
|
historyKey?: string
|
|
224
|
+
initFocus?: boolean
|
|
219
225
|
} & {
|
|
220
226
|
jumpUrl?: string
|
|
221
227
|
urlParams?: string
|
|
@@ -254,6 +260,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
254
260
|
iconType: string
|
|
255
261
|
mode: string
|
|
256
262
|
fontSize: number
|
|
263
|
+
initFocus: boolean
|
|
257
264
|
}
|
|
258
265
|
>
|
|
259
266
|
>
|
|
@@ -284,6 +291,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
284
291
|
linePadding?: number
|
|
285
292
|
lineHeight?: number
|
|
286
293
|
historyKey?: string
|
|
294
|
+
initFocus?: boolean
|
|
287
295
|
} & {
|
|
288
296
|
jumpUrl?: string
|
|
289
297
|
urlParams?: string
|
|
@@ -317,6 +325,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
317
325
|
iconType: string
|
|
318
326
|
mode: string
|
|
319
327
|
fontSize: number
|
|
328
|
+
initFocus: boolean
|
|
320
329
|
}
|
|
321
330
|
>
|
|
322
331
|
>
|
|
@@ -347,6 +356,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
347
356
|
linePadding?: number
|
|
348
357
|
lineHeight?: number
|
|
349
358
|
historyKey?: string
|
|
359
|
+
initFocus?: boolean
|
|
350
360
|
} & {
|
|
351
361
|
jumpUrl?: string
|
|
352
362
|
urlParams?: string
|
|
@@ -379,6 +389,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
379
389
|
iconType: string
|
|
380
390
|
mode: string
|
|
381
391
|
fontSize: number
|
|
392
|
+
initFocus: boolean
|
|
382
393
|
}
|
|
383
394
|
>
|
|
384
395
|
>
|
|
@@ -406,6 +417,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
406
417
|
cityIconColor: string
|
|
407
418
|
lineColor: string
|
|
408
419
|
linePadding: number
|
|
420
|
+
initFocus: boolean
|
|
409
421
|
}
|
|
410
422
|
| {
|
|
411
423
|
mode: 'search' | 'link'
|
|
@@ -430,6 +442,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
430
442
|
cityIconColor: string
|
|
431
443
|
lineColor: string
|
|
432
444
|
linePadding: number
|
|
445
|
+
initFocus: boolean
|
|
433
446
|
}
|
|
434
447
|
| {
|
|
435
448
|
mode: 'search' | 'link'
|
|
@@ -454,6 +467,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
454
467
|
cityIconColor: string
|
|
455
468
|
lineColor: string
|
|
456
469
|
linePadding: number
|
|
470
|
+
initFocus: boolean
|
|
457
471
|
}
|
|
458
472
|
| {
|
|
459
473
|
mode: 'search' | 'link'
|
|
@@ -478,6 +492,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
478
492
|
cityIconColor: string
|
|
479
493
|
lineColor: string
|
|
480
494
|
linePadding: number
|
|
495
|
+
initFocus: boolean
|
|
481
496
|
}
|
|
482
497
|
| {
|
|
483
498
|
mode: 'search' | 'link'
|
|
@@ -502,6 +517,7 @@ declare const _default: import('vue').DefineComponent<
|
|
|
502
517
|
cityIconColor: string
|
|
503
518
|
lineColor: string
|
|
504
519
|
linePadding: number
|
|
520
|
+
initFocus: boolean
|
|
505
521
|
},
|
|
506
522
|
{}
|
|
507
523
|
>
|
package/types/constants.d.ts
CHANGED
|
@@ -7,3 +7,5 @@ export declare const PAGE_TYPE_PROVIDE_KEY = 'page_type_provide'
|
|
|
7
7
|
export declare const PAGE_ANCHOR_PROVIDE_KEY = 'page_anchor_provide'
|
|
8
8
|
/** 用户基本信息 */
|
|
9
9
|
export declare const USER_BASIC_INFO = 'user_basic_info'
|
|
10
|
+
/** 列表页表单选择项 */
|
|
11
|
+
export declare const LIST_FORM_CHOOSER_VALUES = 'list_form_chooser_values'
|