feat: 会员管理支持总会员创建、上架包含子会员与装饰图上传
- 集团新建时可勾选总会员 - 俱乐部上架/编辑时多选包含子会员 - 装饰图上传提示与编辑模式说明 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,7 +47,8 @@
|
||||
<div class="card-header">
|
||||
<div class="member-name-wrap">
|
||||
<div class="member-name">{{ member.jieshao }}</div>
|
||||
<el-tag v-if="member.trial_enabled" size="small" type="warning" class="trial-tag">体验可售</el-tag>
|
||||
<el-tag v-if="member.is_bundle" size="small" type="success" class="trial-tag">总会员</el-tag>
|
||||
<el-tag v-if="member.trial_enabled && !member.is_bundle" size="small" type="warning" class="trial-tag">体验可售</el-tag>
|
||||
</div>
|
||||
<div class="member-price">¥{{ formatMoney(member.jiage) }}<span class="days-hint">/{{ member.formal_days || 30 }}天</span></div>
|
||||
<div
|
||||
@@ -113,10 +114,10 @@
|
||||
<el-form-item label="组长分成(元)" prop="zuzhangfc">
|
||||
<el-input-number v-model="currentMember.zuzhangfc" :min="0" :precision="2" :step="1" :disabled="!isEditMode" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开启体验会员">
|
||||
<el-form-item label="开启体验会员" v-if="!currentMember.is_bundle">
|
||||
<el-switch v-model="currentMember.trial_enabled" :disabled="!isEditMode" />
|
||||
</el-form-item>
|
||||
<template v-if="currentMember.trial_enabled">
|
||||
<template v-if="currentMember.trial_enabled && !currentMember.is_bundle">
|
||||
<el-form-item label="体验价格(元)" prop="trial_price">
|
||||
<el-input-number v-model="currentMember.trial_price" :min="0.01" :precision="2" :step="1" :disabled="!isEditMode" style="width: 100%" />
|
||||
</el-form-item>
|
||||
@@ -133,7 +134,33 @@
|
||||
<el-form-item label="详细规则介绍" prop="jtjieshao">
|
||||
<el-input v-model="currentMember.jtjieshao" type="textarea" rows="4" :disabled="!isEditMode" />
|
||||
</el-form-item>
|
||||
<template v-if="!isAllClubScope">
|
||||
<el-alert
|
||||
v-if="isAllClubScope"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
title="装饰图需在具体俱乐部下配置"
|
||||
description="请先在顶栏切换到具体俱乐部,再点「编辑」上传充值页卡片装饰图/背景图。"
|
||||
class="member-card-scope-tip"
|
||||
/>
|
||||
<template v-else>
|
||||
<el-form-item v-if="currentMember.is_bundle" label="包含的子会员">
|
||||
<el-select
|
||||
v-model="currentMember.included_huiyuan_ids"
|
||||
multiple
|
||||
filterable
|
||||
:disabled="!isEditMode"
|
||||
placeholder="选择本俱乐部已上架的普通会员"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in clubSubMemberOptions"
|
||||
:key="opt.huiyuan_id"
|
||||
:label="`${opt.jieshao} (${opt.huiyuan_id})`"
|
||||
:value="opt.huiyuan_id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="充值页卡片装饰图">
|
||||
<div class="member-card-upload">
|
||||
<el-image v-if="currentMember.card_image" :src="memberCardUrl(currentMember.card_image)" fit="contain" class="member-card-preview" />
|
||||
@@ -147,6 +174,7 @@
|
||||
>
|
||||
<el-button size="small" type="primary" :loading="cardUploadField === 'card_image'">上传装饰图</el-button>
|
||||
</el-upload>
|
||||
<span v-else-if="!currentMember.card_image" class="member-card-hint">点击「编辑」后可上传</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="充值页卡片背景图">
|
||||
@@ -162,6 +190,7 @@
|
||||
>
|
||||
<el-button size="small" type="primary" :loading="cardUploadField === 'card_bg'">上传背景图</el-button>
|
||||
</el-upload>
|
||||
<span v-else-if="!currentMember.card_bg" class="member-card-hint">点击「编辑」后可上传</span>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</template>
|
||||
@@ -201,6 +230,10 @@
|
||||
<el-form-item label="详细规则介绍" prop="jtjieshao">
|
||||
<el-input v-model="addForm.jtjieshao" type="textarea" rows="4" placeholder="选填" />
|
||||
</el-form-item>
|
||||
<el-form-item label="总会员(包含式)">
|
||||
<el-switch v-model="addForm.is_bundle" />
|
||||
<span class="form-hint-inline">开启后可在俱乐部配置包含哪些子会员类型,无体验版</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="addDialogVisible = false">取消</el-button>
|
||||
@@ -223,7 +256,10 @@
|
||||
class="catalog-item"
|
||||
@click="openEnableDialog(item)"
|
||||
>
|
||||
<div class="catalog-name">{{ item.jieshao }}</div>
|
||||
<div class="catalog-name">
|
||||
{{ item.jieshao }}
|
||||
<el-tag v-if="item.is_bundle" size="small" type="success" style="margin-left:8px">总会员</el-tag>
|
||||
</div>
|
||||
<div class="catalog-id">ID: {{ item.huiyuan_id }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -245,6 +281,15 @@
|
||||
:title="enableTarget.jieshao"
|
||||
:description="`会员 ID:${enableTarget.huiyuan_id}`"
|
||||
/>
|
||||
<el-alert
|
||||
v-if="enableTarget.is_bundle"
|
||||
type="success"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="enable-tip"
|
||||
title="总会员(包含式)"
|
||||
description="无体验版。请配置价格/天数,并选择本俱乐部已上架的普通会员作为包含项。"
|
||||
/>
|
||||
<el-form :model="enableForm" :rules="enableRules" ref="enableFormRef" label-width="130px">
|
||||
<el-form-item label="正式价格(元)" prop="jiage">
|
||||
<el-input-number v-model="enableForm.jiage" :min="0.01" :precision="2" :step="1" style="width: 100%" />
|
||||
@@ -258,10 +303,26 @@
|
||||
<el-form-item label="组长分成(元)" prop="zuzhangfc">
|
||||
<el-input-number v-model="enableForm.zuzhangfc" :min="0" :precision="2" :step="1" style="width: 100%" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开启体验会员">
|
||||
<el-form-item v-if="enableTarget.is_bundle" label="包含的子会员" prop="included_huiyuan_ids">
|
||||
<el-select
|
||||
v-model="enableForm.included_huiyuan_ids"
|
||||
multiple
|
||||
filterable
|
||||
placeholder="选择本俱乐部已上架的普通会员(至少一个)"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in enableSubMemberOptions"
|
||||
:key="opt.huiyuan_id"
|
||||
:label="`${opt.jieshao} (${opt.huiyuan_id})`"
|
||||
:value="opt.huiyuan_id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="!enableTarget.is_bundle" label="开启体验会员">
|
||||
<el-switch v-model="enableForm.trial_enabled" />
|
||||
</el-form-item>
|
||||
<template v-if="enableForm.trial_enabled">
|
||||
<template v-if="enableForm.trial_enabled && !enableTarget.is_bundle">
|
||||
<el-form-item label="体验价格(元)" prop="trial_price">
|
||||
<el-input-number v-model="enableForm.trial_price" :min="0.01" :precision="2" :step="1" style="width: 100%" />
|
||||
</el-form-item>
|
||||
@@ -300,6 +361,16 @@ const memberList = ref([])
|
||||
const priceNote = ref('')
|
||||
const clubId = ref('xq')
|
||||
const isAllClubScope = computed(() => getAdminClubScope() === 'all')
|
||||
const clubSubMemberOptions = computed(() =>
|
||||
(memberList.value || []).filter(
|
||||
(m) => !m.is_bundle && m.huiyuan_id !== currentMember.value?.huiyuan_id,
|
||||
),
|
||||
)
|
||||
const enableSubMemberOptions = computed(() =>
|
||||
(memberList.value || []).filter(
|
||||
(m) => !m.is_bundle && m.huiyuan_id !== enableTarget.value?.huiyuan_id,
|
||||
),
|
||||
)
|
||||
|
||||
const detailDialogVisible = ref(false)
|
||||
const isEditMode = ref(false)
|
||||
@@ -371,7 +442,8 @@ function defaultClubPriceForm() {
|
||||
trial_price: 0,
|
||||
trial_days: 7,
|
||||
trial_guanshifc: 0,
|
||||
trial_zuzhangfc: 0
|
||||
trial_zuzhangfc: 0,
|
||||
included_huiyuan_ids: [],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,6 +461,8 @@ function normalizeMember(member) {
|
||||
trial_zuzhangfc: Number(member.trial_zuzhangfc || 0),
|
||||
card_image: member.card_image || '',
|
||||
card_bg: member.card_bg || '',
|
||||
is_bundle: Boolean(member.is_bundle),
|
||||
included_huiyuan_ids: Array.isArray(member.included_huiyuan_ids) ? [...member.included_huiyuan_ids] : [],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -502,6 +576,10 @@ const saveMember = async () => {
|
||||
if (!validatePriceSplit(m.jiage, m.guanshifc, m.zuzhangfc, m.trial_enabled, m.trial_price, m.trial_guanshifc, m.trial_zuzhangfc)) {
|
||||
return
|
||||
}
|
||||
if (m.is_bundle && (!m.included_huiyuan_ids || m.included_huiyuan_ids.length === 0)) {
|
||||
ElMessage.error('总会员请至少选择一个包含的子会员')
|
||||
return
|
||||
}
|
||||
try {
|
||||
await ElMessageBox.confirm('确定保存修改吗?', '确认', {
|
||||
confirmButtonText: '确认',
|
||||
@@ -523,6 +601,7 @@ const saveMember = async () => {
|
||||
jtjieshao: m.jtjieshao || '',
|
||||
card_image: m.card_image || '',
|
||||
card_bg: m.card_bg || '',
|
||||
included_huiyuan_ids: m.is_bundle ? (m.included_huiyuan_ids || []) : undefined,
|
||||
...buildTrialPayload(m)
|
||||
})
|
||||
if (res.code === 0) {
|
||||
@@ -557,7 +636,8 @@ const openAddDialog = () => {
|
||||
jiage: 0,
|
||||
guanshifc: 0,
|
||||
zuzhangfc: 0,
|
||||
jtjieshao: ''
|
||||
jtjieshao: '',
|
||||
is_bundle: false,
|
||||
}
|
||||
addDialogVisible.value = true
|
||||
}
|
||||
@@ -594,7 +674,8 @@ const submitAdd = async () => {
|
||||
jiage: addForm.value.jiage,
|
||||
guanshifc: addForm.value.guanshifc,
|
||||
zuzhangfc: addForm.value.zuzhangfc,
|
||||
jtjieshao: addForm.value.jtjieshao || ''
|
||||
jtjieshao: addForm.value.jtjieshao || '',
|
||||
is_bundle: addForm.value.is_bundle,
|
||||
})
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('创建成功')
|
||||
@@ -640,8 +721,11 @@ const closeCatalogDialog = () => {
|
||||
}
|
||||
|
||||
const openEnableDialog = (item) => {
|
||||
enableTarget.value = item
|
||||
enableTarget.value = { ...item, is_bundle: Boolean(item.is_bundle) }
|
||||
enableForm.value = defaultClubPriceForm()
|
||||
if (item.is_bundle) {
|
||||
enableForm.value.trial_enabled = false
|
||||
}
|
||||
enableDialogVisible.value = true
|
||||
catalogDialogVisible.value = false
|
||||
}
|
||||
@@ -666,16 +750,32 @@ const submitEnable = async () => {
|
||||
if (!validatePriceSplit(f.jiage, f.guanshifc, f.zuzhangfc, f.trial_enabled, f.trial_price, f.trial_guanshifc, f.trial_zuzhangfc)) {
|
||||
return
|
||||
}
|
||||
if (enableTarget.value.is_bundle) {
|
||||
if (!f.included_huiyuan_ids || f.included_huiyuan_ids.length === 0) {
|
||||
ElMessage.error('总会员请至少选择一个包含的子会员')
|
||||
return
|
||||
}
|
||||
if (enableSubMemberOptions.value.length === 0) {
|
||||
ElMessage.error('请先将至少一个普通会员上架,再配置总会员')
|
||||
return
|
||||
}
|
||||
}
|
||||
enabling.value = true
|
||||
try {
|
||||
const res = await request.post(JITUAN_API.memberEnable, {
|
||||
const payload = {
|
||||
username: username.value,
|
||||
huiyuan_id: enableTarget.value.huiyuan_id,
|
||||
jiage: f.jiage,
|
||||
formal_days: f.formal_days,
|
||||
guanshifc: f.guanshifc,
|
||||
zuzhangfc: f.zuzhangfc,
|
||||
...buildTrialPayload(f)
|
||||
})
|
||||
...buildTrialPayload(f),
|
||||
}
|
||||
if (enableTarget.value.is_bundle) {
|
||||
payload.trial_enabled = false
|
||||
payload.included_huiyuan_ids = f.included_huiyuan_ids
|
||||
}
|
||||
const res = await request.post(JITUAN_API.memberEnable, payload)
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('上架成功')
|
||||
enableDialogVisible.value = false
|
||||
@@ -860,6 +960,18 @@ onMounted(() => {
|
||||
border-radius: 8px;
|
||||
background: #0d2137;
|
||||
}
|
||||
.member-card-hint {
|
||||
font-size: 12px;
|
||||
color: #8ab3cf;
|
||||
}
|
||||
.member-card-scope-tip {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.form-hint-inline {
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #8ab3cf;
|
||||
}
|
||||
.no-permission {
|
||||
text-align: center;
|
||||
padding: 80px 20px;
|
||||
|
||||
Reference in New Issue
Block a user