pixelarraythirdparty 1.0.9__tar.gz → 1.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/PKG-INFO +1 -1
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty/__init__.py +1 -3
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty/client.py +19 -0
- pixelarraythirdparty-1.1.1/pixelarraythirdparty/cron/cron.py +113 -0
- pixelarraythirdparty-1.1.1/pixelarraythirdparty/order/order.py +261 -0
- pixelarraythirdparty-1.1.1/pixelarraythirdparty/product/product.py +205 -0
- pixelarraythirdparty-1.1.1/pixelarraythirdparty/unified_login/__init__.py +4 -0
- pixelarraythirdparty-1.1.1/pixelarraythirdparty/unified_login/unified_login.py +270 -0
- pixelarraythirdparty-1.1.1/pixelarraythirdparty/user/user.py +161 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty.egg-info/PKG-INFO +1 -1
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty.egg-info/SOURCES.txt +0 -2
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pyproject.toml +1 -1
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/cron/cron.py +0 -156
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/filestorage/__init__.py +0 -6
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/filestorage/filestorage.py +0 -530
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/order/order.py +0 -341
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/product/product.py +0 -286
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/unified_login/__init__.py +0 -16
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/unified_login/unified_login.py +0 -18
- pixelarraythirdparty-1.0.9/pixelarraythirdparty/user/user.py +0 -227
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/LICENSE +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/MANIFEST.in +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty/cron/__init__.py +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty/order/__init__.py +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty/product/__init__.py +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty/user/__init__.py +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty.egg-info/dependency_links.txt +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty.egg-info/requires.txt +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/pixelarraythirdparty.egg-info/top_level.txt +0 -0
- {pixelarraythirdparty-1.0.9 → pixelarraythirdparty-1.1.1}/setup.cfg +0 -0
|
@@ -11,7 +11,7 @@ PixelArray 第三方微服务客户端
|
|
|
11
11
|
- unified_login: 统一登录模块
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
__version__ = "1.
|
|
14
|
+
__version__ = "1.1.1"
|
|
15
15
|
__author__ = "Lu qi"
|
|
16
16
|
__email__ = "qi.lu@pixelarrayai.com"
|
|
17
17
|
|
|
@@ -21,6 +21,4 @@ __all__ = [
|
|
|
21
21
|
"cron",
|
|
22
22
|
"user",
|
|
23
23
|
"order",
|
|
24
|
-
"filestorage",
|
|
25
|
-
"unified_login",
|
|
26
24
|
]
|
|
@@ -34,3 +34,22 @@ class AsyncClient:
|
|
|
34
34
|
# 如果不是JSON响应,返回空
|
|
35
35
|
pass
|
|
36
36
|
return {}, False
|
|
37
|
+
|
|
38
|
+
async def _request_raw(
|
|
39
|
+
self, method: str, url: str, **kwargs
|
|
40
|
+
) -> Tuple[int, Dict[str, Any]]:
|
|
41
|
+
headers = self.headers.copy()
|
|
42
|
+
if "headers" in kwargs:
|
|
43
|
+
headers.update(kwargs["headers"])
|
|
44
|
+
kwargs = {k: v for k, v in kwargs.items() if k != "headers"}
|
|
45
|
+
|
|
46
|
+
async with aiohttp.ClientSession() as session:
|
|
47
|
+
req_method = getattr(session, method.lower())
|
|
48
|
+
async with req_method(
|
|
49
|
+
f"{self.base_url}{url}", headers=headers, **kwargs
|
|
50
|
+
) as resp:
|
|
51
|
+
try:
|
|
52
|
+
data = await resp.json()
|
|
53
|
+
except:
|
|
54
|
+
data = {}
|
|
55
|
+
return resp.status, data
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from pixelarraythirdparty.client import AsyncClient
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class CronManagerAsync(AsyncClient):
|
|
5
|
+
async def get_cron_status(self):
|
|
6
|
+
"""
|
|
7
|
+
description:
|
|
8
|
+
获取Cron服务状态,包括已注册的任务、工作节点状态等。
|
|
9
|
+
return:
|
|
10
|
+
data(dict): Cron服务状态信息
|
|
11
|
+
- registered_tasks(dict): 已注册的任务列表,按工作节点分组
|
|
12
|
+
- worker_stats(dict): 工作节点统计信息
|
|
13
|
+
- scheduled_task_count(int): 定时任务数量
|
|
14
|
+
- timestamp(str): 状态获取时间
|
|
15
|
+
success(bool): 操作是否成功
|
|
16
|
+
"""
|
|
17
|
+
data, success = await self._request("GET", "/api/cron/status")
|
|
18
|
+
if not success:
|
|
19
|
+
return {}, False
|
|
20
|
+
return data, True
|
|
21
|
+
|
|
22
|
+
async def get_cron_tasks(self):
|
|
23
|
+
"""
|
|
24
|
+
description:
|
|
25
|
+
获取所有已注册的Cron任务列表。
|
|
26
|
+
return:
|
|
27
|
+
data(dict): 任务列表信息
|
|
28
|
+
- tasks(list): 已注册的任务名称列表
|
|
29
|
+
- count(int): 任务数量
|
|
30
|
+
- timestamp(str): 获取时间
|
|
31
|
+
success(bool): 操作是否成功
|
|
32
|
+
"""
|
|
33
|
+
data, success = await self._request("GET", "/api/cron/tasks")
|
|
34
|
+
if not success:
|
|
35
|
+
return {}, False
|
|
36
|
+
return data, True
|
|
37
|
+
|
|
38
|
+
async def get_cron_tasks_scheduled(self):
|
|
39
|
+
"""
|
|
40
|
+
description:
|
|
41
|
+
获取所有配置的定时任务列表,包括任务详情、执行时间、状态等。
|
|
42
|
+
return:
|
|
43
|
+
data(dict): 定时任务列表信息
|
|
44
|
+
- tasks(list): 定时任务列表
|
|
45
|
+
- id(str): 任务ID
|
|
46
|
+
- name(str): 任务名称
|
|
47
|
+
- description(str): 任务描述
|
|
48
|
+
- schedule(str): 执行时间
|
|
49
|
+
- enabled(bool): 是否启用
|
|
50
|
+
- task_name(str): 任务函数名
|
|
51
|
+
- module_name(str): 模块名
|
|
52
|
+
- function_name(str): 函数名
|
|
53
|
+
- file_path(str): 文件路径
|
|
54
|
+
- parameters(list): 参数列表
|
|
55
|
+
- task_config(dict): 任务配置
|
|
56
|
+
- registration_info(dict): 注册信息
|
|
57
|
+
- count(int): 任务数量
|
|
58
|
+
- timestamp(str): 获取时间
|
|
59
|
+
success(bool): 操作是否成功
|
|
60
|
+
"""
|
|
61
|
+
data, success = await self._request("GET", "/api/cron/tasks/scheduled")
|
|
62
|
+
if not success:
|
|
63
|
+
return {}, False
|
|
64
|
+
return data, True
|
|
65
|
+
|
|
66
|
+
async def get_cron_tasks_detail(self, task_name: str):
|
|
67
|
+
"""
|
|
68
|
+
description:
|
|
69
|
+
根据任务名称获取指定任务的详细信息。
|
|
70
|
+
parameters:
|
|
71
|
+
task_name(str): 任务名称
|
|
72
|
+
return:
|
|
73
|
+
data(dict): 任务详细信息
|
|
74
|
+
- task_name(str): 任务名称
|
|
75
|
+
- module_name(str): 模块名
|
|
76
|
+
- function_name(str): 函数名
|
|
77
|
+
- file_path(str): 文件路径
|
|
78
|
+
- description(str): 任务描述
|
|
79
|
+
- parameters(list): 参数列表
|
|
80
|
+
- task_config(dict): 任务配置
|
|
81
|
+
- registration_info(dict): 注册信息
|
|
82
|
+
- timestamp(str): 获取时间
|
|
83
|
+
success(bool): 操作是否成功
|
|
84
|
+
"""
|
|
85
|
+
data, success = await self._request("GET", f"/api/cron/tasks/{task_name}")
|
|
86
|
+
if not success:
|
|
87
|
+
return {}, False
|
|
88
|
+
return data, True
|
|
89
|
+
|
|
90
|
+
async def trigger_cron_task(self, task_name: str, args: list, kwargs: dict):
|
|
91
|
+
"""
|
|
92
|
+
description:
|
|
93
|
+
手动触发指定任务的执行,支持传递参数。
|
|
94
|
+
parameters:
|
|
95
|
+
task_name(str): 任务名称
|
|
96
|
+
args(list): 任务参数列表
|
|
97
|
+
kwargs(dict): 任务关键字参数
|
|
98
|
+
return:
|
|
99
|
+
data(dict): 任务触发信息
|
|
100
|
+
- task_id(str): 任务ID
|
|
101
|
+
- task_name(str): 任务名称
|
|
102
|
+
- status(str): 任务状态,初始为"PENDING"
|
|
103
|
+
- message(str): 触发消息
|
|
104
|
+
success(bool): 操作是否成功
|
|
105
|
+
"""
|
|
106
|
+
data, success = await self._request(
|
|
107
|
+
"POST",
|
|
108
|
+
f"/api/cron/tasks/{task_name}/trigger",
|
|
109
|
+
json={"args": args, "kwargs": kwargs},
|
|
110
|
+
)
|
|
111
|
+
if not success:
|
|
112
|
+
return {}, False
|
|
113
|
+
return data, True
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
from pixelarraythirdparty.client import AsyncClient
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class OrderManagerAsync(AsyncClient):
|
|
5
|
+
async def create_order(
|
|
6
|
+
self,
|
|
7
|
+
product_id: str,
|
|
8
|
+
body: str = None,
|
|
9
|
+
remark: str = None,
|
|
10
|
+
payment_channel: str = "WECHAT",
|
|
11
|
+
):
|
|
12
|
+
"""
|
|
13
|
+
description:
|
|
14
|
+
根据产品ID创建新的订单,系统会自动生成订单号,获取产品价格信息,并创建对应的支付订单。
|
|
15
|
+
parameters:
|
|
16
|
+
product_id(str): 产品ID
|
|
17
|
+
body(str): 商品描述
|
|
18
|
+
remark(str): 订单备注
|
|
19
|
+
payment_channel(str): 支付渠道,可选值:"WECHAT"(微信支付)、"ALIPAY"(支付宝支付)
|
|
20
|
+
return:
|
|
21
|
+
data(dict): 订单信息
|
|
22
|
+
- id(int): 订单ID
|
|
23
|
+
- out_trade_no(str): 商户订单号,格式为"ORD_时间戳_随机字符串"
|
|
24
|
+
- payment_status(str): 支付状态,初始为"PENDING"(待支付)
|
|
25
|
+
- payment_channel(str): 支付渠道
|
|
26
|
+
- product_id(str): 产品ID
|
|
27
|
+
- amount(str): 订单金额(元),格式为"99.00"
|
|
28
|
+
- total_fee(int): 订单金额(分),用于支付接口
|
|
29
|
+
- body(str): 商品描述
|
|
30
|
+
- remark(str): 订单备注
|
|
31
|
+
- created_at(str): 订单创建时间
|
|
32
|
+
- updated_at(str): 订单更新时间
|
|
33
|
+
success(bool): 操作是否成功
|
|
34
|
+
"""
|
|
35
|
+
data = {
|
|
36
|
+
"product_id": product_id,
|
|
37
|
+
"body": body,
|
|
38
|
+
"remark": remark,
|
|
39
|
+
"payment_channel": payment_channel,
|
|
40
|
+
}
|
|
41
|
+
data, success = await self._request("POST", "/api/orders/create", json=data)
|
|
42
|
+
if not success:
|
|
43
|
+
return {}, False
|
|
44
|
+
return data, True
|
|
45
|
+
|
|
46
|
+
async def list_order(
|
|
47
|
+
self,
|
|
48
|
+
page: int = 1,
|
|
49
|
+
page_size: int = 10,
|
|
50
|
+
payment_status: str = None,
|
|
51
|
+
out_trade_no: str = None,
|
|
52
|
+
):
|
|
53
|
+
"""
|
|
54
|
+
description:
|
|
55
|
+
分页查询订单列表,支持按支付状态和订单号进行筛选。
|
|
56
|
+
parameters:
|
|
57
|
+
page(int): 页码
|
|
58
|
+
page_size(int): 每页数量
|
|
59
|
+
payment_status(str): 支付状态,可选值:"PENDING"(待支付)、"PAID"(已支付)、"REFUNDED"(已退款)、"CANCELLED"(已取消)
|
|
60
|
+
out_trade_no(str): 订单号,支持模糊匹配
|
|
61
|
+
return:
|
|
62
|
+
data(dict): 订单列表信息
|
|
63
|
+
- orders(list): 订单列表
|
|
64
|
+
- id(int): 订单ID
|
|
65
|
+
- out_trade_no(str): 商户订单号
|
|
66
|
+
- payment_status(str): 支付状态
|
|
67
|
+
- payment_channel(str): 支付渠道
|
|
68
|
+
- amount(str): 订单金额(元)
|
|
69
|
+
- total_fee(int): 订单金额(分)
|
|
70
|
+
- created_at(str): 订单创建时间
|
|
71
|
+
- updated_at(str): 订单更新时间
|
|
72
|
+
- total(int): 总订单数量
|
|
73
|
+
- page(int): 当前页码
|
|
74
|
+
- page_size(int): 每页数量
|
|
75
|
+
success(bool): 操作是否成功
|
|
76
|
+
"""
|
|
77
|
+
params = {
|
|
78
|
+
"page": page,
|
|
79
|
+
"page_size": page_size,
|
|
80
|
+
}
|
|
81
|
+
# 只添加非None的参数
|
|
82
|
+
if payment_status is not None:
|
|
83
|
+
params["payment_status"] = payment_status
|
|
84
|
+
if out_trade_no is not None:
|
|
85
|
+
params["out_trade_no"] = out_trade_no
|
|
86
|
+
data, success = await self._request("GET", "/api/orders/list", params=params)
|
|
87
|
+
if not success:
|
|
88
|
+
return {}, False
|
|
89
|
+
return data, True
|
|
90
|
+
|
|
91
|
+
async def get_order_detail(self, out_trade_no: str):
|
|
92
|
+
"""
|
|
93
|
+
description:
|
|
94
|
+
根据订单号获取订单的详细信息,包括支付状态、交易信息等。
|
|
95
|
+
parameters:
|
|
96
|
+
out_trade_no(str): 商户订单号
|
|
97
|
+
return:
|
|
98
|
+
data(dict): 订单详细信息
|
|
99
|
+
- id(int): 订单ID
|
|
100
|
+
- out_trade_no(str): 商户订单号
|
|
101
|
+
- payment_status(str): 支付状态
|
|
102
|
+
- product_id(str): 产品ID
|
|
103
|
+
- amount(str): 订单金额(元)
|
|
104
|
+
- total_fee(int): 订单金额(分)
|
|
105
|
+
- body(str): 商品描述
|
|
106
|
+
- transaction_id(str): 微信交易号(支付成功后才有)
|
|
107
|
+
- openid(str): 用户openid(支付成功后才有)
|
|
108
|
+
- trade_type(str): 交易类型(支付成功后才有)
|
|
109
|
+
- bank_type(str): 银行类型(支付成功后才有)
|
|
110
|
+
- fee_type(str): 货币类型,默认为"CNY"
|
|
111
|
+
- is_subscribe(str): 是否关注公众号(支付成功后才有)
|
|
112
|
+
- time_end(str): 支付完成时间(支付成功后才有)
|
|
113
|
+
- created_at(str): 订单创建时间
|
|
114
|
+
- updated_at(str): 订单更新时间
|
|
115
|
+
- paid_at(str): 支付时间(支付成功后才有)
|
|
116
|
+
- remark(str): 订单备注
|
|
117
|
+
success(bool): 操作是否成功
|
|
118
|
+
"""
|
|
119
|
+
data, success = await self._request("GET", f"/api/orders/{out_trade_no}")
|
|
120
|
+
if not success:
|
|
121
|
+
return {}, False
|
|
122
|
+
return data, True
|
|
123
|
+
|
|
124
|
+
async def update_order_status(self, out_trade_no: str, payment_status: str):
|
|
125
|
+
"""
|
|
126
|
+
description:
|
|
127
|
+
更新指定订单的支付状态,仅支持状态修改,其他字段不可修改。
|
|
128
|
+
parameters:
|
|
129
|
+
out_trade_no(str): 商户订单号
|
|
130
|
+
payment_status(str): 支付状态,可选值:"PENDING"(待支付)、"PAID"(已支付)、"REFUNDED"(已退款)、"CANCELLED"(已取消)
|
|
131
|
+
return:
|
|
132
|
+
data(dict): 更新后的订单信息
|
|
133
|
+
- id(int): 订单ID
|
|
134
|
+
- out_trade_no(str): 商户订单号
|
|
135
|
+
- payment_status(str): 更新后的支付状态
|
|
136
|
+
- transaction_id(str): 微信交易号(如果已支付)
|
|
137
|
+
- openid(str): 用户openid(如果已支付)
|
|
138
|
+
- trade_type(str): 交易类型(如果已支付)
|
|
139
|
+
- bank_type(str): 银行类型(如果已支付)
|
|
140
|
+
- fee_type(str): 货币类型
|
|
141
|
+
- is_subscribe(str): 是否关注公众号(如果已支付)
|
|
142
|
+
- time_end(str): 支付完成时间(如果已支付)
|
|
143
|
+
- paid_at(str): 支付时间(如果已支付)
|
|
144
|
+
- updated_at(str): 订单更新时间
|
|
145
|
+
- remark(str): 订单备注
|
|
146
|
+
success(bool): 操作是否成功
|
|
147
|
+
"""
|
|
148
|
+
data = {"payment_status": payment_status}
|
|
149
|
+
data, success = await self._request(
|
|
150
|
+
"PUT", f"/api/orders/{out_trade_no}/status", json=data
|
|
151
|
+
)
|
|
152
|
+
if not success:
|
|
153
|
+
return {}, False
|
|
154
|
+
return data, True
|
|
155
|
+
|
|
156
|
+
async def delete_order(self, out_trade_no: str):
|
|
157
|
+
"""
|
|
158
|
+
description:
|
|
159
|
+
根据订单号删除指定的订单记录。
|
|
160
|
+
parameters:
|
|
161
|
+
out_trade_no(str): 商户订单号
|
|
162
|
+
return:
|
|
163
|
+
data(None): 删除成功时返回None
|
|
164
|
+
success(bool): 操作是否成功
|
|
165
|
+
"""
|
|
166
|
+
data, success = await self._request("DELETE", f"/api/orders/{out_trade_no}")
|
|
167
|
+
if not success:
|
|
168
|
+
return {}, False
|
|
169
|
+
return data, True
|
|
170
|
+
|
|
171
|
+
async def get_order_stats(self):
|
|
172
|
+
"""
|
|
173
|
+
description:
|
|
174
|
+
获取订单的统计汇总信息,包括总订单数、各状态订单数量、总金额等。
|
|
175
|
+
return:
|
|
176
|
+
data(dict): 订单统计信息
|
|
177
|
+
- total_orders(int): 总订单数量
|
|
178
|
+
- pending_orders(int): 待支付订单数量
|
|
179
|
+
- paid_orders(int): 已支付订单数量
|
|
180
|
+
- refunded_orders(int): 已退款订单数量
|
|
181
|
+
- total_amount(float): 总订单金额(元)
|
|
182
|
+
- total_fee(int): 总订单金额(分)
|
|
183
|
+
success(bool): 操作是否成功
|
|
184
|
+
"""
|
|
185
|
+
data, success = await self._request("GET", "/api/orders/stats/summary")
|
|
186
|
+
if not success:
|
|
187
|
+
return {}, False
|
|
188
|
+
return data, True
|
|
189
|
+
|
|
190
|
+
async def generate_qr_code(self, out_trade_no: str):
|
|
191
|
+
"""
|
|
192
|
+
description:
|
|
193
|
+
为指定订单生成支付二维码,支持微信支付和支付宝。二维码会自动上传到OSS并返回访问URL。
|
|
194
|
+
如果不指定payment_channel,会自动从订单详情中获取支付渠道。
|
|
195
|
+
parameters:
|
|
196
|
+
out_trade_no(str): 商户订单号
|
|
197
|
+
return:
|
|
198
|
+
data(dict): 二维码信息
|
|
199
|
+
- qr_code_url(str): 二维码图片URL,可直接用于显示
|
|
200
|
+
- out_trade_no(str): 商户订单号
|
|
201
|
+
success(bool): 操作是否成功
|
|
202
|
+
"""
|
|
203
|
+
order_detail, success = await self.get_order_detail(out_trade_no)
|
|
204
|
+
print(order_detail)
|
|
205
|
+
if not success:
|
|
206
|
+
return {}, False
|
|
207
|
+
|
|
208
|
+
if order_detail.get("payment_channel") == "WECHAT":
|
|
209
|
+
url = "/api/orders/wx_pay/generate_qr_code"
|
|
210
|
+
request_data = {
|
|
211
|
+
"out_trade_no": out_trade_no,
|
|
212
|
+
}
|
|
213
|
+
elif order_detail.get("payment_channel") == "ALIPAY":
|
|
214
|
+
url = "/api/orders/ali_pay/generate_qr_code"
|
|
215
|
+
# 支付宝需要total_fee和subject,从已获取的订单详情中提取
|
|
216
|
+
request_data = {
|
|
217
|
+
"out_trade_no": out_trade_no,
|
|
218
|
+
"total_fee": order_detail.get("total_fee"),
|
|
219
|
+
"subject": order_detail.get("body", ""),
|
|
220
|
+
}
|
|
221
|
+
else:
|
|
222
|
+
raise ValueError("Invalid payment channel")
|
|
223
|
+
data, success = await self._request("POST", url, json=request_data)
|
|
224
|
+
if not success:
|
|
225
|
+
return {}, False
|
|
226
|
+
return data, True
|
|
227
|
+
|
|
228
|
+
async def refund_order(self, out_trade_no: str):
|
|
229
|
+
"""
|
|
230
|
+
description:
|
|
231
|
+
为指定订单申请退款,支持微信支付和支付宝。退款申请提交后,系统会处理退款并更新订单状态。
|
|
232
|
+
parameters:
|
|
233
|
+
out_trade_no(str): 商户订单号
|
|
234
|
+
return:
|
|
235
|
+
data(dict): 退款信息
|
|
236
|
+
- out_refund_no(str): 退款单号,格式为"REFUND_订单号_时间戳"
|
|
237
|
+
- out_trade_no(str): 商户订单号
|
|
238
|
+
- total_fee(int): 退款金额(分,微信支付)
|
|
239
|
+
- refund_amount(float): 退款金额(元,支付宝)
|
|
240
|
+
success(bool): 操作是否成功
|
|
241
|
+
"""
|
|
242
|
+
order_detail, success = await self.get_order_detail(out_trade_no)
|
|
243
|
+
if not success:
|
|
244
|
+
return {}, False
|
|
245
|
+
|
|
246
|
+
if order_detail.get("payment_channel") == "WECHAT":
|
|
247
|
+
url = "/api/orders/wx_pay/refund"
|
|
248
|
+
request_data = {"out_trade_no": out_trade_no}
|
|
249
|
+
elif order_detail.get("payment_channel") == "ALIPAY":
|
|
250
|
+
url = "/api/orders/ali_pay/refund"
|
|
251
|
+
request_data = {
|
|
252
|
+
"out_trade_no": out_trade_no,
|
|
253
|
+
"refund_amount": order_detail.get("total_fee") / 100.0,
|
|
254
|
+
"refund_reason": "用户退款",
|
|
255
|
+
}
|
|
256
|
+
else:
|
|
257
|
+
raise ValueError("Invalid payment channel")
|
|
258
|
+
data, success = await self._request("POST", url, json=request_data)
|
|
259
|
+
if not success:
|
|
260
|
+
return {}, False
|
|
261
|
+
return data, True
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
from pixelarraythirdparty.client import AsyncClient
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ProductManagerAsync(AsyncClient):
|
|
5
|
+
async def create_product(
|
|
6
|
+
self,
|
|
7
|
+
name: str,
|
|
8
|
+
description: str,
|
|
9
|
+
price: float,
|
|
10
|
+
category: str,
|
|
11
|
+
status: str,
|
|
12
|
+
is_subscription: bool,
|
|
13
|
+
subscription_period: str,
|
|
14
|
+
features: str,
|
|
15
|
+
sort_order: int,
|
|
16
|
+
):
|
|
17
|
+
"""
|
|
18
|
+
description:
|
|
19
|
+
创建新的产品,支持订阅产品和一次性产品,产品信息包括名称、描述、价格、分类等。
|
|
20
|
+
parameters:
|
|
21
|
+
name(str): 产品名称
|
|
22
|
+
description(str): 产品描述
|
|
23
|
+
price(float): 产品价格(元)
|
|
24
|
+
category(str): 产品分类
|
|
25
|
+
status(str): 产品状态,可选值:"ACTIVE"(激活)、"INACTIVE"(停用)
|
|
26
|
+
is_subscription(bool): 是否为订阅产品
|
|
27
|
+
subscription_period(str): 订阅周期,可选值:"MONTHLY"(月付)、"YEARLY"(年付)
|
|
28
|
+
features(str): 产品特性,JSON格式字符串
|
|
29
|
+
sort_order(int): 排序权重
|
|
30
|
+
return:
|
|
31
|
+
data(dict): 产品信息
|
|
32
|
+
- id(int): 产品ID
|
|
33
|
+
- name(str): 产品名称
|
|
34
|
+
- description(str): 产品描述
|
|
35
|
+
- price(float): 产品价格(元)
|
|
36
|
+
- category(str): 产品分类
|
|
37
|
+
- status(str): 产品状态
|
|
38
|
+
- is_subscription(bool): 是否为订阅产品
|
|
39
|
+
- subscription_period(str): 订阅周期
|
|
40
|
+
- features(str): 产品特性(JSON格式)
|
|
41
|
+
- sort_order(int): 排序权重
|
|
42
|
+
- created_at(str): 产品创建时间
|
|
43
|
+
- updated_at(str): 产品更新时间
|
|
44
|
+
success(bool): 操作是否成功
|
|
45
|
+
"""
|
|
46
|
+
data = {
|
|
47
|
+
"name": name,
|
|
48
|
+
"description": description,
|
|
49
|
+
"price": price,
|
|
50
|
+
"category": category,
|
|
51
|
+
"status": status,
|
|
52
|
+
"is_subscription": is_subscription,
|
|
53
|
+
"subscription_period": subscription_period,
|
|
54
|
+
"features": features,
|
|
55
|
+
"sort_order": sort_order,
|
|
56
|
+
}
|
|
57
|
+
data, success = await self._request("POST", "/api/products/create", json=data)
|
|
58
|
+
if not success:
|
|
59
|
+
return {}, False
|
|
60
|
+
return data, True
|
|
61
|
+
|
|
62
|
+
async def list_product(
|
|
63
|
+
self,
|
|
64
|
+
page: int = 1,
|
|
65
|
+
page_size: int = 10,
|
|
66
|
+
status: str = None,
|
|
67
|
+
category: str = None,
|
|
68
|
+
name: str = None,
|
|
69
|
+
):
|
|
70
|
+
"""
|
|
71
|
+
description:
|
|
72
|
+
分页查询产品列表,支持按状态、分类和名称进行筛选。
|
|
73
|
+
parameters:
|
|
74
|
+
page(int): 页码
|
|
75
|
+
page_size(int): 每页数量
|
|
76
|
+
status(str): 产品状态筛选,可选值:"ACTIVE"(激活)、"INACTIVE"(停用)
|
|
77
|
+
category(str): 产品分类筛选
|
|
78
|
+
name(str): 产品名称搜索,支持模糊匹配
|
|
79
|
+
return:
|
|
80
|
+
data(dict): 产品列表信息
|
|
81
|
+
- products(list): 产品列表
|
|
82
|
+
- total(int): 总产品数量
|
|
83
|
+
- page(int): 当前页码
|
|
84
|
+
- page_size(int): 每页数量
|
|
85
|
+
success(bool): 操作是否成功
|
|
86
|
+
"""
|
|
87
|
+
params = {
|
|
88
|
+
"page": page,
|
|
89
|
+
"page_size": page_size,
|
|
90
|
+
}
|
|
91
|
+
if status is not None:
|
|
92
|
+
params["status"] = status
|
|
93
|
+
if category is not None:
|
|
94
|
+
params["category"] = category
|
|
95
|
+
if name is not None:
|
|
96
|
+
params["name"] = name
|
|
97
|
+
data, success = await self._request("GET", "/api/products/list", params=params)
|
|
98
|
+
if not success:
|
|
99
|
+
return {}, False
|
|
100
|
+
return data, True
|
|
101
|
+
|
|
102
|
+
async def get_product_detail(self, product_id: str):
|
|
103
|
+
"""
|
|
104
|
+
description:
|
|
105
|
+
根据产品ID获取产品的详细信息。
|
|
106
|
+
parameters:
|
|
107
|
+
product_id(str): 产品ID
|
|
108
|
+
return:
|
|
109
|
+
data(dict): 产品详细信息
|
|
110
|
+
success(bool): 操作是否成功
|
|
111
|
+
"""
|
|
112
|
+
data, success = await self._request("GET", f"/api/products/{product_id}")
|
|
113
|
+
if not success:
|
|
114
|
+
return {}, False
|
|
115
|
+
return data, True
|
|
116
|
+
|
|
117
|
+
async def update_product(
|
|
118
|
+
self,
|
|
119
|
+
product_id: str,
|
|
120
|
+
name: str,
|
|
121
|
+
description: str,
|
|
122
|
+
price: float,
|
|
123
|
+
category: str,
|
|
124
|
+
status: str,
|
|
125
|
+
is_subscription: bool,
|
|
126
|
+
subscription_period: str,
|
|
127
|
+
features: str,
|
|
128
|
+
sort_order: int,
|
|
129
|
+
):
|
|
130
|
+
"""
|
|
131
|
+
description:
|
|
132
|
+
更新指定产品的信息,包括名称、描述、价格、状态等。
|
|
133
|
+
parameters:
|
|
134
|
+
product_id(str): 产品ID
|
|
135
|
+
name(str): 产品名称
|
|
136
|
+
description(str): 产品描述
|
|
137
|
+
price(float): 产品价格(元)
|
|
138
|
+
category(str): 产品分类
|
|
139
|
+
status(str): 产品状态,可选值:"ACTIVE"(激活)、"INACTIVE"(停用)
|
|
140
|
+
is_subscription(bool): 是否为订阅产品
|
|
141
|
+
subscription_period(str): 订阅周期,可选值:"MONTHLY"(月付)、"YEARLY"(年付)
|
|
142
|
+
features(str): 产品特性,JSON格式字符串
|
|
143
|
+
sort_order(int): 排序权重
|
|
144
|
+
return:
|
|
145
|
+
data(dict): 更新后的产品信息
|
|
146
|
+
- id(int): 产品ID
|
|
147
|
+
- name(str): 产品名称
|
|
148
|
+
- description(str): 产品描述
|
|
149
|
+
- price(float): 产品价格(元)
|
|
150
|
+
- category(str): 产品分类
|
|
151
|
+
- status(str): 产品状态
|
|
152
|
+
- is_subscription(bool): 是否为订阅产品
|
|
153
|
+
- subscription_period(str): 订阅周期
|
|
154
|
+
- features(str): 产品特性(JSON格式)
|
|
155
|
+
- sort_order(int): 排序权重
|
|
156
|
+
- created_at(str): 产品创建时间
|
|
157
|
+
- updated_at(str): 产品更新时间
|
|
158
|
+
success(bool): 操作是否成功
|
|
159
|
+
"""
|
|
160
|
+
data = {
|
|
161
|
+
"name": name,
|
|
162
|
+
"description": description,
|
|
163
|
+
"price": price,
|
|
164
|
+
"category": category,
|
|
165
|
+
"status": status,
|
|
166
|
+
"is_subscription": is_subscription,
|
|
167
|
+
"subscription_period": subscription_period,
|
|
168
|
+
"features": features,
|
|
169
|
+
"sort_order": sort_order,
|
|
170
|
+
}
|
|
171
|
+
data, success = await self._request(
|
|
172
|
+
"PUT", f"/api/products/{product_id}", json=data
|
|
173
|
+
)
|
|
174
|
+
if not success:
|
|
175
|
+
return {}, False
|
|
176
|
+
return data, True
|
|
177
|
+
|
|
178
|
+
async def delete_product(self, product_id: str):
|
|
179
|
+
"""
|
|
180
|
+
description:
|
|
181
|
+
根据产品ID删除指定的产品记录。
|
|
182
|
+
parameters:
|
|
183
|
+
product_id(str): 产品ID
|
|
184
|
+
return:
|
|
185
|
+
data(None): 删除成功时返回None
|
|
186
|
+
success(bool): 操作是否成功
|
|
187
|
+
"""
|
|
188
|
+
data, success = await self._request("DELETE", f"/api/products/{product_id}")
|
|
189
|
+
if not success:
|
|
190
|
+
return {}, False
|
|
191
|
+
return data, True
|
|
192
|
+
|
|
193
|
+
async def get_product_categories(self):
|
|
194
|
+
"""
|
|
195
|
+
description:
|
|
196
|
+
获取所有可用的产品分类列表。
|
|
197
|
+
return:
|
|
198
|
+
data(dict): 产品分类信息
|
|
199
|
+
- categories(list): 产品分类列表,如["subscription", "service", "addon"]
|
|
200
|
+
success(bool): 操作是否成功
|
|
201
|
+
"""
|
|
202
|
+
data, success = await self._request("GET", "/api/products/categories/list")
|
|
203
|
+
if not success:
|
|
204
|
+
return {}, False
|
|
205
|
+
return data, True
|