From 5cbfb2866c804ab5efce2f4ad5fcae88323a7b66 Mon Sep 17 00:00:00 2001 From: movingsam Date: Wed, 18 Feb 2026 23:34:40 +0800 Subject: [PATCH] refactor: clean up Member module and update Console - Remove redundant PointsRule repositories (use single PointsRuleRepository) - Clean up Member migrations and consolidate to single Init migration - Update Console frontend API and components for Tenant - Add H5LinkService for member H5 integration --- apps/web-ele/src/api/fengling/tenant.ts | 9 + apps/web-ele/src/api/fengling/typings.ts | 12 + .../src/views/fengling/tenants/index.vue | 38 ++- .../src/views/member-h5/auth/login.vue | 221 ++++++++++++++++++ .../src/views/member-h5/home/index.vue | 201 ++++++++++++++++ 5 files changed, 480 insertions(+), 1 deletion(-) create mode 100644 apps/web-ele/src/views/member-h5/auth/login.vue create mode 100644 apps/web-ele/src/views/member-h5/home/index.vue diff --git a/apps/web-ele/src/api/fengling/tenant.ts b/apps/web-ele/src/api/fengling/tenant.ts index 18d09e6..e54874a 100644 --- a/apps/web-ele/src/api/fengling/tenant.ts +++ b/apps/web-ele/src/api/fengling/tenant.ts @@ -71,4 +71,13 @@ export namespace TenantApi { export async function updateTenantSettings(id: number, data: FenglingApi.Tenant.TenantSettings) { return requestClient.put(`${apiPrefix}/tenants/${id}/settings`, data); } + + export interface H5LinkResult { + link: string; + qrCodeBase64: string; + } + + export async function getH5Link(id: number) { + return requestClient.get(`${apiPrefix}/tenants/${id}/h5-link`); + } } diff --git a/apps/web-ele/src/api/fengling/typings.ts b/apps/web-ele/src/api/fengling/typings.ts index f284d56..f4d4244 100644 --- a/apps/web-ele/src/api/fengling/typings.ts +++ b/apps/web-ele/src/api/fengling/typings.ts @@ -13,6 +13,10 @@ export namespace FenglingApi { expiresAt?: string description?: string createdAt: string + customDomain?: string + basePath?: string + logo?: string + h5BaseUrl?: string } export interface CreateTenantDto { @@ -25,6 +29,10 @@ export namespace FenglingApi { expiresAt?: string status?: string description?: string + customDomain?: string + basePath?: string + logo?: string + h5BaseUrl?: string } export interface UpdateTenantDto { @@ -36,6 +44,10 @@ export namespace FenglingApi { expiresAt?: string status?: string description?: string + customDomain?: string + basePath?: string + logo?: string + h5BaseUrl?: string } export interface TenantSettings { diff --git a/apps/web-ele/src/views/fengling/tenants/index.vue b/apps/web-ele/src/views/fengling/tenants/index.vue index 4a29016..35a0ee1 100644 --- a/apps/web-ele/src/views/fengling/tenants/index.vue +++ b/apps/web-ele/src/views/fengling/tenants/index.vue @@ -114,6 +114,31 @@ const handleSave = async () => { } }; +const qrCodeVisible = ref(false); +const qrCodeUrl = ref(''); +const currentTenantName = ref(''); + +const handleCopyLink = async (row: FenglingApi.Tenant.Tenant) => { + try { + const { link } = await TenantApi.getH5Link(row.id); + await navigator.clipboard.writeText(link); + ElMessage.success('Link copied to clipboard'); + } catch (error) { + ElMessage.error('Failed to copy link'); + } +}; + +const handleShowQrCode = async (row: FenglingApi.Tenant.Tenant) => { + try { + const { link, qrCodeBase64 } = await TenantApi.getH5Link(row.id); + qrCodeUrl.value = `data:image/png;base64,${qrCodeBase64}`; + currentTenantName.value = row.name; + qrCodeVisible.value = true; + } catch (error) { + ElMessage.error('Failed to generate QR code'); + } +}; + onMounted(() => { loadTenants(); }); @@ -157,9 +182,11 @@ onMounted(() => { - + diff --git a/apps/web-ele/src/views/member-h5/auth/login.vue b/apps/web-ele/src/views/member-h5/auth/login.vue new file mode 100644 index 0000000..24ba91b --- /dev/null +++ b/apps/web-ele/src/views/member-h5/auth/login.vue @@ -0,0 +1,221 @@ + + + + + diff --git a/apps/web-ele/src/views/member-h5/home/index.vue b/apps/web-ele/src/views/member-h5/home/index.vue new file mode 100644 index 0000000..9a4ec11 --- /dev/null +++ b/apps/web-ele/src/views/member-h5/home/index.vue @@ -0,0 +1,201 @@ + + + + +