UserSceneSession.java 5.11 KB
package com.xly.entity;


import cn.hutool.core.util.ObjectUtil;
import lombok.Data;

import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 用户会话状态:记录每个用户的场景选择状态,实现场景会话持久化
 * 存储:用户ID、权限内场景、是否已选场景、当前选定场景
 */
@Data
public class UserSceneSession {
    /**
     * 唯一标识:用户ID
     */
    private String userId;
    private String userName;
    private String authorization;

    private String sUserName;
    private String sBrandsId;
    private String sSubsidiaryId;
    /**
     * 该用户权限内可访问的所有场景(从权限映射中获取)
     */
    private List<SceneDto> authScenes;

    private List<ToolMeta> authTool;
    /**
     * 是否已选择场景(true=已选,进入专属场景交互;false=未选,先展示选择界面)
     */
    private boolean sceneSelected = false;
    /**
     * 当前选定的业务场景(sceneSelected=true时才有值)
     */
    private SceneDto currentScene;

    private ToolMeta currentTool;

    /***
     * 当前未清返回的数据集
     **/
    private Map<Integer,Map<String,Object>> currentRowData;

    /***
     * @Author 钱豹
     * @Date 10:07 2026/1/31
     * @Param
     * @return
     * @Description  当前已有参数
     **/
    private Map<String,Object> currentArgs;

    private String sFunPrompts; //方法返回的参数补全提示

    private Boolean bCleanMemory = false;
    /**
     * 构建场景选择提示语:展示权限内场景,引导用户选择
     * @return 自然语言提示语
     */
    public String buildSceneSelectHint() {
        if (authScenes == null || authScenes.isEmpty()) {
            return "<p style='color:red;'>抱歉,你暂无任何业务场景的访问权限,请联系管理员开通!</p>";
        }
        // 按名称分组
        StringBuilder sb = new StringBuilder("<div style='line-height:1.8;'>");
        sb.append("<span>请输入序号或点链接进入</span>");
        sb.append("<ul style='padding-left:10px;margin:0;list-style: none;'>");
        for(int i=0;i<authScenes.size();i++){
            SceneDto sceneDto = authScenes.get(i);
            sb.append("<li>").append(i+1).append("、").append("<span  style=\"text-decoration: underline;\"  data-action=\"reset\"  data-text=\"") .append(i+1).append("\" onclick=\"reset('").append(i+1).append("')\">") .append(sceneDto.getSNickName()).append("</span><font style='color:#666; font-size:14px;'>(").append(sceneDto.getSSceneContext()).append(")</font>").append("</li>");
        }
        sb.append("</ul>");
        sb.append("<span style='color:red; font-size:14px;'>提示:可直接输入问题,系统会自动匹配智能体! </span>");
        sb.append("</div>");
        return sb.toString();

    }


    // 新增:将权限内场景转换为「大模型可识别的描述字符串」
    public String buildAuthScenesForLlm(List<ToolMeta> metasAll) {
        if (authScenes == null || authScenes.isEmpty()) {
            return "无可用场景";
        }
        // 格式:场景编码-场景名称-支持功能,如ORDER_OPERATE-订单操作-下单、查订单、取消订单
        return authScenes.stream()
                .map(scene -> "sceneCode:" + scene.getSSceneNo() + ",场景名称:" + scene.getSSceneName() + ",场景内容:\n" + getSceneContext(scene,metasAll))
                .collect(Collectors.joining("\n"));
    }
    /***
     * @Author 钱豹
     * @Date 14:12 2026/2/6
     * @Param [sceneDto, metasAll]
     * @return java.lang.String
     * @Description 方法名称拼接
     **/
    private String getSceneContext(SceneDto sceneDto,List<ToolMeta> metasAll){
        List<ToolMeta> metas = metasAll.stream().filter(m->m.getSSceneId().equals(sceneDto.getSId())).collect(Collectors.toUnmodifiableList());
        StringBuilder sb = new StringBuilder();
        AtomicInteger index = new AtomicInteger(1);
        metas.forEach(m -> {
            sb.append(index.getAndIncrement())
                    .append(". 【")
//                    .append(m.getSMethodNo())
//                    .append("-")
                    .append(m.getSMethodName())
                    .append("】")
                    .append(m.getStoolDesc())
                    .append("\n");
        });
        if(ObjectUtil.isEmpty(sb)){
            sb.append(sceneDto.getSSceneContext());
        }
        return sb.toString();
    }

    /**
     * 根据用户输入的序号,匹配选定场景
     * @param input 用户输入的序号(如1/2/3)
     * @return true=匹配成功,false=匹配失败
     */
    public boolean selectSceneByInput(String input) {
        try {
            int index = Integer.parseInt(input) - 1;
            if (index >= 0 && index < authScenes.size()) {
                this.currentScene = authScenes.get(index);
                this.sceneSelected = true;
                return true;
            }
        } catch (NumberFormatException e) {
            // 非数字输入,直接返回false
        }
        return false;
    }


}