fix(merchant-products): 严格锁定商品价格与库存编辑权限,仅对平台超级管理员开放
1. 前端 ProductsTab 增加 canEditPricing={isAdmin} 显式权限透传,仅超级管理员可见【编辑】按钮,普通分销商/商户完全隐藏;
2. 后端 UpdateProduct 接口补充 middleware.GetRole(c) != model.RoleAdmin 强校验,普通分销商发起请求直接 403 阻断;
3. 保障平台商品进货成本与对外积分售价的权威性,杜绝下游分销商私自篡改价格与库存风险。
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"time"
|
||||
|
||||
"affiliate_dash/internal/middleware"
|
||||
"affiliate_dash/internal/model"
|
||||
"affiliate_dash/internal/pkg/response"
|
||||
"affiliate_dash/internal/service"
|
||||
|
||||
@@ -78,7 +79,12 @@ type merchantProductStatusReq struct {
|
||||
// UpdateProductStatus PATCH /api/merchant/products/:id/status
|
||||
// 商户仅能上架/下架商品,价格、成本等配置由平台管理员维护。
|
||||
// UpdateProduct PATCH /api/merchant/products/:id — 编辑商品(显示名称、售价、成本、库存、状态)。
|
||||
// 严格风控门禁:仅平台超级管理员(model.RoleAdmin)拥有修改商品价格、成本、库存与名称的权限,普通分销商严禁修改。
|
||||
func (h *MerchantHandler) UpdateProduct(c *gin.Context) {
|
||||
if middleware.GetRole(c) != model.RoleAdmin {
|
||||
response.Forbidden(c, "权限不足:仅平台超级管理员可编辑商品价格、成本与库存")
|
||||
return
|
||||
}
|
||||
id, _ := strconv.ParseUint(c.Param("id"), 10, 64)
|
||||
if id == 0 {
|
||||
response.BadRequest(c, "参数错误")
|
||||
|
||||
@@ -564,6 +564,7 @@ export default function MerchantCenter({ fixedTab, title = '商户中心' }: Mer
|
||||
loading={loading}
|
||||
products={products}
|
||||
canManage={canManage}
|
||||
canEditPricing={isAdmin}
|
||||
filters={productFilters}
|
||||
onToggleProduct={openProductToggle}
|
||||
onDeleteProduct={deleteProduct}
|
||||
|
||||
@@ -63,6 +63,7 @@ export function ProductsTab({
|
||||
loading,
|
||||
products,
|
||||
canManage,
|
||||
canEditPricing = false,
|
||||
filters,
|
||||
onToggleProduct,
|
||||
onDeleteProduct,
|
||||
@@ -73,6 +74,7 @@ export function ProductsTab({
|
||||
loading: boolean
|
||||
products: PageResult<MerchantProduct>
|
||||
canManage: boolean
|
||||
canEditPricing?: boolean
|
||||
filters: { keyword: string; status: string }
|
||||
onToggleProduct: (record: MerchantProduct) => void
|
||||
onDeleteProduct: (record: MerchantProduct) => void
|
||||
@@ -196,13 +198,15 @@ export function ProductsTab({
|
||||
fixed: 'right',
|
||||
render: (_, record) => canManage ? (
|
||||
<Space size={4}>
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openEditModal(record)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
{canEditPricing && (
|
||||
<Button
|
||||
type="link"
|
||||
size="small"
|
||||
onClick={() => openEditModal(record)}
|
||||
>
|
||||
编辑
|
||||
</Button>
|
||||
)}
|
||||
<Popconfirm
|
||||
title={record.status === 'active' ? '下架该商品?' : '上架该商品?'}
|
||||
description={record.status === 'active' ? '下架后商户将无法再创建该商品订单' : '上架后商户可正常下单'}
|
||||
|
||||
Reference in New Issue
Block a user