会员模块+入驻配置模块

This commit is contained in:
yuhawu 2025-07-04 18:38:16 +08:00
parent cf13ef2881
commit d04e5d5f3d
7 changed files with 2279 additions and 26 deletions

1
.idea/newAdmin.iml generated
View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4"> <module type="JAVA_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager" inherit-compiler-output="true"> <component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$" /> <content url="file://$MODULE_DIR$" />

View File

@ -7,4 +7,5 @@ setupRequestInterceptors(instance)
setupResponseInterceptors(instance) setupResponseInterceptors(instance)
// 导出所有模块接口 // 导出所有模块接口
export { adminApi } from './modules/admin' export { adminApi } from './modules/admin'
export { invitationApi } from './modules/invitation'

View File

@ -56,6 +56,15 @@
} }
] ]
}, },
{
title: '邀请管理',
path: '/invitation',
children: [{
title: '邀请列表',
path: '/invitation/list'
}
]
},
{ {
title: '日志管理', title: '日志管理',
path: '/log', path: '/log',

View File

@ -52,6 +52,11 @@ const routes = [{
path: '/useModule/vas/list', path: '/useModule/vas/list',
component: () => import('@/views/UseModule/Vas/List.vue'), component: () => import('@/views/UseModule/Vas/List.vue'),
meta: { title: '订阅服务' } meta: { title: '订阅服务' }
},
{
path: '/invitation/list',
component: () => import('@/views/Invitation/List/index.vue'),
meta: { title: '邀请列表' }
} }
] ]
}] }]

File diff suppressed because it is too large Load Diff

View File

@ -73,6 +73,7 @@
<el-table-column prop="id" align="center" label="记录ID" width="80" /> <el-table-column prop="id" align="center" label="记录ID" width="80" />
<el-table-column prop="userId" align="center" label="用户ID" width="100" /> <el-table-column prop="userId" align="center" label="用户ID" width="100" />
<el-table-column prop="title" align="center" label="会员名称" width="120" /> <el-table-column prop="title" align="center" label="会员名称" width="120" />
<el-table-column prop="phoneNumber" align="center" label="手机号" width="120" />
<el-table-column prop="settledCostKey" align="center" label="入驻标识" width="150" /> <el-table-column prop="settledCostKey" align="center" label="入驻标识" width="150" />
<el-table-column align="center" label="创建时间" width="180"> <el-table-column align="center" label="创建时间" width="180">
<template #default="{ row }"> <template #default="{ row }">
@ -483,7 +484,7 @@ watch(() => formData.constraintJson, (newVal) => {
// //
onMounted(() => { onMounted(() => {
fetchData() fetchData()
fetchConfigOptions() // fetchConfigOptions()
}) })
// //

View File

@ -2,7 +2,7 @@
<el-dialog <el-dialog
:title="formData.id ? '编辑入驻配置' : '新增入驻配置'" :title="formData.id ? '编辑入驻配置' : '新增入驻配置'"
v-model="dialogVisible" v-model="dialogVisible"
width="600px" width="800px"
:close-on-click-modal="false" :close-on-click-modal="false"
@close="handleClose" @close="handleClose"
> >
@ -10,7 +10,7 @@
ref="formRef" ref="formRef"
:model="formData" :model="formData"
:rules="rules" :rules="rules"
label-width="120px" label-width="150px"
label-position="right" label-position="right"
> >
<el-form-item label="标题" prop="title"> <el-form-item label="标题" prop="title">
@ -21,6 +21,18 @@
<el-input v-model="formData.settledCostKey" placeholder="请输入入驻标识" /> <el-input v-model="formData.settledCostKey" placeholder="请输入入驻标识" />
</el-form-item> </el-form-item>
<el-form-item label="最小书本数量">
<el-input-number v-model="constraint.books_count_min" :min="0" :precision="0" @change="updateConstraintJson" />
<span class="unit-label"></span>
</el-form-item>
<el-form-item label="最大书本数量">
<el-input-number v-model="constraint.books_count_max" :min="0" :precision="0" @change="updateConstraintJson" />
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">佣金设置</el-divider>
<el-form-item label="佣金类型" prop="kickbackType"> <el-form-item label="佣金类型" prop="kickbackType">
<el-select v-model="formData.kickbackType" placeholder="请选择佣金类型"> <el-select v-model="formData.kickbackType" placeholder="请选择佣金类型">
<el-option label="预留" :value="0" /> <el-option label="预留" :value="0" />
@ -59,6 +71,320 @@
<span class="unit-label"></span> <span class="unit-label"></span>
</el-form-item> </el-form-item>
<el-divider content-position="center">小程序收费</el-divider>
<el-form-item label="小程序月收费">
<el-input-number v-model="constraint.miniapp.month_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="小程序年收费">
<el-input-number v-model="constraint.miniapp.year_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="小程序佣金类型">
<el-select v-model="constraint.miniapp.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.miniapp.kickback_type)" label="小程序提点比例">
<el-input-number
v-model="constraint.miniapp.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.miniapp.kickback_type)" label="小程序固定费用">
<el-input-number
v-model="constraint.miniapp.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">新增账号收费</el-divider>
<el-form-item label="新增账号月收费">
<el-input-number v-model="constraint.new_account.month_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="新增账号年收费">
<el-input-number v-model="constraint.new_account.year_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="新增账号佣金类型">
<el-select v-model="constraint.new_account.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.new_account.kickback_type)" label="新增账号提点比例">
<el-input-number
v-model="constraint.new_account.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.new_account.kickback_type)" label="新增账号固定费用">
<el-input-number
v-model="constraint.new_account.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">孔夫子店铺收费</el-divider>
<el-form-item label="孔夫子店铺月收费">
<el-input-number v-model="constraint.kongfz_store.month_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="孔夫子店铺年收费">
<el-input-number v-model="constraint.kongfz_store.year_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="孔夫子店铺佣金类型">
<el-select v-model="constraint.kongfz_store.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.kongfz_store.kickback_type)" label="孔夫子店铺提点比例">
<el-input-number
v-model="constraint.kongfz_store.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.kongfz_store.kickback_type)" label="孔夫子店铺固定费用">
<el-input-number
v-model="constraint.kongfz_store.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">拼多多专营店收费</el-divider>
<el-form-item label="拼多多专营店月收费">
<el-input-number v-model="constraint.pdd_store.month_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="拼多多专营店年收费">
<el-input-number v-model="constraint.pdd_store.year_fee" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="拼多多专营店佣金类型">
<el-select v-model="constraint.pdd_store.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.pdd_store.kickback_type)" label="拼多多专营店提点比例">
<el-input-number
v-model="constraint.pdd_store.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.pdd_store.kickback_type)" label="拼多多专营店固定费用">
<el-input-number
v-model="constraint.pdd_store.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">资源费阶梯设置</el-divider>
<el-form-item label="图书数量范围">
<div class="range-fields">
<span>0 - 3000:</span>
<el-input-number v-model="constraint.resource_fee.range1" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</div>
</el-form-item>
<el-form-item label="3000 - 20000条">
<el-input-number v-model="constraint.resource_fee.range2" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="20000 - 50000条">
<el-input-number v-model="constraint.resource_fee.range3" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="50000 - 100000条">
<el-input-number v-model="constraint.resource_fee.range4" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="100000条以上">
<el-input-number v-model="constraint.resource_fee.range5" :min="0" :precision="2" @change="updateConstraintJson" />
<span class="unit-label">/</span>
</el-form-item>
<el-form-item label="资源费佣金类型">
<el-select v-model="constraint.resource_fee.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.resource_fee.kickback_type)" label="资源费提点比例">
<el-input-number
v-model="constraint.resource_fee.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.resource_fee.kickback_type)" label="资源费固定费用">
<el-input-number
v-model="constraint.resource_fee.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">交易手续费设置</el-divider>
<el-form-item label="同库房同店铺佣金类型">
<el-select v-model="constraint.transaction_fee.same_store.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.transaction_fee.same_store.kickback_type)" label="同库房同店铺提点比例">
<el-input-number
v-model="constraint.transaction_fee.same_store.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.transaction_fee.same_store.kickback_type)" label="同库房同店铺固定费用">
<el-input-number
v-model="constraint.transaction_fee.same_store.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider content-position="center">同库房不同店铺设置</el-divider>
<el-form-item label="扣库房金额">
<el-input-number
v-model="constraint.transaction_fee.diff_store.warehouse_fee"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-form-item label="扣店主金额">
<el-input-number
v-model="constraint.transaction_fee.diff_store.shop_owner_fee"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-form-item label="不同店铺佣金类型">
<el-select v-model="constraint.transaction_fee.diff_store.kickback_type" placeholder="请选择佣金类型" @change="updateConstraintJson">
<el-option label="预留" :value="0" />
<el-option label="提点" :value="1" />
<el-option label="固定费用" :value="2" />
<el-option label="提点/固费" :value="3" />
</el-select>
</el-form-item>
<el-form-item v-if="[1, 3].includes(constraint.transaction_fee.diff_store.kickback_type)" label="不同店铺提点比例">
<el-input-number
v-model="constraint.transaction_fee.diff_store.kickback_point"
:min="0"
:max="100"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label">%</span>
</el-form-item>
<el-form-item v-if="[2, 3].includes(constraint.transaction_fee.diff_store.kickback_type)" label="不同店铺固定费用">
<el-input-number
v-model="constraint.transaction_fee.diff_store.kickback_fixed"
:min="0"
:precision="2"
@change="updateConstraintJson"
/>
<span class="unit-label"></span>
</el-form-item>
<el-divider></el-divider>
<el-form-item label="资源费类型" prop="resourceCostType"> <el-form-item label="资源费类型" prop="resourceCostType">
<el-select v-model="formData.resourceCostType" placeholder="请选择资源费类型"> <el-select v-model="formData.resourceCostType" placeholder="请选择资源费类型">
<el-option label="类型1" :value="1" /> <el-option label="类型1" :value="1" />
@ -126,6 +452,117 @@ const dialogVisible = ref(props.visible)
const loading = ref(false) const loading = ref(false)
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
//
const constraint = reactive({
books_count_min: 0,
books_count_max: 3000,
miniapp: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
new_account: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
kongfz_store: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
pdd_store: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
resource_fee: {
range1: 0, // 0-3000
range2: 50, // 3000-20000
range3: 100, // 20000-50000
range4: 200, // 50000-100000
range5: 300, // 100000
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
transaction_fee: {
same_store: {
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
diff_store: {
warehouse_fee: 0,
shop_owner_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
}
}
})
// constraintJson
const updateConstraintJson = () => {
formData.constraintJson = JSON.stringify(constraint)
}
// constraintJson
const parseConstraintJson = (jsonStr: string) => {
try {
const data = JSON.parse(jsonStr)
// books_count
constraint.books_count_min = data.books_count_min ?? 0
constraint.books_count_max = data.books_count_max ?? 3000
//
if (data.miniapp) {
Object.assign(constraint.miniapp, data.miniapp)
}
//
if (data.new_account) {
Object.assign(constraint.new_account, data.new_account)
}
//
if (data.kongfz_store) {
Object.assign(constraint.kongfz_store, data.kongfz_store)
}
//
if (data.pdd_store) {
Object.assign(constraint.pdd_store, data.pdd_store)
}
//
if (data.resource_fee) {
Object.assign(constraint.resource_fee, data.resource_fee)
}
//
if (data.transaction_fee) {
if (data.transaction_fee.same_store) {
Object.assign(constraint.transaction_fee.same_store, data.transaction_fee.same_store)
}
if (data.transaction_fee.diff_store) {
Object.assign(constraint.transaction_fee.diff_store, data.transaction_fee.diff_store)
}
}
} catch (e) {
console.error('解析约束条件失败:', e)
}
}
// //
const formData = reactive({ const formData = reactive({
id: '', id: '',
@ -139,7 +576,7 @@ const formData = reactive({
price: 0, price: 0,
state: 1, state: 1,
note: '', note: '',
constraintJson: '{"books_count_min":0,"books_count_max":3000}' constraintJson: JSON.stringify(constraint)
}) })
// //
@ -185,6 +622,13 @@ watch(() => formData.kickbackValue, (newVal) => {
} }
}, { immediate: true }) }, { immediate: true })
// constraintJson
watch(() => formData.constraintJson, (newVal) => {
if (newVal && typeof newVal === 'string') {
parseConstraintJson(newVal)
}
}, { immediate: true })
// visible // visible
watch(() => props.visible, (val) => { watch(() => props.visible, (val) => {
dialogVisible.value = val dialogVisible.value = val
@ -208,6 +652,10 @@ watch(() => props.visible, (val) => {
if (props.editData.kickback_value) { if (props.editData.kickback_value) {
parseKickbackJson(props.editData.kickback_value) parseKickbackJson(props.editData.kickback_value)
} }
//
if (props.editData.constraint_json) {
parseConstraintJson(props.editData.constraint_json)
}
} }
}) })
@ -224,6 +672,69 @@ const resetForm = () => {
if (formRef.value) { if (formRef.value) {
formRef.value.resetFields() formRef.value.resetFields()
} }
//
Object.assign(constraint, {
books_count_min: 0,
books_count_max: 3000,
miniapp: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
new_account: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
kongfz_store: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
pdd_store: {
month_fee: 0,
year_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
resource_fee: {
range1: 0,
range2: 50,
range3: 100,
range4: 200,
range5: 300,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
transaction_fee: {
same_store: {
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
},
diff_store: {
warehouse_fee: 0,
shop_owner_fee: 0,
kickback_type: 0,
kickback_point: 0,
kickback_fixed: 0
}
}
})
// constraintJson
updateConstraintJson()
//
Object.assign(formData, { Object.assign(formData, {
id: '', id: '',
title: '', title: '',
@ -236,8 +747,9 @@ const resetForm = () => {
price: 0, price: 0,
state: 1, state: 1,
note: '', note: '',
constraintJson: '{"books_count_min":0,"books_count_max":3000}' constraintJson: JSON.stringify(constraint)
}) })
kickbackPoint.value = 0 kickbackPoint.value = 0
kickbackFixed.value = 0 kickbackFixed.value = 0
} }
@ -246,6 +758,9 @@ const resetForm = () => {
const handleSubmit = async () => { const handleSubmit = async () => {
if (!formRef.value) return if (!formRef.value) return
// constraintJson
updateConstraintJson()
await formRef.value.validate(async (valid) => { await formRef.value.validate(async (valid) => {
if (valid) { if (valid) {
loading.value = true loading.value = true
@ -288,4 +803,14 @@ const handleClose = () => {
margin-left: 8px; margin-left: 8px;
color: #909399; color: #909399;
} }
.el-divider {
margin: 16px 0;
}
.range-fields {
display: flex;
align-items: center;
gap: 8px;
}
</style> </style>