jy-safe-app/components/custom/query-selector.vue

226 lines
4.5 KiB
Vue
Raw Permalink Normal View History

2025-10-14 15:17:30 +08:00
<template>
<view class="auto-complete">
<u-popup
:show="show"
:round="10"
mode="bottom"
:closeable="true"
:closeIconPos="multiple ? 'top-left' : 'top-right'"
@open="onOpen"
@close="handleClosePopup">
<u--text
v-if="multiple"
text="确定"
type="primary"
bold
class="ok-button"
size="16"
@click="handleOk"
></u--text>
<u-list
@scrolltolower="scrolltolower"
:pagingEnabled="true"
>
<view class="head">
<view class="title">{{title}}</view>
</view>
<view class="search" style="padding-top: 6px">
<u-search
v-model="searchValue"
@search="handleSearch"
@custom="handleSearch"
:clearabled="true">
</u-search>
</view>
<view v-if="multiple" class="multi-checkbox" @click.stop="">
<u-checkbox-group
placement="column"
@onchange="onCheckboxChange"
>
<u-checkbox
:customStyle="checkboxStyle"
v-for="(item, index) in indexList"
:key="index"
:label="item.NAME"
:name="item.ID"
:checked="multipleSelect.map(i => i.ID).includes(item.ID)"
>
</u-checkbox>
</u-checkbox-group>
</view>
<u-list-item
v-else
v-for="(item, index) in indexList"
:key="index"
class="single-select"
>
<view @click="handleSelected(item)">
<u-cell
:title="`${item.name}`"
>
<text v-if="item.code" slot="right-icon">{{item.code}}</text>
</u-cell>
</view>
</u-list-item>
</u-list>
</u-popup>
</view>
</template>
<script>
import UText from '../../uni_modules/uview-ui/components/u-text/u-text.vue'
export default {
components: { UText },
props: {
show: {
type: Boolean,
default: false,
required: true
},
multiple: {
type: Boolean,
default: false
},
lists: {
type: Array,
default() {
return undefined
}
},
defaultValue: {
type: String,
default: null
},
defaultChecked: {
type: Array,
default() {
return []
}
},
title:{
type: String,
default: ''
},
total:{
type: Number,
default: 0
}
},
data() {
return {
searchValue: '',
indexList: [],
pageIndex: 1,
multipleSelect: [],
checkboxStyle: {
marginBottom: '8px',
padding: '10px 0',
borderBottom: '1px solid #e5e5e5'
}
}
},
methods: {
onCheckboxChange(e) {
if (e.checked) {
const obj = this.indexList.filter(i => i.ID === e.id)[0]
this.multipleSelect.push(obj)
} else {
this.multipleSelect.forEach(item => {
if (e.id === item.ID) {
this.multipleSelect = this.multipleSelect.filter(i => i.ID !== e.id)
}
})
}
},
onOpen() {
this.pageIndex = 1
if (this.defaultValue) {
this.searchValue = this.defaultValue
this.handleSearch(this.defaultValue)
} else {
this.searchValue = ''
// this.indexList = this.lists
}
this.multipleSelect = this.defaultChecked
},
handleClosePopup() {
this.searchValue = ''
this.indexList = []
this.multipleSelect = []
this.$emit('close')
},
handleSearch(val) {
this.searchValue = val
this.indexList = []
this.$emit('search', val, 1)
},
handleSelected(val) {
this.searchValue = ''
this.indexList = []
this.multipleSelect = []
this.$emit('select', val)
},
handleOk() {
this.searchValue = ''
this.indexList = []
this.$emit('select', this.multipleSelect)
},
scrolltolower() {
if (this.total > this.pageIndex * 20) {
this.pageIndex++
this.$emit('search', this.searchValue, this.pageIndex)
}
}
},
watch: {
lists(newLists) {
this.indexList = this.indexList.concat(newLists)
}
}
}
</script>
<style scoped>
.head {
height: 46px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.head .cancel,
.head .ok {
font-size: 15px;
padding: 0 15px;
}
.head .cancel {
color: rgb(144, 145, 147);
}
.head .ok {
color: rgb(60, 156, 255)
}
.head .title {
color: #303133;
padding: 0 22px;
font-size: 16px;
flex: 1;
text-align: center;
}
.search {
padding: 0 10px;
}
.multi-checkbox {
padding: 16px;
}
.single-select {
margin-right: 16px;
margin-left: 16px
}
.ok-button {
position: absolute;
top: 15px;
right: 15px;
width: max-content;
z-index: 10;
}
</style>