811 lines
20 KiB
Vue
811 lines
20 KiB
Vue
<template>
|
|
<view :class="['select-list', { disabled }, { active: selectList.length }]" @click="open">
|
|
<view class="left">
|
|
<view v-if="selectList.length" class="select-items">
|
|
<view class="select-item" v-for="item in selectedListBaseinfo" :key="item[dataValue]">
|
|
<view class="name">
|
|
<text>{{ item[dataLabel] }}</text>
|
|
</view>
|
|
<view v-if="!disabled && !item.disabled && deleteSource" class="close"
|
|
@click.stop="removeSelectedItem(item)">
|
|
<uni-icons type="closeempty" size="16" color="#999"></uni-icons>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view v-else class="no-data">
|
|
<text>{{ placeholder }}</text>
|
|
</view>
|
|
</view>
|
|
<view>
|
|
<uni-icons v-if="!selectList.length || !clearable" type="bottom" color="#333333"></uni-icons>
|
|
<view @click.stop>
|
|
<uni-icons v-if="selectList.length && clearable" type="clear" size="24" color="#c0c4cc"
|
|
@click="clearSelectList"></uni-icons>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<uni-popup ref="popup" :animation="animation" :is-mask-click="isMaskClick"
|
|
:mask-background-color="maskBackgroundColor" :background-color="backgroundColor" :safe-area="safeArea"
|
|
type="bottom" @change="change" @maskClick="maskClick">
|
|
<view class="popup-content" :style="{ height: contentHeight }">
|
|
<view class="title">
|
|
<view v-if="mutiple && canSelectAll" class="left" @click="handleSelectAll">
|
|
<text>{{ isSelectedAll ? '取消全选' : '全选' }}</text>
|
|
</view>
|
|
<view class="center">
|
|
<text>{{ placeholder }}</text>
|
|
</view>
|
|
<view class="right" :style="{ color: confirmTextColor }" @click="close">
|
|
<text>{{ confirmText }}</text>
|
|
</view>
|
|
</view>
|
|
<view v-if="search" class="search-box">
|
|
<uni-easyinput :maxlength="-1" prefixIcon="search" placeholder="搜索" v-model="searchStr"
|
|
confirm-type="search" @confirm="handleSearch(false)" @clear="handleSearch(true)">
|
|
</uni-easyinput>
|
|
<button type="primary" size="mini" class="search-btn" @click="handleSearch(false)">搜索</button>
|
|
</view>
|
|
<view v-if="treeData.length" class="select-content">
|
|
<scroll-view class="scroll-view-box" :scroll-top="scrollTop" scroll-y="true" @touchmove.stop>
|
|
<view v-if="!filterTreeData.length" class="no-data center">
|
|
<text>暂无数据</text>
|
|
</view>
|
|
<data-select-item v-for="item in filterTreeData" :key="item[dataValue]" :node="item"
|
|
:dataLabel="dataLabel" :dataValue="dataValue" :dataChildren="dataChildren"
|
|
:choseParent="choseParent" :border="border" :linkage="linkage"
|
|
:lazyLoadChildren="lazyLoadChildren"></data-select-item>
|
|
<view class="sentry" />
|
|
</scroll-view>
|
|
</view>
|
|
<view v-else class="no-data center">
|
|
<text>暂无数据</text>
|
|
</view>
|
|
</view>
|
|
</uni-popup>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { ref, computed, watch, onMounted, nextTick, provide } from 'vue'
|
|
import dataSelectItem from './data-select-item.vue';
|
|
import { isString, paging } from './utils';
|
|
const props = defineProps({
|
|
canSelectAll: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
safeArea: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
search: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
clearResetSearch: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
animation: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
'is-mask-click': {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
'mask-background-color': {
|
|
type: String,
|
|
default: 'rgba(0,0,0,0.4)'
|
|
},
|
|
'background-color': {
|
|
type: String,
|
|
default: 'none'
|
|
},
|
|
'safe-area': {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
choseParent: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
placeholder: {
|
|
type: String,
|
|
default: '请选择'
|
|
},
|
|
confirmText: {
|
|
type: String,
|
|
default: '确认'
|
|
},
|
|
confirmTextColor: {
|
|
type: String,
|
|
default: '#007aff'
|
|
},
|
|
dataSource: {
|
|
type: Array,
|
|
default: () => []
|
|
},
|
|
dataLabel: {
|
|
type: String,
|
|
default: 'name'
|
|
},
|
|
dataValue: {
|
|
type: String,
|
|
default: 'id'
|
|
},
|
|
dataChildren: {
|
|
type: String,
|
|
default: 'children'
|
|
},
|
|
linkage: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
removeLinkage: {
|
|
type: Boolean,
|
|
default: true
|
|
},
|
|
clearable: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
mutiple: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
deleteSource: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
showChildren: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
border: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
lazyLoadChildren: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
load: {
|
|
type: Function,
|
|
default: function () { }
|
|
},
|
|
modelValue: {
|
|
type: [Array, String],
|
|
default: () => []
|
|
}
|
|
})
|
|
|
|
const emits = defineEmits(['update:modelValue', 'change', 'maskClick', 'select-change', 'removeSelect'])
|
|
|
|
const contentHeight = ref('500px')
|
|
const treeData = ref([])
|
|
const filterTreeData = ref([])
|
|
const clearTimerList = ref([])
|
|
const selectedListBaseinfo = ref([])
|
|
const showPopup = ref(false)
|
|
const isSelectedAll = ref(false)
|
|
const scrollTop = ref(0)
|
|
const searchStr = ref('')
|
|
const popup = ref<any>(null)
|
|
|
|
const partCheckedSet = new Set()
|
|
|
|
provide('nodeFn', {
|
|
nodeClick: handleNodeClick,
|
|
nameClick: handleHideChildren,
|
|
loadNode: props.load,
|
|
initData: initData,
|
|
addNode: addNode
|
|
})
|
|
|
|
const selectList = computed(() => {
|
|
const newVal = props.modelValue === null ? '' : props.modelValue
|
|
return isString(newVal) ? (newVal.length ? newVal.split(',') : []) : newVal.map((item : any) => item.toString())
|
|
})
|
|
|
|
onMounted(() => {
|
|
getContentHeight(uni.getSystemInfoSync())
|
|
})
|
|
|
|
function getContentHeight({ screenHeight } : { screenHeight : number }) {
|
|
contentHeight.value = `${Math.floor(screenHeight * 0.7)}px`
|
|
}
|
|
|
|
watch(
|
|
() => props.dataSource,
|
|
(newVal : any[]) => {
|
|
if (newVal) {
|
|
treeData.value = initData(newVal)
|
|
if (showPopup.value) {
|
|
resetClearTimerList()
|
|
renderTree(treeData.value)
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true, deep: true }
|
|
)
|
|
|
|
watch(
|
|
() => props.modelValue,
|
|
(newVal : any[] | string) => {
|
|
const ids = newVal ? (Array.isArray(newVal) ? newVal : newVal.split(',')) : []
|
|
changeStatus(treeData.value, ids, true)
|
|
filterTreeData.value.length && changeStatus(filterTreeData.value, ids)
|
|
},
|
|
{ immediate: true }
|
|
)
|
|
|
|
// 搜索完成返回顶部
|
|
function goTop() {
|
|
scrollTop.val = 10
|
|
nextTick(() => {
|
|
scrollTop.value = 0
|
|
})
|
|
}
|
|
|
|
// 处理搜索
|
|
function handleSearch(isClear = false) {
|
|
resetClearTimerList()
|
|
if (isClear) {
|
|
// 点击清空按钮并且设置清空按钮会重置搜索
|
|
if (props.clearResetSearch) {
|
|
renderTree(treeData.value)
|
|
}
|
|
} else {
|
|
renderTree(searchValue(searchStr.value, treeData.value))
|
|
}
|
|
goTop()
|
|
uni.hideKeyboard()
|
|
}
|
|
|
|
// 具体搜索方法
|
|
function searchValue(str : any, arr : any[]) {
|
|
const res : any = []
|
|
arr.forEach((item) => {
|
|
if (item.visible) {
|
|
if (item[props.dataLabel].toString().toLowerCase().indexOf(str.toLowerCase()) > -1) {
|
|
res.push(item)
|
|
} else {
|
|
if (item[props.dataChildren]?.length) {
|
|
const data = searchValue(str, item[props.dataChildren])
|
|
if (data?.length) {
|
|
if (str && !item.showChildren && item[props.dataChildren]?.length) {
|
|
item.showChildren = true
|
|
}
|
|
res.push({
|
|
...item,
|
|
[props.dataChildren]: data
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
})
|
|
return res
|
|
}
|
|
|
|
// 打开弹窗
|
|
async function open() {
|
|
// disaled模式下禁止打开弹窗
|
|
if (props.disabled) return
|
|
showPopup.value = true
|
|
popup.value.open()
|
|
renderTree(treeData.value)
|
|
}
|
|
|
|
// 关闭弹窗
|
|
function close() {
|
|
popup.value.close()
|
|
}
|
|
|
|
// 弹窗状态变化 包括点击回显框和遮罩
|
|
function change(data : any) {
|
|
if (!data.show) {
|
|
resetClearTimerList()
|
|
searchStr.value = ''
|
|
showPopup.value = false
|
|
}
|
|
emits('change', data)
|
|
}
|
|
|
|
// 点击遮罩
|
|
function maskClick() {
|
|
emits('maskClick')
|
|
}
|
|
|
|
// 初始化数据
|
|
function initData(arr : any[], parentVisible ?: undefined | boolean) {
|
|
if (!Array.isArray(arr)) return []
|
|
const res = []
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
const obj : any = {
|
|
[props.dataLabel]: arr[i][props.dataLabel],
|
|
[props.dataValue]: arr[i][props.dataValue]
|
|
}
|
|
|
|
obj.checked = selectList.value.includes(arr[i][props.dataValue].toString())
|
|
|
|
obj.disabled = Boolean(arr[i].disabled)
|
|
|
|
//半选
|
|
obj.partChecked = Boolean(arr[i].partChecked === undefined ? false : arr[i].partChecked)
|
|
obj.partChecked && obj.partCheckedSet.add(obj[props.dataValue])
|
|
!obj.partChecked && (isSelectedAll.value = false)
|
|
|
|
const parentVisibleState = parentVisible === undefined ? true : parentVisible
|
|
const curVisibleState = arr[i].visible === undefined ? true : Boolean(arr[i].visible)
|
|
if (parentVisibleState === curVisibleState) {
|
|
obj.visible = parentVisibleState
|
|
} else if (!parentVisibleState || !curVisibleState) {
|
|
obj.visible = false
|
|
} else {
|
|
obj.visible = true
|
|
}
|
|
|
|
obj.showChildren =
|
|
'showChildren' in arr[i] && arr[i].showChildren != undefined ? arr[i].showChildren : props.showChildren
|
|
|
|
if (arr[i].visible && !arr[i].disabled && !arr[i].checked) {
|
|
isSelectedAll.value = false
|
|
}
|
|
|
|
if (arr[i][props.dataChildren]?.length) {
|
|
obj[props.dataChildren] = initData(arr[i][props.dataChildren], obj.visible)
|
|
}
|
|
|
|
res.push(obj)
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
function addNode(node : any, children : any[]) {
|
|
getReflectNode(node, treeData.value)[props.dataChildren] = children
|
|
handleHideChildren(node)
|
|
}
|
|
|
|
// 中断懒加载
|
|
function resetClearTimerList() {
|
|
const list = [...clearTimerList.value]
|
|
clearTimerList.value = []
|
|
list.forEach((fn) => fn())
|
|
}
|
|
|
|
// 懒加载
|
|
function renderTree(arr : any[]) {
|
|
const pagingArr = paging(arr)
|
|
filterTreeData.value = pagingArr?.[0] || []
|
|
lazyRenderList(pagingArr, 1)
|
|
}
|
|
|
|
// 懒加载具体逻辑
|
|
function lazyRenderList(arr : any[], startIndex : number) {
|
|
for (let i = startIndex; i < arr.length; i++) {
|
|
let timer : any = null
|
|
timer = setTimeout(() => {
|
|
filterTreeData.value.push(...arr[i])
|
|
}, i * 500)
|
|
clearTimerList.push(() => clearTimeout(timer))
|
|
}
|
|
}
|
|
|
|
// 根据 dataValue 找节点
|
|
function changeStatus(list : any[], ids : any[] | string, needEmit = false) {
|
|
const arr = [...list]
|
|
let flag = true
|
|
needEmit && (selectedListBaseinfo.value = [])
|
|
while (arr.length) {
|
|
const item = arr.shift()
|
|
|
|
if (ids.includes(item[props.dataValue].toString())) {
|
|
item.checked = true
|
|
// 数据被选中清除半选状态
|
|
item.partChecked = false
|
|
partCheckedSet.delete(item[props.dataValue])
|
|
needEmit && selectedListBaseinfo.value.push(item)
|
|
} else {
|
|
item.checked = false
|
|
if (item.visible && !item.disabled) {
|
|
flag = false
|
|
}
|
|
if (partCheckedSet.has(item[props.dataValue])) {
|
|
// filtertreedata 更新状态
|
|
item.partChecked = true
|
|
} else {
|
|
item.partChecked = false
|
|
}
|
|
}
|
|
|
|
if (item[props.dataChildren]?.length) {
|
|
arr.push(...item[props.dataChildren])
|
|
}
|
|
}
|
|
isSelectedAll.value = flag
|
|
|
|
needEmit && emits('select-change', [...selectedListBaseinfo.value])
|
|
}
|
|
|
|
// 移除选项
|
|
function removeSelectedItem(node : any) {
|
|
isSelectedAll.value = false
|
|
if (props.linkage) {
|
|
handleNodeClick(node, false)
|
|
emits('removeSelect', node)
|
|
} else {
|
|
const emitData = selectList.value.filter((item : any) => item !== node[props.dataValue].toString())
|
|
emits('removeSelect', node)
|
|
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
|
}
|
|
}
|
|
|
|
// 获取对应数据
|
|
function getReflectNode(node : any, arr : any[]) {
|
|
const array = [...arr]
|
|
while (array.length) {
|
|
const item = array.shift()
|
|
if (item[props.dataValue] === node[props.dataValue]) {
|
|
return item
|
|
}
|
|
if (item[props.dataChildren]?.length) {
|
|
array.push(...item[props.dataChildren])
|
|
}
|
|
}
|
|
return {}
|
|
}
|
|
|
|
// 获取某个节点孩子节点
|
|
function getChildren(node : any) {
|
|
if (!node[props.dataChildren]?.length) return []
|
|
const res = node[props.dataChildren].reduce((pre : any, val : any) => {
|
|
if (val.visible) {
|
|
return [...pre, val]
|
|
}
|
|
return pre
|
|
}, [])
|
|
for (let i = 0; i < node[props.dataChildren].length; i++) {
|
|
res.push(...getChildren(node[props.dataChildren][i]))
|
|
}
|
|
return res
|
|
}
|
|
|
|
// 获取某个节点祖先元素
|
|
function getParentNode(target : any, arr : any[]) {
|
|
let res : any[] = []
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
if (arr[i][props.dataValue] === target[props.dataValue]) {
|
|
return true
|
|
}
|
|
|
|
if (arr[i][props.dataChildren]?.length) {
|
|
const childRes = getParentNode(target, arr[i][props.dataChildren])
|
|
if (typeof childRes === 'boolean' && childRes) {
|
|
res = [arr[i]]
|
|
} else if (Array.isArray(childRes) && childRes.length) {
|
|
res = [...childRes, arr[i]]
|
|
}
|
|
}
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
// 点击checkbox
|
|
function handleNodeClick(data : any, status : boolean | undefined) {
|
|
const node = getReflectNode(data, treeData.value)
|
|
node.checked = typeof status === 'boolean' ? status : !node.checked
|
|
node.partChecked = false
|
|
partCheckedSet.delete(node[props.dataValue])
|
|
// 如果是单选不考虑其他情况
|
|
if (!props.mutiple) {
|
|
let emitData : any[] = []
|
|
if (node.checked) {
|
|
emitData = [node[props.dataValue].toString()]
|
|
}
|
|
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
|
} else {
|
|
// 多选情况
|
|
if (!props.linkage) {
|
|
// 不需要联动
|
|
let emitData = null
|
|
if (node.checked) {
|
|
emitData = Array.from(new Set([...selectList.value, node[props.dataValue].toString()]))
|
|
} else {
|
|
emitData = selectList.value.filter((id : number | string) => id !== node[props.dataValue].toString())
|
|
}
|
|
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
|
} else {
|
|
// 需要联动
|
|
let emitData = [...selectList.value]
|
|
const parentNodes : any = getParentNode(node, treeData.value)
|
|
const childrenVal = getChildren(node).filter((item : any) => !item.disabled)
|
|
if (node.checked) {
|
|
// 选中
|
|
emitData = Array.from(new Set([...emitData, node[props.dataValue].toString()]))
|
|
if (childrenVal.length) {
|
|
emitData = Array.from(
|
|
new Set([...emitData, ...childrenVal.map((item : any) => item[props.dataValue].toString())])
|
|
)
|
|
// 孩子节点全部选中并且清除半选状态
|
|
childrenVal.forEach((childNode : any) => {
|
|
childNode.partChecked = false
|
|
partCheckedSet.delete(childNode[props.dataValue])
|
|
})
|
|
}
|
|
if (parentNodes.length) {
|
|
let flag = false
|
|
// 有父元素 如果父元素下所有子元素全部选中,选中父元素
|
|
while (parentNodes.length) {
|
|
const item = parentNodes.shift()
|
|
if (!item.disabled) {
|
|
if (flag) {
|
|
// 前一个没选中并且为半选那么之后的全为半选
|
|
item.partChecked = true
|
|
partCheckedSet.add(item[props.dataValue])
|
|
} else {
|
|
const allChecked = item[props.dataChildren]
|
|
.filter((node : any) => node.visible && !node.disabled)
|
|
.every((node : any) => node.checked)
|
|
if (allChecked) {
|
|
item.checked = true
|
|
item.partChecked = false
|
|
partCheckedSet.delete(item[props.dataValue])
|
|
emitData = Array.from(new Set([...emitData, item[props.dataValue].toString()]))
|
|
} else {
|
|
item.partChecked = true
|
|
partCheckedSet.add(item[props.dataValue])
|
|
flag = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// 取消选中
|
|
emitData = emitData.filter((id) => id !== node[props.dataValue].toString())
|
|
if (childrenVal.length) {
|
|
// 取消选中全部子节点
|
|
childrenVal.forEach((childNode : any) => {
|
|
emitData = emitData.filter((id) => id !== childNode[props.dataValue].toString())
|
|
})
|
|
}
|
|
if (parentNodes.length) {
|
|
parentNodes.forEach((parentNode : any) => {
|
|
if (emitData.includes(parentNode[props.dataValue].toString())) {
|
|
parentNode.checked = false
|
|
}
|
|
emitData = emitData.filter((id) => id !== parentNode[props.dataValue].toString())
|
|
const hasChecked = parentNode[props.dataChildren]
|
|
.filter((node : any) => node.visible && !node.disabled)
|
|
.some((node : any) => node.checked || node.partChecked)
|
|
|
|
parentNode.partChecked = hasChecked
|
|
if (hasChecked) {
|
|
partCheckedSet.add(parentNode[props.dataValue])
|
|
} else {
|
|
partCheckedSet.delete(parentNode[props.dataValue])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 点击名称折叠或展开
|
|
function handleHideChildren(node : any) {
|
|
const status = !node.showChildren
|
|
getReflectNode(node, treeData.value).showChildren = status
|
|
getReflectNode(node, filterTreeData.value).showChildren = status
|
|
}
|
|
|
|
// 全部选中
|
|
function handleSelectAll() {
|
|
isSelectedAll.value = !isSelectedAll.value
|
|
if (isSelectedAll.value) {
|
|
if (!props.mutiple) {
|
|
uni.showToast({
|
|
title: '单选模式下不能全选',
|
|
icon: 'none',
|
|
duration: 1000
|
|
})
|
|
return
|
|
}
|
|
let emitData : any[] = []
|
|
treeData.value.forEach((item : any) => {
|
|
if (item.visible || (item.disabled && item.checked)) {
|
|
emitData = Array.from(new Set([...emitData, item[props.dataValue].toString()]))
|
|
if (item[props.dataChildren]?.length) {
|
|
emitData = Array.from(
|
|
new Set([
|
|
...emitData,
|
|
...getChildren(item)
|
|
.filter((item : any) => !item.disabled || (item.disabled && item.checked))
|
|
.map((item : any) => item[props.dataValue].toString())
|
|
])
|
|
)
|
|
}
|
|
}
|
|
})
|
|
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
|
} else {
|
|
clearSelectList()
|
|
}
|
|
}
|
|
// 清空选项
|
|
function clearSelectList() {
|
|
if (props.disabled) return
|
|
partCheckedSet.clear()
|
|
const emitData : any[] = []
|
|
selectedListBaseinfo.value.forEach((node : any) => {
|
|
if (node.visible && node.checked && node.disabled) {
|
|
emitData.push(node[props.dataValue])
|
|
}
|
|
})
|
|
emits('update:modelValue', isString(props.modelValue) ? emitData.join(',') : emitData)
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
$primary-color: #007aff;
|
|
$col-sm: 4px;
|
|
$col-base: 8px;
|
|
$col-lg: 12px;
|
|
$row-sm: 5px;
|
|
$row-base: 10px;
|
|
$row-lg: 15px;
|
|
$radius-sm: 3px;
|
|
$radius-base: 6px;
|
|
|
|
.select-list {
|
|
padding-left: $row-base;
|
|
min-height: 35px;
|
|
// border: 1px solid #e5e5e5;
|
|
// border-radius: $radius-sm;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
|
|
&.active {
|
|
padding: calc(#{$col-sm} / 2) 0 calc(#{$col-sm} / 2) $row-base;
|
|
}
|
|
|
|
.left {
|
|
flex: 1;
|
|
|
|
.select-items {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.select-item {
|
|
max-width: auto;
|
|
height: auto;
|
|
// background-color: #eaeaea;
|
|
// border-radius: $radius-sm;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.name {
|
|
flex: 1;
|
|
// padding-right: $row-base;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.close {
|
|
width: 18px;
|
|
height: 18px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
overflow: hidden;
|
|
}
|
|
}
|
|
}
|
|
|
|
// .right {
|
|
// margin-right: $row-sm;
|
|
// display: flex;
|
|
// justify-content: flex-end;
|
|
// align-items: center;
|
|
// }
|
|
|
|
&.disabled {
|
|
background-color: #f5f7fa;
|
|
|
|
.left {
|
|
.select-item {
|
|
.name {
|
|
padding: 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.popup-content {
|
|
flex: 1;
|
|
background-color: #fff;
|
|
border-top-left-radius: 20px;
|
|
border-top-right-radius: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.title {
|
|
padding: $col-base 3rem;
|
|
border-bottom: 1px solid $uni-border-color;
|
|
font-size: 14px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
position: relative;
|
|
|
|
.left {
|
|
position: absolute;
|
|
left: 10px;
|
|
}
|
|
|
|
.center {
|
|
flex: 1;
|
|
text-align: center;
|
|
}
|
|
|
|
.right {
|
|
position: absolute;
|
|
right: 10px;
|
|
}
|
|
}
|
|
|
|
.search-box {
|
|
margin: $col-base $row-base 0;
|
|
background-color: #fff;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.search-btn {
|
|
margin-left: $row-base;
|
|
height: 35px;
|
|
line-height: 35px;
|
|
}
|
|
}
|
|
|
|
.select-content {
|
|
margin: $col-base $row-base;
|
|
flex: 1;
|
|
overflow: hidden;
|
|
position: relative;
|
|
}
|
|
|
|
.scroll-view-box {
|
|
touch-action: none;
|
|
flex: 1;
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
left: 0;
|
|
}
|
|
|
|
.sentry {
|
|
height: 48px;
|
|
}
|
|
}
|
|
|
|
.no-data {
|
|
font-size: 28rpx;
|
|
color: #999999;
|
|
}
|
|
|
|
// .no-data.center {
|
|
// text-align: center;
|
|
// }
|
|
</style> |