Skip to content

Commit 635637f

Browse files
添加依赖注入支持 (#57)
1 parent 3d82a17 commit 635637f

File tree

11 files changed

+407
-75
lines changed

11 files changed

+407
-75
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"python.analysis.autoImportCompletions": true
3+
}

README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,18 @@
2626

2727
## 核心特性
2828

29-
`nonebot_plugin_value` 是一个基于 NoneBot2 的通用经济系统插件,提供以下核心功能:
30-
31-
- 📈 账户系统:各货币账户独立
32-
- 🪙 多货币系统:支持创建任意数量的货币类型
33-
- 💰 原子化交易:保证转账等操作的事务性
34-
- 🔁 钩子系统:支持交易前后触发自定义逻辑
35-
- 📊 完整审计:所有交易记录包含完整上下文信息
36-
- 🔐 安全控制:支持负余额限制
37-
- 📝 批量操作:支持批量修改用户的货币数据
38-
- 🔍 时间范围审计日志:从时间范围获取交易记录
39-
- 🚀 导出数据:支持从Json文件导入,导出到Json文件
29+
`nonebot_plugin_value` 是一个基于 NoneBot2 的通用经济系统插件,提供以下核心功能:
30+
31+
- 📈 账户系统: 各货币账户独立
32+
- 🪙 多货币系统: 支持创建任意数量的货币类型
33+
- 💰 原子化交易: 保证转账等操作的事务性
34+
- 🔁 钩子系统: 支持交易前后触发自定义逻辑
35+
- 📊 完整审计: 所有交易记录包含完整上下文信息
36+
- 🔐 安全控制: 支持负余额限制
37+
- 📝 批量操作: 支持批量修改用户的货币数据
38+
- 🔍 时间范围审计日志: 从时间范围获取交易记录
39+
- 🚀 导出数据: 支持从Json文件导入,导出到Json文件
40+
- 🔧 依赖注入: 支持依赖注入模式调用
4041

4142
### 快速开始
4243

docs/api.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ erDiagram
4747

4848
> 开发规范:我们推荐您使用 UUID.hex 作为唯一 ID,而不是直接传入 ID(我们在uuid_lib.py提供了字符串转换函数`to_uuid`)。
4949
50+
### [依赖注入](./apis/depends.md)
51+
5052
### [标准 API(表现层)](./apis/standard.md)
5153

5254
### [进阶 API(服务层)](./apis/advanced.md)

docs/apis/depends.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# EconomyValue-依赖注入模式 API 文档
2+
3+
> **本质为 [标准 API](./standard.md) 的二次封装,用于依赖注入**
4+
5+
## `~.api.depends.factory`
6+
7+
> **依赖注入模式工厂**
8+
9+
```python
10+
class DependsSwitch:
11+
@staticmethod
12+
def account_data(
13+
*,
14+
currency_id: str | None = None,
15+
) -> Callable[..., Awaitable[UserAccountData]]:
16+
"""获得账户数据
17+
18+
Args:
19+
currency_id (str | None, optional): 货币ID. Defaults to None.
20+
21+
Returns:
22+
Callable[..., Awaitable[UserAccountData]]: 可供NoneBot调用的依赖函数类
23+
"""
24+
...
25+
26+
@staticmethod
27+
def currency_data(
28+
*,
29+
currency_id: str | None = None,
30+
) -> Callable[..., Awaitable[CurrencyData | None]]:
31+
"""
32+
获取货币数据依赖函数
33+
34+
Args:
35+
currency_id (str | None, optional): 货币ID. Defaults to None.
36+
37+
Returns:
38+
Callable[..., Awaitable[CurrencyData | None]]: 可供NoneBot调用的依赖函数类
39+
"""
40+
...
41+
42+
@staticmethod
43+
def transaction_data(
44+
*,
45+
limit: int = 10,
46+
timerange: tuple[float, float] | None = None,
47+
) -> Callable[..., Awaitable[list[TransactionData]]]:
48+
"""
49+
获取交易记录
50+
51+
Args:
52+
limit (int, optional): 交易记录数量限制. Defaults to 10.
53+
timerange (tuple[float, float] | None, optional): 时间范围. Defaults to None.
54+
55+
Returns:
56+
Callable[..., Awaitable[list[TransactionData]]]: 可供NoneBot调用的依赖函数类
57+
"""
58+
...
59+
60+
@staticmethod
61+
def account_executor(
62+
*,
63+
currency_id: str | None = None,
64+
) -> Callable[..., Awaitable[AccountExecutor]]:
65+
"""
66+
Args:
67+
currency_id (str | None, optional): 货币ID. Defaults to None.
68+
69+
Returns:
70+
Callable[..., Awaitable[AccountExecutor]]: 账号数据操作对象
71+
"""
72+
...
73+
74+
```
75+
76+
## 示例使用
77+
78+
```python
79+
from nonebot import on_command, require
80+
from nonebot.adapters import Event
81+
from nonebot.params import Depends
82+
83+
require("nonebot_plugin_value")
84+
from nonebot_plugin_value.api.depends.factory import DependsSwitch, UserAccountData
85+
86+
test = on_command("test")
87+
88+
89+
@test.handle()
90+
async def _(user_data: UserAccountData = Depends(DependsSwitch.account_data())):
91+
await test.finish(user_data.balance)
92+
```

nonebot_plugin_value/__init__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from . import action_type, migrations, repository
88
from .api import api_balance, api_currency, api_transaction
99
from .api.api_currency import get_or_create_currency
10+
from .api.depends import factory
1011
from .hook import context, exception, hooks_manager, hooks_type
1112
from .models import currency
1213
from .pyd_models import balance_pyd, base_pyd, currency_pyd
@@ -21,8 +22,8 @@
2122
usage="请查看API文档。",
2223
type="library",
2324
homepage="https://github.com/JohnRichard4096/nonebot_plugin_value",
24-
extra={"orm_version_location": migrations}, # 迁移文件
25-
supported_adapters=None, # 没有使用任何适配器提供的功能
25+
extra={"orm_version_location": migrations}, # 迁移文件
26+
supported_adapters=None,
2627
)
2728

2829
__all__ = [
@@ -38,6 +39,7 @@
3839
"currency_api",
3940
"currency_pyd",
4041
"exception",
42+
"factory",
4143
"hook",
4244
"hooks_manager",
4345
"hooks_type",
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from dataclasses import dataclass, field
2+
3+
from nonebot.adapters import Event
4+
5+
from ...uuid_lib import to_uuid
6+
from ..api_balance import UserAccountData, get_or_create_account
7+
from ..api_currency import CurrencyData, get_currency, get_default_currency
8+
from ..api_transaction import (
9+
TransactionData,
10+
get_transaction_history,
11+
get_transaction_history_by_time_range,
12+
)
13+
14+
15+
@dataclass
16+
class TransactionHistory:
17+
limit: int
18+
timerange: tuple[float, float] | None = field(default=None)
19+
20+
async def __call__(self, event: Event) -> list[TransactionData]:
21+
if self.timerange is None:
22+
return await get_transaction_history(
23+
to_uuid(event.get_user_id()), self.limit
24+
)
25+
start_time, end_time = self.timerange
26+
return await get_transaction_history_by_time_range(
27+
to_uuid(event.get_user_id()), start_time, end_time, self.limit
28+
)
29+
30+
31+
@dataclass
32+
class Account:
33+
currency_id: str | None = field(default=None)
34+
35+
async def __call__(self, event: Event) -> UserAccountData:
36+
if self.currency_id is None:
37+
self.currency_id = (await get_default_currency()).id
38+
return await get_or_create_account(
39+
to_uuid(event.get_user_id()), self.currency_id
40+
)
41+
42+
43+
@dataclass
44+
class Currency:
45+
c_id: str | None
46+
47+
async def __call__(self) -> CurrencyData | None:
48+
if self.c_id is None:
49+
return await get_default_currency()
50+
return await get_currency(self.c_id)
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
from collections.abc import Awaitable, Callable
2+
3+
from ...pyd_models.balance_pyd import UserAccountData
4+
from ...pyd_models.currency_pyd import CurrencyData
5+
from ...pyd_models.transaction_pyd import TransactionData
6+
from ..executor import AccountExecutor
7+
from .data_classes import Account, Currency, TransactionHistory
8+
9+
10+
class DependsSwitch:
11+
@staticmethod
12+
def account_data(
13+
*,
14+
currency_id: str | None = None,
15+
) -> Callable[..., Awaitable[UserAccountData]]:
16+
"""获得账户数据
17+
18+
Args:
19+
currency_id (str | None, optional): 货币ID. Defaults to None.
20+
21+
Returns:
22+
Callable[..., Awaitable[UserAccountData]]: 可供NoneBot调用的依赖函数类
23+
"""
24+
return Account(currency_id)
25+
26+
@staticmethod
27+
def currency_data(
28+
*,
29+
currency_id: str | None = None,
30+
) -> Callable[..., Awaitable[CurrencyData | None]]:
31+
"""
32+
获取货币数据依赖函数
33+
34+
Args:
35+
currency_id (str | None, optional): 货币ID. Defaults to None.
36+
37+
Returns:
38+
Callable[..., Awaitable[CurrencyData | None]]: 可供NoneBot调用的依赖函数类
39+
"""
40+
return Currency(currency_id)
41+
42+
@staticmethod
43+
def transaction_data(
44+
*,
45+
limit: int = 10,
46+
timerange: tuple[float, float] | None = None,
47+
) -> Callable[..., Awaitable[list[TransactionData]]]:
48+
"""
49+
获取交易记录
50+
51+
Args:
52+
limit (int, optional): 交易记录数量限制. Defaults to 10.
53+
timerange (tuple[float, float] | None, optional): 时间范围. Defaults to None.
54+
55+
Returns:
56+
Callable[..., Awaitable[list[TransactionData]]]: 可供NoneBot调用的依赖函数类
57+
"""
58+
return TransactionHistory(limit, timerange)
59+
60+
@staticmethod
61+
def account_executor(
62+
*,
63+
currency_id: str | None = None,
64+
) -> Callable[..., Awaitable[AccountExecutor]]:
65+
"""
66+
Args:
67+
currency_id (str | None, optional): 货币ID. Defaults to None.
68+
69+
Returns:
70+
Callable[..., Awaitable[AccountExecutor]]: 账号数据操作对象
71+
"""
72+
return AccountExecutor(currency_id)

0 commit comments

Comments
 (0)