batch customer event
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
<template>
|
||||
<div class="customer-list">
|
||||
<t-cell-group v-if="customerList.length">
|
||||
<t-cell
|
||||
v-for="(item, index) in customerList"
|
||||
:key="item.id || item.code || index"
|
||||
:note="item.code"
|
||||
hover
|
||||
@click="handleSelect(item)"
|
||||
>
|
||||
<template #title>
|
||||
<div class="cell-title">
|
||||
<span v-text="item.name || item.code || '未命名客户'" />
|
||||
<gender-icon :value="item.gender" />
|
||||
</div>
|
||||
</template>
|
||||
<template #description>
|
||||
<telephone-link :value="item.telephone" placeholder="未填写电话" />
|
||||
</template>
|
||||
<template #leftIcon>
|
||||
<div class="left-icon">
|
||||
<span v-if="selectable" class="check" :class="{selected: isSelected(item)}">
|
||||
<t-icon v-if="isSelected(item)" name="check" />
|
||||
</span>
|
||||
<t-image v-if="getCustomerPhotoURL(item)" :src="getCustomerPhotoURL(item)" :alt="item.name" fit="cover" class="avatar" />
|
||||
<div v-else class="avatar fallback" v-text="(item.name || item.code || '客').slice(0, 1)" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="removable" #rightIcon>
|
||||
<t-button theme="danger" size="extra-small" @click.stop="handleRemove(item)">移除</t-button>
|
||||
</template>
|
||||
</t-cell>
|
||||
</t-cell-group>
|
||||
<div v-else class="empty-block" v-text="emptyText" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Customer } from "@/types/Customer";
|
||||
import { getCustomerPhotoURL } from "@/utils/customer";
|
||||
|
||||
defineOptions({
|
||||
name: "CustomerList"
|
||||
});
|
||||
|
||||
interface Props {
|
||||
customerList: Customer[];
|
||||
selectedIdList?: string[];
|
||||
selectable?: boolean;
|
||||
removable?: boolean;
|
||||
emptyText?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
selectedIdList: () => [],
|
||||
selectable: false,
|
||||
removable: false,
|
||||
emptyText: "暂无客户"
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
select: [customer: Customer];
|
||||
remove: [customer: Customer];
|
||||
}>();
|
||||
|
||||
const selectedIdSet = computed(() => new Set(props.selectedIdList));
|
||||
|
||||
function isSelected(customer: Customer): boolean {
|
||||
return !!customer.id && selectedIdSet.value.has(customer.id);
|
||||
}
|
||||
|
||||
function handleSelect(customer: Customer): void {
|
||||
emit("select", customer);
|
||||
}
|
||||
|
||||
function handleRemove(customer: Customer): void {
|
||||
emit("remove", customer);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.customer-list {
|
||||
.cell-title {
|
||||
gap: .5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.left-icon {
|
||||
gap: .5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.check {
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex: none;
|
||||
border: 1px solid var(--td-component-border);
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
&.selected {
|
||||
border-color: var(--td-brand-color);
|
||||
background: var(--td-brand-color);
|
||||
}
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 3.5rem;
|
||||
height: 3.5rem;
|
||||
border-radius: .5rem;
|
||||
|
||||
&.fallback {
|
||||
color: #2563eb;
|
||||
display: flex;
|
||||
font-size: 1.25rem;
|
||||
background: #dbeafe;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-block {
|
||||
color: #52607a;
|
||||
margin: 1rem;
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
background: #f8fbff;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.avatar .t-image__img) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
:global(html.theme-dark) {
|
||||
.customer-list {
|
||||
.check {
|
||||
border-color: rgba(148, 163, 184, .4);
|
||||
}
|
||||
|
||||
.empty-block {
|
||||
color: #e2e8f0;
|
||||
background: rgba(30, 41, 59, .9);
|
||||
}
|
||||
|
||||
.avatar.fallback {
|
||||
color: #93c5fd;
|
||||
background: rgba(30, 64, 175, .32);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user