222 lines
4.7 KiB
Vue
222 lines
4.7 KiB
Vue
<template>
|
|
<view>
|
|
|
|
<view class="box" @click.stop="openPopup">
|
|
<text class="u-font-28 color-999 u-p-r-16" v-if="!modelValue||list.length==0">请选择用户</text>
|
|
<text class="u-font-28 color-333 u-p-r-16 u-line-1" v-else :style="{
|
|
maxWidth: maxWidth+'rpx'
|
|
}">{{returnLabel()}}</text>
|
|
<view class="icon ">
|
|
<up-icon name="arrow-down" size="14" color="#999"></up-icon>
|
|
</view>
|
|
</view>
|
|
<up-popup :show="show" placement="bottom" round="18rpx" closeOnClickOverlay @close="close">
|
|
<view class="u-p-30">
|
|
<view class="font-bold color-333 u-font-32">选择用户</view>
|
|
<view class="u-m-t-24">
|
|
<up-search v-model="query.key" @clear="search" @custom="search" @search="search"></up-search>
|
|
</view>
|
|
<scroll-view scroll-with-animation :scroll-into-view="selId" class="scroll-view u-m-t-30"
|
|
scroll-y="true" style="max-height :60vh;" @scrolltolower="scrolltolower">
|
|
<view class="u-m-b-10 u-flex item" v-for="item in list" :key="item.id" @click="itemClick(item)"
|
|
:id="'item_'+item.id" :class="{active:selItem&&selItem.id==item.id}">
|
|
<view class="checkbox">
|
|
<up-icon name="checkbox-mark" color="#fff"></up-icon>
|
|
</view>
|
|
<view class="u-flex-1">{{item.nickName}}/{{item.phone}}</view>
|
|
</view>
|
|
<template v-if="search.key!==''">
|
|
<up-empty v-if="list.length==0" text="未搜到相关用户"></up-empty>
|
|
<up-loadmore v-else :status="isEnd?'nomore':'loading'"></up-loadmore>
|
|
</template>
|
|
<template v-else>
|
|
<up-empty v-if="list.length==0" text="暂无用户"></up-empty>
|
|
<up-loadmore v-else :status="isEnd?'nomore':'loading'"></up-loadmore>
|
|
</template>
|
|
</scroll-view>
|
|
<view class="u-flex gap-20 u-m-t-30">
|
|
<view class="u-flex-1">
|
|
<my-button type="default" @click="close">取消</my-button>
|
|
</view>
|
|
<view class="u-flex-1">
|
|
<my-button type="primary" @click="submit">确定</my-button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</up-popup>
|
|
</view>
|
|
</template>
|
|
<script setup>
|
|
import {
|
|
computed,
|
|
onMounted,
|
|
reactive,
|
|
ref,
|
|
watch
|
|
} from 'vue';
|
|
import {
|
|
getShopUser
|
|
} from '@/http/api/market/index.js';
|
|
|
|
const customStyle = ref({
|
|
marginRight: '20px'
|
|
});
|
|
|
|
const show = ref(false);
|
|
let modelValue = defineModel('modelValue', {
|
|
default: '',
|
|
});
|
|
|
|
const props = defineProps({
|
|
maxWidth: {
|
|
default: 240
|
|
}
|
|
})
|
|
|
|
const selId = ref('')
|
|
|
|
function returnLabel() {
|
|
const findItem = list.value.find(v => v.id == modelValue.value)
|
|
if (findItem) {
|
|
return findItem.nickName + (findItem.phone ? ('/' + findItem.phone) : '')
|
|
}
|
|
return ''
|
|
}
|
|
|
|
const selItem = ref(null)
|
|
|
|
function itemClick(item) {
|
|
selItem.value = item
|
|
}
|
|
|
|
function returnShopName(id) {
|
|
const item = list.value.find((v) => v.id == id);
|
|
return item?.shopName || '';
|
|
}
|
|
|
|
function close() {
|
|
show.value = false;
|
|
}
|
|
|
|
|
|
const emits = defineEmits(['change'])
|
|
|
|
function submit() {
|
|
if (!selItem.value) {
|
|
return uni.showToast({
|
|
title: '请选择用户'
|
|
})
|
|
}
|
|
if (modelValue.value != selItem.value.id) {
|
|
modelValue.value=selItem.value.id
|
|
emits('change')
|
|
}else{
|
|
modelValue.value=selItem.value.id
|
|
}
|
|
show.value = false;
|
|
}
|
|
|
|
|
|
const list = ref([]);
|
|
|
|
function openPopup() {
|
|
selId.value = 'item_' + modelValue.value
|
|
init()
|
|
show.value = true;
|
|
|
|
}
|
|
const isEnd = ref(false)
|
|
const query = reactive({
|
|
page: 1,
|
|
size: 10,
|
|
key: ''
|
|
})
|
|
|
|
function search() {
|
|
isEnd.value = false
|
|
query.page = 1
|
|
selItem.value = null
|
|
init()
|
|
}
|
|
async function init() {
|
|
const res = await getShopUser(query);
|
|
if (res) {
|
|
isEnd.value = query.page >= res.totalPage * 1
|
|
if (query.page == 1) {
|
|
list.value = res.records
|
|
} else {
|
|
list.value.push(...res.records)
|
|
}
|
|
}
|
|
}
|
|
|
|
function scrolltolower() {
|
|
if (!isEnd.value) {
|
|
query.page++
|
|
init()
|
|
}
|
|
}
|
|
</script>
|
|
<style lang="scss">
|
|
.box {
|
|
border-radius: 8upx;
|
|
display: flex;
|
|
flex-direction: row;
|
|
align-items: top;
|
|
flex-wrap: wrap;
|
|
padding: 10rpx 24rpx;
|
|
border: 2rpx solid #e5e5e5;
|
|
position: relative;
|
|
|
|
.icon {
|
|
position: absolute;
|
|
top: 50%;
|
|
right: 24rpx;
|
|
transform: translateY(-50%);
|
|
}
|
|
}
|
|
|
|
.shop-item {
|
|
padding: 4rpx 8rpx 4rpx 16rpx;
|
|
border-radius: 4rpx;
|
|
border: 2rpx solid #f0f0f0;
|
|
background-color: #f5f5f5;
|
|
margin-bottom: 16rpx;
|
|
margin-left: 16rpx;
|
|
}
|
|
|
|
.scroll-view {
|
|
.item {
|
|
border: 1px solid #eee;
|
|
padding: 20rpx;
|
|
border-radius: 12rpx;
|
|
|
|
&.active {
|
|
border-color: $my-main-color;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
.checkbox {
|
|
margin-right: 10rpx;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
border-radius: 6rpx;
|
|
border: 1px solid #999;
|
|
|
|
}
|
|
|
|
.item {
|
|
&.active {
|
|
.checkbox {
|
|
background-color: $my-main-color;
|
|
border-color: $my-main-color;
|
|
}
|
|
}
|
|
}
|
|
</style> |