update list load
This commit is contained in:
@@ -8,8 +8,7 @@
|
|||||||
@right-button-click="confirmSelection"
|
@right-button-click="confirmSelection"
|
||||||
>
|
>
|
||||||
<div class="customer-selector">
|
<div class="customer-selector">
|
||||||
<div class="search-wrapper">
|
<div class="search-wrap">
|
||||||
<div class="search-row">
|
|
||||||
<t-input
|
<t-input
|
||||||
v-model.trim="keyword"
|
v-model.trim="keyword"
|
||||||
class="search"
|
class="search"
|
||||||
@@ -19,7 +18,8 @@
|
|||||||
/>
|
/>
|
||||||
<t-button
|
<t-button
|
||||||
v-if="props.enableScan"
|
v-if="props.enableScan"
|
||||||
class="scan-button"
|
class="scan"
|
||||||
|
size="small"
|
||||||
theme="primary"
|
theme="primary"
|
||||||
@click="toggleScanner"
|
@click="toggleScanner"
|
||||||
>
|
>
|
||||||
@@ -29,8 +29,7 @@
|
|||||||
<span v-text="scannerVisible ? '关闭扫码' : '扫码'" />
|
<span v-text="scannerVisible ? '关闭扫码' : '扫码'" />
|
||||||
</t-button>
|
</t-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div v-if="scannerVisible" class="scanner-wrap">
|
||||||
<div v-if="scannerVisible" class="scanner-wrapper">
|
|
||||||
<code-scanner
|
<code-scanner
|
||||||
:visible="scannerVisible"
|
:visible="scannerVisible"
|
||||||
:status-text="scanStatus"
|
:status-text="scanStatus"
|
||||||
@@ -39,7 +38,13 @@
|
|||||||
@status-change="handleScanStatusChange"
|
@status-change="handleScanStatusChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div ref="resultListRef" class="result-list">
|
<t-pull-down-refresh
|
||||||
|
class="result-list"
|
||||||
|
v-model="isRefreshing"
|
||||||
|
:refresh-timeout="30000"
|
||||||
|
@refresh="refresh"
|
||||||
|
@scrolltolower="loadCustomers"
|
||||||
|
>
|
||||||
<customer-list
|
<customer-list
|
||||||
:customer-list="customerOptions"
|
:customer-list="customerOptions"
|
||||||
:selected-id-list="draftSelectedIdList"
|
:selected-id-list="draftSelectedIdList"
|
||||||
@@ -47,13 +52,13 @@
|
|||||||
:empty-text="loading ? '正在加载客户' : '未找到匹配客户'"
|
:empty-text="loading ? '正在加载客户' : '未找到匹配客户'"
|
||||||
@select="toggleCustomer"
|
@select="toggleCustomer"
|
||||||
/>
|
/>
|
||||||
</div>
|
</t-pull-down-refresh>
|
||||||
</div>
|
</div>
|
||||||
</bottom-popup>
|
</bottom-popup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Scroller } from "timi-web";
|
import { Toolkit } from "timi-web";
|
||||||
import { BottomPopup } from "timi-tdesign-mobile";
|
import { BottomPopup } from "timi-tdesign-mobile";
|
||||||
import CustomerAPI from "@/api/CustomerAPI";
|
import CustomerAPI from "@/api/CustomerAPI";
|
||||||
import CodeScanner from "@/components/CodeScanner.vue";
|
import CodeScanner from "@/components/CodeScanner.vue";
|
||||||
@@ -86,18 +91,16 @@ const emit = defineEmits<{
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
const pageSize = 20;
|
const pageSize = 20;
|
||||||
const scrollListenerName = "CustomerSelector";
|
|
||||||
const keyword = ref("");
|
const keyword = ref("");
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const noMore = ref(false);
|
const noMore = ref(false);
|
||||||
const pageIndex = ref(0);
|
const pageIndex = ref(0);
|
||||||
const totalCount = ref(0);
|
const totalCount = ref(0);
|
||||||
const customerOptions = ref<Customer[]>([]);
|
const customerOptions = ref<Customer[]>([]);
|
||||||
const resultListRef = ref<HTMLElement>();
|
const isRefreshing = ref(false);
|
||||||
const draftSelectedIdList = ref<string[]>([]);
|
const draftSelectedIdList = ref<string[]>([]);
|
||||||
const selectedCustomerCache = new Map<string, Customer>();
|
const selectedCustomerCache = new Map<string, Customer>();
|
||||||
let searchToken = 0;
|
let searchToken = 0;
|
||||||
let keywordTimer: number | undefined;
|
|
||||||
const scannerVisible = ref(false);
|
const scannerVisible = ref(false);
|
||||||
const scanStatus = ref("点击扫码开始识别");
|
const scanStatus = ref("点击扫码开始识别");
|
||||||
let latestDecodedText = "";
|
let latestDecodedText = "";
|
||||||
@@ -122,6 +125,18 @@ async function reloadCustomers(): Promise<void> {
|
|||||||
await loadCustomers();
|
await loadCustomers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refresh(): Promise<void> {
|
||||||
|
try {
|
||||||
|
await reloadCustomers();
|
||||||
|
} finally {
|
||||||
|
isRefreshing.value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const reloadByKeyword = Toolkit.debounce(async () => {
|
||||||
|
await reloadCustomers();
|
||||||
|
}, false);
|
||||||
|
|
||||||
async function loadCustomers(): Promise<void> {
|
async function loadCustomers(): Promise<void> {
|
||||||
if (loading.value || noMore.value) {
|
if (loading.value || noMore.value) {
|
||||||
return;
|
return;
|
||||||
@@ -161,19 +176,6 @@ async function loadCustomers(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function bindScrollListener(): Promise<void> {
|
|
||||||
if (!props.visible || 0 === customerOptions.value.length) {
|
|
||||||
Scroller.removeListener(scrollListenerName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await nextTick();
|
|
||||||
Scroller.addBottomListener(scrollListenerName, loadCustomers, {
|
|
||||||
distance: 48,
|
|
||||||
canLoad: () => props.visible && !loading.value && !noMore.value,
|
|
||||||
getElement: () => resultListRef.value
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getModelValueIdList(): string[] {
|
function getModelValueIdList(): string[] {
|
||||||
const value = props.modelValue;
|
const value = props.modelValue;
|
||||||
return (Array.isArray(value) ? value : [value]).filter((item): item is string => Boolean(item));
|
return (Array.isArray(value) ? value : [value]).filter((item): item is string => Boolean(item));
|
||||||
@@ -283,13 +285,11 @@ watch(() => props.visible, async (value) => {
|
|||||||
latestDecodedText = "";
|
latestDecodedText = "";
|
||||||
scanToken++;
|
scanToken++;
|
||||||
scanStatus.value = "点击扫码开始识别";
|
scanStatus.value = "点击扫码开始识别";
|
||||||
window.clearTimeout(keywordTimer);
|
reloadByKeyword.cancel();
|
||||||
Scroller.removeListener(scrollListenerName);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syncDraftSelection();
|
syncDraftSelection();
|
||||||
await reloadCustomers();
|
await reloadCustomers();
|
||||||
await bindScrollListener();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => props.enableScan, (value) => {
|
watch(() => props.enableScan, (value) => {
|
||||||
@@ -305,27 +305,17 @@ watch(() => props.storeId, async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await reloadCustomers();
|
await reloadCustomers();
|
||||||
await bindScrollListener();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(keyword, async () => {
|
watch(keyword, () => {
|
||||||
if (!props.visible) {
|
if (!props.visible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
window.clearTimeout(keywordTimer);
|
reloadByKeyword();
|
||||||
keywordTimer = window.setTimeout(async () => {
|
|
||||||
await reloadCustomers();
|
|
||||||
await bindScrollListener();
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
|
|
||||||
watch(() => customerOptions.value.length, async () => {
|
|
||||||
await bindScrollListener();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.clearTimeout(keywordTimer);
|
reloadByKeyword.cancel();
|
||||||
Scroller.removeListener(scrollListenerName);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -335,34 +325,31 @@ onUnmounted(() => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
.search-wrapper {
|
.search-wrap {
|
||||||
z-index: 1;
|
|
||||||
padding: 1rem 0 .5rem;
|
|
||||||
box-shadow: 0 4px 4px rgba(0, 0, 0, .05);
|
|
||||||
|
|
||||||
.search-row {
|
|
||||||
gap: .5rem;
|
gap: .5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 0 1rem;
|
z-index: 1;
|
||||||
|
padding: .5rem;
|
||||||
|
box-shadow: 0 4px 4px rgba(0, 0, 0, .05);
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
.search {
|
||||||
--td-input-vertical-padding: 8px 14px;
|
--td-input-vertical-padding: 8px 14px;
|
||||||
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
border: 1px solid var(--td-component-border);
|
border: 1px solid var(--td-component-border);
|
||||||
|
padding: .25rem .5rem;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
border-radius: .875rem;
|
border-radius: .75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scan-button {
|
.scan {
|
||||||
--td-button-border-radius: .75rem;
|
--td-button-border-radius: .75rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.scanner-wrapper {
|
.scanner-wrap {
|
||||||
padding: .5rem 1rem 0;
|
padding: .5rem 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user