From e35bacffc14ab77b2182ab2a2dd2cce423e5b495 Mon Sep 17 00:00:00 2001 From: ClovertaTheTrilobita Date: Sat, 12 Jul 2025 19:04:53 +0800 Subject: [PATCH] =?UTF-8?q?feature(question):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=97=AE=E7=AD=94=E6=A8=A1=E5=9D=97=EF=BC=8C=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8F=AF=E5=9C=A8=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=AD=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E9=A2=84=E8=AE=BE=E5=A5=BD=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E5=92=8C=E5=9B=9E=E7=AD=94=20TODO:=20=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=AF=A5=E6=A8=A1=E5=9D=97=E7=9A=84web?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E9=9D=A2=E6=9D=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend.py | 22 ++++ bot.py | 16 +++ requirements.txt | 3 +- src/clover_sqlite/models/questions.py | 176 ++++++++++++++++++++++++++ src/plugins/check.py | 2 +- src/plugins/question.py | 14 ++ 6 files changed, 231 insertions(+), 2 deletions(-) create mode 100644 backend.py create mode 100644 src/clover_sqlite/models/questions.py create mode 100644 src/plugins/question.py diff --git a/backend.py b/backend.py new file mode 100644 index 0000000..e40b09c --- /dev/null +++ b/backend.py @@ -0,0 +1,22 @@ +from flask import Flask +from src.clover_sqlite.models.questions import Question +app = Flask(__name__) + +@app.route("/") +def hello(): + return "Hello World!" + +@app.route("/list") +async def list_data(): + return await Question.fetch() + +@app.route("/init") +async def init_data(): + if await Question.insert_one("你好", "你好哦"): + return "success" + + return "failed" + +def start_flask(): + print("Flask启动中...") + app.run(host='0.0.0.0', port=5000, debug=False, use_reloader=False) \ No newline at end of file diff --git a/bot.py b/bot.py index e3b1ed1..6aa430a 100644 --- a/bot.py +++ b/bot.py @@ -1,6 +1,8 @@ import os import glob +import threading import logging + import nonebot from pathlib import Path from nonebot import logger @@ -10,6 +12,10 @@ from apscheduler.schedulers.background import BackgroundScheduler from src.configs.path_config import log_path,temp_path,video_path,yuc_wiki_path nonebot.init() + +from backend import start_flask + + driver = nonebot.get_driver() driver.register_adapter(QQAdapter) # 注册QQ适配器 nonebot.load_from_toml("pyproject.toml") @@ -35,5 +41,15 @@ scheduler = BackgroundScheduler() scheduler.add_job(clean_temp_cache, 'cron', hour=0, minute=0) if __name__ == "__main__": + + # nonebot_thread = threading.Thread(target=nonebot.run(), daemon=True) + # nonebot_thread.start() + + + + flask_thread = threading.Thread(target=start_flask, daemon=True) + flask_thread.start() scheduler.start() nonebot.run() + + diff --git a/requirements.txt b/requirements.txt index 5d4b3df..df6e330 100644 --- a/requirements.txt +++ b/requirements.txt @@ -44,4 +44,5 @@ aiohttp pydantic matplotlib httpx -crypto \ No newline at end of file +crypto +flask[async] \ No newline at end of file diff --git a/src/clover_sqlite/models/questions.py b/src/clover_sqlite/models/questions.py new file mode 100644 index 0000000..8667c74 --- /dev/null +++ b/src/clover_sqlite/models/questions.py @@ -0,0 +1,176 @@ +from lazy_object_proxy.utils import await_ +from tortoise import fields +from src.clover_sqlite.data_init.db_connect import Model + + +class Question(Model): + id = fields.IntField(primary_key=True, generated=True) + question = fields.CharField(max_length=155, description="问题") + answer = fields.CharField(max_length=400,description="回答") + + class Meta: + table = "question" + table_description = "问答表" + + @classmethod + async def _fetch_data(cls) -> list: + return await cls.all().order_by("id").values_list("id", "question", "answer") + + @classmethod + async def _get_data_by_id(cls, get_id: int | None) -> list | None: + """ + 通过id获取问答内容 + """ + if not get_id: + return None + else: + return await cls.filter(id=get_id).order_by("id").values_list("id", "question", "answer") + + @classmethod + async def _get_data_by_ques_keyword_exact(cls, keyword: str | None) -> list | None: + """ + 通过关键字精确地获取问题内容 + """ + if not keyword: + return None + else: + return await cls.filter(question__icontains=keyword).order_by("id").values_list("id", "question", "answer") + + @classmethod + async def _get_data_by_ques_keyword_fuzzy(cls, keyword: str | None) -> list | None: + """ + 通过关键字模糊匹配问题内容 + """ + if not keyword: + return None + else: + key_list = list(keyword) + + result = cls.filter(question__icontains=key_list[0]) + for key in key_list: + result = result.filter(question__icontains=key) + return await result.order_by("id").values_list("id", "question", "answer") + + @classmethod + async def _get_data_by_ans_keyword_exact(cls, keyword: str | None) -> list | None: + """ + 通过关键字精确地获取回答内容 + """ + if not keyword: + return None + else: + return await cls.filter(answer__icontains=keyword).order_by("id").values_list("id", "question", "answer") + + @classmethod + async def _get_data_by_ans_keyword_fuzzy(cls, keyword: str | None) -> list | None: + """ + 通过关键字模糊匹配回答内容 + """ + if not keyword: + return None + else: + key_list = list(keyword) + + result = cls.filter(answer__icontains=key_list[0]) + for key in key_list: + result = result.filter(answer__icontains=key) + return await result.order_by("id").values_list("id", "question", "answer") + + @classmethod + async def _insert_data(cls, + question: str | None, + answer: str | None) -> bool: + + data = { + "question": question, + "answer": answer + } + + if await cls.create(**data): + return True + else: + return False + + @classmethod + async def _delete_data(cls, del_id: int | None) -> bool: + if del_id is None: + return False + + if await cls.filter(id=del_id).delete(): + return True + else: + return False + + @classmethod + async def _alter_data(cls, + alter_id: int | None, + question: str | None, + answer: str | None) -> bool: + + updated_count = cls.filter(id=alter_id).update( + question=question, + answer=answer + ) + + print(f"更新了{updated_count}条数据") + return True + + @classmethod + async def fetch(cls) -> list: + return await cls._fetch_data() + + @classmethod + async def search(cls, + keyword, + via_id: bool = False, + via_question: bool = False, + via_ans: bool = False, + fuzzy: bool = False) -> list | None: + if (via_id and via_ans and via_question is False) or (fuzzy and via_id is True): + print("不合法传参") + return None + + if via_id: + return await cls._get_data_by_id(keyword) + elif via_question: + if fuzzy: + return await cls._get_data_by_ques_keyword_fuzzy(keyword) + else: + return await cls._get_data_by_ques_keyword_exact(keyword) + elif via_ans: + if fuzzy: + return await cls._get_data_by_ans_keyword_fuzzy(keyword) + else: + return await cls._get_data_by_ans_keyword_exact(keyword) + return None + + @classmethod + async def update(cls, update_id, question, answer) -> bool: + return await cls._alter_data(update_id, question, answer) + + @classmethod + async def delete_one(cls, delete_id) -> bool: + return await cls._delete_data(delete_id) + + @classmethod + async def delete_many(cls, delete_id_list: list | None) -> bool: + for delete_id in delete_id_list: + await cls._delete_data(delete_id) + + return True + + @classmethod + async def insert_one(cls, + question: str | None, + answer: str | None) -> bool: + return await cls._insert_data(question, answer) + + @classmethod + async def insert_many(cls, data_list: list | None) -> bool: + + for question, answer in data_list: + flag = await cls._insert_data(question, answer) + if flag is False: + return flag + + return True \ No newline at end of file diff --git a/src/plugins/check.py b/src/plugins/check.py index 96ac5b3..7966c59 100644 --- a/src/plugins/check.py +++ b/src/plugins/check.py @@ -10,7 +10,7 @@ from src.clover_sqlite.models.user import UserList menu = ["/重启","/今日运势","/今日塔罗","/图","/随机图","/搜番","/日报","/点歌","/摸摸头","/群老婆","/今日老婆", "/开启ai","/关闭ai","/角色列表","/添加人设", "/更新人设", "/删除人设", "/切换人设", "/管理员注册", "/待办", "/test","/天气","我喜欢你", "❤", "/待办查询", "/新建待办", "/删除待办" ,"/cf","/B站搜索", "/BV搜索", "/喜报", "/悲报", "/luxun","/鲁迅说", - "/奶龙", "/repo", "/info", "/menu", "/轻小说","/本季新番","/下季新番","/新番观察","/绝对色感" ,"/jm", "/cfrt"] + "/奶龙", "/repo", "/info", "/menu", "/轻小说","/本季新番","/下季新番","/新番观察","/绝对色感" ,"/jm", "/cfrt", "/问答"] send_menu = ["/menu","/今日运势","/今日塔罗","/图","/随机图","搜番","/日报","/点歌","/摸摸头","/群老婆","/待办","/天气", "/待办查询", "/新建待办", "/删除待办" , "/cf", "/cfrt", "/B站搜索", "/BV搜索", "/喜报", "/悲报","/鲁迅说", diff --git a/src/plugins/question.py b/src/plugins/question.py new file mode 100644 index 0000000..3cb1213 --- /dev/null +++ b/src/plugins/question.py @@ -0,0 +1,14 @@ +from nonebot.adapters.qq import MessageEvent +from nonebot.plugin import on_command +from nonebot.rule import to_me +from src.clover_sqlite.models.questions import Question + +get_question = on_command("问答", rule=to_me(), priority=10) +@get_question.handle() +async def answer_question(message: MessageEvent): + content = message.get_plaintext().replace("/问答", "").strip(" ") + reply = await Question.search(content, via_question=True, fuzzy=False) + if len(reply) > 0: + await get_question.finish(reply[0][2]) + else: + await get_question.finish("这个问题我没听说过哦")