Files
admin-web/src/modules/self-operated/components/OwnerPicker.vue
T

54 lines
3.2 KiB
Vue
Raw Normal View History

<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>