feat:
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Issue Close Require / close-issues (push) Has been cancelled
Close stale issues / stale (push) Has been cancelled
1. 创建就诊人功能增强 2. 优化交互细节
This commit is contained in:
202
apps/web-antd/src/components/vip/VipHubModal.vue
Normal file
202
apps/web-antd/src/components/vip/VipHubModal.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<script lang="ts" setup>
|
||||
/**
|
||||
* 门店 VIP 入口弹窗
|
||||
* 先展示两张操作卡片:开通/升级、开通记录;再分别打开对应子弹窗
|
||||
*/
|
||||
import { computed, ref } from 'vue';
|
||||
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
|
||||
import VipBadgeCombo from '#/components/vip/VipBadgeCombo.vue';
|
||||
import VipStoreRecordsModal from '#/components/vip/VipStoreRecordsModal.vue';
|
||||
import VipUpgradeModal from '#/components/vip/VipUpgradeModal.vue';
|
||||
|
||||
const gridApi = ref<any>();
|
||||
const onSuccess = ref<null | (() => void)>(null);
|
||||
const storeId = ref(0);
|
||||
const storeName = ref('');
|
||||
const vip = ref<Record<string, any> | null>(null);
|
||||
|
||||
const title = computed(
|
||||
() => `VIP管理 - ${storeName.value || storeId.value || ''}`,
|
||||
);
|
||||
|
||||
const currentLevelText = computed(() => {
|
||||
const v = vip.value;
|
||||
if (!v) return '当前:普通会员';
|
||||
const name = String(v.level_name || '').trim();
|
||||
const code = String(v.level_code || '').trim();
|
||||
const duration = String(v.duration_label || '').trim();
|
||||
const level =
|
||||
name && code ? `${name}(${code})` : name || code || '普通会员';
|
||||
return duration ? `当前:${level} · ${duration}` : `当前:${level}`;
|
||||
});
|
||||
|
||||
const [UpgradeModalComp, upgradeModalApi] = useVbenModal({
|
||||
connectedComponent: VipUpgradeModal,
|
||||
});
|
||||
const [RecordsModalComp, recordsModalApi] = useVbenModal({
|
||||
connectedComponent: VipStoreRecordsModal,
|
||||
});
|
||||
|
||||
const [Modal, modalApi] = useVbenModal({
|
||||
fullscreenButton: false,
|
||||
draggable: true,
|
||||
class: 'w-[640px]',
|
||||
showConfirmButton: false,
|
||||
cancelText: '关闭',
|
||||
onCancel() {
|
||||
modalApi.close();
|
||||
},
|
||||
async onOpenChange(isOpen: boolean) {
|
||||
if (!isOpen) {
|
||||
storeId.value = 0;
|
||||
storeName.value = '';
|
||||
vip.value = null;
|
||||
gridApi.value = null;
|
||||
onSuccess.value = null;
|
||||
return;
|
||||
}
|
||||
const data = modalApi.getData<Record<string, any>>() || {};
|
||||
storeId.value = Number(data.store_id || 0);
|
||||
storeName.value = String(data.store_name || '');
|
||||
vip.value = data.vip || null;
|
||||
gridApi.value = data.gridApi || null;
|
||||
onSuccess.value = data.onSuccess || null;
|
||||
modalApi.setState({ title: title.value });
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* 打开开通/升级弹窗
|
||||
* 为什么不直接嵌在本弹窗:升级表单已有独立组件,复用可保持交互一致
|
||||
*/
|
||||
function openUpgrade() {
|
||||
if (!storeId.value) return;
|
||||
upgradeModalApi.setData({
|
||||
store_id: storeId.value,
|
||||
store_name: storeName.value,
|
||||
vip: vip.value,
|
||||
gridApi: gridApi.value,
|
||||
onSuccess: () => {
|
||||
onSuccess.value?.();
|
||||
gridApi.value?.query?.();
|
||||
},
|
||||
});
|
||||
upgradeModalApi.open();
|
||||
}
|
||||
|
||||
/** 打开当前门店开通记录(含开通人) */
|
||||
function openRecords() {
|
||||
if (!storeId.value) return;
|
||||
recordsModalApi.setData({
|
||||
store_id: storeId.value,
|
||||
store_name: storeName.value,
|
||||
});
|
||||
recordsModalApi.open();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal>
|
||||
<div class="vip-hub-current mb-4">
|
||||
<VipBadgeCombo
|
||||
size="md"
|
||||
:badge-url="vip?.badge_url"
|
||||
:duration-badge-url="vip?.duration_badge_url"
|
||||
:level-name="vip?.level_name"
|
||||
:duration-label="vip?.duration_label"
|
||||
/>
|
||||
<div class="vip-hub-current__text">{{ currentLevelText }}</div>
|
||||
</div>
|
||||
<div class="vip-hub-grid">
|
||||
<button type="button" class="vip-hub-card" @click="openUpgrade">
|
||||
<div class="vip-hub-card__icon">↑</div>
|
||||
<div class="vip-hub-card__title">开通 / 升级</div>
|
||||
<div class="vip-hub-card__desc">
|
||||
为该门店开通或调整会员等级与时长
|
||||
</div>
|
||||
</button>
|
||||
<button type="button" class="vip-hub-card" @click="openRecords">
|
||||
<div class="vip-hub-card__icon">☰</div>
|
||||
<div class="vip-hub-card__title">开通记录</div>
|
||||
<div class="vip-hub-card__desc">
|
||||
查看历史开通流水与开通人
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</Modal>
|
||||
<UpgradeModalComp />
|
||||
<RecordsModalComp />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.vip-hub-current {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 12px 14px;
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-radius: 10px;
|
||||
background: hsl(var(--muted) / 0.25);
|
||||
}
|
||||
.vip-hub-current__text {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
.vip-hub-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
.vip-hub-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
min-height: 148px;
|
||||
padding: 18px 16px;
|
||||
border: 1px solid hsl(var(--border));
|
||||
border-radius: 12px;
|
||||
background: hsl(var(--card, var(--background)));
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
border-color 0.15s,
|
||||
background 0.15s,
|
||||
box-shadow 0.15s;
|
||||
}
|
||||
.vip-hub-card:hover {
|
||||
border-color: hsl(var(--primary));
|
||||
background: hsl(var(--primary) / 0.08);
|
||||
box-shadow: 0 0 0 1px hsl(var(--primary) / 0.2);
|
||||
}
|
||||
.vip-hub-card__icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: hsl(var(--primary));
|
||||
background: hsl(var(--primary) / 0.12);
|
||||
}
|
||||
.vip-hub-card__title {
|
||||
font-size: 16px;
|
||||
font-weight: 650;
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
.vip-hub-card__desc {
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
color: hsl(var(--muted-foreground));
|
||||
}
|
||||
@media (max-width: 560px) {
|
||||
.vip-hub-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user