feat: 转盘活动页与路由放行,轮播增加点单背景/横幅选项

修复侧栏可见但点转盘被踢到板块配置的问题;Carousel 增加 boss_center 与 accept_order_banner2。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-22 20:21:55 +08:00
parent 69fe2a51e0
commit 772d142a40
6 changed files with 313 additions and 10 deletions

View File

@@ -0,0 +1,269 @@
<template>
<div class="zhuanpan-page">
<el-alert
type="info"
:closable="false"
show-icon
class="tip"
title="转盘活动按当前俱乐部隔离"
description="切换顶部俱乐部后,此处活动/奖品只属于该俱乐部。任意俱乐部都可配置;小程序端接好转盘接口即可使用。"
/>
<div class="toolbar">
<el-button type="primary" @click="openHuodong()">新建转盘活动</el-button>
<el-button @click="loadHuodong">刷新</el-button>
</div>
<el-table :data="huodongList" v-loading="loading" border stripe>
<el-table-column prop="id" label="ID" width="70" />
<el-table-column prop="mingzi" label="活动名" min-width="140" />
<el-table-column prop="shangpin_id" label="购票商品ID" width="120" />
<el-table-column label="启用" width="90">
<template #default="{ row }">
<el-tag :type="row.qiyong ? 'success' : 'info'">{{ row.qiyong ? '启用' : '停用' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="beizhu" label="备注" min-width="120" />
<el-table-column label="操作" width="280" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="openHuodong(row)">编辑</el-button>
<el-button link type="primary" @click="openJiangpin(row)">奖品/概率</el-button>
<el-button link type="warning" @click="toggleHuodong(row)">{{ row.qiyong ? '停用' : '启用' }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 活动弹窗 -->
<el-dialog v-model="hdVisible" :title="hdForm.id ? '编辑活动' : '新建活动'" width="480px">
<el-form label-width="110px">
<el-form-item label="活动名称">
<el-input v-model="hdForm.mingzi" maxlength="64" />
</el-form-item>
<el-form-item label="购票商品ID">
<el-input-number v-model="hdForm.shangpin_id" :min="1" controls-position="right" />
<div class="form-tip">请填本俱乐部商品 ID保存后会标记该商品为转盘购票商品</div>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="hdForm.beizhu" />
</el-form-item>
<el-form-item label="启用">
<el-switch v-model="hdForm.qiyong" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="hdVisible = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="saveHuodong">保存</el-button>
</template>
</el-dialog>
<!-- 奖品弹窗 -->
<el-dialog v-model="jpVisible" :title="'奖品配置 - ' + (currentHd?.mingzi || '')" width="720px">
<div class="toolbar">
<el-button type="primary" size="small" @click="openJpEdit()">添加奖品</el-button>
<el-button size="small" @click="loadJiangpin">刷新</el-button>
</div>
<el-table :data="jiangpinList" v-loading="jpLoading" border size="small">
<el-table-column prop="paixu" label="格子序" width="80" />
<el-table-column prop="mingzi" label="名称" min-width="120" />
<el-table-column prop="quanzhong" label="权重" width="80" />
<el-table-column prop="shangpin_id" label="履约商品ID" width="110" />
<el-table-column label="谢谢参与" width="90">
<template #default="{ row }">{{ row.shi_xiexie ? '是' : '否' }}</template>
</el-table-column>
<el-table-column label="操作" width="140">
<template #default="{ row }">
<el-button link type="primary" @click="openJpEdit(row)">编辑</el-button>
<el-button link type="danger" @click="delJiangpin(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<el-dialog v-model="jpEditVisible" :title="jpForm.id ? '编辑奖品' : '添加奖品'" width="480px">
<el-form label-width="110px">
<el-form-item label="名称"><el-input v-model="jpForm.mingzi" /></el-form-item>
<el-form-item label="格子序号"><el-input-number v-model="jpForm.paixu" :min="0" :max="20" /></el-form-item>
<el-form-item label="中奖权重"><el-input-number v-model="jpForm.quanzhong" :min="0" /></el-form-item>
<el-form-item label="履约商品ID">
<el-input-number v-model="jpForm.shangpin_id" :min="0" />
<div class="form-tip">中奖后生成抢单池订单的商品谢谢参与可留空</div>
</el-form-item>
<el-form-item label="图标URL"><el-input v-model="jpForm.tupian_url" placeholder="相对路径或完整URL" /></el-form-item>
<el-form-item label="谢谢参与"><el-switch v-model="jpForm.shi_xiexie" /></el-form-item>
</el-form>
<template #footer>
<el-button @click="jpEditVisible = false">取消</el-button>
<el-button type="primary" :loading="saving" @click="saveJiangpin">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import request from '@/utils/request'
const loading = ref(false)
const jpLoading = ref(false)
const saving = ref(false)
const huodongList = ref([])
const jiangpinList = ref([])
const currentHd = ref(null)
const hdVisible = ref(false)
const hdForm = reactive({ id: null, mingzi: '幸运转盘', shangpin_id: null, beizhu: '', qiyong: true })
const jpVisible = ref(false)
const jpEditVisible = ref(false)
const jpForm = reactive({
id: null, mingzi: '', paixu: 0, quanzhong: 1, shangpin_id: null, tupian_url: '', shi_xiexie: false
})
async function loadHuodong() {
loading.value = true
try {
const res = await request.post('/shangpin/adzhuanpanhd', { action: 'list' })
if (res.code === 0) huodongList.value = res.data || []
else ElMessage.error(res.msg || '加载失败')
} finally {
loading.value = false
}
}
function openHuodong(row) {
if (row) {
Object.assign(hdForm, {
id: row.id,
mingzi: row.mingzi,
shangpin_id: row.shangpin_id,
beizhu: row.beizhu || '',
qiyong: !!row.qiyong
})
} else {
Object.assign(hdForm, { id: null, mingzi: '幸运转盘', shangpin_id: null, beizhu: '', qiyong: true })
}
hdVisible.value = true
}
async function saveHuodong() {
if (!hdForm.shangpin_id) {
ElMessage.warning('请填写购票商品ID')
return
}
saving.value = true
try {
const res = await request.post('/shangpin/adzhuanpanhd', {
action: 'save',
id: hdForm.id,
mingzi: hdForm.mingzi,
shangpin_id: hdForm.shangpin_id,
beizhu: hdForm.beizhu,
qiyong: hdForm.qiyong
})
if (res.code === 0) {
ElMessage.success('已保存')
hdVisible.value = false
loadHuodong()
} else ElMessage.error(res.msg || '保存失败')
} finally {
saving.value = false
}
}
async function toggleHuodong(row) {
const res = await request.post('/shangpin/adzhuanpanhd', { action: 'toggle', id: row.id })
if (res.code === 0) {
ElMessage.success('已更新')
loadHuodong()
} else ElMessage.error(res.msg || '操作失败')
}
async function openJiangpin(row) {
currentHd.value = row
jpVisible.value = true
await loadJiangpin()
}
async function loadJiangpin() {
if (!currentHd.value) return
jpLoading.value = true
try {
const res = await request.post('/shangpin/adzhuanpanjp', {
action: 'list',
huodong_id: currentHd.value.id
})
if (res.code === 0) jiangpinList.value = res.data || []
else ElMessage.error(res.msg || '加载失败')
} finally {
jpLoading.value = false
}
}
function openJpEdit(row) {
if (row) {
Object.assign(jpForm, {
id: row.id,
mingzi: row.mingzi,
paixu: row.paixu,
quanzhong: row.quanzhong,
shangpin_id: row.shangpin_id,
tupian_url: row.tupian_url || '',
shi_xiexie: !!row.shi_xiexie
})
} else {
Object.assign(jpForm, {
id: null, mingzi: '', paixu: jiangpinList.value.length, quanzhong: 1,
shangpin_id: null, tupian_url: '', shi_xiexie: false
})
}
jpEditVisible.value = true
}
async function saveJiangpin() {
if (!currentHd.value) return
saving.value = true
try {
const res = await request.post('/shangpin/adzhuanpanjp', {
action: 'save',
huodong_id: currentHd.value.id,
id: jpForm.id,
mingzi: jpForm.mingzi,
paixu: jpForm.paixu,
quanzhong: jpForm.quanzhong,
shangpin_id: jpForm.shangpin_id || null,
tupian_url: jpForm.tupian_url,
shi_xiexie: jpForm.shi_xiexie
})
if (res.code === 0) {
ElMessage.success('已保存')
jpEditVisible.value = false
loadJiangpin()
} else ElMessage.error(res.msg || '保存失败')
} finally {
saving.value = false
}
}
async function delJiangpin(row) {
await ElMessageBox.confirm('确认删除该奖品?', '提示')
const res = await request.post('/shangpin/adzhuanpanjp', {
action: 'delete',
huodong_id: currentHd.value.id,
id: row.id
})
if (res.code === 0) {
ElMessage.success('已删除')
loadJiangpin()
} else ElMessage.error(res.msg || '删除失败')
}
onMounted(loadHuodong)
</script>
<style scoped>
.zhuanpan-page { padding: 8px; }
.tip { margin-bottom: 12px; }
.toolbar { margin-bottom: 12px; display: flex; gap: 8px; }
.form-tip { color: #909399; font-size: 12px; line-height: 1.4; margin-top: 4px; }
</style>