lingxingapi 1.1.4__py3-none-any.whl
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.
- lingxingapi/__init__.py +7 -0
- lingxingapi/ads/__init__.py +0 -0
- lingxingapi/ads/api.py +5946 -0
- lingxingapi/ads/param.py +192 -0
- lingxingapi/ads/route.py +134 -0
- lingxingapi/ads/schema.py +2615 -0
- lingxingapi/api.py +557 -0
- lingxingapi/base/__init__.py +0 -0
- lingxingapi/base/api.py +568 -0
- lingxingapi/base/param.py +59 -0
- lingxingapi/base/route.py +11 -0
- lingxingapi/base/schema.py +198 -0
- lingxingapi/basic/__init__.py +0 -0
- lingxingapi/basic/api.py +466 -0
- lingxingapi/basic/param.py +72 -0
- lingxingapi/basic/route.py +20 -0
- lingxingapi/basic/schema.py +218 -0
- lingxingapi/errors.py +152 -0
- lingxingapi/fba/__init__.py +0 -0
- lingxingapi/fba/api.py +1691 -0
- lingxingapi/fba/param.py +250 -0
- lingxingapi/fba/route.py +30 -0
- lingxingapi/fba/schema.py +987 -0
- lingxingapi/fields.py +50 -0
- lingxingapi/finance/__init__.py +0 -0
- lingxingapi/finance/api.py +3091 -0
- lingxingapi/finance/param.py +616 -0
- lingxingapi/finance/route.py +44 -0
- lingxingapi/finance/schema.py +1243 -0
- lingxingapi/product/__init__.py +0 -0
- lingxingapi/product/api.py +2643 -0
- lingxingapi/product/param.py +934 -0
- lingxingapi/product/route.py +49 -0
- lingxingapi/product/schema.py +1004 -0
- lingxingapi/purchase/__init__.py +0 -0
- lingxingapi/purchase/api.py +496 -0
- lingxingapi/purchase/param.py +126 -0
- lingxingapi/purchase/route.py +11 -0
- lingxingapi/purchase/schema.py +215 -0
- lingxingapi/sales/__init__.py +0 -0
- lingxingapi/sales/api.py +3200 -0
- lingxingapi/sales/param.py +723 -0
- lingxingapi/sales/route.py +70 -0
- lingxingapi/sales/schema.py +1718 -0
- lingxingapi/source/__init__.py +0 -0
- lingxingapi/source/api.py +1799 -0
- lingxingapi/source/param.py +176 -0
- lingxingapi/source/route.py +38 -0
- lingxingapi/source/schema.py +1011 -0
- lingxingapi/tools/__init__.py +0 -0
- lingxingapi/tools/api.py +291 -0
- lingxingapi/tools/param.py +73 -0
- lingxingapi/tools/route.py +8 -0
- lingxingapi/tools/schema.py +169 -0
- lingxingapi/utils.py +456 -0
- lingxingapi/warehourse/__init__.py +0 -0
- lingxingapi/warehourse/api.py +1778 -0
- lingxingapi/warehourse/param.py +506 -0
- lingxingapi/warehourse/route.py +28 -0
- lingxingapi/warehourse/schema.py +926 -0
- lingxingapi-1.1.4.dist-info/METADATA +73 -0
- lingxingapi-1.1.4.dist-info/RECORD +65 -0
- lingxingapi-1.1.4.dist-info/WHEEL +5 -0
- lingxingapi-1.1.4.dist-info/licenses/LICENSE +22 -0
- lingxingapi-1.1.4.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import datetime
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
from typing_extensions import Self
|
|
5
|
+
from pydantic import BaseModel, Field, model_validator
|
|
6
|
+
from lingxingapi import errors
|
|
7
|
+
from lingxingapi.fields import StrOrNone2Blank
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# Token 令牌 --------------------------------------------------------------------------------------------------------------------
|
|
11
|
+
class Token(BaseModel):
|
|
12
|
+
# 接口的访问令牌
|
|
13
|
+
access_token: str
|
|
14
|
+
# 用于续约 access_token 的更新令牌
|
|
15
|
+
refresh_token: str
|
|
16
|
+
# 访问令牌的有效时间 (单位: 秒)
|
|
17
|
+
expires_in: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# 公用 Schema -------------------------------------------------------------------------------------------------------------------
|
|
21
|
+
class TagInfo(BaseModel):
|
|
22
|
+
"""商品的标签信息."""
|
|
23
|
+
|
|
24
|
+
# 领星标签ID (GlobalTag.tag_id) [原字段 'global_tag_id']
|
|
25
|
+
tag_id: str = Field(validation_alias="global_tag_id")
|
|
26
|
+
# 领星标签名称 (GlobalTag.tag_name) [原字段 'tag_name']
|
|
27
|
+
tag_name: str = Field(validation_alias="tag_name")
|
|
28
|
+
# 领星标签颜色 (如: "#FF0000") [原字段 'color']
|
|
29
|
+
tag_color: str = Field(validation_alias="color")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AttachmentFile(BaseModel):
|
|
33
|
+
"""附件信息"""
|
|
34
|
+
|
|
35
|
+
# 文件ID
|
|
36
|
+
file_id: int
|
|
37
|
+
# 文件名称
|
|
38
|
+
file_name: str
|
|
39
|
+
# 文件类型 (0: 未知, 1: 图片, 2: 压缩包)
|
|
40
|
+
file_type: int = 0
|
|
41
|
+
# 文件链接
|
|
42
|
+
file_url: str = ""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class SpuProductAttribute(BaseModel):
|
|
46
|
+
"""SPU 商品属性"""
|
|
47
|
+
|
|
48
|
+
# 属性ID
|
|
49
|
+
attr_id: int
|
|
50
|
+
# 属性名称
|
|
51
|
+
attr_name: str
|
|
52
|
+
# 属性值
|
|
53
|
+
attr_value: str
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class CustomField(BaseModel):
|
|
57
|
+
"""自定义字段"""
|
|
58
|
+
|
|
59
|
+
# 自定义字段ID
|
|
60
|
+
field_id: int = Field(validation_alias="id")
|
|
61
|
+
# 自定义字段名称
|
|
62
|
+
field_name: str = Field(validation_alias="name")
|
|
63
|
+
# 自定义字段值
|
|
64
|
+
field_value: str = Field(validation_alias="val_text")
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class BaseResponse(BaseModel):
|
|
68
|
+
"""基础响应数据"""
|
|
69
|
+
|
|
70
|
+
# 状态码
|
|
71
|
+
code: int = 0
|
|
72
|
+
# 提示信息
|
|
73
|
+
message: Optional[StrOrNone2Blank] = None
|
|
74
|
+
# 错误信息
|
|
75
|
+
errors: Optional[list] = Field(None, validation_alias="error_details")
|
|
76
|
+
# 请求链路id
|
|
77
|
+
request_id: Optional[str] = None
|
|
78
|
+
# 响应时间
|
|
79
|
+
response_time: Optional[str] = None
|
|
80
|
+
|
|
81
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
82
|
+
@model_validator(mode="after")
|
|
83
|
+
def _adjustments(self) -> Self:
|
|
84
|
+
# 设置默认数值
|
|
85
|
+
if self.message is None:
|
|
86
|
+
self.message = "success"
|
|
87
|
+
if self.errors is None:
|
|
88
|
+
self.errors = []
|
|
89
|
+
if self.request_id is None:
|
|
90
|
+
self.request_id = ""
|
|
91
|
+
if self.response_time is None:
|
|
92
|
+
# fmt: off
|
|
93
|
+
dt = datetime.datetime.now()
|
|
94
|
+
self.response_time = "%04d-%02d-%02d %02d:%02d:%02d" % (
|
|
95
|
+
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second
|
|
96
|
+
)
|
|
97
|
+
# fmt: on
|
|
98
|
+
|
|
99
|
+
# 返回
|
|
100
|
+
return self
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ResponseV1(BaseResponse):
|
|
104
|
+
"""响应数据 - 下划线命名"""
|
|
105
|
+
|
|
106
|
+
# 响应数据量
|
|
107
|
+
response_count: int = 0
|
|
108
|
+
# 总数据量
|
|
109
|
+
total_count: int = Field(0, validation_alias="total")
|
|
110
|
+
# 响应数据
|
|
111
|
+
data: Any = None
|
|
112
|
+
|
|
113
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
114
|
+
@model_validator(mode="after")
|
|
115
|
+
def _set_count(self) -> Self:
|
|
116
|
+
# 计算响应数据量
|
|
117
|
+
if isinstance(self.data, list):
|
|
118
|
+
self.response_count = len(self.data)
|
|
119
|
+
elif isinstance(self.data, (dict, BaseModel)):
|
|
120
|
+
self.response_count = 1
|
|
121
|
+
else:
|
|
122
|
+
return self
|
|
123
|
+
|
|
124
|
+
# 调整总数据量
|
|
125
|
+
if self.response_count > 0:
|
|
126
|
+
self.total_count = max(self.total_count, self.response_count)
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
class ResponseV1Token(ResponseV1):
|
|
131
|
+
"""响应数据 - 下划线命名 + 分页游标 (next_token)"""
|
|
132
|
+
|
|
133
|
+
# 分页游标
|
|
134
|
+
next_token: StrOrNone2Blank
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class ResponseV1TraceId(ResponseV1):
|
|
138
|
+
"""响应数据 - request_id 替换为 traceId"""
|
|
139
|
+
|
|
140
|
+
# 请求链路id
|
|
141
|
+
request_id: Optional[str] = Field(None, validation_alias="traceId")
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class ResponseV2(ResponseV1):
|
|
145
|
+
"""响应数据 - 驼峰命名"""
|
|
146
|
+
|
|
147
|
+
# 错误信息
|
|
148
|
+
errors: Optional[list] = Field(None, validation_alias="errorDetails")
|
|
149
|
+
# 请求链路id
|
|
150
|
+
request_id: Optional[str] = Field(None, validation_alias="requestId")
|
|
151
|
+
# 响应时间
|
|
152
|
+
response_time: Optional[str] = Field(None, validation_alias="responseTime")
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class ResponseResult(BaseResponse):
|
|
156
|
+
"""响应结果"""
|
|
157
|
+
|
|
158
|
+
# 响应结果
|
|
159
|
+
data: Any = None
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
# 特殊 Schema -------------------------------------------------------------------------------------------------------------------
|
|
163
|
+
class FlattenDataRecords(BaseModel):
|
|
164
|
+
"""从嵌套数据中提取列表数据 (records)
|
|
165
|
+
|
|
166
|
+
- 1. 从 data 字段中, 提取 total 并赋值至基础层
|
|
167
|
+
- 2. 从 data 字段中, 提取 records 并覆盖 data 字段
|
|
168
|
+
"""
|
|
169
|
+
|
|
170
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
171
|
+
@model_validator(mode="before")
|
|
172
|
+
def _flatten_data(cls, data: dict) -> dict:
|
|
173
|
+
try:
|
|
174
|
+
inner: dict = data.pop("data", {})
|
|
175
|
+
data["total"] = max(inner.get("total", 0), data.get("total", 0))
|
|
176
|
+
data["data"] = inner.get("records", [])
|
|
177
|
+
except Exception:
|
|
178
|
+
raise errors.ResponseDataError(cls.__name__, data=data)
|
|
179
|
+
return data
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class FlattenDataList(BaseModel):
|
|
183
|
+
"""从嵌套数据中提取列表数据 (list)
|
|
184
|
+
|
|
185
|
+
- 1. 从 data 字段中, 提取 total 并赋值至基础层
|
|
186
|
+
- 2. 从 data 字段中, 提取 list 并覆盖 data 字段
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
190
|
+
@model_validator(mode="before")
|
|
191
|
+
def _flatten_data(cls, data: dict) -> dict:
|
|
192
|
+
try:
|
|
193
|
+
inner: dict = data.pop("data", {})
|
|
194
|
+
data["total"] = max(inner.get("total", 0), data.get("total", 0))
|
|
195
|
+
data["data"] = inner.get("list", [])
|
|
196
|
+
except Exception:
|
|
197
|
+
raise errors.ResponseDataError(cls.__name__, data=data)
|
|
198
|
+
return data
|
|
File without changes
|
lingxingapi/basic/api.py
ADDED
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-c
|
|
2
|
+
import datetime
|
|
3
|
+
from decimal import Decimal
|
|
4
|
+
from lingxingapi import errors
|
|
5
|
+
from lingxingapi.base.api import BaseAPI
|
|
6
|
+
from lingxingapi.base import schema as base_schema
|
|
7
|
+
from lingxingapi.basic import param, route, schema
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# API ------------------------------------------------------------------------------------------------------------------
|
|
11
|
+
class BasicAPI(BaseAPI):
|
|
12
|
+
"""领星API `基础数据` 接口
|
|
13
|
+
|
|
14
|
+
## Notice
|
|
15
|
+
请勿直接实例化此类
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# 公共 API --------------------------------------------------------------------------------------
|
|
19
|
+
# . 基础数据
|
|
20
|
+
async def Marketplaces(self) -> schema.Marketplaces:
|
|
21
|
+
"""查询所有的亚马逊站点信息
|
|
22
|
+
|
|
23
|
+
## Docs
|
|
24
|
+
- 基础数据: [查询亚马逊市场列表](https://apidoc.lingxing.com/#/docs/BasicData/AllMarketplace)
|
|
25
|
+
|
|
26
|
+
:returns `<'Marketplaces'>`: 返回所有的亚马逊站点信息
|
|
27
|
+
```python
|
|
28
|
+
{
|
|
29
|
+
# 状态码
|
|
30
|
+
"code": 0,
|
|
31
|
+
# 提示信息
|
|
32
|
+
"message": "success",
|
|
33
|
+
# 错误信息
|
|
34
|
+
"errors": [],
|
|
35
|
+
# 请求ID
|
|
36
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
37
|
+
# 响应时间
|
|
38
|
+
"response_time": "2025-08-13 19:23:04",
|
|
39
|
+
# 响应数据量
|
|
40
|
+
"response_count": 2,
|
|
41
|
+
# 总数据量
|
|
42
|
+
"total_count": 2,
|
|
43
|
+
# 响应数据
|
|
44
|
+
"data": [
|
|
45
|
+
{
|
|
46
|
+
# 领星站点ID [唯一标识]
|
|
47
|
+
"mid": 1,
|
|
48
|
+
# 站点区域
|
|
49
|
+
"region": "NA",
|
|
50
|
+
# 站点亚马逊仓库所属区域 [原字段 'aws_region']
|
|
51
|
+
"region_aws": "NA",
|
|
52
|
+
# 站点国家 (中文)
|
|
53
|
+
"country": "美国",
|
|
54
|
+
# 站点国家代码 [原字段 'code']
|
|
55
|
+
"country_code": "US",
|
|
56
|
+
# 亚马逊市场ID
|
|
57
|
+
"marketplace_id": "ATVPDKIKX0DER"
|
|
58
|
+
},
|
|
59
|
+
...
|
|
60
|
+
],
|
|
61
|
+
}
|
|
62
|
+
"""
|
|
63
|
+
data = await self._request_with_sign("GET", route.MARKETPLACES)
|
|
64
|
+
return schema.Marketplaces.model_validate(data)
|
|
65
|
+
|
|
66
|
+
async def States(self, country_code: str) -> schema.States:
|
|
67
|
+
"""查询亚马逊指定国家的周/省信息
|
|
68
|
+
|
|
69
|
+
## Docs
|
|
70
|
+
- 基础数据: [查询亚马逊国家下地区列表](https://apidoc.lingxing.com/#/docs/BasicData/WorldStateLists)
|
|
71
|
+
|
|
72
|
+
:param country_code `<'str'>`: 国家代码, 如: `"US"`
|
|
73
|
+
:returns `<'States'>`: 返回指定国家的省/州信息
|
|
74
|
+
```python
|
|
75
|
+
{
|
|
76
|
+
# 状态码
|
|
77
|
+
"code": 0,
|
|
78
|
+
# 提示信息
|
|
79
|
+
"message": "success",
|
|
80
|
+
# 错误信息
|
|
81
|
+
"errors": [],
|
|
82
|
+
# 请求ID
|
|
83
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
84
|
+
# 响应时间
|
|
85
|
+
"response_time": "2025-08-13 19:23:04",
|
|
86
|
+
# 响应数据量
|
|
87
|
+
"response_count": 2,
|
|
88
|
+
# 总数据量
|
|
89
|
+
"total_count": 2,
|
|
90
|
+
# 响应数据
|
|
91
|
+
"data": [
|
|
92
|
+
{
|
|
93
|
+
# 国家代码
|
|
94
|
+
"country_code": "US",
|
|
95
|
+
# 省/州名称 [原字段 'state_or_province_name']
|
|
96
|
+
"state": "California",
|
|
97
|
+
# 省/州代码 # [原字段 'code']
|
|
98
|
+
"state_code": "CA"
|
|
99
|
+
},
|
|
100
|
+
...
|
|
101
|
+
],
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
"""
|
|
105
|
+
url = route.STATES
|
|
106
|
+
# 解析并验证参数
|
|
107
|
+
args = {"country_code": country_code}
|
|
108
|
+
try:
|
|
109
|
+
p = param.CountryCode.model_validate(args)
|
|
110
|
+
except Exception as err:
|
|
111
|
+
raise errors.InvalidParametersError(err, url, args) from err
|
|
112
|
+
# 发送请求
|
|
113
|
+
data = await self._request_with_sign("POST", url, body=p.model_dump_params())
|
|
114
|
+
return schema.States.model_validate(data)
|
|
115
|
+
|
|
116
|
+
async def Sellers(self) -> schema.Sellers:
|
|
117
|
+
"""查询已授权到领星 ERP 全部的亚马逊店铺信息
|
|
118
|
+
|
|
119
|
+
## Docs
|
|
120
|
+
- 基础数据: [查询亚马逊店铺列表](https://apidoc.lingxing.com/#/docs/BasicData/SellerLists)
|
|
121
|
+
|
|
122
|
+
:returns `<'Sellers'>`: 返回已授权到领星 ERP 全部的亚马逊店铺信息
|
|
123
|
+
```python
|
|
124
|
+
{
|
|
125
|
+
# 状态码
|
|
126
|
+
"code": 0,
|
|
127
|
+
# 提示信息
|
|
128
|
+
"message": "success",
|
|
129
|
+
# 错误信息
|
|
130
|
+
"errors": [],
|
|
131
|
+
# 请求ID
|
|
132
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
133
|
+
# 响应时间
|
|
134
|
+
"response_time": "2025-08-13 19:23:04",
|
|
135
|
+
# 响应数据量
|
|
136
|
+
"response_count": 2,
|
|
137
|
+
# 总数据量
|
|
138
|
+
"total_count": 2,
|
|
139
|
+
# 响应数据
|
|
140
|
+
"data": [
|
|
141
|
+
{
|
|
142
|
+
# 领星站点ID (Marketplace.mid)
|
|
143
|
+
"mid": 1,
|
|
144
|
+
# 领星店铺ID [唯一标识]
|
|
145
|
+
"sid": 1,
|
|
146
|
+
# 亚马逊卖家ID
|
|
147
|
+
"seller_id": "AZTOL********",
|
|
148
|
+
# 领星店铺名称 (含国家信息) [原字段 'name']
|
|
149
|
+
"seller_name": "account**-ES",
|
|
150
|
+
# 领星店铺帐号ID [原字段 'seller_account_id']
|
|
151
|
+
"account_id": 1,
|
|
152
|
+
# 领星店铺帐号名称
|
|
153
|
+
"account_name": "account**",
|
|
154
|
+
# 亚马逊市场ID (Marketplace.marketplace_id)
|
|
155
|
+
"marketplace_id": "ATVPDKIKX0DER",
|
|
156
|
+
# 店铺区域
|
|
157
|
+
"region": "EU",
|
|
158
|
+
# 店铺国家 (中文)
|
|
159
|
+
"country": "西班牙",
|
|
160
|
+
# 店铺状态 (0: 停止同步, 1: 正常, 2: 授权异常, 3: 欠费停服)
|
|
161
|
+
"status": 1
|
|
162
|
+
# 店铺是否授权广告 (0: 否, 1: 是) [原字段 'has_ads_setting']
|
|
163
|
+
"ads_authorized": 0,
|
|
164
|
+
},
|
|
165
|
+
...
|
|
166
|
+
],
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
"""
|
|
170
|
+
data = await self._request_with_sign("GET", route.SELLERS)
|
|
171
|
+
return schema.Sellers.model_validate(data)
|
|
172
|
+
|
|
173
|
+
async def ConceptSellers(self) -> schema.ConceptSellers:
|
|
174
|
+
"""查询全部的亚马逊概念店铺信息
|
|
175
|
+
|
|
176
|
+
## Docs
|
|
177
|
+
- 基础数据: [查询亚马逊概念店铺列表](https://apidoc.lingxing.com/#/docs/BasicData/ConceptSellerLists)
|
|
178
|
+
|
|
179
|
+
:returns `<'ConceptSellers'>`: 返回全部的亚马逊概念店铺信息
|
|
180
|
+
```python
|
|
181
|
+
{
|
|
182
|
+
# 状态码
|
|
183
|
+
"code": 0,
|
|
184
|
+
# 提示信息
|
|
185
|
+
"message": "success",
|
|
186
|
+
# 错误信息
|
|
187
|
+
"errors": [],
|
|
188
|
+
# 请求ID
|
|
189
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
190
|
+
# 响应时间
|
|
191
|
+
"response_time": "2025-08-13 19:23:04",
|
|
192
|
+
# 响应数据量
|
|
193
|
+
"response_count": 2,
|
|
194
|
+
# 总数据量
|
|
195
|
+
"total_count": 2,
|
|
196
|
+
# 响应数据
|
|
197
|
+
"data": [
|
|
198
|
+
{
|
|
199
|
+
# 领星概念站点ID [原字段 'mid']
|
|
200
|
+
"cmid": 10*****,
|
|
201
|
+
# 领星概念店铺ID [唯一标识, 原字段 'id']
|
|
202
|
+
"csid": 1222**************,
|
|
203
|
+
# 亚马逊卖家ID
|
|
204
|
+
"seller_id": "AZTOL********",
|
|
205
|
+
# 领星概念店铺名称 (含区域信息)
|
|
206
|
+
"seller_name": "account**-EU",
|
|
207
|
+
# 领星概念店铺账号ID [原字段 'seller_account_id']
|
|
208
|
+
"account_id": 1,
|
|
209
|
+
# 领星概念店铺帐号名称 [原字段 'seller_account_name']
|
|
210
|
+
"account_name": "account**",
|
|
211
|
+
# 概念店铺区域
|
|
212
|
+
"region": "EU",
|
|
213
|
+
# 概念店铺国家, 如: "北美共享", "欧洲共享"
|
|
214
|
+
"country": "欧洲共享",
|
|
215
|
+
# 概念店铺状态 (1: 启用, 2: 停用)
|
|
216
|
+
"status": 1
|
|
217
|
+
},
|
|
218
|
+
...
|
|
219
|
+
],
|
|
220
|
+
}
|
|
221
|
+
"""
|
|
222
|
+
data = await self._request_with_sign("GET", route.CONCEPT_SELLERS)
|
|
223
|
+
return schema.ConceptSellers.model_validate(data)
|
|
224
|
+
|
|
225
|
+
async def RenameSellers(self, *rename: dict) -> schema.RenameSellersResult:
|
|
226
|
+
"""批量修改领星店铺名称
|
|
227
|
+
|
|
228
|
+
## Docs
|
|
229
|
+
- 基础数据: [批量修改店铺名称](https://apidoc.lingxing.com/#/docs/BasicData/SellerBatchRename)
|
|
230
|
+
|
|
231
|
+
:param *rename `<'dict'>`: 支持最多10个店铺名称的批量修改
|
|
232
|
+
|
|
233
|
+
- 每个字典必须包含 `sid` 和 `name` 字段, 如:
|
|
234
|
+
`{"sid": 1, "name": "account-ES"}`
|
|
235
|
+
- 必填字段 `sid` 领星店铺ID, 必须是 int 类型, 参数来源: `Seller.sid`
|
|
236
|
+
- 必填字段 `name` 新的店铺名称, 必须是 str 类型
|
|
237
|
+
|
|
238
|
+
:returns `<'RenameSellerResult'>`: 返回批量修改的结果
|
|
239
|
+
```python
|
|
240
|
+
{
|
|
241
|
+
# 状态码
|
|
242
|
+
"code": 0,
|
|
243
|
+
# 提示信息
|
|
244
|
+
"message": "success",
|
|
245
|
+
# 错误信息
|
|
246
|
+
"errors": [],
|
|
247
|
+
# 请求ID
|
|
248
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
249
|
+
# 响应时间
|
|
250
|
+
"response_time": "2025-08-13 19:23:04",
|
|
251
|
+
# 响应结果
|
|
252
|
+
"data": {
|
|
253
|
+
# 修改成功数量 [原字段 'success_num']
|
|
254
|
+
"success": 1,
|
|
255
|
+
# 修改失败数量 [原字段 'failure_num']
|
|
256
|
+
"failure": 1,
|
|
257
|
+
# 修改失败详情
|
|
258
|
+
"failure_detail": [
|
|
259
|
+
{
|
|
260
|
+
# 领星店铺ID (Seller.sid)
|
|
261
|
+
"sid": 1,
|
|
262
|
+
# 新店铺名称
|
|
263
|
+
"name": "account-ES",
|
|
264
|
+
# 失败信息 [原字段 'error']
|
|
265
|
+
"message": "新旧店铺名相同",
|
|
266
|
+
},
|
|
267
|
+
...
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
"""
|
|
273
|
+
url = route.RENAME_SELLERS
|
|
274
|
+
# 解析并验证参数
|
|
275
|
+
args = {"renames": rename}
|
|
276
|
+
try:
|
|
277
|
+
p = param.RenameSellers.model_validate(args)
|
|
278
|
+
except Exception as err:
|
|
279
|
+
raise errors.InvalidParametersError(err, url, args) from err
|
|
280
|
+
|
|
281
|
+
# 发送请求
|
|
282
|
+
data = await self._request_with_sign("POST", url, body=p.model_dump_params())
|
|
283
|
+
return schema.RenameSellersResult.model_validate(data)
|
|
284
|
+
|
|
285
|
+
async def Accounts(self) -> schema.Accounts:
|
|
286
|
+
"""查询所有领星的ERP账号信息
|
|
287
|
+
|
|
288
|
+
## Docs
|
|
289
|
+
- 基础数据: [查询ERP用户信息列表](https://apidoc.lingxing.com/#/docs/BasicData/AccoutLists)
|
|
290
|
+
|
|
291
|
+
:returns `<'Accounts'>`: 返回所有领星的ERP账号信息
|
|
292
|
+
```python
|
|
293
|
+
{
|
|
294
|
+
# 状态码
|
|
295
|
+
"code": 0,
|
|
296
|
+
# 提示信息
|
|
297
|
+
"message": "success",
|
|
298
|
+
# 错误信息
|
|
299
|
+
"errors": [],
|
|
300
|
+
# 请求ID
|
|
301
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
302
|
+
# 响应时间
|
|
303
|
+
"response_time": "2025-08-13 19:23:04",
|
|
304
|
+
# 响应数据量
|
|
305
|
+
"response_count": 2,
|
|
306
|
+
# 总数据量
|
|
307
|
+
"total_count": 2,
|
|
308
|
+
# 响应数据
|
|
309
|
+
"data": [
|
|
310
|
+
{
|
|
311
|
+
# 领星账号所从属的ID (如主帐号ID) [原字段 'zid']
|
|
312
|
+
"parent_id": 1,
|
|
313
|
+
# 领星帐号ID [唯一标识] [原字段 'uid']
|
|
314
|
+
"user_id": 1,
|
|
315
|
+
# 是否为主账号 (0: 否, 1: 是)
|
|
316
|
+
"is_master": 1
|
|
317
|
+
# 帐号角色
|
|
318
|
+
"role": "",
|
|
319
|
+
# 领星帐号显示的姓名 [原字段 'realname']
|
|
320
|
+
"display_name": "超级管理员",
|
|
321
|
+
# 领星帐号登陆用户名
|
|
322
|
+
"username": "user****",
|
|
323
|
+
# 领星帐号电子邮箱
|
|
324
|
+
"email": "15*******@qq.com",
|
|
325
|
+
# 领星帐号电话号码 [原字段 'mobile']
|
|
326
|
+
"phone": "15********",
|
|
327
|
+
# 领星帐号创建时间 (北京时间)
|
|
328
|
+
"create_time": "2024-07-12 19:07",
|
|
329
|
+
# 领星帐号最后登录时间 (北京时间)
|
|
330
|
+
"last_login_time": "2024-07-12 19:07",
|
|
331
|
+
# 领星帐号最后登录IP
|
|
332
|
+
"last_login_ip": "",
|
|
333
|
+
# 领星帐号登录次数 [原字段 'login_num']
|
|
334
|
+
"login_count": 1
|
|
335
|
+
# 领星帐号状态 (0: 禁用, 1: 正常)
|
|
336
|
+
"status": 1,
|
|
337
|
+
# 关联的领星店铺名称, 逗号分隔 [原字段 'seller']
|
|
338
|
+
"sellers": "acc**1,acc**2",
|
|
339
|
+
},
|
|
340
|
+
...
|
|
341
|
+
],
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
"""
|
|
345
|
+
data = await self._request_with_sign("GET", route.ACCOUNTS)
|
|
346
|
+
return schema.Accounts.model_validate(data)
|
|
347
|
+
|
|
348
|
+
async def ExchangeRates(
|
|
349
|
+
self,
|
|
350
|
+
date: str | datetime.date | datetime.datetime | None = None,
|
|
351
|
+
) -> schema.ExchangeRates:
|
|
352
|
+
"""查询指定月份的汇率信息
|
|
353
|
+
|
|
354
|
+
## Docs
|
|
355
|
+
- 基础数据: [查询汇率](https://apidoc.lingxing.com/#/docs/BasicData/Currency)
|
|
356
|
+
|
|
357
|
+
:param date `<'str/date/datetime'>`: 指定查询的月份, 默认 `None` (当前月份)
|
|
358
|
+
|
|
359
|
+
- 如果是字符串, 必须是有效的日期字符串, 如: `"2025-07"`, `"2025-07-01"`
|
|
360
|
+
- 如果是 `date` 或 `datetime` 对象, 将自动转换为 `YYYY-MM` 格式
|
|
361
|
+
- 如果为 `None`, 则使用当前月份作为参数
|
|
362
|
+
|
|
363
|
+
:returns `<'ExchangeRates'>`: 返回指定月份的汇率信息
|
|
364
|
+
```python
|
|
365
|
+
{
|
|
366
|
+
# 状态码
|
|
367
|
+
"code": 0,
|
|
368
|
+
# 提示信息
|
|
369
|
+
"message": "success",
|
|
370
|
+
# 错误信息
|
|
371
|
+
"errors": [],
|
|
372
|
+
# 请求ID
|
|
373
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
374
|
+
# 响应时间
|
|
375
|
+
"response_time": "2025-08-13 19:23:04",
|
|
376
|
+
# 响应数据量
|
|
377
|
+
"response_count": 2,
|
|
378
|
+
# 总数据量
|
|
379
|
+
"total_count": 2,
|
|
380
|
+
# 响应数据
|
|
381
|
+
"data": [
|
|
382
|
+
{
|
|
383
|
+
# 汇率日期 (格式: YYYY-MM-DD)
|
|
384
|
+
"date": "2025-01-01",
|
|
385
|
+
# 货币名称 (中文) [原字段 'name']
|
|
386
|
+
"currency": "美元",
|
|
387
|
+
# 货币代码 [原字段 'code']
|
|
388
|
+
"currency_code": "USD",
|
|
389
|
+
# 货币符号 [原字段 'icon']
|
|
390
|
+
"currency_icon": "$",
|
|
391
|
+
# 中国银行官方汇率 (对比人民币) [原字段 'rate_org']
|
|
392
|
+
"boc_rate": "7.1698",
|
|
393
|
+
# 用户汇率 (对比人民币) [原字段 'my_rate']
|
|
394
|
+
"user_rate": "7.1315",
|
|
395
|
+
# 用户汇率修改时间 (北京时间)
|
|
396
|
+
"update_time": "2025-03-10 17:14:10",
|
|
397
|
+
},
|
|
398
|
+
...
|
|
399
|
+
],
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
"""
|
|
403
|
+
url = route.EXCHANGE_RATES
|
|
404
|
+
# 解析并验证参数
|
|
405
|
+
args = {"date": date}
|
|
406
|
+
try:
|
|
407
|
+
p = param.ExchangeRateDate.model_validate(args)
|
|
408
|
+
except Exception as err:
|
|
409
|
+
raise errors.InvalidParametersError(err, url, args) from err
|
|
410
|
+
|
|
411
|
+
# 发送请求
|
|
412
|
+
data = await self._request_with_sign("POST", url, body={"date": p.date})
|
|
413
|
+
return schema.ExchangeRates.model_validate(data)
|
|
414
|
+
|
|
415
|
+
async def EditExchangeRate(
|
|
416
|
+
self,
|
|
417
|
+
date: str | datetime.date | datetime.datetime,
|
|
418
|
+
currency_code: str,
|
|
419
|
+
user_rate: str | float | Decimal,
|
|
420
|
+
) -> base_schema.ResponseResult:
|
|
421
|
+
"""修改指定月份的用户汇率
|
|
422
|
+
|
|
423
|
+
## Docs
|
|
424
|
+
- 基础数据: [修改我的汇率](https://apidoc.lingxing.com/#/docs/BasicData/ExchangeRateUpdate)
|
|
425
|
+
|
|
426
|
+
:param date `<'str/date/datetime'>`: 指定要修改的汇率月份
|
|
427
|
+
|
|
428
|
+
- 如果是字符串, 必须是有效的日期字符串, 如: `"2025-07"`, `"2025-07-01"`
|
|
429
|
+
- 如果是 `date` 或 `datetime` 对象, 将自动转换为 `YYYY-MM` 格式
|
|
430
|
+
|
|
431
|
+
:param currency_code `<'str'>`: 指定的货币代码, 如: `"USD"`
|
|
432
|
+
:param user_rate `<'str/float/Decimal'>`: 用户自定义汇率, 对比人民币,
|
|
433
|
+
如: `"7.2008000000"`, 最多支持10位小数
|
|
434
|
+
:returns `<'ResponseResult'>`: 返回修改结果
|
|
435
|
+
```python
|
|
436
|
+
{
|
|
437
|
+
# 状态码
|
|
438
|
+
"code": 0,
|
|
439
|
+
# 提示信息
|
|
440
|
+
"message": "success",
|
|
441
|
+
# 错误信息
|
|
442
|
+
"errors": [],
|
|
443
|
+
# 请求ID
|
|
444
|
+
"request_id": "44DAC5AE-7D76-9054-2431-0EF7E357CFE5",
|
|
445
|
+
# 响应时间
|
|
446
|
+
"response_time": "2025-08-13 19:23:04",
|
|
447
|
+
# 编辑结果
|
|
448
|
+
"data": None
|
|
449
|
+
}
|
|
450
|
+
```
|
|
451
|
+
"""
|
|
452
|
+
url = route.EDIT_EXCHANGE_RATE
|
|
453
|
+
# 解析并验证参数
|
|
454
|
+
args = {
|
|
455
|
+
"date": date,
|
|
456
|
+
"currency_code": currency_code,
|
|
457
|
+
"user_rate": user_rate,
|
|
458
|
+
}
|
|
459
|
+
try:
|
|
460
|
+
p = param.EditExchangeRate.model_validate(args)
|
|
461
|
+
except Exception as err:
|
|
462
|
+
raise errors.InvalidParametersError(err, url, args) from err
|
|
463
|
+
|
|
464
|
+
# 发送请求
|
|
465
|
+
data = await self._request_with_sign("POST", url, body=p.model_dump_params())
|
|
466
|
+
return base_schema.ResponseResult.model_validate(data)
|