54 lines
3.2 KiB
Vue
54 lines
3.2 KiB
Vue
<script setup lang="ts">
|
||
import { onUnmounted, ref, watch } from 'vue'
|
||
import { analyticsApi } from '../api/analytics'
|
||
import type { OwnerOption, QueryContext } from '../types'
|
||
import { contextParams, RequestFence, sameContext } from '../state'
|
||
import { getApiErrorMessage } from '@/shared/api/http'
|
||
|
||
const props = defineProps<{ modelValue: string; sourceAccount: string; warehouseCode: string; context: QueryContext | null }>()
|
||
const emit = defineEmits<{ 'update:modelValue': [value: string] }>()
|
||
const options = ref<OwnerOption[]>([])
|
||
const keyword = ref('')
|
||
const current = ref(1)
|
||
const total = ref(0)
|
||
const loading = ref(false)
|
||
const error = ref('')
|
||
const fence = new RequestFence()
|
||
async function load() {
|
||
const request = fence.begin()
|
||
if (!props.warehouseCode || !props.context) { options.value = []; total.value = 0; loading.value = false; return }
|
||
loading.value = true
|
||
error.value = ''
|
||
try {
|
||
const result = await analyticsApi.owners({ sourceAccount: props.sourceAccount, warehouseCode: props.warehouseCode, ...contextParams(props.context), keyword: keyword.value || undefined, current: current.value, size: 20 }, request.signal)
|
||
if (!request.current()) return
|
||
if (!props.context || !sameContext(props.context, result.context)) {
|
||
options.value = []; total.value = 0; error.value = '货主选项版本已变化,请整体刷新'
|
||
return
|
||
}
|
||
options.value = result.records
|
||
total.value = result.total
|
||
} catch (cause) { if (request.current()) { options.value = []; total.value = 0; error.value = getApiErrorMessage(cause, '货主选项读取失败') } }
|
||
finally { if (request.current()) loading.value = false }
|
||
}
|
||
function search(value: string) { keyword.value = value; current.value = 1; void load() }
|
||
function page(delta: number) { current.value += delta; void load() }
|
||
watch(() => [props.warehouseCode, props.context?.queryAsOf, props.context?.salesRunId, props.context?.inventoryRunId], () => { current.value = 1; keyword.value = ''; void load() }, { immediate: true })
|
||
onUnmounted(() => fence.cancel())
|
||
</script>
|
||
<template>
|
||
<div class="density-actions">
|
||
<label>货主
|
||
<el-select :model-value="modelValue" :disabled="!warehouseCode || !context" clearable filterable remote :remote-method="search" :loading="loading" placeholder="全部货主;输入编码前缀查找" aria-label="货主选择" @update:model-value="emit('update:modelValue', String($event ?? ''))">
|
||
<el-option v-if="modelValue && !options.some(option => option.customerCode === modelValue)" :value="modelValue" :label="modelValue" />
|
||
<el-option v-for="option in options" :key="option.customerCode" :value="option.customerCode" :label="option.customerName ? `${option.customerCode} · ${option.customerName}` : option.customerCode" />
|
||
</el-select>
|
||
</label>
|
||
<el-button :disabled="loading || current <= 1" @click="page(-1)">上一页货主</el-button>
|
||
<span>第 {{ current }} 页 · 共 {{ total }} 个货主</span>
|
||
<el-button :disabled="loading || current * 20 >= total" @click="page(1)">下一页货主</el-button>
|
||
<span v-if="error" role="alert">{{ error }}</span>
|
||
<span v-else-if="context && !loading && !total">当前查询无可用货主资料;未发布数据不代表仓库没有货主。</span>
|
||
</div>
|
||
</template>
|