fix: 商品管理菜单在具体俱乐部可见,支持专区与商品管理

侧栏不再要求集团汇总才显示商品列表/类型专区;类型CRUD仍仅集团汇总可写。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-21 03:24:44 +08:00
parent c5bb036b68
commit 23f7263996
4 changed files with 94 additions and 27 deletions

View File

@@ -110,6 +110,10 @@
<el-icon><Warning /></el-icon>
<span>处罚管理</span>
</el-menu-item>
<el-menu-item v-if="canShow('gongdan')" index="/gongdan">
<el-icon><ChatDotRound /></el-icon>
<span>投诉工单</span>
</el-menu-item>
<!-- 商品管理 -->
<el-sub-menu v-if="canShow('product')" index="/product">
@@ -117,9 +121,9 @@
<el-icon><Goods /></el-icon>
<span>商品管理</span>
</template>
<el-menu-item v-if="canShow('product.list') && isAllClubScope" index="/product/list">商品列表</el-menu-item>
<el-menu-item v-if="canShow('product.type-zone') && isAllClubScope" index="/product/type-zone">商品类型专区管理</el-menu-item>
<el-menu-item v-if="canShow('product.data') && isAllClubScope" index="/product/data">商品数据分析</el-menu-item>
<el-menu-item v-if="canShow('product.list')" index="/product/list">商品列表</el-menu-item>
<el-menu-item v-if="canShow('product.type-zone')" index="/product/type-zone">商品类型专区管理</el-menu-item>
<el-menu-item v-if="canShow('product.data')" index="/product/data">商品数据分析</el-menu-item>
<el-menu-item v-if="canShow('product.fake-orders')" index="/product/fake-orders">假单管理</el-menu-item>
</el-sub-menu>
@@ -251,7 +255,7 @@ import { useRoute, useRouter } from 'vue-router'
import { ElMessage, ElNotification } from 'element-plus'
import {
List, User, Warning, Money, Fold, Expand, Connection, Setting,
Goods, UserFilled, Shop, Comment,DataAnalysis, Medal // 新增
Goods, UserFilled, Shop, Comment, DataAnalysis, Medal, ChatDotRound
} from '@element-plus/icons-vue'
import request from '@/utils/request'
import KefuConnect from '@/components/KefuConnect.vue'
@@ -430,9 +434,9 @@ const agentUnread = ref(0) // 未读消息总数
const permPrefixMap = {
'abca1': 'Ds', // 打手
'baac2': 'Boss', // 老板
'cabc3': 'Gs', // 管事
'cabc3': 'Ds', // 管事(与小程序一致,统一 Ds
'cb3a2': 'Sj', // 商家
'bcaa4': 'Zz' // 组长
'bcaa4': 'Ds' // 组长(与小程序一致,统一 Ds
}
// 获取客服权限及GoEasy配置

View File

@@ -7,24 +7,41 @@
<div class="no-permission-desc">请联系管理员开通权限</div>
</div>
<div v-else-if="!isAllClubScope" class="scope-block">
<div v-else>
<el-alert
type="warning"
v-if="isAllClubScope"
type="info"
:closable="false"
show-icon
title="当前为具体小程序视图"
description="商品为集团全局数据,不可在此视图修改。请切换顶栏为「集团汇总(全部子公司)」后管理商品;本俱乐部抢单展示请在「小程序配置 → 抢单商品类型」中上架/换图标。"
class="scope-tip"
title="当前为集团汇总视图"
description="此处可看全部俱乐部专区/商品。新增商品会写入当前请求头俱乐部;「只看审核」开关请切到具体小程序后再改。类型定义仍在「商品类型专区管理」;各小程序上架类型请用「抢单商品类型」。"
/>
<el-alert
v-else
type="success"
:closable="false"
show-icon
class="scope-tip"
title="当前为具体小程序视图"
description="专区与商品按本俱乐部隔离。类型为集团共享定义;本俱乐部抢单展示请在「小程序配置 → 抢单商品类型」上架。下方可设置未绑店用户看审核商品还是正常商品。"
/>
<el-button type="primary" link @click="$router.push('/miniapp/leixing')">前往抢单商品类型</el-button>
</div>
<div v-else>
<!-- 顶部操作栏 -->
<div class="action-bar">
<el-button type="primary" @click="openAddDialog" :icon="Plus">添加商品</el-button>
<div class="audit-switch">
<span>显示审核专用</span>
<el-switch v-model="showAudit" @change="onAuditSwitchChange" />
<template v-if="!isAllClubScope">
<span class="switch-gap">只看审核商品</span>
<el-switch
v-model="zhiKanShenhe"
:loading="zhiKanLoading"
@change="onZhiKanChange"
/>
<span class="switch-hint">未绑店且无打手等身份时生效</span>
</template>
</div>
</div>
@@ -265,6 +282,7 @@
<el-button type="primary" @click="submitAddProduct" :loading="submitting">确认发布</el-button>
</template>
</el-dialog>
</div>
</div>
</template>
@@ -288,6 +306,9 @@ const zoneList = ref([]) // 同上
const memberList = ref([])
const showAudit = ref(false)
const zhiKanShenhe = ref(true)
const zhiKanLoading = ref(false)
const zhiKanReady = ref(false) // 避免初次赋值触发 change
// 展示用的类型列表:按 paixu 降序(大的在前),并过滤审核状态
const typeListDisplay = computed(() => {
let list = [...typeList.value]
@@ -775,15 +796,15 @@ const handleDeleteProduct = async (productId) => {
// ---------- 基础数据获取 ----------
const fetchBaseData = async () => {
if (!isAllClubScope.value) return
try {
const res = await request.post('/houtai/htsphqjcsx', { username: username.value })
if (res.code === 0) {
typeList.value = res.data.type_list || []
zoneList.value = res.data.zone_list || []
memberList.value = res.data.member_list || []
// 注意:后端返回的 paixu 已经是倒序值(越大越靠前),我们不需要修改
// 展示时会通过计算属性按 paixu 降序排序,视觉上从上到下顺序正确
zhiKanReady.value = false
zhiKanShenhe.value = res.data.zhi_kan_shenhe !== false
nextTick(() => { zhiKanReady.value = true })
const firstNormal = typeListDisplay.value[0]
if (firstNormal) {
selectedTypeId.value = firstNormal.id
@@ -800,6 +821,28 @@ const fetchBaseData = async () => {
}
}
const onZhiKanChange = async (val) => {
if (!zhiKanReady.value || isAllClubScope.value) return
zhiKanLoading.value = true
try {
const res = await request.post('/houtai/htxgzhikan', {
username: username.value,
zhi_kan_shenhe: val,
})
if (res.code === 0) {
ElMessage.success(val ? '已开启:未绑店无身份用户只看审核商品' : '已关闭:未绑店用户看正常商品')
} else {
zhiKanShenhe.value = !val
ElMessage.error(res.msg || '更新失败')
}
} catch (e) {
zhiKanShenhe.value = !val
ElMessage.error('更新失败')
} finally {
zhiKanLoading.value = false
}
}
const getFullUrl = (path) => {
if (!path) return ''
const ossUrl = window.$ossURL || ''
@@ -820,6 +863,7 @@ onMounted(() => {
<style scoped>
.scope-block { padding: 24px; }
.scope-tip { margin-bottom: 16px; }
/* 整体容器 */
.product-list-container {
padding: 20px;
@@ -837,10 +881,18 @@ onMounted(() => {
align-items: center;
gap: 12px;
background: rgba(0,0,0,0.4);
flex-wrap: wrap;
padding: 6px 16px;
border-radius: 20px;
backdrop-filter: blur(4px);
}
.switch-gap {
margin-left: 8px;
}
.switch-hint {
font-size: 12px;
opacity: 0.7;
}
.types-zones-section {
display: flex;
gap: 24px;

View File

@@ -7,20 +7,28 @@
<div class="no-permission-desc">请联系管理员开通权限</div>
</div>
<div v-else-if="!isAllClubScope" class="scope-block">
<div v-else>
<el-alert
type="warning"
v-if="!isAllClubScope"
type="success"
:closable="false"
show-icon
class="scope-tip"
title="当前为具体小程序视图"
description="此处不可新增/编辑/删除全局商品类型请切换顶栏为「集团汇总」后使用本页;或在「小程序配置 → 抢单商品类型」中仅做上架/下架与换图标。"
description="可管理本俱乐部专区(增删改)。商品类型为集团共享定义,添加/编辑/删除类型请切「集团汇总」;本俱乐部上架类型请用「小程序配置 → 抢单商品类型」。"
/>
<el-alert
v-else
type="info"
:closable="false"
show-icon
class="scope-tip"
title="当前为集团汇总视图"
description="可维护全局商品类型。专区会写入当前请求头对应俱乐部;管理某小程序专区请切到该小程序。"
/>
<el-button type="primary" link @click="$router.push('/miniapp/leixing')">前往抢单商品类型</el-button>
</div>
<div v-else>
<!-- 费率展示区域 -->
<div class="rate-card">
<!-- 费率展示区域集团汇总才改费率 -->
<div class="rate-card" v-if="isAllClubScope">
<el-row :gutter="20">
<el-col :xs="24" :sm="12">
<div class="rate-item">
@@ -46,7 +54,7 @@
<div class="section-header">
<h3>商品类型</h3>
<div class="header-actions">
<el-button type="primary" size="small" @click="addType">+ 添加类型</el-button>
<el-button v-if="isAllClubScope" type="primary" size="small" @click="addType">+ 添加类型</el-button>
<div class="audit-toggle">
<span>显示审核专用</span>
<el-switch v-model="showAuditType" @change="refreshTypeList" />
@@ -71,7 +79,7 @@
<span class="zone-count">专区数{{ getZoneCountByType(type.id) }}</span>
</div>
</div>
<div class="type-actions">
<div class="type-actions" v-if="isAllClubScope">
<el-button type="primary" link size="small" @click.stop="editType(type)">编辑</el-button>
<el-button type="danger" link size="small" @click.stop="deleteType(type)">删除</el-button>
</div>
@@ -676,6 +684,9 @@ onMounted(() => {
background: transparent;
color: #eef2ff;
}
.scope-tip {
margin-bottom: 16px;
}
.no-permission {
text-align: center;
padding: 80px 20px;

View File

@@ -20,7 +20,7 @@
inactive-text="关闭"
:before-change="beforeSwitchZhiKan"
/>
<span class="switch-desc">开启后未绑店且未注册打手/商家等身份只看审核专用商品关闭后未绑店一律看正常商品绑店仍看店铺商品</span>
<span class="switch-desc">按当前顶栏俱乐部生效开启后未绑店且未注册打手/商家等身份只看审核专用商品关闭后未绑店一律看正常商品绑店仍看店铺商品集团汇总下不可改请先切到具体小程序</span>
</div>
</el-card>