wui-components-v2 1.1.68 → 1.1.70
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/api/core/index.ts +74 -74
- package/api/menu.ts +45 -45
- package/api/page.ts +114 -114
- package/api/sys.ts +12 -12
- package/components/action-popup/action-popup.vue +46 -17
- package/components/add-address-page/add-address-page.vue +77 -77
- package/components/custom-date-picker/custom-date-picker.vue +106 -106
- package/components/custom-select-picker/custom-select-picker.vue +95 -95
- package/components/demo-block/demo-block.vue +63 -63
- package/components/detail-popup/detail-popup.vue +99 -99
- package/components/evaluation-page/evaluation-page.vue +196 -192
- package/components/fold-card/fold-card.vue +171 -171
- package/components/form-control/form-control.vue +661 -661
- package/components/global-message/global-message.vue +68 -68
- package/components/label-value/label-value.vue +144 -144
- package/components/list-top-buttons/list-top-buttons.vue +19 -19
- package/components/login-form/login-form.vue +126 -126
- package/components/mulselect-picker/mulselect-picker.vue +86 -86
- package/components/product-card/product-card.vue +201 -201
- package/components/search/search.vue +128 -128
- package/components/user-choose/user-choose.vue +1 -1
- package/components/wui-enume-select-control/wui-enume-select-control.vue +92 -92
- package/components/wui-list/wui-list.vue +235 -235
- package/components/wui-menus/wui-menus.vue +247 -247
- package/components/wui-menus1/components/navbar.vue +43 -43
- package/components/wui-menus1/wui-menus.vue +564 -564
- package/components/wui-notify-info/wui-notify-info.vue +280 -280
- package/components/wui-search-history-babbar/wui-search-history-babbar.vue +204 -204
- package/components/wui-select-list/wui-select-list.vue +310 -310
- package/components/wui-select-popup/wui-select-popup.vue +612 -612
- package/components/wui-system-settings/wui-system-settings.vue +144 -144
- package/components/wui-tabbar/wui-tabbar.vue +106 -106
- package/components/wui-tree-page/components/tree-item.vue +238 -238
- package/components/wui-user/wui-user.vue +202 -197
- package/composables/useCompanyFieldFilter.ts +91 -91
- package/composables/useEnumes.ts +2 -2
- package/composables/useMenus.ts +193 -193
- package/index.ts +83 -83
- package/package.json +1 -1
- package/static/iconfont/iconfont.css +63 -63
- package/store/language.ts +151 -151
- package/styles/dark-mode.css +523 -485
- package/styles/dark-mode.min.css +1 -1
- package/styles/dark-mode.scss +28 -0
- package/type.ts +2 -2
- package/utils/control-tree.ts +2 -2
- package/utils/control-type-supportor.ts +148 -148
|
@@ -1,77 +1,77 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<view class="rounded-md mb-3">
|
|
3
|
-
<view class="rounded-md shadow-md bg-
|
|
4
|
-
<wd-textarea v-model="personDetail" placeholder="「粘贴识别」或输入文本,智能拆分、姓名、电话和地址" />
|
|
5
|
-
<view class="flex justify-end align-center px-3">
|
|
6
|
-
<view class="px-3 text-white bg-[#007AFF] rounded-md py-1 text-sm box-border" @click="identifyingFn">
|
|
7
|
-
智能识别
|
|
8
|
-
</view>
|
|
9
|
-
</view>
|
|
10
|
-
</view>
|
|
11
|
-
</view>
|
|
12
|
-
</template>
|
|
13
|
-
<script setup lang="ts">
|
|
14
|
-
import { ref } from 'vue'
|
|
15
|
-
import { useGlobalToast } from '../../composables/useGlobalToast'
|
|
16
|
-
import parse from 'china-address-parse'
|
|
17
|
-
const toast = useGlobalToast()
|
|
18
|
-
defineOptions({
|
|
19
|
-
name: 'AddAddressPage',
|
|
20
|
-
})
|
|
21
|
-
const props = defineProps<{
|
|
22
|
-
group: any
|
|
23
|
-
}>()
|
|
24
|
-
const model = defineModel<any>()
|
|
25
|
-
const personDetail = ref('')
|
|
26
|
-
const loading = ref(false)
|
|
27
|
-
const form = ref(null)
|
|
28
|
-
/**
|
|
29
|
-
* @description: 智能识别
|
|
30
|
-
*/
|
|
31
|
-
function identifyingFn() {
|
|
32
|
-
if (!personDetail.value) {
|
|
33
|
-
toast.info('请输入内容')
|
|
34
|
-
return
|
|
35
|
-
}
|
|
36
|
-
const currentValue: any = parse(personDetail.value)
|
|
37
|
-
console.log('智能识别', currentValue)
|
|
38
|
-
if (!currentValue) {
|
|
39
|
-
toast.info('无法识别地址')
|
|
40
|
-
return
|
|
41
|
-
}
|
|
42
|
-
if (!model.value) {
|
|
43
|
-
model.value = {}
|
|
44
|
-
}
|
|
45
|
-
props.group?.fields?.forEach((item: any, index: number) => {
|
|
46
|
-
switch (index) {
|
|
47
|
-
case 0:
|
|
48
|
-
model.value[item.sourceId] = currentValue.name || ''
|
|
49
|
-
break
|
|
50
|
-
case 1:
|
|
51
|
-
model.value[item.sourceId] = currentValue.telNumber || currentValue.phone || ''
|
|
52
|
-
break
|
|
53
|
-
case 2:
|
|
54
|
-
model.value[item.sourceId] = currentValue.provinceName || ''
|
|
55
|
-
break
|
|
56
|
-
case 3:
|
|
57
|
-
model.value[item.sourceId] = currentValue.cityName || ''
|
|
58
|
-
break
|
|
59
|
-
case 4:
|
|
60
|
-
model.value[item.sourceId] = currentValue.countyName || ''
|
|
61
|
-
break
|
|
62
|
-
case 5:
|
|
63
|
-
model.value[item.sourceId] = currentValue.address || ''
|
|
64
|
-
break
|
|
65
|
-
default:
|
|
66
|
-
break
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
console.log('智能识别', currentValue)
|
|
70
|
-
}
|
|
71
|
-
</script>
|
|
72
|
-
|
|
73
|
-
<style scoped>
|
|
74
|
-
.custom-border {
|
|
75
|
-
border-bottom: 0.6px solid #e8e8e8;
|
|
76
|
-
}
|
|
77
|
-
</style>
|
|
1
|
+
<template>
|
|
2
|
+
<view class="rounded-md mb-3">
|
|
3
|
+
<view class="rounded-md shadow-md dark:bg-[#252530] pb-3">
|
|
4
|
+
<wd-textarea v-model="personDetail" placeholder="「粘贴识别」或输入文本,智能拆分、姓名、电话和地址" />
|
|
5
|
+
<view class="flex justify-end align-center px-3">
|
|
6
|
+
<view class="px-3 text-white bg-[#007AFF] rounded-md py-1 text-sm box-border" @click="identifyingFn">
|
|
7
|
+
智能识别
|
|
8
|
+
</view>
|
|
9
|
+
</view>
|
|
10
|
+
</view>
|
|
11
|
+
</view>
|
|
12
|
+
</template>
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import { ref } from 'vue'
|
|
15
|
+
import { useGlobalToast } from '../../composables/useGlobalToast'
|
|
16
|
+
import parse from 'china-address-parse'
|
|
17
|
+
const toast = useGlobalToast()
|
|
18
|
+
defineOptions({
|
|
19
|
+
name: 'AddAddressPage',
|
|
20
|
+
})
|
|
21
|
+
const props = defineProps<{
|
|
22
|
+
group: any
|
|
23
|
+
}>()
|
|
24
|
+
const model = defineModel<any>()
|
|
25
|
+
const personDetail = ref('')
|
|
26
|
+
const loading = ref(false)
|
|
27
|
+
const form = ref(null)
|
|
28
|
+
/**
|
|
29
|
+
* @description: 智能识别
|
|
30
|
+
*/
|
|
31
|
+
function identifyingFn() {
|
|
32
|
+
if (!personDetail.value) {
|
|
33
|
+
toast.info('请输入内容')
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
const currentValue: any = parse(personDetail.value)
|
|
37
|
+
console.log('智能识别', currentValue)
|
|
38
|
+
if (!currentValue) {
|
|
39
|
+
toast.info('无法识别地址')
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if (!model.value) {
|
|
43
|
+
model.value = {}
|
|
44
|
+
}
|
|
45
|
+
props.group?.fields?.forEach((item: any, index: number) => {
|
|
46
|
+
switch (index) {
|
|
47
|
+
case 0:
|
|
48
|
+
model.value[item.sourceId] = currentValue.name || ''
|
|
49
|
+
break
|
|
50
|
+
case 1:
|
|
51
|
+
model.value[item.sourceId] = currentValue.telNumber || currentValue.phone || ''
|
|
52
|
+
break
|
|
53
|
+
case 2:
|
|
54
|
+
model.value[item.sourceId] = currentValue.provinceName || ''
|
|
55
|
+
break
|
|
56
|
+
case 3:
|
|
57
|
+
model.value[item.sourceId] = currentValue.cityName || ''
|
|
58
|
+
break
|
|
59
|
+
case 4:
|
|
60
|
+
model.value[item.sourceId] = currentValue.countyName || ''
|
|
61
|
+
break
|
|
62
|
+
case 5:
|
|
63
|
+
model.value[item.sourceId] = currentValue.address || ''
|
|
64
|
+
break
|
|
65
|
+
default:
|
|
66
|
+
break
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
console.log('智能识别', currentValue)
|
|
70
|
+
}
|
|
71
|
+
</script>
|
|
72
|
+
|
|
73
|
+
<style scoped>
|
|
74
|
+
.custom-border {
|
|
75
|
+
border-bottom: 0.6px solid #e8e8e8;
|
|
76
|
+
}
|
|
77
|
+
</style>
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, ref, watch } from 'vue'
|
|
3
|
-
import dayjs from 'dayjs/esm/index'
|
|
4
|
-
|
|
5
|
-
defineOptions({
|
|
6
|
-
name: 'CustomDatePicker',
|
|
7
|
-
})
|
|
8
|
-
const props = defineProps({
|
|
9
|
-
modelValue: String,
|
|
10
|
-
placeholder: String,
|
|
11
|
-
columns: {
|
|
12
|
-
type: Array as PropType<SelectOption[]>,
|
|
13
|
-
default: () => [],
|
|
14
|
-
},
|
|
15
|
-
labelKey: { type: String, default: 'label' },
|
|
16
|
-
valueKey: { type: String, default: 'value' },
|
|
17
|
-
type: { type: String, default: 'date' },
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
const emit = defineEmits<{
|
|
21
|
-
'update:modelValue': [value: string | number]
|
|
22
|
-
}>()
|
|
23
|
-
|
|
24
|
-
interface SelectOption {
|
|
25
|
-
label: string
|
|
26
|
-
value: string | number
|
|
27
|
-
[key: string]: any
|
|
28
|
-
}
|
|
29
|
-
const open = ref(false)
|
|
30
|
-
const currentValue = ref<any>(props.modelValue)
|
|
31
|
-
function clear() {
|
|
32
|
-
currentValue.value = ''
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
watch(
|
|
36
|
-
() => props.modelValue,
|
|
37
|
-
val => {
|
|
38
|
-
currentValue.value = val
|
|
39
|
-
}
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
watch(currentValue, val => {
|
|
43
|
-
const newVal = props.type === 'year' ? dayjs(val).format('YYYY') : val
|
|
44
|
-
emit('update:modelValue', newVal)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
const labelText = computed(() => {
|
|
48
|
-
const formatMap: {
|
|
49
|
-
date: string
|
|
50
|
-
datetime: string
|
|
51
|
-
[key: string]: string // 索引签名:允许任意字符串作为键
|
|
52
|
-
} = {
|
|
53
|
-
date: 'YYYY-MM-DD',
|
|
54
|
-
datetime: 'YYYY-MM-DD HH:mm',
|
|
55
|
-
year: 'YYYY',
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (['date', 'datetime', 'year'].includes(props.type)) {
|
|
59
|
-
return currentValue.value ? dayjs(currentValue.value).format(formatMap[props.type] as string) : ''
|
|
60
|
-
} else {
|
|
61
|
-
return currentValue.value || ''
|
|
62
|
-
}
|
|
63
|
-
})
|
|
64
|
-
</script>
|
|
65
|
-
|
|
66
|
-
<template>
|
|
67
|
-
<div class="flex items-center justify-between">
|
|
68
|
-
<wd-input v-model="labelText" readonly :placeholder="placeholder" class="flex-1" @click="open = true" />
|
|
69
|
-
<wd-icon v-if="labelText" name="close-circle" size="16px" @click="clear" />
|
|
70
|
-
<wd-icon v-else name="right" size="16px" @click="clear" />
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<wd-calendar
|
|
74
|
-
v-if="['date', 'datetime'].includes(type)"
|
|
75
|
-
v-model="currentValue"
|
|
76
|
-
v-model:visible="open"
|
|
77
|
-
label-key="label"
|
|
78
|
-
value-key="value"
|
|
79
|
-
class="custom-date-picker"
|
|
80
|
-
:type="type as any"
|
|
81
|
-
/>
|
|
82
|
-
<wd-datetime-picker
|
|
83
|
-
v-else
|
|
84
|
-
v-model="currentValue"
|
|
85
|
-
v-model:visible="open"
|
|
86
|
-
label-key="label"
|
|
87
|
-
value-key="value"
|
|
88
|
-
class="custom-date-picker"
|
|
89
|
-
:type="type as any"
|
|
90
|
-
/>
|
|
91
|
-
</template>
|
|
92
|
-
|
|
93
|
-
<style scoped lang="scss">
|
|
94
|
-
.custom-date-picker {
|
|
95
|
-
width: 100%;
|
|
96
|
-
:deep(.wd-calendar__wrapper) {
|
|
97
|
-
padding: 0 20px;
|
|
98
|
-
overflow: auto;
|
|
99
|
-
scrollbar-width: none;
|
|
100
|
-
-ms-overflow-style: none;
|
|
101
|
-
}
|
|
102
|
-
:deep(.uni-scroll-view) {
|
|
103
|
-
scrollbar-width: none;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import dayjs from 'dayjs/esm/index'
|
|
4
|
+
|
|
5
|
+
defineOptions({
|
|
6
|
+
name: 'CustomDatePicker',
|
|
7
|
+
})
|
|
8
|
+
const props = defineProps({
|
|
9
|
+
modelValue: String,
|
|
10
|
+
placeholder: String,
|
|
11
|
+
columns: {
|
|
12
|
+
type: Array as PropType<SelectOption[]>,
|
|
13
|
+
default: () => [],
|
|
14
|
+
},
|
|
15
|
+
labelKey: { type: String, default: 'label' },
|
|
16
|
+
valueKey: { type: String, default: 'value' },
|
|
17
|
+
type: { type: String, default: 'date' },
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits<{
|
|
21
|
+
'update:modelValue': [value: string | number]
|
|
22
|
+
}>()
|
|
23
|
+
|
|
24
|
+
interface SelectOption {
|
|
25
|
+
label: string
|
|
26
|
+
value: string | number
|
|
27
|
+
[key: string]: any
|
|
28
|
+
}
|
|
29
|
+
const open = ref(false)
|
|
30
|
+
const currentValue = ref<any>(props.modelValue)
|
|
31
|
+
function clear() {
|
|
32
|
+
currentValue.value = ''
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
watch(
|
|
36
|
+
() => props.modelValue,
|
|
37
|
+
val => {
|
|
38
|
+
currentValue.value = val
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
watch(currentValue, val => {
|
|
43
|
+
const newVal = props.type === 'year' ? dayjs(val).format('YYYY') : val
|
|
44
|
+
emit('update:modelValue', newVal)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const labelText = computed(() => {
|
|
48
|
+
const formatMap: {
|
|
49
|
+
date: string
|
|
50
|
+
datetime: string
|
|
51
|
+
[key: string]: string // 索引签名:允许任意字符串作为键
|
|
52
|
+
} = {
|
|
53
|
+
date: 'YYYY-MM-DD',
|
|
54
|
+
datetime: 'YYYY-MM-DD HH:mm',
|
|
55
|
+
year: 'YYYY',
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (['date', 'datetime', 'year'].includes(props.type)) {
|
|
59
|
+
return currentValue.value ? dayjs(currentValue.value).format(formatMap[props.type] as string) : ''
|
|
60
|
+
} else {
|
|
61
|
+
return currentValue.value || ''
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<template>
|
|
67
|
+
<div class="flex items-center justify-between">
|
|
68
|
+
<wd-input v-model="labelText" readonly :placeholder="placeholder" class="flex-1" @click="open = true" />
|
|
69
|
+
<wd-icon v-if="labelText" name="close-circle" size="16px" @click="clear" />
|
|
70
|
+
<wd-icon v-else name="right" size="16px" @click="clear" />
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<wd-calendar
|
|
74
|
+
v-if="['date', 'datetime'].includes(type)"
|
|
75
|
+
v-model="currentValue"
|
|
76
|
+
v-model:visible="open"
|
|
77
|
+
label-key="label"
|
|
78
|
+
value-key="value"
|
|
79
|
+
class="custom-date-picker"
|
|
80
|
+
:type="type as any"
|
|
81
|
+
/>
|
|
82
|
+
<wd-datetime-picker
|
|
83
|
+
v-else
|
|
84
|
+
v-model="currentValue"
|
|
85
|
+
v-model:visible="open"
|
|
86
|
+
label-key="label"
|
|
87
|
+
value-key="value"
|
|
88
|
+
class="custom-date-picker"
|
|
89
|
+
:type="type as any"
|
|
90
|
+
/>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<style scoped lang="scss">
|
|
94
|
+
.custom-date-picker {
|
|
95
|
+
width: 100%;
|
|
96
|
+
:deep(.wd-calendar__wrapper) {
|
|
97
|
+
padding: 0 20px;
|
|
98
|
+
overflow: auto;
|
|
99
|
+
scrollbar-width: none;
|
|
100
|
+
-ms-overflow-style: none;
|
|
101
|
+
}
|
|
102
|
+
:deep(.uni-scroll-view) {
|
|
103
|
+
scrollbar-width: none;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
</style>
|
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, ref, watch } from 'vue'
|
|
3
|
-
|
|
4
|
-
defineOptions({
|
|
5
|
-
name: 'CustomSelectPicker',
|
|
6
|
-
})
|
|
7
|
-
const props = defineProps({
|
|
8
|
-
modelValue: [String, Array],
|
|
9
|
-
placeholder: String,
|
|
10
|
-
columns: {
|
|
11
|
-
type: Array as PropType<SelectOption[]>,
|
|
12
|
-
default: () => [],
|
|
13
|
-
},
|
|
14
|
-
labelKey: { type: String, default: 'label' },
|
|
15
|
-
valueKey: { type: String, default: 'value' },
|
|
16
|
-
type: { type: String, default: 'radio' },
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
const emit = defineEmits<{
|
|
20
|
-
'update:modelValue': [value: string | number]
|
|
21
|
-
}>()
|
|
22
|
-
|
|
23
|
-
interface SelectOption {
|
|
24
|
-
label: string
|
|
25
|
-
value: string | number
|
|
26
|
-
[key: string]: any
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const open = ref(false)
|
|
30
|
-
const currentValue = ref<any>(props.modelValue)
|
|
31
|
-
function clear() {
|
|
32
|
-
currentValue.value = ''
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
watch(
|
|
36
|
-
() => props.modelValue,
|
|
37
|
-
val => {
|
|
38
|
-
console.log('val', val, Array.isArray(val))
|
|
39
|
-
currentValue.value = val
|
|
40
|
-
}
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
watch(currentValue, val => {
|
|
44
|
-
emit('update:modelValue', val)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
const labelText = computed(() => {
|
|
48
|
-
// 多选情况:currentValue 是数组
|
|
49
|
-
if (Array.isArray(currentValue.value)) {
|
|
50
|
-
const labels = currentValue.value
|
|
51
|
-
.map(val => {
|
|
52
|
-
const item = props.columns.find(item => item[props.valueKey] === val)
|
|
53
|
-
return item ? item[props.labelKey] : ''
|
|
54
|
-
})
|
|
55
|
-
.filter(Boolean)
|
|
56
|
-
return labels.join(', ')
|
|
57
|
-
}
|
|
58
|
-
// 单选情况:currentValue 是单个值
|
|
59
|
-
const item = props.columns.find(item => item[props.valueKey] === currentValue.value)
|
|
60
|
-
return item ? item[props.labelKey] : ''
|
|
61
|
-
})
|
|
62
|
-
</script>
|
|
63
|
-
|
|
64
|
-
<template>
|
|
65
|
-
<div class="flex items-center justify-between">
|
|
66
|
-
<wd-input v-model="labelText" readonly :placeholder="placeholder" class="flex-1" @click="open = true" />
|
|
67
|
-
<wd-icon v-if="labelText" name="close-circle" size="16px" @click="clear" />
|
|
68
|
-
<wd-icon v-else name="right" size="16px" @click="clear" />
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
<wd-select-picker
|
|
72
|
-
v-model="currentValue"
|
|
73
|
-
v-model:visible="open"
|
|
74
|
-
:columns="columns"
|
|
75
|
-
label-key="label"
|
|
76
|
-
value-key="value"
|
|
77
|
-
class="custom-select-picker"
|
|
78
|
-
:type="type as any"
|
|
79
|
-
/>
|
|
80
|
-
</template>
|
|
81
|
-
|
|
82
|
-
<style scoped lang="scss">
|
|
83
|
-
.custom-select-picker {
|
|
84
|
-
width: 100%;
|
|
85
|
-
:deep(.wd-select-picker__wrapper) {
|
|
86
|
-
padding: 0 20px;
|
|
87
|
-
overflow: auto;
|
|
88
|
-
scrollbar-width: none;
|
|
89
|
-
-ms-overflow-style: none;
|
|
90
|
-
}
|
|
91
|
-
:deep(.uni-scroll-view) {
|
|
92
|
-
scrollbar-width: none;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, ref, watch } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'CustomSelectPicker',
|
|
6
|
+
})
|
|
7
|
+
const props = defineProps({
|
|
8
|
+
modelValue: [String, Array],
|
|
9
|
+
placeholder: String,
|
|
10
|
+
columns: {
|
|
11
|
+
type: Array as PropType<SelectOption[]>,
|
|
12
|
+
default: () => [],
|
|
13
|
+
},
|
|
14
|
+
labelKey: { type: String, default: 'label' },
|
|
15
|
+
valueKey: { type: String, default: 'value' },
|
|
16
|
+
type: { type: String, default: 'radio' },
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const emit = defineEmits<{
|
|
20
|
+
'update:modelValue': [value: string | number]
|
|
21
|
+
}>()
|
|
22
|
+
|
|
23
|
+
interface SelectOption {
|
|
24
|
+
label: string
|
|
25
|
+
value: string | number
|
|
26
|
+
[key: string]: any
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const open = ref(false)
|
|
30
|
+
const currentValue = ref<any>(props.modelValue)
|
|
31
|
+
function clear() {
|
|
32
|
+
currentValue.value = ''
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
watch(
|
|
36
|
+
() => props.modelValue,
|
|
37
|
+
val => {
|
|
38
|
+
console.log('val', val, Array.isArray(val))
|
|
39
|
+
currentValue.value = val
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
watch(currentValue, val => {
|
|
44
|
+
emit('update:modelValue', val)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
const labelText = computed(() => {
|
|
48
|
+
// 多选情况:currentValue 是数组
|
|
49
|
+
if (Array.isArray(currentValue.value)) {
|
|
50
|
+
const labels = currentValue.value
|
|
51
|
+
.map(val => {
|
|
52
|
+
const item = props.columns.find(item => item[props.valueKey] === val)
|
|
53
|
+
return item ? item[props.labelKey] : ''
|
|
54
|
+
})
|
|
55
|
+
.filter(Boolean)
|
|
56
|
+
return labels.join(', ')
|
|
57
|
+
}
|
|
58
|
+
// 单选情况:currentValue 是单个值
|
|
59
|
+
const item = props.columns.find(item => item[props.valueKey] === currentValue.value)
|
|
60
|
+
return item ? item[props.labelKey] : ''
|
|
61
|
+
})
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
<template>
|
|
65
|
+
<div class="flex items-center justify-between">
|
|
66
|
+
<wd-input v-model="labelText" readonly :placeholder="placeholder" class="flex-1" @click="open = true" />
|
|
67
|
+
<wd-icon v-if="labelText" name="close-circle" size="16px" @click="clear" />
|
|
68
|
+
<wd-icon v-else name="right" size="16px" @click="clear" />
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
<wd-select-picker
|
|
72
|
+
v-model="currentValue"
|
|
73
|
+
v-model:visible="open"
|
|
74
|
+
:columns="columns"
|
|
75
|
+
label-key="label"
|
|
76
|
+
value-key="value"
|
|
77
|
+
class="custom-select-picker"
|
|
78
|
+
:type="type as any"
|
|
79
|
+
/>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<style scoped lang="scss">
|
|
83
|
+
.custom-select-picker {
|
|
84
|
+
width: 100%;
|
|
85
|
+
:deep(.wd-select-picker__wrapper) {
|
|
86
|
+
padding: 0 20px;
|
|
87
|
+
overflow: auto;
|
|
88
|
+
scrollbar-width: none;
|
|
89
|
+
-ms-overflow-style: none;
|
|
90
|
+
}
|
|
91
|
+
:deep(.uni-scroll-view) {
|
|
92
|
+
scrollbar-width: none;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { computed, defineOptions, defineProps } from 'vue'
|
|
3
|
-
|
|
4
|
-
defineOptions({
|
|
5
|
-
name: 'DemoBlock',
|
|
6
|
-
})
|
|
7
|
-
|
|
8
|
-
const props = defineProps({
|
|
9
|
-
// 标题
|
|
10
|
-
title: {
|
|
11
|
-
type: String,
|
|
12
|
-
default: '',
|
|
13
|
-
},
|
|
14
|
-
// 自定义类名
|
|
15
|
-
customClass: {
|
|
16
|
-
type: String,
|
|
17
|
-
default: '',
|
|
18
|
-
},
|
|
19
|
-
// 垂直间距
|
|
20
|
-
ver: {
|
|
21
|
-
type: [Number, String],
|
|
22
|
-
default: 10,
|
|
23
|
-
},
|
|
24
|
-
// 水平间距
|
|
25
|
-
hor: {
|
|
26
|
-
type: [Number, String],
|
|
27
|
-
default: 15,
|
|
28
|
-
},
|
|
29
|
-
// 是否透明
|
|
30
|
-
transparent: {
|
|
31
|
-
type: Boolean,
|
|
32
|
-
default: false,
|
|
33
|
-
},
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
const style = computed(() => {
|
|
37
|
-
return `margin: 0 ${props.hor}px;padding:${props.ver}px 0;`
|
|
38
|
-
})
|
|
39
|
-
</script>
|
|
40
|
-
|
|
41
|
-
<script lang="ts">
|
|
42
|
-
export default {
|
|
43
|
-
options: {
|
|
44
|
-
addGlobalClass: true,
|
|
45
|
-
virtualHost: true,
|
|
46
|
-
styleIsolation: 'shared',
|
|
47
|
-
},
|
|
48
|
-
}
|
|
49
|
-
</script>
|
|
50
|
-
|
|
51
|
-
<template>
|
|
52
|
-
<view
|
|
53
|
-
class="mb-3 box-border w-full px-3 text-gray-500 last:mb-0 dark:text-gray-300"
|
|
54
|
-
:class="[transparent ? '' : 'bg-white dark:bg-[var(--wot-dark-background2)]', customClass]"
|
|
55
|
-
>
|
|
56
|
-
<view v-if="title" class="px-4 py-3 text-26rpx dark:text-gray-200">
|
|
57
|
-
{{ title }}
|
|
58
|
-
</view>
|
|
59
|
-
<view :style="transparent ? '' : style">
|
|
60
|
-
<slot />
|
|
61
|
-
</view>
|
|
62
|
-
</view>
|
|
63
|
-
</template>
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed, defineOptions, defineProps } from 'vue'
|
|
3
|
+
|
|
4
|
+
defineOptions({
|
|
5
|
+
name: 'DemoBlock',
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
const props = defineProps({
|
|
9
|
+
// 标题
|
|
10
|
+
title: {
|
|
11
|
+
type: String,
|
|
12
|
+
default: '',
|
|
13
|
+
},
|
|
14
|
+
// 自定义类名
|
|
15
|
+
customClass: {
|
|
16
|
+
type: String,
|
|
17
|
+
default: '',
|
|
18
|
+
},
|
|
19
|
+
// 垂直间距
|
|
20
|
+
ver: {
|
|
21
|
+
type: [Number, String],
|
|
22
|
+
default: 10,
|
|
23
|
+
},
|
|
24
|
+
// 水平间距
|
|
25
|
+
hor: {
|
|
26
|
+
type: [Number, String],
|
|
27
|
+
default: 15,
|
|
28
|
+
},
|
|
29
|
+
// 是否透明
|
|
30
|
+
transparent: {
|
|
31
|
+
type: Boolean,
|
|
32
|
+
default: false,
|
|
33
|
+
},
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const style = computed(() => {
|
|
37
|
+
return `margin: 0 ${props.hor}px;padding:${props.ver}px 0;`
|
|
38
|
+
})
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<script lang="ts">
|
|
42
|
+
export default {
|
|
43
|
+
options: {
|
|
44
|
+
addGlobalClass: true,
|
|
45
|
+
virtualHost: true,
|
|
46
|
+
styleIsolation: 'shared',
|
|
47
|
+
},
|
|
48
|
+
}
|
|
49
|
+
</script>
|
|
50
|
+
|
|
51
|
+
<template>
|
|
52
|
+
<view
|
|
53
|
+
class="mb-3 box-border w-full px-3 text-gray-500 last:mb-0 dark:text-gray-300"
|
|
54
|
+
:class="[transparent ? '' : 'bg-white dark:bg-[var(--wot-dark-background2)]', customClass]"
|
|
55
|
+
>
|
|
56
|
+
<view v-if="title" class="px-4 py-3 text-26rpx dark:text-gray-200">
|
|
57
|
+
{{ title }}
|
|
58
|
+
</view>
|
|
59
|
+
<view :style="transparent ? '' : style">
|
|
60
|
+
<slot />
|
|
61
|
+
</view>
|
|
62
|
+
</view>
|
|
63
|
+
</template>
|