From ccb12da7f339b2dd5e95aa4e44f2c88791cae27b Mon Sep 17 00:00:00 2001 From: zhouyonggao <1971162852@qq.com> Date: Fri, 19 Dec 2025 02:24:54 +0800 Subject: [PATCH] =?UTF-8?q?fix(exports):=20=E6=9B=B4=E6=96=B0=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E9=80=BB=E8=BE=91=E4=BB=A5=E7=A7=BB=E9=99=A4=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E7=94=A8=E6=88=B7ID=E8=BD=AC=E6=8D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 删除从 URL 参数 userId 和 current_user_id 自动转换为 creator_in 的逻辑 - 更新相关注释,明确 current_user_id 仅用于记录导出任务的 owner,不用于数据过滤 - 强调用户需手动选择 creator 进行过滤,提升数据过滤的安全性和灵活性 --- server/internal/api/exports.go | 52 +++++++++++----------------------- web/main.js | 24 +++------------- 2 files changed, 21 insertions(+), 55 deletions(-) diff --git a/server/internal/api/exports.go b/server/internal/api/exports.go index 237e564..d36c227 100644 --- a/server/internal/api/exports.go +++ b/server/internal/api/exports.go @@ -102,40 +102,8 @@ func (a *ExportsAPI) create(w http.ResponseWriter, r *http.Request) { } // merge permission scope into filters to enforce boundary p.Filters = mergePermissionIntoFilters(p.Datasource, main, p.Permission, p.Filters) - // support multiple userId in query: e.g., userId=15,25 → filters.creator_in - { - uidStr := r.URL.Query().Get("userId") - if uidStr != "" { - parts := strings.Split(uidStr, ",") - ids := make([]interface{}, 0, len(parts)) - for _, s := range parts { - s = strings.TrimSpace(s) - if s == "" { - continue - } - if n, err := strconv.ParseUint(s, 10, 64); err == nil { - ids = append(ids, n) - } - } - if len(ids) > 0 { - // 如果传递了 plan_id_eq 或 reseller_id_eq,不设置 creator_in(适用于所有数据源) - skipCreator := false - if main == "order" || main == "order_info" { - if v, ok := p.Filters["plan_id_eq"]; ok && v != nil && v != "" && v != 0 { - skipCreator = true - } - if v, ok := p.Filters["reseller_id_eq"]; ok && v != nil && v != "" && v != 0 { - skipCreator = true - } - } - if !skipCreator { - if _, exists := p.Filters["creator_in"]; !exists { - p.Filters["creator_in"] = ids - } - } - } - } - } + // 注意:不再从 URL 参数 userId 或 current_user_id 自动转换为 creator_in 过滤 + // current_user_id 仅用于记录导出任务的 owner,不用于数据过滤 // support multiple merchantId in query: e.g., merchantId=1,2,3 → filters.merchant_id_in { midStr := r.URL.Query().Get("merchantId") @@ -1658,7 +1626,7 @@ func mergePermissionIntoFilters(ds, main string, perm map[string]interface{}, fi if hasNonEmptyIDs(filters["creator_in"]) { return filters } - // try known keys + // try known keys (明确排除 current_user_id,它仅用于记录 owner,不用于数据过滤) { candidates := []string{"creator_in", "creator_ids", "user_ids", "user_id_in", "user_id", "owner_id"} ids := []interface{}{} @@ -1666,6 +1634,10 @@ func mergePermissionIntoFilters(ds, main string, perm map[string]interface{}, fi if perm == nil { break } + // 明确排除 current_user_id 字段(即使不在 candidates 列表中,也显式检查以确保安全) + if k == "current_user_id" { + continue + } if v, ok := perm[k]; ok { ids = normalizeIDs(v) if len(ids) > 0 { @@ -1674,9 +1646,14 @@ func mergePermissionIntoFilters(ds, main string, perm map[string]interface{}, fi } } // also check filters incoming alternative keys and normalize into creator_in + // 明确排除 current_user_id 字段 if len(ids) == 0 { alt := []string{"creator_ids", "user_ids", "user_id_in", "user_id", "owner_id"} for _, k := range alt { + // 明确排除 current_user_id 字段 + if k == "current_user_id" { + continue + } if v, ok := filters[k]; ok { ids = normalizeIDs(v) if len(ids) > 0 { @@ -1685,6 +1662,11 @@ func mergePermissionIntoFilters(ds, main string, perm map[string]interface{}, fi } } } + // 额外检查:如果 permission 或 filters 中直接有 current_user_id,明确排除它 + if perm != nil { + delete(perm, "current_user_id") + } + delete(filters, "current_user_id") if len(ids) > 0 { filters["creator_in"] = ids } diff --git a/web/main.js b/web/main.js index 81ebfbf..ea53495 100644 --- a/web/main.js +++ b/web/main.js @@ -666,32 +666,16 @@ const app = createApp({ if (state.exportForm.datasource === 'marketing') { loadCreators(); - const userId = Api.getUserId(); - if (userId) { - const parts = String(userId).split(',').map(s => s.trim()).filter(Boolean); - if (parts.length === 1) { - // 单个用户 ID,同时设置 creatorId 和 creatorIds - state.exportForm.creatorId = Number(parts[0]); - state.exportForm.creatorIds = [Number(parts[0])]; - } else { - // 多个用户 ID,只设置 creatorIds - state.exportForm.creatorId = null; - state.exportForm.creatorIds = parts.map(Number); - } - } + // 注意:不再自动从 current_user_id 设置 creatorId/creatorIds + // 用户需要手动选择 creator 进行过滤 } if (state.exportForm.datasource === 'ymt') { await loadYmtCreators(); await loadYmtMerchants(); await loadYmtActivities(); - const userId = Api.getUserId(); - if (userId) { - const first = String(userId).split(',').map(s => s.trim()).filter(Boolean)[0]; - if (first) { - state.exportForm.ymtCreatorId = Number(first); - } - } + // 注意:不再自动从 current_user_id 设置 ymtCreatorId + // 用户需要手动选择 creator 进行过滤 } if (!state.exportForm.dateRange?.length) {