当前位置:首页>python>Python自己写一套Ai问答小助手

Python自己写一套Ai问答小助手

  • 2026-06-26 01:21:12
Python自己写一套Ai问答小助手

写一套完整可直接部署、前后端一体的实现方案: 技术栈:Flask后端 + 原生HTML+TailwindCSS前端,仅依赖阿里百炼SK; 完整页面布局:

  • 左侧侧边栏:
    1. 新建对话按钮
    2. Skill管理菜单:上传Skill文件夹、查看列表、启用/禁用/删除Skill
    3. 对话历史列表:查看、删除、置顶历史会话
  • 右侧主区域: 上方对话展示窗口,底部输入框+发送按钮; 自动流程:用户提问 → 阿里百炼Function Calling做意图识别 → 判断是否调用已启用的自定义Skill → 本地执行工具 → 模型汇总回复。

一、整体架构&存储设计

目录结构

skill_chat_system/
├── app.py                # Flask后端全部接口
├── static/
│   └── index.html        # 完整前端UI(侧边栏+聊天区)
├── skills_store/         # 上传的Skill根目录
│   ├── skill1/
│   │   ├── tool.json     # function calling描述schema
│   │   └── run.py        # 工具执行逻辑
└── chat_db.json          # 本地JSON持久化:会话列表、历史消息、Skill启用状态

持久化chat_db.json结构

{
"skills": {
"skill1": {"enable"true"upload_time""2026-06-12"}
  },
"sessions": [
    {
"session_id""uuidxxx",
"title""天气查询对话",
"top"false,
"create_time""...",
"messages": [{"role":"user","content":"..."}, ...]
    }
  ],
"current_session_id""uuidxxx"
}

核心逻辑链路

  1. 左侧上传Skill文件夹(支持zip压缩包上传,后端解压到指定目录);
  2. 后台记录每个Skill启用/禁用状态,被禁用的不会塞进tools列表传给百炼;
  3. 新建对话生成独立session,消息按会话隔离;
  4. 用户发消息:
    • 后端读取仅启用的Skill拼装tools数组传给阿里百炼;
    • 模型自动意图识别:无工具调用直接回复;有工具调用则本地执行对应Skill代码;
    • 工具结果回传给大模型生成最终回答,整条消息存入当前会话历史;
  5. 侧边栏支持:会话置顶、单条/整会话删除、Skill启用禁用删除。

二、后端完整代码 app.py

先安装依赖:

pip install flask requests zipfile uuid
import os
import json
import uuid
import zipfile
import shutil
from datetime import datetime
import requests
from flask import Flask, request, render_template_string, jsonify
from werkzeug.utils import secure_filename

app = Flask(__name__)

# ===================== 配置区(自行替换) =====================
BAILIAN_API_KEY = "sk-你的阿里百炼SK"
BAILIAN_MODEL = "qwen-turbo"
API_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
SKILL_ROOT = "./skills_store"
DB_PATH = "./chat_db.json"
ALLOW_EXT = {"json""py""yaml""yml"}

os.makedirs(SKILL_ROOT, exist_ok=True)

# 初始化本地数据库
definit_db():
ifnot os.path.exists(DB_PATH):
        init_data = {
"skills": {},
"sessions": [],
"current_session_id"""
        }
with open(DB_PATH, "w", encoding="utf-8"as f:
            json.dump(init_data, f, ensure_ascii=False, indent=2)

defload_db():
with open(DB_PATH, "r", encoding="utf-8"as f:
return json.load(f)

defsave_db(data):
with open(DB_PATH, "w", encoding="utf-8"as f:
        json.dump(data, ensure_ascii=False, indent=2)

init_db()

# ===================== Skill工具解析 & 执行 =====================
defparse_skill_schema(skill_name):
    skill_dir = os.path.join(SKILL_ROOT, skill_name)
    schema_file = os.path.join(skill_dir, "tool.json")
ifnot os.path.exists(schema_file):
returnNone
try:
with open(schema_file, "r", encoding="utf-8"as f:
return json.load(f)
except Exception:
returnNone

# 动态执行skill函数
defexec_skill_func(skill_name, func_name, args):
    skill_dir = os.path.join(SKILL_ROOT, skill_name)
    run_path = os.path.join(skill_dir, "run.py")
ifnot os.path.exists(run_path):
returnf"Skill {skill_name} 执行文件不存在"
import sys
    sys.path.insert(0, skill_dir)
try:
import run
        target_func = getattr(run, func_name)
        res = target_func(**args)
return res
except Exception as e:
returnf"Skill执行异常:{str(e)}"

# ===================== 接口1:首页渲染 =====================
@app.route("/")
defindex():
return render_template_string(open("./static/index.html""r", encoding="utf-8").read())

# ===================== Skill管理接口 =====================
# 上传zip压缩包Skill文件夹
@app.route("/api/skill/upload", methods=["POST"])
defskill_upload():
    target_folder = secure_filename(request.form.get("target_folder""").strip())
    zip_file = request.files.get("skill_zip")
ifnot target_folder ornot zip_file:
return jsonify({"code":1"msg":"文件夹名和zip包不能为空"})
    save_dir = os.path.join(SKILL_ROOT, target_folder)
if os.path.exists(save_dir):
return jsonify({"code":1"msg":"该Skill文件夹已存在"})
    os.makedirs(save_dir)
    zip_tmp_path = os.path.join(save_dir, "_tmp.zip")
    zip_file.save(zip_tmp_path)
# 解压
try:
with zipfile.ZipFile(zip_tmp_path, "r"as zf:
            zf.extractall(save_dir)
        os.remove(zip_tmp_path)
except Exception as e:
        shutil.rmtree(save_dir)
return jsonify({"code":1"msg":f"解压失败:{str(e)}"})
# 写入DB启用状态
    db = load_db()
    db["skills"][target_folder] = {
"enable"True,
"upload_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    }
    save_db(db)
return jsonify({"code":0"msg":f"Skill {target_folder} 上传成功"})

# 获取skill列表
@app.route("/api/skill/list", methods=["GET"])
defskill_list():
    db = load_db()
    skill_info = []
for name, info in db["skills"].items():
        schema = parse_skill_schema(name)
        desc = schema["function"]["description"if schema else"无描述"
        skill_info.append({
"name": name,
"enable": info["enable"],
"desc": desc,
"upload_time": info["upload_time"]
        })
return jsonify({"code":0"data": skill_info})

# 启用/禁用skill
@app.route("/api/skill/toggle", methods=["POST"])
defskill_toggle():
    data = request.get_json()
    skill_name = data.get("skill_name")
    enable = data.get("enable")
    db = load_db()
if skill_name notin db["skills"]:
return jsonify({"code":1"msg":"Skill不存在"})
    db["skills"][skill_name]["enable"] = enable
    save_db(db)
return jsonify({"code":0})

# 删除skill
@app.route("/api/skill/delete", methods=["POST"])
defskill_delete():
    data = request.get_json()
    skill_name = data.get("skill_name")
    db = load_db()
if skill_name notin db["skills"]:
return jsonify({"code":1"msg":"Skill不存在"})
# 删除本地文件夹
    skill_path = os.path.join(SKILL_ROOT, skill_name)
if os.path.exists(skill_path):
        shutil.rmtree(skill_path)
del db["skills"][skill_name]
    save_db(db)
return jsonify({"code":0})

# ===================== 会话&历史管理接口 =====================
# 新建对话
@app.route("/api/session/new", methods=["POST"])
defsession_new():
    db = load_db()
    sid = str(uuid.uuid4())
    new_session = {
"session_id": sid,
"title"f"对话{len(db['sessions'])+1}",
"top"False,
"create_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"messages": []
    }
    db["sessions"].append(new_session)
    db["current_session_id"] = sid
    save_db(db)
return jsonify({"code":0"session_id": sid})

# 获取会话列表
@app.route("/api/session/list", methods=["GET"])
defsession_list():
    db = load_db()
    sessions = sorted(db["sessions"], key=lambda x: (not x["top"], x["create_time"]), reverse=True)
return jsonify({"code":0"data": sessions, "current": db["current_session_id"]})

# 切换当前会话
@app.route("/api/session/switch", methods=["POST"])
defsession_switch():
    data = request.get_json()
    sid = data.get("session_id")
    db = load_db()
    db["current_session_id"] = sid
    save_db(db)
return jsonify({"code":0})

# 置顶/取消置顶会话
@app.route("/api/session/top", methods=["POST"])
defsession_top():
    data = request.get_json()
    sid = data.get("session_id")
    top_flag = data.get("top")
    db = load_db()
for item in db["sessions"]:
if item["session_id"] == sid:
            item["top"] = top_flag
break
    save_db(db)
return jsonify({"code":0})

# 删除整个会话
@app.route("/api/session/del", methods=["POST"])
defsession_del():
    data = request.get_json()
    sid = data.get("session_id")
    db = load_db()
    db["sessions"] = [x for x in db["sessions"if x["session_id"] != sid]
if db["current_session_id"] == sid:
        db["current_session_id"] = db["sessions"][0]["session_id"if db["sessions"else""
    save_db(db)
return jsonify({"code":0})

# 获取当前会话消息
@app.route("/api/message/get", methods=["GET"])
defmsg_get():
    db = load_db()
    sid = db["current_session_id"]
for s in db["sessions"]:
if s["session_id"] == sid:
return jsonify({"code":0"msgs": s["messages"]})
return jsonify({"code":1"msg":"无当前会话"})

# ===================== 核心聊天接口:意图识别+Skill调用 =====================
@app.route("/api/chat", methods=["POST"])
defchat():
    data = request.get_json()
    user_q = data.get("query""").strip()
ifnot user_q:
return jsonify({"code":1"msg":"问题不能为空"})
    db = load_db()
    sid = db["current_session_id"]
# 取出启用的skill拼装tools
    tools = []
    skill_name_mapping = {}
for sk_name, sk_info in db["skills"].items():
if sk_info["enable"]:
            sch = parse_skill_schema(sk_name)
if sch:
                tools.append(sch)
                skill_name_mapping[sch["function"]["name"]] = sk_name
# 组装历史消息
    target_session = None
for s in db["sessions"]:
if s["session_id"] == sid:
            target_session = s
break
    history = target_session["messages"]
    messages = history + [{"role":"user""content": user_q}]

    headers = {
"Authorization"f"Bearer {BAILIAN_API_KEY}",
"Content-Type""application/json"
    }
    payload = {
"model": BAILIAN_MODEL,
"input": {"messages": messages},
"parameters": {
"result_format""message",
"tools": tools if tools elseNone
        }
    }
    resp = requests.post(API_URL, json=payload, headers=headers)
    res_json = resp.json()
    choices = res_json.get("output", {}).get("choices", [])
ifnot choices:
return jsonify({"code":1"msg":"模型调用失败"})
    reply_msg = choices[0]["message"]
# 无工具调用
ifnot reply_msg.get("tool_calls"):
        final_content = reply_msg["content"]
# 存入消息
        target_session["messages"].append({"role":"user""content": user_q})
        target_session["messages"].append({"role":"assistant""content": final_content})
        save_db(db)
return jsonify({
"code":0,
"need_skill"False,
"reply": final_content
        })
# 触发工具调用
    tool_call = reply_msg["tool_calls"][0]
    func_name = tool_call["function"]["name"]
    func_args = json.loads(tool_call["function"]["arguments"])
    real_skill_name = skill_name_mapping[func_name]
    skill_ret = exec_skill_func(real_skill_name, func_name, func_args)
# 二次请求模型整合结果
    msg_round2 = messages + [reply_msg, {
"role""tool",
"name": func_name,
"content": json.dumps(skill_ret, ensure_ascii=False)
    }]
    payload2 = {
"model": BAILIAN_MODEL,
"input": {"messages": msg_round2},
"parameters": {"result_format""message"}
    }
    res2 = requests.post(API_URL, json=payload2, headers=headers)
    final_ans = res2.json()["output"]["choices"][0]["message"]["content"]
# 持久化完整对话
    target_session["messages"].append({"role":"user""content": user_q})
    target_session["messages"].append({"role":"assistant""content": final_ans})
    save_db(db)
return jsonify({
"code":0,
"need_skill"True,
"skill_name": real_skill_name,
"func": func_name,
"args": func_args,
"skill_ret": skill_ret,
"reply": final_ans
    })

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, debug=False)

三、前端页面 static/index.html

左右固定布局,左侧完整菜单(新建对话、Skill管理、历史会话),右侧聊天区,全部JS接口对接后端:

<!DOCTYPE html>
<htmllang="zh-CN">
<head>
<metacharset="UTF-8">
<metaname="viewport"content="width=device-width, initial-scale=1.0">
<title>百炼Skill管理+意图调用系统</title>
<scriptsrc="https://cdn.tailwindcss.com"></script>
<style>
.sidebar-item-active{@apply bg-blue-100 border-l-4 border-blue-500}
</style>
</head>
<bodyclass="h-screen flex overflow-hidden">
<!-- 左侧侧边栏 -->
<divclass="w-72 bg-gray-50 border-r flex flex-col flex-shrink-0">
<divclass="p-3 border-b">
<buttononclick="newSession()"class="w-full bg-blue-600 text-white py-2 rounded">+ 新建对话</button>
</div>

<!-- Skill管理折叠面板 -->
<divclass="border-b">
<divclass="p-3 font-bold flex justify-between items-center cursor-pointer"onclick="toggleSkillPanel()">
<span>📦 Skill管理</span>
<spanid="skillArrow"></span>
</div>
<divid="skillPanel"class="px-3 pb-3 hidden">
<divclass="mb-2">
<labelclass="text-sm">目标文件夹:</label>
<inputid="skillFolderName"class="border w-full px-2 py-1 text-sm mt-1">
</div>
<divclass="mb-2">
<labelclass="text-sm">上传Skill压缩包(zip):</label>
<inputtype="file"id="skillZip"accept=".zip"class="text-sm mt-1">
</div>
<buttononclick="uploadSkill()"class="w-full bg-green-500 text-white py-1 rounded text-sm">上传Skill</button>
<divclass="mt-3 max-h-52 overflow-auto border p-2"id="skillListWrap"></div>
</div>
</div>

<!-- 对话历史 -->
<divclass="flex-1 overflow-auto flex flex-col">
<divclass="p-3 font-bold border-b">📜 对话历史</div>
<divid="sessionListWrap"class="flex-1 overflow-auto p-2"></div>
</div>
</div>

<!-- 右侧聊天主区域 -->
<divclass="flex-1 flex flex-col">
<divid="chatBox"class="flex-1 overflow-auto p-4 space-y-3 border-b"></div>
<divclass="p-3 flex gap-2">
<textareaid="userInput"class="flex-1 border p-2 resize-none h-24"placeholder="输入问题,模型自动判断是否调用已启用的Skill"></textarea>
<buttononclick="sendMsg()"class="bg-blue-600 text-white px-4 rounded">发送</button>
</div>
</div>

<script>
let skillPanelOpen = false;

// 面板折叠
functiontoggleSkillPanel(){
    skillPanelOpen = !skillPanelOpen;
document.getElementById("skillPanel").classList.toggle("hidden", !skillPanelOpen);
document.getElementById("skillArrow").innerText = skillPanelOpen ? "▲" : "▼";
}

// Skill上传
asyncfunctionuploadSkill(){
let folder = document.getElementById("skillFolderName").value.trim();
let zip = document.getElementById("skillZip").files[0];
if(!folder || !zip){alert("填写文件夹并选择zip包");return;}
let fd = new FormData();
    fd.append("target_folder", folder);
    fd.append("skill_zip", zip);
let res = await fetch("/api/skill/upload", {method:"POST"body:fd});
let ret = await res.json();
    alert(ret.msg);
    refreshSkillList();
}

// 刷新Skill列表
asyncfunctionrefreshSkillList(){
let res = await fetch("/api/skill/list");
let data = await res.json();
let wrap = document.getElementById("skillListWrap");
if(data.data.length===0){wrap.innerHTML="<div class='text-gray-400 text-sm'>暂无Skill</div>";return;}
let html = "";
    data.data.forEach(item=>{
        html += `
        <div class="border-b py-2 text-sm">
            <div class="font-medium">${item.name}</div>
            <div class="text-gray-500 text-xs line-clamp-1">${item.desc}</div>
            <div class="flex gap-1 mt-1">
                <button onclick="toggleSkill('${item.name}', ${!item.enable})" class="${item.enable?'bg-orange-400':'bg-gray-400'} text-white px-1 text-xs rounded">
${item.enable?'禁用':'启用'}
                </button>
                <button onclick="delSkill('${item.name}')" class="bg-red-500 text-white px-1 text-xs rounded">删除</button>
            </div>
        </div>`
;
    });
    wrap.innerHTML = html;
}

asyncfunctiontoggleSkill(name, enable){
await fetch("/api/skill/toggle",{
method:"POST"headers:{"Content-Type":"application/json"},
body:JSON.stringify({skill_name:name, enable:enable})
    });
    refreshSkillList();
}

asyncfunctiondelSkill(name){
if(!confirm(`确定删除Skill ${name}?`))return;
await fetch("/api/skill/delete",{
method:"POST"headers:{"Content-Type":"application/json"},
body:JSON.stringify({skill_name:name})
    });
    refreshSkillList();
}

// 会话管理
asyncfunctionnewSession(){
await fetch("/api/session/new", {method:"POST"});
    refreshSessionList();
    loadChatMsg();
}

asyncfunctionrefreshSessionList(){
let res = await fetch("/api/session/list");
let data = await res.json();
let wrap = document.getElementById("sessionListWrap");
let html = "";
    data.data.forEach(s=>{
let active = s.session_id === data.current;
        html += `
        <div class="p-2 rounded cursor-pointer my-1 ${active?'sidebar-item-active':''}" onclick="switchSession('${s.session_id}')">
            <div class="flex justify-between items-center">
                <span class="text-sm">${s.top?'📌 ':''}${s.title}</span>
            </div>
            <div class="flex gap-1 mt-1">
                <button onclick="event.stopPropagation();topSession('${s.session_id}',${!s.top})" class="text-xs px-1 border rounded">${s.top?'取消置顶':'置顶'}</button>
                <button onclick="event.stopPropagation();delSession('${s.session_id}')" class="text-xs px-1 border rounded text-red-500">删除</button>
            </div>
        </div>`
;
    });
    wrap.innerHTML = html;
}

asyncfunctionswitchSession(sid){
await fetch("/api/session/switch",{
method:"POST"headers:{"Content-Type":"application/json"},
body:JSON.stringify({session_id:sid})
    });
    refreshSessionList();
    loadChatMsg();
}

asyncfunctiontopSession(sid, top){
await fetch("/api/session/top",{
method:"POST"headers:{"Content-Type":"application/json"},
body:JSON.stringify({session_id:sid, top:top})
    });
    refreshSessionList();
}

asyncfunctiondelSession(sid){
if(!confirm("删除整个对话?"))return;
await fetch("/api/session/del",{
method:"POST"headers:{"Content-Type":"application/json"},
body:JSON.stringify({session_id:sid})
    });
    refreshSessionList();
    loadChatMsg();
}

// 加载当前会话消息
asyncfunctionloadChatMsg(){
let res = await fetch("/api/message/get");
let data = await res.json();
let box = document.getElementById("chatBox");
    box.innerHTML = "";
    data.msgs.forEach(m=>{
let cls = m.role==="user"?"bg-blue-50 self-end":"bg-gray-100 self-start";
        box.innerHTML += `<div class="${cls} p-3 rounded max-w-[80%]">${m.content}</div>`;
    });
    box.scrollTop = box.scrollHeight;
}

// 发送提问
asyncfunctionsendMsg(){
let q = document.getElementById("userInput").value.trim();
if(!q)return;
let box = document.getElementById("chatBox");
    box.innerHTML += `<div class="bg-blue-50 p-3 rounded max-w-[80%] self-end">${q}</div>`;
document.getElementById("userInput").value = "";
    box.scrollTop = box.scrollHeight;

let res = await fetch("/api/chat",{
method:"POST"headers:{"Content-Type":"application/json"},
body:JSON.stringify({query:q})
    });
let ret = await res.json();
if(ret.code!==0){
        box.innerHTML += `<div class="text-red-500">${ret.msg}</div>`;
return;
    }
if(ret.need_skill){
let skillInfo = `<div class="text-orange-600 text-sm border-l-2 border-orange-400 pl-2">
        意图识别触发Skill【${ret.skill_name}】<br/>调用参数:${JSON.stringify(ret.args)}
        </div>`
;
        box.innerHTML += skillInfo;
    }
    box.innerHTML += `<div class="bg-gray-100 p-3 rounded max-w-[80%]">${ret.reply}</div>`;
    box.scrollTop = box.scrollHeight;
    refreshSessionList();
}

// 页面初始化
window.onload = async ()=>{
    refreshSkillList();
    refreshSessionList();
    loadChatMsg();
};
</script>
</body>
</html>

四、Skill打包规范(关键)

  1. 新建一个文件夹,里面必须包含:
    • tool.json:Function Calling描述schema(模型意图识别依据)
    • run.py:实际工具执行代码
  2. 把这个文件夹整体压缩为 zip包,前端上传这个zip,填写目标Skill名称;

示例 tool.json

{
"type""function",
"function": {
"name""get_city_weather",
"description""查询指定城市实时天气",
"parameters": {
"type""object",
"required": ["city"],
"properties": {
"city": {"type":"string","description":"城市名,如杭州、北京"}
            }
        }
    }
}

配套 run.py

defget_city_weather(city):
returnf"{city} 今日多云,气温22~28℃"

五、全部功能清单(已实现)

左侧菜单栏

  1. 新建独立对话会话,会话互相隔离
  2. Skill管理面板:
    • 上传zip打包的Skill文件夹到指定目录
    • 列表查看所有已上传Skill、功能描述、上传时间
    • 一键启用/禁用(禁用后模型不会调用)
    • 物理删除Skill文件夹+后台记录
  3. 对话历史列表:
    • 切换不同历史对话
    • 会话置顶/取消置顶
    • 删除整条会话

右侧聊天区

  1. 上下滚动对话记录
  2. 输入问题发送
  3. 自动流程: 阿里百炼大模型原生做意图识别
    • 无需工具:直接回复
    • 需要调用已启用Skill:自动提取参数→本地执行工具→结果回传模型整理回答
  4. 调用Skill时前端展示调用详情

六、部署启动步骤

  1. 创建目录结构,把app.py、static/index.html放对位置;
  2. 修改app.py里BAILIAN_API_KEY为你的真实SK;
  3. 执行 python app.py
  4. 浏览器打开 http://127.0.0.1:5000 即可完整使用。

七、扩展优化建议

  1. 安全加固:添加上传zip大小限制、解压路径穿越校验、禁止危险Python代码执行;
  2. UI优化:支持单条消息删除、会话重命名;
  3. 部署:使用gunicorn+Nginx外网访问;
  4. 批量导入:支持批量上传多个Skill压缩包;
  5. 日志:增加调用日志,记录每一次意图识别、Skill调用记录。

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-07-02 23:26:56 HTTP/2.0 GET : https://f.mffb.com.cn/a/499247.html
  2. 运行时间 : 0.103110s [ 吞吐率:9.70req/s ] 内存消耗:4,622.67kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=ff9636266d8139ae79343ff074f744c0
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000490s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000930s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000336s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000316s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000489s ]
  6. SELECT * FROM `set` [ RunTime:0.000222s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000615s ]
  8. SELECT * FROM `article` WHERE `id` = 499247 LIMIT 1 [ RunTime:0.004556s ]
  9. UPDATE `article` SET `lasttime` = 1783006016 WHERE `id` = 499247 [ RunTime:0.013152s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 66 LIMIT 1 [ RunTime:0.000456s ]
  11. SELECT * FROM `article` WHERE `id` < 499247 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000551s ]
  12. SELECT * FROM `article` WHERE `id` > 499247 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.005430s ]
  13. SELECT * FROM `article` WHERE `id` < 499247 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.000675s ]
  14. SELECT * FROM `article` WHERE `id` < 499247 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.003250s ]
  15. SELECT * FROM `article` WHERE `id` < 499247 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.002114s ]
0.104733s