diff --git a/.gitignore b/.gitignore index 12907baa..db7233b2 100644 --- a/.gitignore +++ b/.gitignore @@ -179,5 +179,4 @@ plugins/activity/ !/resources/image/genshin/alc/back.png !/data/genshin_alc/ .vscode/launch.json -/resources/template/my_info plugins_/ \ No newline at end of file diff --git a/resources/template/check/res/font/fzrzExtraBold.ttf b/resources/font/fzrzExtraBold.ttf similarity index 100% rename from resources/template/check/res/font/fzrzExtraBold.ttf rename to resources/font/fzrzExtraBold.ttf diff --git a/resources/template/help/res/font/syht.otf b/resources/font/syht.otf similarity index 100% rename from resources/template/help/res/font/syht.otf rename to resources/font/syht.otf diff --git a/resources/template/help/res/font/syst.otf b/resources/font/syst.otf similarity index 100% rename from resources/template/help/res/font/syst.otf rename to resources/font/syst.otf diff --git a/resources/template/bar_chart/main.html b/resources/template/bar_chart/main.html index 8728b14b..5cc1fbdd 100644 --- a/resources/template/bar_chart/main.html +++ b/resources/template/bar_chart/main.html @@ -1,5 +1,6 @@ + ECharts Example @@ -7,14 +8,15 @@ +
- + + \ No newline at end of file diff --git a/resources/template/check/main.css b/resources/template/check/main.css index 97ee0c66..f6790712 100644 --- a/resources/template/check/main.css +++ b/resources/template/check/main.css @@ -3,7 +3,7 @@ @font-face { font-family: fzrzFont; /* 导入的字体文件 */ - src: url("./res/font/fzrzExtraBold.ttf"); + src: url("../../font/fzrzExtraBold.ttf"); } diff --git a/resources/template/help/main.css b/resources/template/help/main.css index 1f2d7c0e..a8bb2c15 100644 --- a/resources/template/help/main.css +++ b/resources/template/help/main.css @@ -3,25 +3,9 @@ @font-face { font-family: fzrzFont; /* 导入的字体文件 */ - src: url("./res/font/fzrzExtraBold.ttf"); + src: url("../../font/fzrzExtraBold.ttf"); } -@font-face { - font-family: syhtFont; - /* 导入的字体文件 */ - src: url("./res/font/syht.otf"); -} - -@font-face { - font-family: systFont; - /* 导入的字体文件 */ - src: url("./res/font/syst.otf"); -} - - - - - body { position: absolute; left: -8px; diff --git a/resources/template/help/res/font/fzrzExtraBold.ttf b/resources/template/help/res/font/fzrzExtraBold.ttf deleted file mode 100644 index 8afeafca..00000000 Binary files a/resources/template/help/res/font/fzrzExtraBold.ttf and /dev/null differ diff --git a/resources/template/my_info/main.css b/resources/template/my_info/main.css new file mode 100644 index 00000000..1bab0894 --- /dev/null +++ b/resources/template/my_info/main.css @@ -0,0 +1,235 @@ + + +@font-face { + font-family: fzrzFont; + /* 导入的字体文件 */ + src: url("../../font/HYWenHei-85W.ttf"); +} + +@font-face { + font-family: systFont; + /* 导入的字体文件 */ + src: url("../../font/syst.otf"); +} + +@font-face { + font-family: syhtFont; + /* 导入的字体文件 */ + src: url("../../font/syht.otf"); +} + + + + + + +body { + position: absolute; + left: -8px; + top: -8px; +} + +.wrapper{ + width: 1754px; + height: 1240px; + position: relative; + background-size: cover; + font-family: 'fzrzFont'; + padding: 20px; + background-color: #E08A9F; + border-radius: 50px; + padding: 40px; + color: #E08A9F; + font-size: 30px; +} + +.main{ + width: 100%; + height: 100%; + display: flex; +} + +.main-content { + background-color: white; + height: 1123px; + width: 682px; + border-radius: 50px; + padding: 56px 83px; + position: relative; +} + +.weather-img { + position: absolute; + height: 60px; + left: 325px; + top: -10px; +} + +.top-date { + display: flex; + position: relative; + font-family: "systFont"; +} + +.user-info { + display: flex; + margin-top: 65px; +} + +.user-info-ava { + position: relative; + +} + +.ava-img { + height: 250px; + border-radius: 50%; + overflow: hidden; + display: inline-block; + border: 2px solid #E0899E; +} + +.user-info-data { + margin-left: 30px; +} + +.nickname { + position: absolute; + width: 140px; + left: 50%; + bottom: -27px; + transform: translate(-50%, -50%); + background-color: #E0899E; + color: white; + padding: 5px 10px; + border-radius: 15px; + text-align: center; +} + +.user-des { + margin-top: 60px; + font-size: 35px; + position: relative; + height: 710px; +} + +.des-img { + height: 430px; + position: absolute; + bottom: -28px; + left: 85px; +} + +.tag-img-content { + height: 120px; + width: 75px; + background-color: #E8BB88; + position: absolute; + top: 0px; + left: 120px; +} + +.tag-img-test { + border-left: 37px solid transparent; + border-right: 38px solid transparent; + border-bottom: 54px solid white; + width: 0; + height: 68px; +} + +.menu { + position: absolute; + right: 0px; + height: 496px; + top: 175px; +} + +.menu-item { + writing-mode: vertical-rl; /* 从右向左垂直排列 */ + color: #754E43; + height: 190px; + width: 65px; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 30px; + border-top-left-radius: 30px; + border-bottom-left-radius: 30px; + gap: 20px; +} + +.main-img { + position: absolute; + height: 200px; + right: 150px; + top: 10px; +} + +.sign-data { + margin-top: 105px; +} + +.base-title { + font-size: 35px; +} + +.sign-level { + border: 2px solid #E08A9F; + padding: 7px 3px; + font-size: 28px; +} + +.line { + border: 1px solid #E08A9F; + margin-top: 30px; +} + +.text-item { + display: flex; +} + + +.test-icon { + height: 50px; + margin-right: 10px; +} + +.test-content { + display: flex; + align-items: center; + margin-top: 30px; +} + +.test-title { + display: flex; + align-items: center; + margin-bottom: 10px; +} + +.text-chart { + margin-top: 20px; + background-color: #E0899E; + color: white; + padding: 30px; + border-radius: 30px; + height: 560px; +} + +.chart { + height: 490px; + width: 622px; + background-color: white; +} + +.select { + background-color: #E0899E; + color: white; +} + +.uname { + display: -webkit-box; + -webkit-line-clamp: 1; /* 显示的最大行数 */ + -webkit-box-orient: vertical; + overflow: hidden; /* 隐藏溢出内容 */ + text-overflow: ellipsis; /* 溢出部分显示为省略号 */ +} \ No newline at end of file diff --git a/resources/template/my_info/main.html b/resources/template/my_info/main.html new file mode 100644 index 00000000..9cdb9f69 --- /dev/null +++ b/resources/template/my_info/main.html @@ -0,0 +1,177 @@ + + + + + + + + + test + + + + + +
+
+
+
{{data.date}}...... + sun + 24℃ +
+ +
+

个人简介:

+
+ {{data.description}} +
+ +
+
+
+
+ +
+
+
+
+
+ +
+

好感度等级: {{data.sign_level}}级

+
+ 路人 + 陌生 + 初识 + 普通 + 熟悉 + 信赖 + 相知 + 厚谊 + 亲密 +
+
+
+
+ + 权限等级: {{data.level}} +
+
+
+
+ + 金币数量: {{data.gold}} +
+
+ + 道具数量: {{data.prop}} +
+
+
+
+ + 调用次数: {{data.call}} +
+
+ + 发言统计: {{data.say}} +
+
+ +
+
+ + 发言趋势图 +
+
+
+
+
+
+
+ + + + + \ No newline at end of file diff --git a/resources/template/my_info/main.js b/resources/template/my_info/main.js new file mode 100644 index 00000000..4aabcc9b --- /dev/null +++ b/resources/template/my_info/main.js @@ -0,0 +1,32 @@ +// var chartDom = document.getElementById("chart") +// var myChart = echarts.init(chartDom) +// var option + +// option = { +// backgroundColor: "#E0899E", +// animation: false, +// xAxis: { +// type: "category", +// data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], +// axisLabel: { +// color: "#fff", +// fontSize: 20, +// }, +// }, +// yAxis: { +// type: "value", +// axisLabel: { +// color: "#fff", +// fontSize: 20, +// }, +// }, +// series: [ +// { +// data: [820, 932, 901, 934, 1290, 1330, 1320], +// type: "line", +// smooth: true, +// }, +// ], +// } + +// option && myChart.setOption(option) diff --git a/resources/template/my_info/main_copy.html b/resources/template/my_info/main_copy.html new file mode 100644 index 00000000..6444252d --- /dev/null +++ b/resources/template/my_info/main_copy.html @@ -0,0 +1,130 @@ + + + + + + + + + test + + + + + +
+
+
+
2024/08/14...... + sun + 24℃ +
+ +
+

个人简介:

+
+ 这是人类勇者的传奇在这片古老而神秘的土地上, + 每当黑暗的力量威胁到和平与正义之时总会有一位英雄挺身而出。 + 他们不仅拥有超凡的力量更重要的是更重要的是更重要的是 +
+ +
+
+
+
+ +
+
+
+
+
+ +
+

好感度等级: 5级

+
+ 路人 + 陌生 + 初识 + 普通 + 熟悉 + 信赖 + 相知 + 厚谊 + 亲密 +
+
+
+
+ + 权限等级: 9 +
+
+
+
+ + 金币数量: 999 +
+
+ + 道具数量: 933 +
+
+
+
+ + 调用次数: 6443 +
+
+ + 发言统计: 233 +
+
+ +
+
+ + 发言趋势图 +
+
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/resources/template/my_info/res/img/1.png b/resources/template/my_info/res/img/1.png new file mode 100644 index 00000000..2d48a151 Binary files /dev/null and b/resources/template/my_info/res/img/1.png differ diff --git a/resources/template/my_info/res/img/2.png b/resources/template/my_info/res/img/2.png new file mode 100644 index 00000000..54c40fbf Binary files /dev/null and b/resources/template/my_info/res/img/2.png differ diff --git a/resources/template/my_info/res/img/3.jpg b/resources/template/my_info/res/img/3.jpg new file mode 100644 index 00000000..076a4e1a Binary files /dev/null and b/resources/template/my_info/res/img/3.jpg differ diff --git a/resources/template/my_info/res/img/call.png b/resources/template/my_info/res/img/call.png new file mode 100644 index 00000000..a2b2b870 Binary files /dev/null and b/resources/template/my_info/res/img/call.png differ diff --git a/resources/template/my_info/res/img/gold.png b/resources/template/my_info/res/img/gold.png new file mode 100644 index 00000000..d6dd1eba Binary files /dev/null and b/resources/template/my_info/res/img/gold.png differ diff --git a/resources/template/my_info/res/img/level.png b/resources/template/my_info/res/img/level.png new file mode 100644 index 00000000..df2dc360 Binary files /dev/null and b/resources/template/my_info/res/img/level.png differ diff --git a/resources/template/my_info/res/img/moon.png b/resources/template/my_info/res/img/moon.png new file mode 100644 index 00000000..0a59e19a Binary files /dev/null and b/resources/template/my_info/res/img/moon.png differ diff --git a/resources/template/my_info/res/img/prop.png b/resources/template/my_info/res/img/prop.png new file mode 100644 index 00000000..e9b09247 Binary files /dev/null and b/resources/template/my_info/res/img/prop.png differ diff --git a/resources/template/my_info/res/img/say.png b/resources/template/my_info/res/img/say.png new file mode 100644 index 00000000..1f169058 Binary files /dev/null and b/resources/template/my_info/res/img/say.png differ diff --git a/resources/template/my_info/res/img/sun.png b/resources/template/my_info/res/img/sun.png new file mode 100644 index 00000000..3c81e1b3 Binary files /dev/null and b/resources/template/my_info/res/img/sun.png differ diff --git a/resources/template/my_info/res/img/test.jpg b/resources/template/my_info/res/img/test.jpg new file mode 100644 index 00000000..bf95d664 Binary files /dev/null and b/resources/template/my_info/res/img/test.jpg differ diff --git a/resources/template/my_info/res/img/xian.png b/resources/template/my_info/res/img/xian.png new file mode 100644 index 00000000..da7667a2 Binary files /dev/null and b/resources/template/my_info/res/img/xian.png differ diff --git a/resources/template/sign/main.css b/resources/template/sign/main.css index d217f74a..d96bf2b4 100644 --- a/resources/template/sign/main.css +++ b/resources/template/sign/main.css @@ -34,11 +34,6 @@ src: url("./res/font/jcyt.ttf"); } -@font-face { - font-family: yshsFont; - /* 导入的字体文件 */ - src: url("/resources/font/YSHaoShenTi-2.ttf"); -} body { position: absolute; diff --git a/resources/template/sign/main.html b/resources/template/sign/main.html index cfc8a228..040cf87e 100644 --- a/resources/template/sign/main.html +++ b/resources/template/sign/main.html @@ -16,7 +16,7 @@
- +

{{data.name}}

diff --git a/resources/template/ss_menu/main.css b/resources/template/ss_menu/main.css index 1cde35f4..dde33819 100644 --- a/resources/template/ss_menu/main.css +++ b/resources/template/ss_menu/main.css @@ -3,19 +3,19 @@ @font-face { font-family: fzrzFont; /* 导入的字体文件 */ - src: url("./res/font/fzrzExtraBold.ttf"); + src: url("../../font/fzrzExtraBold.ttf"); } @font-face { font-family: syhtFont; /* 导入的字体文件 */ - src: url("./res/font/syht.otf"); + src: url("../../font/syht.otf"); } @font-face { font-family: systFont; /* 导入的字体文件 */ - src: url("./res/font/syst.otf"); + src: url("../../font/syst.otf"); } diff --git a/resources/template/ss_menu/res/font/fzrzExtraBold.ttf b/resources/template/ss_menu/res/font/fzrzExtraBold.ttf deleted file mode 100644 index 8afeafca..00000000 Binary files a/resources/template/ss_menu/res/font/fzrzExtraBold.ttf and /dev/null differ diff --git a/resources/template/ss_menu/res/font/syht.otf b/resources/template/ss_menu/res/font/syht.otf deleted file mode 100644 index 630d5467..00000000 Binary files a/resources/template/ss_menu/res/font/syht.otf and /dev/null differ diff --git a/resources/template/ss_menu/res/font/syst.otf b/resources/template/ss_menu/res/font/syst.otf deleted file mode 100644 index efa94cb5..00000000 Binary files a/resources/template/ss_menu/res/font/syst.otf and /dev/null differ diff --git a/zhenxun/builtin_plugins/info/__init__.py b/zhenxun/builtin_plugins/info/__init__.py new file mode 100644 index 00000000..2d71bf8c --- /dev/null +++ b/zhenxun/builtin_plugins/info/__init__.py @@ -0,0 +1,56 @@ +from nonebot.adapters import Bot +from nonebot.plugin import PluginMetadata +from nonebot_plugin_session import EventSession +from nonebot_plugin_alconna import At, Args, Match, Alconna, Arparma, on_alconna + +from zhenxun.services.log import logger +from zhenxun.utils.enum import PluginType +from zhenxun.utils.depends import UserName +from zhenxun.utils.message import MessageUtils +from zhenxun.utils.platform import PlatformUtils +from zhenxun.configs.utils import PluginExtraData +from zhenxun.models.group_member_info import GroupInfoUser + +from .my_info import get_user_info + +__plugin_meta__ = PluginMetadata( + name="查看信息", + description="查看个人信息", + usage=""" + 查看个人/群组信息 + 指令: + 我的信息 ?[at] + """.strip(), + extra=PluginExtraData(author="HibiKier", version="0.1").dict(), +) + + +_matcher = on_alconna(Alconna("我的信息", Args["at_user?", At]), priority=5, block=True) + + +@_matcher.handle() +async def _( + bot: Bot, + session: EventSession, + arparma: Arparma, + at_user: Match[At], + nickname: str = UserName(), +): + user_id = session.id1 + if at_user.available: + user_id = at_user.result.target + if user := await GroupInfoUser.get_or_none( + user_id=user_id, group_id=session.id2 + ): + nickname = user.user_name + else: + nickname = user_id + if not user_id: + await MessageUtils.build_message("用户id为空...").finish(reply_to=True) + try: + result = await get_user_info(bot, user_id, session.id2, nickname) + await MessageUtils.build_message(result).send(at_sender=True) + logger.info("获取用户信息", arparma.header_result, session=session) + except Exception as e: + logger.error("获取用户信息失败", arparma.header_result, session=session, e=e) + await MessageUtils.build_message("获取用户信息失败...").finish(reply_to=True) diff --git a/zhenxun/builtin_plugins/info/my_info.py b/zhenxun/builtin_plugins/info/my_info.py new file mode 100644 index 00000000..43eda62c --- /dev/null +++ b/zhenxun/builtin_plugins/info/my_info.py @@ -0,0 +1,193 @@ +import random +from datetime import datetime, timedelta + +from nonebot.adapters import Bot +from tortoise.functions import Count +from tortoise.expressions import RawSQL +from nonebot_plugin_htmlrender import template_to_pic + +from zhenxun.models.sign_user import SignUser +from zhenxun.models.level_user import LevelUser +from zhenxun.models.statistics import Statistics +from zhenxun.utils.platform import PlatformUtils +from zhenxun.models.chat_history import ChatHistory +from zhenxun.models.user_console import UserConsole +from zhenxun.configs.path_config import TEMPLATE_PATH + +RACE = [ + "龙族", + "魅魔", + "森林精灵", + "血精灵", + "暗夜精灵", + "狗头人", + "狼人", + "猫人", + "猪头人", + "骷髅", + "僵尸", + "虫族", + "人类", + "天使", + "恶魔", + "甲壳虫", + "猎猫", + "人鱼", + "哥布林", + "地精", + "泰坦", + "矮人", + "山巨人", + "石巨人", +] + +SEX = ["男", "女", "雌", "雄"] + +OCC = [ + "猎人", + "战士", + "魔法师", + "狂战士", + "魔战士", + "盗贼", + "术士", + "牧师", + "骑士", + "刺客", + "游侠", + "召唤师", + "圣骑士", + "魔使", + "龙骑士", + "赏金猎手", + "吟游诗人", + "德鲁伊", + "祭司", + "符文师", + "狂暴术士", + "萨满", + "裁决者", + "角斗士", +] + +lik2level = { + 400: 8, + 270: 7, + 200: 6, + 140: 5, + 90: 4, + 50: 3, + 25: 2, + 10: 1, + 0: 0, +} + + +def get_level(impression: float) -> int: + """获取好感度等级""" + return next((level for imp, level in lik2level.items() if impression >= imp), 0) + + +async def get_chat_history( + user_id: str, group_id: str | None +) -> tuple[list[str], list[str]]: + """获取用户聊天记录 + + 参数: + user_id: 用户id + group_id: 群id + + 返回: + tuple[list[str], list[str]]: 日期列表, 次数列表 + + """ + now = datetime.now() + filter_date = now - timedelta(days=7, hours=now.hour, minutes=now.minute) + date_list = ( + await ChatHistory.filter( + user_id=user_id, group_id=group_id, create_time__gte=filter_date + ) + .annotate(date=RawSQL("DATE(create_time)"), count=Count("id")) + .group_by("date") + .values("date", "count") + ) + chart_date = [] + count_list = [] + date2cnt = {str(date["date"]): date["count"] for date in date_list} + date = now.date() + for _ in range(7): + if str(date) in date2cnt: + count_list.append(date2cnt[str(date)]) + else: + count_list.append(0) + chart_date.append(str(date)) + date -= timedelta(days=1) + for c in chart_date: + chart_date[chart_date.index(c)] = c[5:] + chart_date.reverse() + count_list.reverse() + return chart_date, count_list + + +async def get_user_info( + bot: Bot, user_id: str, group_id: str | None, nickname: str +) -> bytes: + """获取用户个人信息 + + 参数: + bot: Bot + user_id: 用户id + group_id: 群id + nickname: 用户昵称 + + 返回: + bytes: 图片数据 + """ + platform = PlatformUtils.get_platform(bot) or "" + ava_url = PlatformUtils.get_user_avatar_url(user_id, platform) + user = await UserConsole.get_user(user_id, platform) + level = await LevelUser.get_user_level(user_id, group_id) + sign_level = 0 + if sign_user := await SignUser.get_or_none(user_id=user_id): + sign_level = get_level(float(sign_user.impression)) + chat_count = await ChatHistory.filter(user_id=user_id, group_id=group_id).count() + stat_count = await Statistics.filter(user_id=user_id, group_id=group_id).count() + select_index = ["" for _ in range(9)] + select_index[sign_level] = "select" + uid = f"{user.uid}".rjust(8, "0") + uid = f"{uid[:4]} {uid[4:]}" + now = datetime.now() + weather = "moon" if now.hour < 6 or now.hour > 19 else "sun" + chart_date, count_list = await get_chat_history(user_id, group_id) + data = { + "date": now.date(), + "weather": weather, + "ava_url": ava_url, + "nickname": nickname, + "title": "勇 者", + "race": random.choice(RACE), + "sex": random.choice(SEX), + "occ": random.choice(OCC), + "uid": uid, + "description": "这是一个传奇的故事," + "人类的赞歌是勇气的赞歌,人类的伟大是勇气的伟译。", + "sign_level": sign_level, + "level": level, + "gold": user.gold, + "prop": len(user.props), + "call": stat_count, + "say": chat_count, + "select_index": select_index, + "chart_date": chart_date, + "count_list": count_list, + } + return await template_to_pic( + template_path=str((TEMPLATE_PATH / "my_info").absolute()), + template_name="main.html", + templates={"data": data}, + pages={ + "viewport": {"width": 1754, "height": 1240}, + "base_url": f"file://{TEMPLATE_PATH}", + }, + wait=2, + ) diff --git a/zhenxun/builtin_plugins/sign_in/utils.py b/zhenxun/builtin_plugins/sign_in/utils.py index def67870..c78e63ed 100644 --- a/zhenxun/builtin_plugins/sign_in/utils.py +++ b/zhenxun/builtin_plugins/sign_in/utils.py @@ -13,6 +13,7 @@ from zhenxun.models.sign_log import SignLog from zhenxun.models.sign_user import SignUser from zhenxun.utils.utils import get_user_avatar from zhenxun.utils.image_utils import BuildImage +from zhenxun.utils.platform import PlatformUtils from zhenxun.configs.config import Config, BotConfig from zhenxun.configs.path_config import IMAGE_PATH, TEMPLATE_PATH @@ -419,8 +420,9 @@ async def _generate_html_card( next_impression - previous_impression ) now = datetime.now() + ava_url = PlatformUtils.get_user_avatar_url(user.user_id, "qq") data = { - "ava": AVA_URL.format(user.user_id), + "ava_url": ava_url, "name": nickname, "uid": uid, "sign_count": f"{user.sign_count}", diff --git a/zhenxun/utils/platform.py b/zhenxun/utils/platform.py index 91ab8eb0..6ecddb54 100644 --- a/zhenxun/utils/platform.py +++ b/zhenxun/utils/platform.py @@ -267,7 +267,7 @@ class PlatformUtils: return None @classmethod - async def get_user_avatar_url(cls, user_id: str, platform: str) -> str | None: + def get_user_avatar_url(cls, user_id: str, platform: str) -> str | None: """快捷获取用户头像url 参数: