admin-vben/apps/web-antd/src/views/mes/wm/salesnotice/components/select.vue

142 lines
3.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<script lang="ts" setup>
import type { MesWmSalesNoticeApi } from '#/api/mes/wm/salesnotice';
import { computed, ref, useAttrs, watch } from 'vue';
import { IconifyIcon } from '@vben/icons';
import { Input, Tooltip } from 'ant-design-vue';
import { getSalesNotice } from '#/api/mes/wm/salesnotice';
import WmSalesNoticeSelectDialog from './select-dialog.vue';
defineOptions({ name: 'WmSalesNoticeSelect', inheritAttrs: false });
const props = withDefaults(
defineProps<{
allowClear?: boolean;
disabled?: boolean;
modelValue?: number;
placeholder?: string;
status?: number; // 固定状态筛选
}>(),
{
allowClear: true,
disabled: false,
modelValue: undefined,
placeholder: '请选择发货通知单',
status: undefined,
},
);
const emit = defineEmits<{
change: [item: MesWmSalesNoticeApi.SalesNotice | undefined];
'update:modelValue': [value: number | undefined];
}>();
const attrs = useAttrs();
const dialogRef = ref<InstanceType<typeof WmSalesNoticeSelectDialog>>();
const hovering = ref(false);
const selectedItem = ref<MesWmSalesNoticeApi.SalesNotice>();
const displayLabel = computed(() => selectedItem.value?.name ?? '');
const showClear = computed(
() =>
props.allowClear &&
!props.disabled &&
hovering.value &&
props.modelValue !== undefined &&
props.modelValue !== null,
);
/** 根据编号单条查询通知单信息(用于编辑回显) */
async function resolveItemById(id: number | undefined) {
if (!id) {
selectedItem.value = undefined;
return;
}
if (selectedItem.value?.id === id) {
return;
}
selectedItem.value = await getSalesNotice(id);
}
watch(() => props.modelValue, resolveItemById, { immediate: true });
/** 清空已选通知单 */
function clearSelected() {
selectedItem.value = undefined;
emit('update:modelValue', undefined);
emit('change', undefined);
}
/** 打开通知单选择弹窗 */
function handleClick(event: MouseEvent) {
if (props.disabled) {
return;
}
const target = event.target as HTMLElement;
if (showClear.value && target.closest('.ant-input-suffix')) {
event.stopPropagation();
clearSelected();
return;
}
const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
dialogRef.value?.open(selectedIds, {
multiple: false,
status: props.status,
});
}
/** 弹窗选中回调 */
function handleSelected(rows: MesWmSalesNoticeApi.SalesNotice[]) {
const item = rows[0];
if (!item) {
return;
}
selectedItem.value = item;
emit('update:modelValue', item.id);
emit('change', item);
}
</script>
<template>
<div
v-bind="attrs"
class="w-full"
:class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
@click="handleClick"
@mouseenter="hovering = true"
@mouseleave="hovering = false"
>
<Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false">
<template #title>
<div v-if="selectedItem" class="leading-6">
<div>编号{{ selectedItem.code || '-' }}</div>
<div>名称{{ selectedItem.name || '-' }}</div>
<div>客户{{ selectedItem.clientName || '-' }}</div>
<div>销售订单{{ selectedItem.salesOrderCode || '-' }}</div>
</div>
</template>
<Input
:disabled="disabled"
:placeholder="placeholder"
:value="displayLabel"
readonly
>
<template #suffix>
<IconifyIcon
class="size-4"
:icon="showClear ? 'lucide:circle-x' : 'lucide:search'"
/>
</template>
</Input>
</Tooltip>
</div>
<WmSalesNoticeSelectDialog ref="dialogRef" @selected="handleSelected" />
</template>