pixelarraythirdparty 1.1.5__tar.gz → 1.1.6__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.
Files changed (27) hide show
  1. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/PKG-INFO +1 -1
  2. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/__init__.py +1 -1
  3. pixelarraythirdparty-1.1.6/pixelarraythirdparty/feedback/feedback.py +251 -0
  4. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty.egg-info/PKG-INFO +1 -1
  5. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pyproject.toml +1 -1
  6. pixelarraythirdparty-1.1.5/pixelarraythirdparty/feedback/feedback.py +0 -110
  7. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/LICENSE +0 -0
  8. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/MANIFEST.in +0 -0
  9. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/client.py +0 -0
  10. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/cron/__init__.py +0 -0
  11. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/cron/cron.py +0 -0
  12. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/feedback/__init__.py +0 -0
  13. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/order/__init__.py +0 -0
  14. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/order/order.py +0 -0
  15. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/product/__init__.py +0 -0
  16. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/product/product.py +0 -0
  17. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/project/__init__.py +0 -0
  18. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/project/project.py +0 -0
  19. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/unified_login/__init__.py +0 -0
  20. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/unified_login/unified_login.py +0 -0
  21. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/user/__init__.py +0 -0
  22. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty/user/user.py +0 -0
  23. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty.egg-info/SOURCES.txt +0 -0
  24. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty.egg-info/dependency_links.txt +0 -0
  25. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty.egg-info/requires.txt +0 -0
  26. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/pixelarraythirdparty.egg-info/top_level.txt +0 -0
  27. {pixelarraythirdparty-1.1.5 → pixelarraythirdparty-1.1.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pixelarraythirdparty
3
- Version: 1.1.5
3
+ Version: 1.1.6
4
4
  Summary: PixelArray 第三方微服务客户端
5
5
  Author-email: Lu qi <qi.lu@pixelarrayai.com>
6
6
  License-Expression: MIT
@@ -13,7 +13,7 @@ PixelArray 第三方微服务客户端
13
13
  - project: 项目管理模块
14
14
  """
15
15
 
16
- __version__ = "1.1.5"
16
+ __version__ = "1.1.6"
17
17
  __author__ = "Lu qi"
18
18
  __email__ = "qi.lu@pixelarrayai.com"
19
19
 
@@ -0,0 +1,251 @@
1
+ from pixelarraythirdparty.client import AsyncClient
2
+ from typing import List, Optional, Union, BinaryIO
3
+ import aiohttp
4
+ import os
5
+ import mimetypes
6
+
7
+
8
+ class FeedbackManagerAsync(AsyncClient):
9
+ async def create_feedback(
10
+ self,
11
+ project_id: int,
12
+ content: str,
13
+ contact_info: str,
14
+ images: Optional[List[Union[str, BinaryIO, bytes]]] = None,
15
+ video: Optional[Union[str, BinaryIO, bytes]] = None,
16
+ ):
17
+ """
18
+ description:
19
+ 创建新的客户反馈,反馈必须关联一个项目。支持上传图片和视频文件。
20
+ parameters:
21
+ project_id(int): 项目ID,必须关联一个已存在的项目
22
+ content(str): 反馈内容
23
+ contact_info(str): 反馈人联系方式
24
+ images(List[Union[str, BinaryIO, bytes]], optional): 图片文件列表,可以是文件路径、文件对象或字节数据,最多9张
25
+ video(Union[str, BinaryIO, bytes], optional): 视频文件,可以是文件路径、文件对象或字节数据,最多1个
26
+ return:
27
+ data(dict): 反馈信息
28
+ - id(int): 反馈ID
29
+ - project_id(int): 项目ID
30
+ - content(str): 反馈内容
31
+ - contact_info(str): 反馈人联系方式
32
+ - created_at(str): 反馈创建时间
33
+ success(bool): 操作是否成功
34
+ """
35
+ # 先创建反馈
36
+ data = {
37
+ "project_id": project_id,
38
+ "content": content,
39
+ "contact_info": contact_info,
40
+ }
41
+ feedback_data, success = await self._request("POST", "/api/feedback/create", json=data)
42
+ if not success:
43
+ return {}, False
44
+
45
+ feedback_id = feedback_data.get("id")
46
+ if not feedback_id:
47
+ return feedback_data, True
48
+
49
+ # 如果有文件需要上传,则上传文件
50
+ if images or video:
51
+ # 上传图片
52
+ if images:
53
+ if len(images) > 9:
54
+ return {}, False # 图片数量超过限制
55
+ for image in images:
56
+ await self._upload_file(feedback_id, image, "image")
57
+
58
+ # 上传视频
59
+ if video:
60
+ await self._upload_file(feedback_id, video, "video")
61
+
62
+ return feedback_data, True
63
+
64
+ async def _upload_file(
65
+ self,
66
+ feedback_id: int,
67
+ file_data: Union[str, BinaryIO, bytes],
68
+ file_type: str,
69
+ ):
70
+ """
71
+ 内部方法:上传文件到OSS
72
+ """
73
+ # 读取文件数据
74
+ file_content = None
75
+ file_name = None
76
+ file_size = None
77
+ mime_type = None
78
+
79
+ if isinstance(file_data, str):
80
+ # 文件路径
81
+ file_name = os.path.basename(file_data)
82
+ with open(file_data, "rb") as f:
83
+ file_content = f.read()
84
+ file_size = len(file_content)
85
+ mime_type, _ = mimetypes.guess_type(file_data)
86
+ elif isinstance(file_data, bytes):
87
+ # 字节数据
88
+ file_name = f"file.{file_type}"
89
+ file_content = file_data
90
+ file_size = len(file_content)
91
+ else:
92
+ # 文件对象
93
+ file_name = getattr(file_data, "name", None) or getattr(file_data, "filename", f"file.{file_type}")
94
+ try:
95
+ # 尝试异步读取
96
+ if hasattr(file_data, "read"):
97
+ read_method = file_data.read
98
+ # 检查是否是协程函数
99
+ import inspect
100
+ if inspect.iscoroutinefunction(read_method):
101
+ file_content = await read_method()
102
+ else:
103
+ file_content = read_method()
104
+ else:
105
+ file_content = file_data
106
+ except Exception as e:
107
+ print(f"读取文件对象失败: {str(e)}")
108
+ return False
109
+ file_size = len(file_content) if file_content else 0
110
+ mime_type, _ = mimetypes.guess_type(file_name)
111
+
112
+ if not file_content:
113
+ return False
114
+
115
+ # 获取上传签名链接
116
+ upload_data = {
117
+ "feedback_id": feedback_id,
118
+ "file_name": file_name,
119
+ "file_type": file_type,
120
+ }
121
+ if file_size:
122
+ upload_data["file_size"] = file_size
123
+ if mime_type:
124
+ upload_data["mime_type"] = mime_type
125
+
126
+ upload_info, success = await self._request(
127
+ "POST", "/api/feedback/files/upload/presigned-url", json=upload_data
128
+ )
129
+ if not success:
130
+ return False
131
+
132
+ presigned_url = upload_info.get("presigned_url")
133
+ oss_path = upload_info.get("oss_path")
134
+
135
+ if not presigned_url:
136
+ return False
137
+
138
+ # 上传文件到OSS
139
+ try:
140
+ headers = {}
141
+ if mime_type:
142
+ headers["Content-Type"] = mime_type
143
+
144
+ async with aiohttp.ClientSession() as session:
145
+ async with session.put(presigned_url, data=file_content, headers=headers) as resp:
146
+ if resp.status not in [200, 204]:
147
+ return False
148
+ except Exception as e:
149
+ print(f"上传文件到OSS失败: {str(e)}")
150
+ return False
151
+
152
+ # 调用上传完成接口
153
+ complete_data = {
154
+ "feedback_id": feedback_id,
155
+ "oss_path": oss_path,
156
+ "file_name": file_name,
157
+ "file_type": file_type,
158
+ }
159
+ if file_size:
160
+ complete_data["file_size"] = file_size
161
+ if mime_type:
162
+ complete_data["mime_type"] = mime_type
163
+
164
+ _, success = await self._request(
165
+ "POST", "/api/feedback/files/upload/complete", json=complete_data
166
+ )
167
+ return success
168
+
169
+ async def list_feedback(
170
+ self,
171
+ page: int = 1,
172
+ page_size: int = 10,
173
+ project_id: int = None,
174
+ ):
175
+ """
176
+ description:
177
+ 分页查询反馈列表,支持按项目ID进行筛选。
178
+ parameters:
179
+ page(int): 页码
180
+ page_size(int): 每页数量
181
+ project_id(int): 项目ID筛选,可选
182
+ return:
183
+ data(dict): 反馈列表信息
184
+ - feedbacks(list): 反馈列表
185
+ - id(int): 反馈ID
186
+ - project_id(int): 项目ID
187
+ - project_name(str): 项目名称
188
+ - content(str): 反馈内容
189
+ - contact_info(str): 反馈人联系方式
190
+ - created_at(str): 反馈创建时间
191
+ - total(int): 总反馈数量
192
+ - page(int): 当前页码
193
+ - page_size(int): 每页数量
194
+ success(bool): 操作是否成功
195
+ """
196
+ params = {
197
+ "page": page,
198
+ "page_size": page_size,
199
+ }
200
+ if project_id is not None:
201
+ params["project_id"] = project_id
202
+ data, success = await self._request("GET", "/api/feedback/list", params=params)
203
+ if not success:
204
+ return {}, False
205
+ return data, True
206
+
207
+ async def get_feedback_detail(self, feedback_id: int):
208
+ """
209
+ description:
210
+ 根据反馈ID获取反馈的详细信息。如果反馈中包含图片和视频,返回的文件信息会包含预览签名链接。
211
+ parameters:
212
+ feedback_id(int): 反馈ID
213
+ return:
214
+ data(dict): 反馈详细信息
215
+ - id(int): 反馈ID
216
+ - project_id(int): 项目ID
217
+ - project_name(str): 项目名称
218
+ - content(str): 反馈内容
219
+ - contact_info(str): 反馈人联系方式
220
+ - created_at(str): 反馈创建时间
221
+ - files(list, optional): 文件列表,如果反馈包含文件
222
+ - id(int): 文件ID
223
+ - feedback_id(int): 反馈ID
224
+ - oss_path(str): OSS存储路径
225
+ - file_name(str): 文件名
226
+ - file_type(str): 文件类型("image"或"video")
227
+ - file_size(int, optional): 文件大小(字节)
228
+ - mime_type(str, optional): MIME类型
229
+ - presigned_url(str): 预览签名链接,有效期1小时
230
+ success(bool): 操作是否成功
231
+ """
232
+ data, success = await self._request("GET", f"/api/feedback/{feedback_id}")
233
+ if not success:
234
+ return {}, False
235
+ return data, True
236
+
237
+ async def delete_feedback(self, feedback_id: int):
238
+ """
239
+ description:
240
+ 根据反馈ID删除指定的反馈记录。仅管理员可删除反馈。
241
+ parameters:
242
+ feedback_id(int): 反馈ID
243
+ return:
244
+ data(None): 删除成功时返回None
245
+ success(bool): 操作是否成功
246
+ """
247
+ data, success = await self._request("DELETE", f"/api/feedback/{feedback_id}")
248
+ if not success:
249
+ return {}, False
250
+ return data, True
251
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pixelarraythirdparty
3
- Version: 1.1.5
3
+ Version: 1.1.6
4
4
  Summary: PixelArray 第三方微服务客户端
5
5
  Author-email: Lu qi <qi.lu@pixelarrayai.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pixelarraythirdparty"
7
- version = "1.1.5"
7
+ version = "1.1.6"
8
8
  authors = [
9
9
  {name = "Lu qi", email = "qi.lu@pixelarrayai.com"},
10
10
  ]
@@ -1,110 +0,0 @@
1
- from pixelarraythirdparty.client import AsyncClient
2
-
3
-
4
- class FeedbackManagerAsync(AsyncClient):
5
- async def create_feedback(
6
- self,
7
- project_id: int,
8
- content: str,
9
- contact_info: str,
10
- ):
11
- """
12
- description:
13
- 创建新的客户反馈,反馈必须关联一个项目。
14
- parameters:
15
- project_id(int): 项目ID,必须关联一个已存在的项目
16
- content(str): 反馈内容
17
- contact_info(str): 反馈人联系方式
18
- return:
19
- data(dict): 反馈信息
20
- - id(int): 反馈ID
21
- - project_id(int): 项目ID
22
- - content(str): 反馈内容
23
- - contact_info(str): 反馈人联系方式
24
- - created_at(str): 反馈创建时间
25
- success(bool): 操作是否成功
26
- """
27
- data = {
28
- "project_id": project_id,
29
- "content": content,
30
- "contact_info": contact_info,
31
- }
32
- data, success = await self._request("POST", "/api/feedback/create", json=data)
33
- if not success:
34
- return {}, False
35
- return data, True
36
-
37
- async def list_feedback(
38
- self,
39
- page: int = 1,
40
- page_size: int = 10,
41
- project_id: int = None,
42
- ):
43
- """
44
- description:
45
- 分页查询反馈列表,支持按项目ID进行筛选。
46
- parameters:
47
- page(int): 页码
48
- page_size(int): 每页数量
49
- project_id(int): 项目ID筛选,可选
50
- return:
51
- data(dict): 反馈列表信息
52
- - feedbacks(list): 反馈列表
53
- - id(int): 反馈ID
54
- - project_id(int): 项目ID
55
- - project_name(str): 项目名称
56
- - content(str): 反馈内容
57
- - contact_info(str): 反馈人联系方式
58
- - created_at(str): 反馈创建时间
59
- - total(int): 总反馈数量
60
- - page(int): 当前页码
61
- - page_size(int): 每页数量
62
- success(bool): 操作是否成功
63
- """
64
- params = {
65
- "page": page,
66
- "page_size": page_size,
67
- }
68
- if project_id is not None:
69
- params["project_id"] = project_id
70
- data, success = await self._request("GET", "/api/feedback/list", params=params)
71
- if not success:
72
- return {}, False
73
- return data, True
74
-
75
- async def get_feedback_detail(self, feedback_id: int):
76
- """
77
- description:
78
- 根据反馈ID获取反馈的详细信息。
79
- parameters:
80
- feedback_id(int): 反馈ID
81
- return:
82
- data(dict): 反馈详细信息
83
- - id(int): 反馈ID
84
- - project_id(int): 项目ID
85
- - project_name(str): 项目名称
86
- - content(str): 反馈内容
87
- - contact_info(str): 反馈人联系方式
88
- - created_at(str): 反馈创建时间
89
- success(bool): 操作是否成功
90
- """
91
- data, success = await self._request("GET", f"/api/feedback/{feedback_id}")
92
- if not success:
93
- return {}, False
94
- return data, True
95
-
96
- async def delete_feedback(self, feedback_id: int):
97
- """
98
- description:
99
- 根据反馈ID删除指定的反馈记录。仅管理员可删除反馈。
100
- parameters:
101
- feedback_id(int): 反馈ID
102
- return:
103
- data(None): 删除成功时返回None
104
- success(bool): 操作是否成功
105
- """
106
- data, success = await self._request("DELETE", f"/api/feedback/{feedback_id}")
107
- if not success:
108
- return {}, False
109
- return data, True
110
-