Files
gao-customer-h5/src/components/StoreRemoveDialog.vue
T
2026-08-29 00:49:22 +08:00

196 lines
4.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<t-dialog
class="remove-dialog"
v-model:visible="visible"
title="删除门店"
>
<div class="content">
<div class="warning">删除后将同步处理以下数据:</div>
<ul class="items">
<li>删除该门店下的所有客户</li>
<li>删除客户的登记记录及相关附件</li>
<li>删除积分规则和积分账户</li>
<li>删除登记事件及事件角色关联</li>
<li>删除门店营业日数据</li>
<li>删除门店用户关系</li>
<li>删除门店自有标签</li>
</ul>
<div class="warning">特别说明:</div>
<ul class="items">
<li>已产生的积分流水不会删除,将保留积分撤销记录</li>
<li>关联的系统用户账号不会删除</li>
<li>删除后无法恢复,请谨慎操作</li>
</ul>
<div class="hint">
请输入门店名称
<span class="name red" v-text="storeName" />
以确认删除
</div>
<t-input
class="confirm-input"
v-model.trim="confirmName"
size="small"
borderless
clearable
placeholder="请输入门店名称"
/>
</div>
<template #cancelBtn>
<t-button
theme="default"
content="取消"
block
@click="close"
/>
</template>
<template #confirmBtn>
<t-button
theme="danger"
:content="confirmButtonText"
block
:loading="loading"
:disabled="!canConfirm || loading || 0 < countdown"
@click="confirm"
/>
</template>
</t-dialog>
</template>
<script setup lang="ts">
import type { Store } from "@/types/Store";
defineOptions({
name: "StoreRemoveDialog"
});
interface Props {
visible?: boolean;
store?: Store;
loading?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
visible: false,
loading: false
});
const emit = defineEmits<{
"update:visible": [visible: boolean];
confirm: [store: Store];
}>();
const COUNTDOWN_SECONDS = 30;
const confirmName = ref("");
const countdown = ref(COUNTDOWN_SECONDS);
let countdownTimer: number | undefined;
const visible = computed({
get: () => props.visible,
set: (value: boolean) => emit("update:visible", value)
});
const storeName = computed(() => props.store?.name || "");
const canConfirm = computed(() => !!storeName.value && confirmName.value === storeName.value);
const confirmButtonText = computed(() => countdown.value ? `删除(${countdown.value} 秒)` : "删除");
watch(() => props.visible, () => {
confirmName.value = "";
resetCountdown();
}, { immediate: true });
onUnmounted(clearCountdown);
function resetCountdown(): void {
clearCountdown();
countdown.value = COUNTDOWN_SECONDS;
if (!props.visible) {
return;
}
countdownTimer = window.setInterval(() => {
if (countdown.value < 2) {
countdown.value = 0;
clearCountdown();
return;
}
countdown.value -= 1;
}, 1000);
}
function clearCountdown(): void {
if (countdownTimer === undefined) {
return;
}
window.clearInterval(countdownTimer);
countdownTimer = undefined;
}
function close(): void {
visible.value = false;
}
function confirm(): void {
if (!props.store?.id || !canConfirm.value || props.loading || 0 < countdown.value) {
return;
}
emit("confirm", props.store);
}
</script>
<style scoped lang="less">
.remove-dialog {
:deep(.t-dialog__footer) {
gap: 1rem;
}
.content {
text-align: left;
.warning {
color: #b42318;
font-weight: 700;
}
.items {
margin: .25rem 0 1rem;
max-height: 5rem;
display: flex;
overflow-y: auto;
line-height: 1.2;
padding-left: 1.25rem;
flex-direction: column;
}
.name {
font-weight: 700;
}
.countdown-hint {
color: var(--td-text-color-secondary);
margin-top: .5rem;
font-size: .875rem;
}
.confirm-input {
--td-input-vertical-padding: 10px;
border: 1px solid var(--td-component-border);
margin-top: .5rem;
border-radius: .75rem;
}
}
}
:global(html.theme-dark) {
.remove-dialog {
.warning {
color: #fda29b;
}
.confirm-input {
background: rgba(15, 23, 42, .72);
border-color: rgba(148, 163, 184, .16);
}
}
}
</style>