|
@@ -0,0 +1,452 @@
|
|
|
|
|
+# 程序的主入口
|
|
|
|
|
+# 承担服务器容器+程序作用
|
|
|
|
|
+# 服务器容器:提供http容器服务,程序放置于该容器中运行
|
|
|
|
|
+# 程序:本体-智能瞭望与智能问数系统 B/s架构
|
|
|
|
|
+import os
|
|
|
|
|
+import sys
|
|
|
|
|
+import tornado.ioloop
|
|
|
|
|
+import tornado.web
|
|
|
|
|
+from tornado.httpserver import HTTPServer
|
|
|
|
|
+
|
|
|
|
|
+# from app.controllers.base import BaseHandler
|
|
|
|
|
+# 引入auth - controller层
|
|
|
|
|
+from app.controllers.auth import LoginHandler,LogoutHandler
|
|
|
|
|
+from app.controllers.home import IndexHandler, DashboardHandler, DashboardApiHandler
|
|
|
|
|
+from app.controllers.user import UserPageHandler, UserApiHandler
|
|
|
|
|
+from app.controllers.menu import MenuPageHandler, MenuApiHandler
|
|
|
|
|
+from app.controllers.role import RolePageHandler, RoleApiHandler
|
|
|
|
|
+from app.controllers.model_engine import ModelEnginePageHandler, ModelEngineApiHandler, ModelTestApiHandler
|
|
|
|
|
+from app.controllers.spy_source import SpySourcePageHandler, SpySourceApiHandler
|
|
|
|
|
+from app.controllers.data_warehouse import DataWarehousePageHandler, DataWarehouseApiHandler, DataWarehouseDeepCrawlSseHandler
|
|
|
|
|
+from app.controllers.spy import SpyPageHandler, SpyRunApiHandler, SpyCommitApiHandler
|
|
|
|
|
+from app.controllers.api_manage import ApiManagePageHandler, ApiManageApiHandler, ApiInterfaceProxyHandler
|
|
|
|
|
+from app.controllers.digital_employee import DigitalEmployeePageHandler, DigitalEmployeeApiHandler, DigitalEmployeeChatApiHandler
|
|
|
|
|
+from app.controllers.chat_admin import ChatSessionsAdminPageHandler, ChatSessionsAdminApiHandler, ChatMessagesAdminPageHandler, ChatMessagesAdminApiHandler
|
|
|
|
|
+from app.controllers.skill_manage import SkillManagePageHandler, SkillManageApiHandler
|
|
|
|
|
+from app.controllers.portal import PortalRootHandler, PortalLoginHandler, PortalRegisterHandler, PortalChatPageHandler, PortalLogoutHandler, PortalModelsApiHandler, PortalEmployeesApiHandler, PortalSessionsApiHandler, PortalMessagesApiHandler, PortalChatStreamApiHandler, PortalAudioProxyHandler
|
|
|
|
|
+# 引入db - model层
|
|
|
|
|
+from app.models.db import init_db, get_connection
|
|
|
|
|
+from app.models.user import UserRepository
|
|
|
|
|
+from app.models.role import RoleRepository
|
|
|
|
|
+from app.models.menu import MenuRepository
|
|
|
|
|
+
|
|
|
|
|
+try:
|
|
|
|
|
+ if hasattr(sys.stdout, "reconfigure"):
|
|
|
|
|
+ sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
|
|
|
+ if hasattr(sys.stderr, "reconfigure"):
|
|
|
|
|
+ sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
|
|
|
+except Exception:
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+# class HealthHandler(tornado.web.RequestHandler):
|
|
|
|
|
+# def get(self):
|
|
|
|
|
+# self.write({"status":"ok"})
|
|
|
|
|
+
|
|
|
|
|
+# class LoginHandler(tornado.web.RequestHandler):
|
|
|
|
|
+# def get(self):
|
|
|
|
|
+# self.write(f"""<h3>模拟登录验证测试BaesHandler</h3>
|
|
|
|
|
+
|
|
|
|
|
+# <form method="post">
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# <button type="submit">登录admin</button>
|
|
|
|
|
+# """
|
|
|
|
|
+# + self.xsrf_form_html() +
|
|
|
|
|
+# """
|
|
|
|
|
+# </form>
|
|
|
|
|
+# """)
|
|
|
|
|
+
|
|
|
|
|
+# def post(self):
|
|
|
|
|
+# next_url = self.get_argument("next","/private")
|
|
|
|
|
+# self.set_secure_cookie("username","admin")
|
|
|
|
|
+# # 写完安全的cookie以后,跳转到目标地址
|
|
|
|
|
+# self.redirect(next_url)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+# class PrivateHandler(BaseHandler):
|
|
|
|
|
+# @tornado.web.authenticated
|
|
|
|
|
+# def get(self):
|
|
|
|
|
+# self.write(self.current_user)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def make_app():
|
|
|
|
|
+ # return tornado.web.Application([
|
|
|
|
|
+ # ("/abc",HealthHandler),
|
|
|
|
|
+ # ("/login.jsp",HealthHandler),
|
|
|
|
|
+ # ("/",HealthHandler),
|
|
|
|
|
+ # ("/login.php",HealthHandler)
|
|
|
|
|
+ # ],debug=True)
|
|
|
|
|
+ # return tornado.web.Application([
|
|
|
|
|
+ # (r"/",LoginHandler),
|
|
|
|
|
+ # (r"/login",LoginHandler),
|
|
|
|
|
+ # (r"/abc",HealthHandler),
|
|
|
|
|
+ # (r"/private",PrivateHandler)
|
|
|
|
|
+ # ],
|
|
|
|
|
+ # cookie_secret="demo-cookie-secret-change-me",
|
|
|
|
|
+ # login_url="/",
|
|
|
|
|
+ # xsrf_cookies=True,
|
|
|
|
|
+ # debug=True
|
|
|
|
|
+ # )
|
|
|
|
|
+ base_url = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
+ settings = dict(
|
|
|
|
|
+ # 预留view 层的内容配置
|
|
|
|
|
+ template_path=os.path.join(base_url,"app","templates"),
|
|
|
|
|
+ static_path=os.path.join(base_url,"app","static"),
|
|
|
|
|
+ cookie_secret="demo-cookie-secret-change-me",
|
|
|
|
|
+ login_url="/admin/login",
|
|
|
|
|
+ xsrf_cookies=True,
|
|
|
|
|
+ debug=True,
|
|
|
|
|
+ autoreload=True
|
|
|
|
|
+ )
|
|
|
|
|
+ return tornado.web.Application([
|
|
|
|
|
+ (r"/", PortalRootHandler),
|
|
|
|
|
+ (r"/login", PortalLoginHandler),
|
|
|
|
|
+ (r"/register", PortalRegisterHandler),
|
|
|
|
|
+ (r"/chat", PortalChatPageHandler),
|
|
|
|
|
+ (r"/logout", PortalLogoutHandler),
|
|
|
|
|
+ (r"/api/models", PortalModelsApiHandler),
|
|
|
|
|
+ (r"/api/employees", PortalEmployeesApiHandler),
|
|
|
|
|
+ (r"/api/sessions", PortalSessionsApiHandler),
|
|
|
|
|
+ (r"/api/messages", PortalMessagesApiHandler),
|
|
|
|
|
+ (r"/api/chat/stream", PortalChatStreamApiHandler),
|
|
|
|
|
+ (r"/api/audio_proxy", PortalAudioProxyHandler),
|
|
|
|
|
+ (r"/u/?", tornado.web.RedirectHandler, {"url": "/"}),
|
|
|
|
|
+ (r"/u/login", tornado.web.RedirectHandler, {"url": "/login"}),
|
|
|
|
|
+ (r"/u/register", tornado.web.RedirectHandler, {"url": "/register"}),
|
|
|
|
|
+ (r"/u/chat", tornado.web.RedirectHandler, {"url": "/chat"}),
|
|
|
|
|
+ (r"/u/logout", tornado.web.RedirectHandler, {"url": "/logout"}),
|
|
|
|
|
+ (r"/api/u/models", tornado.web.RedirectHandler, {"url": "/api/models"}),
|
|
|
|
|
+ (r"/api/u/employees", tornado.web.RedirectHandler, {"url": "/api/employees"}),
|
|
|
|
|
+ (r"/api/u/sessions", tornado.web.RedirectHandler, {"url": "/api/sessions"}),
|
|
|
|
|
+ (r"/api/u/messages", tornado.web.RedirectHandler, {"url": "/api/messages"}),
|
|
|
|
|
+ (r"/api/u/chat/stream", tornado.web.RedirectHandler, {"url": "/api/chat/stream"}),
|
|
|
|
|
+
|
|
|
|
|
+ (r"/admin/?", IndexHandler),
|
|
|
|
|
+ (r"/admin/login", LoginHandler),
|
|
|
|
|
+ (r"/admin/logout", LogoutHandler),
|
|
|
|
|
+ (r"/admin/dashboard", DashboardHandler),
|
|
|
|
|
+ (r"/dashboard", DashboardHandler),
|
|
|
|
|
+ (r"/api/dashboard", DashboardApiHandler),
|
|
|
|
|
+ (r"/auth/login", LoginHandler),
|
|
|
|
|
+ (r"/auth/logout", LogoutHandler),
|
|
|
|
|
+ (r"/user/list", UserPageHandler),
|
|
|
|
|
+ (r"/api/user", UserApiHandler),
|
|
|
|
|
+ (r"/menu/list", MenuPageHandler),
|
|
|
|
|
+ (r"/api/menu", MenuApiHandler),
|
|
|
|
|
+ (r"/role/list", RolePageHandler),
|
|
|
|
|
+ (r"/api/role", RoleApiHandler),
|
|
|
|
|
+ (r"/model_engine/list", ModelEnginePageHandler),
|
|
|
|
|
+ (r"/api/model_engine", ModelEngineApiHandler),
|
|
|
|
|
+ (r"/api/model_engine/test", ModelTestApiHandler),
|
|
|
|
|
+ # 瞭望数据源管理路由
|
|
|
|
|
+ (r"/spy_source/list", SpySourcePageHandler),
|
|
|
|
|
+ (r"/api/spy_source", SpySourceApiHandler),
|
|
|
|
|
+ # 数据仓库路由
|
|
|
|
|
+ (r"/data_warehouse/list", DataWarehousePageHandler),
|
|
|
|
|
+ (r"/api/data_warehouse", DataWarehouseApiHandler),
|
|
|
|
|
+ (r"/api/data_warehouse/deep_sse", DataWarehouseDeepCrawlSseHandler),
|
|
|
|
|
+ # 独立瞭望采集界面路由
|
|
|
|
|
+ (r"/spy", SpyPageHandler),
|
|
|
|
|
+ (r"/api/spy/run", SpyRunApiHandler),
|
|
|
|
|
+ (r"/api/spy/commit", SpyCommitApiHandler),
|
|
|
|
|
+ # 接口管理
|
|
|
|
|
+ (r"/api_manage/list", ApiManagePageHandler),
|
|
|
|
|
+ (r"/api/api_manage", ApiManageApiHandler),
|
|
|
|
|
+ (r"/api/interface_proxy", ApiInterfaceProxyHandler),
|
|
|
|
|
+ # 数字员工
|
|
|
|
|
+ (r"/digital_employee/list", DigitalEmployeePageHandler),
|
|
|
|
|
+ (r"/api/digital_employee", DigitalEmployeeApiHandler),
|
|
|
|
|
+ (r"/api/digital_employee/chat", DigitalEmployeeChatApiHandler),
|
|
|
|
|
+ # 技能管理
|
|
|
|
|
+ (r"/skill_manage/list", SkillManagePageHandler),
|
|
|
|
|
+ (r"/api/skill_manage", SkillManageApiHandler),
|
|
|
|
|
+ # 用户侧会话/对话管理(后台)
|
|
|
|
|
+ (r"/chat_admin/sessions", ChatSessionsAdminPageHandler),
|
|
|
|
|
+ (r"/api/chat_admin/sessions", ChatSessionsAdminApiHandler),
|
|
|
|
|
+ (r"/chat_admin/messages", ChatMessagesAdminPageHandler),
|
|
|
|
|
+ (r"/api/chat_admin/messages", ChatMessagesAdminApiHandler),
|
|
|
|
|
+ ],
|
|
|
|
|
+ **settings
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+if __name__ == "__main__":
|
|
|
|
|
+ # 启动服务之前,检查并初始化数据库表
|
|
|
|
|
+ init_db()
|
|
|
|
|
+
|
|
|
|
|
+ # 注入默认超管角色
|
|
|
|
|
+ roles = RoleRepository.get_all_roles()
|
|
|
|
|
+ super_role_id = None
|
|
|
|
|
+ for r in roles:
|
|
|
|
|
+ if r['code'] == 'super_admin':
|
|
|
|
|
+ super_role_id = r['id']
|
|
|
|
|
+ break
|
|
|
|
|
+ if not super_role_id:
|
|
|
|
|
+ super_role_id = RoleRepository.create_role("超级管理员", "super_admin", is_system=1)
|
|
|
|
|
+
|
|
|
|
|
+ user_role = RoleRepository.get_by_code("user")
|
|
|
|
|
+ user_role_id = user_role["id"] if user_role else RoleRepository.create_role("普通用户", "user", is_system=1)
|
|
|
|
|
+ member_role = RoleRepository.get_by_code("member")
|
|
|
|
|
+ if not member_role:
|
|
|
|
|
+ RoleRepository.create_role("会员用户", "member", is_system=1)
|
|
|
|
|
+
|
|
|
|
|
+ # 注入默认菜单
|
|
|
|
|
+ menus = MenuRepository.get_all_menus()
|
|
|
|
|
+ if not menus:
|
|
|
|
|
+ sys_id = MenuRepository.create_menu("系统管理", "", "layui-icon-set", 0, 1)
|
|
|
|
|
+ MenuRepository.create_menu("用户管理", "/user/list", "layui-icon-user", sys_id, 1)
|
|
|
|
|
+ MenuRepository.create_menu("角色管理", "/role/list", "layui-icon-group", sys_id, 2)
|
|
|
|
|
+ MenuRepository.create_menu("功能管理", "/menu/list", "layui-icon-app", sys_id, 3)
|
|
|
|
|
+ # 给超管赋权
|
|
|
|
|
+ all_menus = MenuRepository.get_all_menus()
|
|
|
|
|
+ RoleRepository.assign_role_menus(super_role_id, [m['id'] for m in all_menus])
|
|
|
|
|
+
|
|
|
|
|
+ # 注入默认管理员
|
|
|
|
|
+ admin_user = UserRepository.get_user_by_username("admin")
|
|
|
|
|
+ if not admin_user:
|
|
|
|
|
+ UserRepository.create_user("admin", "admin888", super_role_id)
|
|
|
|
|
+ else:
|
|
|
|
|
+ # 确保已存在的 admin 绑定了超管角色
|
|
|
|
|
+ with get_connection() as conn:
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO user_roles (user_id, role_id) VALUES (?, ?)", (admin_user['id'], super_role_id))
|
|
|
|
|
+
|
|
|
|
|
+ with get_connection() as conn:
|
|
|
|
|
+ # 插入默认菜单
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO menus (id, parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?, ?)", (5, 0, '模型引擎', 'layui-icon-engine', '/model_engine/list', 5))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO menus (id, parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?, ?)", (6, 0, '瞭望管理', 'layui-icon-find-fill', '', 6))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO menus (id, parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?, ?)", (7, 6, '数据源管理', '', '/spy_source/list', 1))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO menus (id, parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?, ?)", (8, 6, '瞭望采集', '', '/spy', 2))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO menus (id, parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?, ?)", (9, 0, '数据仓库', 'layui-icon-table', '/data_warehouse/list', 7))
|
|
|
|
|
+ api_parent_row = conn.execute("SELECT id FROM menus WHERE parent_id=0 AND name=?", ("接口服务",)).fetchone()
|
|
|
|
|
+ if not api_parent_row:
|
|
|
|
|
+ api_parent_row = conn.execute("SELECT id FROM menus WHERE parent_id=0 AND name=?", ("系统管理",)).fetchone()
|
|
|
|
|
+ api_parent_id = api_parent_row["id"] if api_parent_row else 0
|
|
|
|
|
+ api_row = conn.execute("SELECT id FROM menus WHERE url=?", ("/api_manage/list",)).fetchone()
|
|
|
|
|
+ if not api_row:
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ "INSERT OR IGNORE INTO menus (id, parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?, ?)",
|
|
|
|
|
+ (10, api_parent_id, '接口管理', 'layui-icon-link', '/api_manage/list', 8)
|
|
|
|
|
+ )
|
|
|
|
|
+ api_row = conn.execute("SELECT id FROM menus WHERE url=?", ("/api_manage/list",)).fetchone()
|
|
|
|
|
+ if not api_row:
|
|
|
|
|
+ cursor = conn.execute(
|
|
|
|
|
+ "INSERT INTO menus (parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
+ (api_parent_id, '接口管理', 'layui-icon-link', '/api_manage/list', 8)
|
|
|
|
|
+ )
|
|
|
|
|
+ api_menu_id = cursor.lastrowid
|
|
|
|
|
+ else:
|
|
|
|
|
+ api_menu_id = api_row["id"]
|
|
|
|
|
+ api_current = conn.execute("SELECT name, icon FROM menus WHERE id=?", (api_menu_id,)).fetchone()
|
|
|
|
|
+ if api_current:
|
|
|
|
|
+ if not (api_current["name"] or "").strip():
|
|
|
|
|
+ conn.execute("UPDATE menus SET name=? WHERE id=?", ('接口管理', api_menu_id))
|
|
|
|
|
+ if not (api_current["icon"] or "").strip():
|
|
|
|
|
+ conn.execute("UPDATE menus SET icon=? WHERE id=?", ('layui-icon-link', api_menu_id))
|
|
|
|
|
+
|
|
|
|
|
+ # 确保超级管理员拥有上述菜单权限
|
|
|
|
|
+ for mid in [5, 6, 7, 8, 9, api_menu_id]:
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO role_menus (role_id, menu_id) VALUES (?, ?)", (super_role_id, mid))
|
|
|
|
|
+
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ """
|
|
|
|
|
+ INSERT OR IGNORE INTO api_endpoints
|
|
|
|
|
+ (name, url, method, response_format, sample_request, qps_window, qps_max, bypass_token, remark, is_active, update_at)
|
|
|
|
|
+ VALUES
|
|
|
|
|
+ (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, current_timestamp)
|
|
|
|
|
+ """,
|
|
|
|
|
+ (
|
|
|
|
|
+ "网易云随机音乐",
|
|
|
|
|
+ "https://api.52vmy.cn/api/music/wy/rand",
|
|
|
|
|
+ "GET",
|
|
|
|
|
+ "JSON",
|
|
|
|
|
+ "https://api.52vmy.cn/api/music/wy/rand",
|
|
|
|
|
+ 2,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ "",
|
|
|
|
|
+ "",
|
|
|
|
|
+ 1,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ """
|
|
|
|
|
+ INSERT OR IGNORE INTO api_endpoints
|
|
|
|
|
+ (name, url, method, response_format, sample_request, qps_window, qps_max, bypass_token, remark, is_active, update_at)
|
|
|
|
|
+ VALUES
|
|
|
|
|
+ (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, current_timestamp)
|
|
|
|
|
+ """,
|
|
|
|
|
+ (
|
|
|
|
|
+ "三日天气查询",
|
|
|
|
|
+ "https://api.52vmy.cn/api/query/tian",
|
|
|
|
|
+ "GET",
|
|
|
|
|
+ "JSON",
|
|
|
|
|
+ "https://api.52vmy.cn/api/query/tian?city=北京市",
|
|
|
|
|
+ 2,
|
|
|
|
|
+ 4,
|
|
|
|
|
+ "",
|
|
|
|
|
+ "点击前往三日天气API",
|
|
|
|
|
+ 1,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ service_row = conn.execute("SELECT id FROM menus WHERE parent_id=0 AND name=?", ("智能服务",)).fetchone()
|
|
|
|
|
+ if not service_row:
|
|
|
|
|
+ cursor = conn.execute(
|
|
|
|
|
+ "INSERT INTO menus (parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
+ (0, "智能服务", "layui-icon-component", "", 4)
|
|
|
|
|
+ )
|
|
|
|
|
+ service_menu_id = cursor.lastrowid
|
|
|
|
|
+ else:
|
|
|
|
|
+ service_menu_id = service_row["id"]
|
|
|
|
|
+
|
|
|
|
|
+ de_row = conn.execute("SELECT id FROM menus WHERE url=?", ("/digital_employee/list",)).fetchone()
|
|
|
|
|
+ if not de_row:
|
|
|
|
|
+ cursor = conn.execute(
|
|
|
|
|
+ "INSERT INTO menus (parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
+ (service_menu_id, "数字员工", "layui-icon-username", "/digital_employee/list", 1)
|
|
|
|
|
+ )
|
|
|
|
|
+ de_menu_id = cursor.lastrowid
|
|
|
|
|
+ else:
|
|
|
|
|
+ de_menu_id = de_row["id"]
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ "UPDATE menus SET name=?, icon=?, parent_id=?, order_num=? WHERE id=?",
|
|
|
|
|
+ ("数字员工", "layui-icon-username", service_menu_id, 1, de_menu_id)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ sess_row = conn.execute("SELECT id FROM menus WHERE url=?", ("/chat_admin/sessions",)).fetchone()
|
|
|
|
|
+ if not sess_row:
|
|
|
|
|
+ cursor = conn.execute(
|
|
|
|
|
+ "INSERT INTO menus (parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
+ (service_menu_id, "会话管理", "layui-icon-dialogue", "/chat_admin/sessions", 2)
|
|
|
|
|
+ )
|
|
|
|
|
+ sess_menu_id = cursor.lastrowid
|
|
|
|
|
+ else:
|
|
|
|
|
+ sess_menu_id = sess_row["id"]
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ "UPDATE menus SET name=?, icon=?, parent_id=?, order_num=? WHERE id=?",
|
|
|
|
|
+ ("会话管理", "layui-icon-dialogue", service_menu_id, 2, sess_menu_id)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ msg_row = conn.execute("SELECT id FROM menus WHERE url=?", ("/chat_admin/messages",)).fetchone()
|
|
|
|
|
+ if not msg_row:
|
|
|
|
|
+ cursor = conn.execute(
|
|
|
|
|
+ "INSERT INTO menus (parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
+ (service_menu_id, "对话管理", "layui-icon-chat", "/chat_admin/messages", 3)
|
|
|
|
|
+ )
|
|
|
|
|
+ msg_menu_id = cursor.lastrowid
|
|
|
|
|
+ else:
|
|
|
|
|
+ msg_menu_id = msg_row["id"]
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ "UPDATE menus SET name=?, icon=?, parent_id=?, order_num=? WHERE id=?",
|
|
|
|
|
+ ("对话管理", "layui-icon-chat", service_menu_id, 3, msg_menu_id)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ skill_row = conn.execute("SELECT id FROM menus WHERE url=?", ("/skill_manage/list",)).fetchone()
|
|
|
|
|
+ if not skill_row:
|
|
|
|
|
+ cursor = conn.execute(
|
|
|
|
|
+ "INSERT INTO menus (parent_id, name, icon, url, order_num) VALUES (?, ?, ?, ?, ?)",
|
|
|
|
|
+ (service_menu_id, "技能管理", "layui-icon-template-1", "/skill_manage/list", 4)
|
|
|
|
|
+ )
|
|
|
|
|
+ skill_menu_id = cursor.lastrowid
|
|
|
|
|
+ else:
|
|
|
|
|
+ skill_menu_id = skill_row["id"]
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ "UPDATE menus SET name=?, icon=?, parent_id=?, order_num=? WHERE id=?",
|
|
|
|
|
+ ("技能管理", "layui-icon-template-1", service_menu_id, 4, skill_menu_id)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO role_menus (role_id, menu_id) VALUES (?, ?)", (super_role_id, service_menu_id))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO role_menus (role_id, menu_id) VALUES (?, ?)", (super_role_id, de_menu_id))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO role_menus (role_id, menu_id) VALUES (?, ?)", (super_role_id, sess_menu_id))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO role_menus (role_id, menu_id) VALUES (?, ?)", (super_role_id, msg_menu_id))
|
|
|
|
|
+ conn.execute("INSERT OR IGNORE INTO role_menus (role_id, menu_id) VALUES (?, ?)", (super_role_id, skill_menu_id))
|
|
|
|
|
+
|
|
|
|
|
+ music_api = conn.execute("SELECT id FROM api_endpoints WHERE url=? AND method='GET'", ("https://api.52vmy.cn/api/music/wy/rand",)).fetchone()
|
|
|
|
|
+ weather_api = conn.execute("SELECT id FROM api_endpoints WHERE url=? AND method='GET'", ("https://api.52vmy.cn/api/query/tian",)).fetchone()
|
|
|
|
|
+
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ """
|
|
|
|
|
+ INSERT OR IGNORE INTO digital_employees
|
|
|
|
|
+ (name, alias, category, description, ai_prompt, api_endpoint_id, api_param_name, is_active, update_at)
|
|
|
|
|
+ VALUES
|
|
|
|
|
+ (?, ?, ?, ?, ?, ?, ?, ?, current_timestamp)
|
|
|
|
|
+ """,
|
|
|
|
|
+ (
|
|
|
|
|
+ "川小农",
|
|
|
|
|
+ "川小农",
|
|
|
|
|
+ "AI",
|
|
|
|
|
+ "基于默认模型与 Prompt 的智能对话数字员工",
|
|
|
|
|
+ "你是数字员工“川小农”。你以专业、克制、可执行的方式回答用户问题。你必须用中文输出。你会先给出结论,再给出清晰步骤与注意事项。遇到信息不足时,先提出最少的澄清点,然后给出可行的默认方案。",
|
|
|
|
|
+ None,
|
|
|
|
|
+ "",
|
|
|
|
|
+ 1,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ if weather_api:
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ """
|
|
|
|
|
+ INSERT OR IGNORE INTO digital_employees
|
|
|
|
|
+ (name, alias, category, description, ai_prompt, api_endpoint_id, api_param_name, is_active, update_at)
|
|
|
|
|
+ VALUES
|
|
|
|
|
+ (?, ?, ?, ?, ?, ?, ?, ?, current_timestamp)
|
|
|
|
|
+ """,
|
|
|
|
|
+ (
|
|
|
|
|
+ "天气",
|
|
|
|
|
+ "天气",
|
|
|
|
|
+ "NORMAL",
|
|
|
|
|
+ "通过接口服务查询天气:@天气 北京市",
|
|
|
|
|
+ "",
|
|
|
|
|
+ int(weather_api["id"]),
|
|
|
|
|
+ "city",
|
|
|
|
|
+ 1,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ if music_api:
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ """
|
|
|
|
|
+ INSERT OR IGNORE INTO digital_employees
|
|
|
|
|
+ (name, alias, category, description, ai_prompt, api_endpoint_id, api_param_name, is_active, update_at)
|
|
|
|
|
+ VALUES
|
|
|
|
|
+ (?, ?, ?, ?, ?, ?, ?, ?, current_timestamp)
|
|
|
|
|
+ """,
|
|
|
|
|
+ (
|
|
|
|
|
+ "音乐",
|
|
|
|
|
+ "音乐",
|
|
|
|
|
+ "NORMAL",
|
|
|
|
|
+ "随机音乐卡片:@音乐",
|
|
|
|
|
+ "",
|
|
|
|
|
+ int(music_api["id"]),
|
|
|
|
|
+ "",
|
|
|
|
|
+ 1,
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ # 注入默认的百度新闻采集源
|
|
|
|
|
+ baidu_source = conn.execute("SELECT id FROM spy_sources WHERE name='百度新闻'").fetchone()
|
|
|
|
|
+ if not baidu_source:
|
|
|
|
|
+ headers_str = """Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
|
|
|
|
|
+Accept-Encoding: gzip, deflate, br, zstd
|
|
|
|
|
+Accept-Language: zh-CN,zh;q=0.9
|
|
|
|
|
+Cache-Control: no-cache
|
|
|
|
|
+Connection: keep-alive
|
|
|
|
|
+Cookie: BIDUPSID=5CFCC8D701BF7571598CE9F66EE8E6B5; PSTM=1775407070; BD_UPN=1a314753; BAIDUID=5CFCC8D701BF75717E6B8B51D00D380F:SL=0:NR=10:FG=1;
|
|
|
|
|
+Host: www.baidu.com
|
|
|
|
|
+Pragma: no-cache
|
|
|
|
|
+Referer: https://news.baidu.com/
|
|
|
|
|
+Upgrade-Insecure-Requests: 1
|
|
|
|
|
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36 QQBrowser/21.1.8743.400"""
|
|
|
|
|
+
|
|
|
|
|
+ conn.execute(
|
|
|
|
|
+ "INSERT INTO spy_sources (name, entry_url, request_headers, is_active) VALUES (?, ?, ?, ?)",
|
|
|
|
|
+ ("百度新闻", "https://www.baidu.com/s?rtt=1&bsst=1&cl=2&tn=news&rsv_dl=ns_pc&word={关键字}&pn={分页步进}", headers_str, 1)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ app = make_app()
|
|
|
|
|
+ server = HTTPServer(app)
|
|
|
|
|
+ server.bind(10088)
|
|
|
|
|
+ # 自动CPU核心数
|
|
|
|
|
+ server.start()
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ print("====== Server 启动成功 ======== 端口:10088 ======", flush=True)
|
|
|
|
|
+ except OSError:
|
|
|
|
|
+ pass
|
|
|
|
|
+ tornado.ioloop.IOLoop.current().start()
|