package com.sckw.system.api.model.dto.res;

import lombok.Data;

import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

/**
 * 数据权限过滤DTO
 * <p>
 * 供其他模块通过Dubbo远程调用获取当前用户的数据权限过滤条件，
 * 用于贸易合同、贸易订单、物流订单、运单等业务数据查询过滤。
 * <p>
 * 规则说明：
 * <ul>
 *     <li>企业数据权限：限制可见的企业范围（角色配置的企业ID列表）</li>
 *     <li>个人数据权限：在企业范围内，仅查看本人作为销售人员的数据</li>
 *     <li>两者为并集（组合）关系：开启个人数据权限后，
 *         查询条件为 ent_id IN (已选企业) AND salesman_id = 当前用户</li>
 *     <li>多角色场景：各角色的企业ID取并集，任一角色开启个人数据权限则整体开启</li>
 * </ul>
 * <p>
 * @author cxf
 * @date 2026-03-31
 */
@Data
public class DataPermissionDTO implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 当前用户ID
     */
    private Long userId;

    /**
     * 是否可见全部数据（未配置任何数据权限时为true）
     */
    private boolean allVisible;

    /**
     * 可见的企业ID集合（企业数据权限配置的企业列表）
     */
    private Set<Long> visibleEntIds;

    /**
     * 是否开启个人数据权限
     * <p>
     * 开启后，在企业范围内仅查看本人作为销售人员的贸易合同及其衍生数据
     * （贸易订单、物流订单、运单）
     */
    private boolean personalDataEnabled;

    /**
     * 将数据权限过滤条件应用到查询参数Map中
     * <p>
     * 注入的参数：
     * <ul>
     *     <li><b>dataPermEntIds</b> (List&lt;Long&gt;) — 可访问的企业ID列表，SQL: ent_id IN (...)</li>
     *     <li><b>dataPermUserId</b> (Long) — 当前用户ID，SQL: salesman_id = #{dataPermUserId}</li>
     * </ul>
     * <p>
     * Mapper XML标准写法（适用于贸易合同/订单/物流/运单等表，t为表别名）：
     * <pre>
     * &lt;!-- 企业数据权限过滤 --&gt;
     * &lt;if test="dataPermEntIds != null and dataPermEntIds.size() > 0"&gt;
     *     AND t.ent_id IN
     *     &lt;foreach collection="dataPermEntIds" item="item" open="(" close=")" separator=","&gt;
     *         #{item}
     *     &lt;/foreach&gt;
     * &lt;/if&gt;
     * &lt;!-- 个人数据权限过滤（销售人员=当前用户） --&gt;
     * &lt;if test="dataPermUserId != null"&gt;
     *     AND t.salesman_id = #{dataPermUserId}
     * &lt;/if&gt;
     * </pre>
     *
     * @param params 查询参数Map
     */
    public void applyTo(Map<String, Object> params) {
        if (this.allVisible && !this.personalDataEnabled) {
            return;
        }

        if (!this.allVisible && visibleEntIds != null && !visibleEntIds.isEmpty()) {
            params.put("dataPermEntIds", new ArrayList<>(this.visibleEntIds));
        }

        if (this.personalDataEnabled) {
            params.put("dataPermUserId", this.userId);
        }
    }

    /**
     * 判断是否需要数据权限过滤
     *
     * @return true=存在数据权限限制，需要过滤
     */
    public boolean needFilter() {
        return !this.allVisible || this.personalDataEnabled;
    }

}
