diff --git a/src/components/CustomerRemoveDialog.vue b/src/components/CustomerRemoveDialog.vue
new file mode 100644
index 0000000..26cfd50
--- /dev/null
+++ b/src/components/CustomerRemoveDialog.vue
@@ -0,0 +1,151 @@
+
+
+
+
删除后无法恢复,将同时清除以下关联数据:
+
+ - 登记事件记录及其附件,并撤销这些登记产生的积分
+ - 客户积分账户、标签和客户附件
+ - 解除该客户与其被邀请客户之间的邀请关系,被邀请客户不会被删除
+ - 减少该客户原介绍人的邀请客户计数
+ - 客户档案本身
+
+
+ 请输入客户姓名
+
+ 以确认删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/customer/CustomerDetail.vue b/src/pages/customer/CustomerDetail.vue
index b01609c..3f73329 100644
--- a/src/pages/customer/CustomerDetail.vue
+++ b/src/pages/customer/CustomerDetail.vue
@@ -105,52 +105,12 @@
>
-
-
-
删除后无法恢复,将同时清除以下关联数据:
-
- - 登记事件记录及其附件,并撤销这些登记产生的积分
- - 客户积分账户、标签和客户附件
- - 解除该客户与其被邀请客户之间的邀请关系,被邀请客户不会被删除
- - 减少该客户原介绍人的邀请客户计数
- - 客户档案本身
-
-
- 请输入客户姓名
-
- 以确认删除
-
-
-
-
-
-
-
-
-
-
+ :customer="removeTarget"
+ :loading="isRemoving"
+ @confirm="removeConfirmedCustomer"
+ />
@@ -163,6 +123,7 @@ import CustomerAPI from "@/api/CustomerAPI";
import PointAPI from "@/api/PointAPI";
import TagAPI from "@/api/TagAPI";
import BodyAreaSelector from "@/components/BodyAreaSelector.vue";
+import CustomerRemoveDialog from "@/components/CustomerRemoveDialog.vue";
import CustomerProfileCard from "@/components/CustomerProfileCard.vue";
import PhotoScroller from "@/components/PhotoScroller.vue";
import TagSelector from "@/components/TagSelector.vue";
@@ -190,15 +151,12 @@ const userStore = useUserStore();
const isRemoving = ref(false);
const removeDialogVisible = ref(false);
const removeTarget = ref();
-const removeConfirmName = ref("");
const canReadStat = computed(() => userStore.hasPermissions(permissionCodes.stat.read));
const canReadPointAccount = computed(() => userStore.hasPermissions(permissionCodes.point.accountRead));
const canReadTag = computed(() => userStore.hasPermissions(corePermissionCodes.tag.read));
const canApplyTag = computed(() => userStore.hasPermissions(corePermissionCodes.tag.apply));
const canUpdateCustomer = computed(() => userStore.hasPermissions(permissionCodes.customer.update));
-const removeCustomerName = computed(() => removeTarget.value?.name || "");
-const canConfirmRemove = computed(() => !!removeCustomerName.value && removeConfirmName.value === removeCustomerName.value);
// ---------- 资料 ----------
@@ -375,25 +333,21 @@ async function confirmRemoveCustomer(): Promise {
}
removeTarget.value = currentCustomer;
- removeConfirmName.value = "";
removeDialogVisible.value = true;
}
function closeRemoveDialog(): void {
removeDialogVisible.value = false;
removeTarget.value = undefined;
- removeConfirmName.value = "";
}
-async function removeConfirmedCustomer(): Promise {
- const customerId = removeTarget.value?.id;
- if (!customerId || !canConfirmRemove.value || isRemoving.value) {
+async function removeConfirmedCustomer(target: Customer): Promise {
+ const customerId = target.id;
+ if (!customerId || isRemoving.value) {
return;
}
- removeDialogVisible.value = false;
- removeTarget.value = undefined;
- removeConfirmName.value = "";
+ closeRemoveDialog();
await removeCustomer(customerId);
}
@@ -531,45 +485,6 @@ onUnmounted(() => navBarStore.clearRight());
}
}
-.remove-dialog {
-
- :deep(.t-dialog__footer) {
- gap: 1rem;
- }
-
- .content {
- text-align: left;
-
- .warning {
- color: #b42318;
- font-weight: 700;
- }
-
- .items {
- gap: .5rem;
- height: 9rem;
- margin: .75rem 0 1rem;
- display: flex;
- overflow-y: auto;
- line-height: 1.2;
- padding-left: 1.25rem;
- flex-direction: column;
- }
-
- .name {
- font-weight: 700;
- }
-
- .confirm-input {
- --td-input-vertical-padding: 10px;
-
- border: 1px solid var(--td-component-border);
- margin-top: .5rem;
- border-radius: .75rem;
- }
- }
-}
-
:global(html.theme-dark) {
.customer-detail {
@@ -581,17 +496,6 @@ onUnmounted(() => navBarStore.clearRight());
color: #94a3b8;
}
- .remove-dialog {
-
- .warning {
- color: #fda29b;
- }
-
- .confirm-input {
- background: rgba(15, 23, 42, .72);
- border-color: rgba(148, 163, 184, .16);
- }
- }
}
}
diff --git a/src/pages/customer/CustomerList.vue b/src/pages/customer/CustomerList.vue
index c7b7c22..9d3c31e 100644
--- a/src/pages/customer/CustomerList.vue
+++ b/src/pages/customer/CustomerList.vue
@@ -38,20 +38,34 @@
@scrolltolower="fetch"
>
+
-
+
+
+ 删除
+
+
+
+
@@ -60,6 +74,12 @@
v-model:visible="tagSelectorVisible"
@change="handleTagFilterChanged"
/>
+
@@ -69,6 +89,7 @@ import { Message } from "@/utils/message";
import { Time, Toolkit, WebToolkit } from "timi-web";
import { type Page, type PageResult, useUserStore } from "timi-web-api";
import CustomerAPI from "@/api/CustomerAPI";
+import CustomerRemoveDialog from "@/components/CustomerRemoveDialog.vue";
import TagSelector from "@/components/TagSelector.vue";
import { useCurrentStoreStore } from "@/store/currentStoreStore";
import { useNavBarStore } from "@/store/navBarStore";
@@ -87,9 +108,14 @@ const currentStoreStore = useCurrentStoreStore();
const navBarStore = useNavBarStore();
const isRefreshing = ref(false);
const isExporting = ref(false);
+const isRemoving = ref(false);
+const removeDialogVisible = ref(false);
+const removeTarget = ref();
+const removingCustomerId = ref("");
const isGlobalManager = computed(() => userStore.hasRoles(gaoRoleCodes.globalManager));
const canReadTag = computed(() => userStore.hasPermissions(corePermissionCodes.tag.read));
const canCreateCustomer = computed(() => userStore.hasPermissions(permissionCodes.customer.create));
+const canDeleteCustomer = computed(() => userStore.hasPermissions(permissionCodes.customer.delete));
const canExportCustomer = computed(() => userStore.hasPermissions(permissionCodes.customer.export));
const canShowActionMenu = computed(() => canCreateCustomer.value || canExportCustomer.value);
@@ -217,6 +243,44 @@ async function toCreate(): Promise {
});
}
+async function toDetail(customer: Customer): Promise {
+ if (!customer.id) {
+ return;
+ }
+ await router.push(`/management/customers/${customer.id}`);
+}
+
+// ---------- 删除客户 ----------
+
+function openRemoveDialog(customer: Customer): void {
+ if (!customer.id || isRemoving.value) {
+ return;
+ }
+ removeTarget.value = customer;
+ removeDialogVisible.value = true;
+}
+
+async function removeCustomer(customer: Customer): Promise {
+ const customerId = customer.id;
+ if (!customerId || isRemoving.value) {
+ return;
+ }
+
+ isRemoving.value = true;
+ removingCustomerId.value = customerId;
+ removeDialogVisible.value = false;
+ removeTarget.value = undefined;
+ try {
+ await CustomerAPI.remove(customerId);
+ pageResult.list = pageResult.list.filter(item => item.id !== customerId);
+ pageResult.total = Math.max(0, pageResult.total - 1);
+ Message.success("客户已删除");
+ } finally {
+ isRemoving.value = false;
+ removingCustomerId.value = "";
+ }
+}
+
// ---------- 导出 ----------
async function doExport(): Promise {
@@ -282,11 +346,10 @@ async function doExport(): Promise {
.list-wrapper {
padding: 1rem 0;
- .items {
-
- .item {
- padding: 10px;
- }
+ .delete {
+ height: 100%;
+ padding: 0 1rem;
+ border-radius: 0;
}
}