ms-vite-plugin 1.1.2 → 1.1.4

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 (94) hide show
  1. package/dist/build.js +6 -0
  2. package/dist/cli.js +91 -1
  3. package/dist/mcp/device-config.d.ts +55 -0
  4. package/dist/mcp/device-config.js +183 -0
  5. package/dist/mcp/docs-service.d.ts +65 -0
  6. package/dist/mcp/docs-service.js +168 -0
  7. package/dist/mcp/project.d.ts +16 -0
  8. package/dist/mcp/project.js +74 -0
  9. package/dist/mcp/tools.d.ts +18 -0
  10. package/dist/mcp/tools.js +825 -0
  11. package/dist/mcp/types.d.ts +32 -0
  12. package/dist/mcp/types.js +11 -0
  13. package/dist/mcp-server.d.ts +2 -0
  14. package/dist/mcp-server.js +86 -0
  15. package/dist/project.d.ts +89 -0
  16. package/dist/project.js +306 -0
  17. package/dist/version.d.ts +12 -0
  18. package/dist/version.js +63 -0
  19. package/docs/api/action.md +922 -0
  20. package/docs/api/appleocr.md +229 -0
  21. package/docs/api/config.md +122 -0
  22. package/docs/api/cryptoUtils.md +232 -0
  23. package/docs/api/device.md +374 -0
  24. package/docs/api/file.md +516 -0
  25. package/docs/api/global.md +617 -0
  26. package/docs/api/hid.md +1032 -0
  27. package/docs/api/hotUpdate.md +166 -0
  28. package/docs/api/http.md +548 -0
  29. package/docs/api/image.md +907 -0
  30. package/docs/api/ime.md +290 -0
  31. package/docs/api/logger.md +324 -0
  32. package/docs/api/media.md +248 -0
  33. package/docs/api/mysql.md +441 -0
  34. package/docs/api/netCard.md +200 -0
  35. package/docs/api/node.md +353 -0
  36. package/docs/api/paddleocr.md +246 -0
  37. package/docs/api/pip.md +242 -0
  38. package/docs/api/system.md +572 -0
  39. package/docs/api/thread.md +269 -0
  40. package/docs/api/tomatoocr.md +425 -0
  41. package/docs/api/tts.md +334 -0
  42. package/docs/api/ui.md +947 -0
  43. package/docs/api/utils.md +265 -0
  44. package/docs/api/yolo.md +310 -0
  45. package/docs/apicn/action.md +919 -0
  46. package/docs/apicn/appleocr.md +233 -0
  47. package/docs/apicn/config.md +120 -0
  48. package/docs/apicn/device.md +385 -0
  49. package/docs/apicn/file.md +511 -0
  50. package/docs/apicn/global.md +613 -0
  51. package/docs/apicn/hid.md +1033 -0
  52. package/docs/apicn/hotUpdate.md +170 -0
  53. package/docs/apicn/http.md +672 -0
  54. package/docs/apicn/image.md +924 -0
  55. package/docs/apicn/ime.md +290 -0
  56. package/docs/apicn/logger.md +332 -0
  57. package/docs/apicn/media.md +252 -0
  58. package/docs/apicn/mysql.md +445 -0
  59. package/docs/apicn/netCard.md +200 -0
  60. package/docs/apicn/node.md +362 -0
  61. package/docs/apicn/paddleocr.md +255 -0
  62. package/docs/apicn/pip.md +242 -0
  63. package/docs/apicn/system.md +575 -0
  64. package/docs/apicn/thread.md +269 -0
  65. package/docs/apicn/tts.md +338 -0
  66. package/docs/apicn/ui.md +933 -0
  67. package/docs/apicn/utils.md +265 -0
  68. package/docs/apicn/yolo.md +314 -0
  69. package/docs/apipython/action.md +901 -0
  70. package/docs/apipython/appleocr.md +226 -0
  71. package/docs/apipython/config.md +126 -0
  72. package/docs/apipython/cryptoUtils.md +246 -0
  73. package/docs/apipython/device.md +365 -0
  74. package/docs/apipython/file.md +476 -0
  75. package/docs/apipython/g.md +154 -0
  76. package/docs/apipython/hid.md +1059 -0
  77. package/docs/apipython/hotUpdate.md +154 -0
  78. package/docs/apipython/image.md +938 -0
  79. package/docs/apipython/ime.md +306 -0
  80. package/docs/apipython/logger.md +330 -0
  81. package/docs/apipython/media.md +221 -0
  82. package/docs/apipython/mysql.md +432 -0
  83. package/docs/apipython/netCard.md +219 -0
  84. package/docs/apipython/node.md +331 -0
  85. package/docs/apipython/overview.md +66 -0
  86. package/docs/apipython/paddleocr.md +211 -0
  87. package/docs/apipython/pip.md +231 -0
  88. package/docs/apipython/system.md +458 -0
  89. package/docs/apipython/tomatoocr.md +444 -0
  90. package/docs/apipython/tts.md +331 -0
  91. package/docs/apipython/ui.md +949 -0
  92. package/docs/apipython/utils.md +284 -0
  93. package/docs/apipython/yolo.md +281 -0
  94. package/package.json +8 -4
@@ -0,0 +1,221 @@
1
+ # 媒体模块 (Media)
2
+
3
+ 媒体模块提供图片/视频的相册管理与 MP3 音频播放控制,支持异步与同步播放模式。
4
+
5
+ ## 功能概览
6
+
7
+ - 相册管理:保存图片/视频到相册,清空相册图片/视频
8
+ - 音频播放:播放/停止 MP3,支持循环播放与等待播放结束
9
+
10
+ ## API 参考
11
+
12
+ ### 相册操作
13
+
14
+ #### saveImageToAlbum - 保存图像到系统相册。
15
+
16
+ ```python
17
+ def saveImageToAlbum(imageId: str) -> bool
18
+ ```
19
+
20
+ **参数:**
21
+
22
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
23
+ | --------- | ---- | -------- | ------ | -------------------------------- |
24
+ | `imageId` | str | 是 | | 图像 ID(通过 `image` 模块获取) |
25
+
26
+ **返回值:**
27
+
28
+ | 类型 | 描述 |
29
+ | ------ | ------------ |
30
+ | `bool` | 是否保存成功 |
31
+
32
+ **示例:**
33
+
34
+ ```python
35
+ from kuaijs import media, image
36
+
37
+ # 保存截图到相册
38
+ img = image.captureFullScreen()
39
+ if img:
40
+ saved = media.saveImageToAlbum(img)
41
+ print("图片已保存到相册" if saved else "保存失败")
42
+ ```
43
+
44
+ #### saveVideoToAlbumPath - 保存视频文件到系统相册。
45
+
46
+ ```python
47
+ def saveVideoToAlbumPath(path: str) -> bool
48
+ ```
49
+
50
+ **参数:**
51
+
52
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
53
+ | ------ | ---- | -------- | ------ | ------------ |
54
+ | `path` | str | 是 | | 视频文件路径 |
55
+
56
+ **返回值:**
57
+
58
+ | 类型 | 描述 |
59
+ | ------ | ------------ |
60
+ | `bool` | 是否保存成功 |
61
+
62
+ **示例:**
63
+
64
+ ```python
65
+ from kuaijs import media, file
66
+
67
+ # 保存视频到相册 (从 documents 目录读取)
68
+ documentsDir = file.getInternalDir("documents")
69
+ videoName = "video.mp4"
70
+ videoPath = f"{documentsDir}/{videoName}"
71
+ saved = media.saveVideoToAlbumPath(videoPath)
72
+ print("视频已保存到相册" if saved else "保存失败")
73
+ ```
74
+
75
+ #### deleteAllPhotos - 清空相册中的所有图片。
76
+
77
+ ```python
78
+ def deleteAllPhotos() -> bool
79
+ ```
80
+
81
+ **返回值:**
82
+
83
+ | 类型 | 描述 |
84
+ | ------ | ------------ |
85
+ | `bool` | 是否删除成功 |
86
+
87
+ **示例:**
88
+
89
+ ```python
90
+ from kuaijs import media
91
+
92
+ deleted = media.deleteAllPhotos()
93
+ print("相册图片已清空" if deleted else "清空失败")
94
+ ```
95
+
96
+ #### deleteAllVideos - 清空相册中的所有视频。
97
+
98
+ ```python
99
+ def deleteAllVideos() -> bool
100
+ ```
101
+
102
+ **返回值:**
103
+
104
+ | 类型 | 描述 |
105
+ | ------ | ------------ |
106
+ | `bool` | 是否删除成功 |
107
+
108
+ **示例:**
109
+
110
+ ```python
111
+ from kuaijs import media
112
+
113
+ deleted = media.deleteAllVideos()
114
+ print("相册视频已清空" if deleted else "清空失败")
115
+ ```
116
+
117
+ #### deleteAllScreenshots - 清空相册中的所有截图。
118
+
119
+ ```python
120
+ def deleteAllScreenshots() -> bool
121
+ ```
122
+
123
+ **返回值:**
124
+
125
+ | 类型 | 描述 |
126
+ | ------ | ------------ |
127
+ | `bool` | 是否删除成功 |
128
+
129
+ **示例:**
130
+
131
+ ```python
132
+ from kuaijs import media
133
+
134
+ deleted = media.deleteAllScreenshots()
135
+ print("相册截图已清空" if deleted else "清空失败")
136
+ ```
137
+
138
+ ### 音频播放
139
+
140
+ #### playMp3 - 异步播放 MP3 音频文件。
141
+
142
+ ```python
143
+ def playMp3(path: str, loop: bool) -> bool
144
+ ```
145
+
146
+ **参数:**
147
+
148
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
149
+ | ------ | ---- | -------- | ------ | ------------ |
150
+ | `path` | str | 是 | | MP3 文件路径 |
151
+ | `loop` | bool | 是 | | 是否循环播放 |
152
+
153
+ **返回值:**
154
+
155
+ | 类型 | 描述 |
156
+ | ------ | ---------------- |
157
+ | `bool` | 是否开始播放成功 |
158
+
159
+ **示例:**
160
+
161
+ ```python
162
+ from kuaijs import media
163
+
164
+ played = media.playMp3("/var/mobile/Media/background.mp3", True)
165
+ if played:
166
+ print("背景音乐开始播放")
167
+
168
+ sound_played = media.playMp3("/var/mobile/Media/sound.mp3", False)
169
+ if sound_played:
170
+ print("音效播放中")
171
+ ```
172
+
173
+ #### stopMp3 - 停止当前播放的 MP3 音频。
174
+
175
+ ```python
176
+ def stopMp3() -> bool
177
+ ```
178
+
179
+ **返回值:**
180
+
181
+ | 类型 | 描述 |
182
+ | ------ | ------------ |
183
+ | `bool` | 是否停止成功 |
184
+
185
+ **示例:**
186
+
187
+ ```python
188
+ from kuaijs import media
189
+
190
+ stopped = media.stopMp3()
191
+ print("音乐已停止" if stopped else "停止失败或没有正在播放的音乐")
192
+ ```
193
+
194
+ #### playMp3WaitEnd - 同步播放 MP3 音频文件(等待播放结束)。
195
+
196
+ ```python
197
+ def playMp3WaitEnd(path: str, loop: bool) -> bool
198
+ ```
199
+
200
+ **参数:**
201
+
202
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
203
+ | ------ | ---- | -------- | ------ | -------------------------------------------------------------------- |
204
+ | `path` | str | 是 | | MP3 文件路径 |
205
+ | `loop` | bool | 是 | | 是否循环播放 注意:循环播放会阻塞线程,慎用,不要在主线程设置为 True |
206
+
207
+ **返回值:**
208
+
209
+ | 类型 | 描述 |
210
+ | ------ | ------------ |
211
+ | `bool` | 是否播放成功 |
212
+
213
+ **示例:**
214
+
215
+ ```python
216
+ from kuaijs import media
217
+
218
+ print("开始播放音频...")
219
+ played = media.playMp3WaitEnd("/var/mobile/Media/notification.mp3", False)
220
+ print("音频播放完成" if played else "播放失败")
221
+ ```
@@ -0,0 +1,432 @@
1
+ # MySQL 数据库模块 (MySQL)
2
+
3
+ MySQL 模块提供了完整的 MySQL 数据库连接和操作功能,支持连接管理、查询执行、事务处理等核心数据库操作。
4
+
5
+ ## 功能概览
6
+
7
+ - **连接管理**: 创建、连接、断开数据库连接
8
+ - **数据查询**: 执行 SELECT 查询操作
9
+ - **数据更新**: 执行 CREATE、INSERT、UPDATE、DELETE 操作
10
+ - **事务支持**: 完整的事务管理功能
11
+ - **参数绑定**: 支持参数化查询,防止 SQL 注入
12
+
13
+ ## 类型定义
14
+
15
+ ### MySQLConfig
16
+
17
+ 数据库连接配置字典。
18
+
19
+ ```python
20
+ from typing import TypedDict, Optional
21
+
22
+ class MySQLConfig(TypedDict):
23
+ host: str # 数据库主机地址
24
+ port: Optional[int] # 数据库端口,默认 3306
25
+ username: str # 用户名
26
+ password: str # 密码
27
+ database: str # 数据库名
28
+ charset: Optional[str] # 字符集,默认 utf8mb4
29
+ connectTimeout: Optional[int] # 连接超时时间,默认 5000 毫秒
30
+ queryTimeout: Optional[int] # 查询超时时间,默认 30000 毫秒
31
+ ```
32
+
33
+ **参数说明:**
34
+
35
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
36
+ | ---------------- | ---- | -------- | ------- | ----------------------------- |
37
+ | `host` | str | 是 | - | 数据库主机地址 |
38
+ | `port` | int | 否 | 3306 | 数据库端口,默认 3306 |
39
+ | `username` | str | 是 | - | 用户名 |
40
+ | `password` | str | 是 | - | 密码 |
41
+ | `database` | str | 是 | - | 数据库名 |
42
+ | `charset` | str | 否 | utf8mb4 | 字符集,默认 utf8mb4 |
43
+ | `connectTimeout` | int | 否 | 5000 | 连接超时时间,默认 5000 毫秒 |
44
+ | `queryTimeout` | int | 否 | 30000 | 查询超时时间,默认 30000 毫秒 |
45
+
46
+ ### MySQLResult
47
+
48
+ 查询结果字典。
49
+
50
+ ```python
51
+ from typing import TypedDict, List, Dict, Any, Optional
52
+
53
+ class MySQLResult(TypedDict):
54
+ rows: List[Dict[str, Any]] # 查询结果数据行
55
+ affectedRows: int # 受影响的行数
56
+ insertId: Optional[int] # 插入ID(仅适用于INSERT操作)
57
+ success: bool # 查询是否成功
58
+ error: Optional[str] # 错误信息
59
+ ```
60
+
61
+ **参数说明:**
62
+
63
+ | 参数名 | 类型 | 描述 |
64
+ | -------------- | -------------------- | ------------------------------- |
65
+ | `rows` | List[Dict[str, Any]] | 查询结果数据行 |
66
+ | `affectedRows` | int | 受影响的行数 |
67
+ | `insertId` | int | 插入 ID(仅适用于 INSERT 操作) |
68
+ | `success` | bool | 查询是否成功 |
69
+ | `error` | str | 错误信息 |
70
+
71
+ ## API 参考
72
+
73
+ ### 连接管理
74
+
75
+ #### connect - 连接到数据库
76
+
77
+ ```python
78
+ def connect(config: MySQLConfig) -> bool
79
+ ```
80
+
81
+ **参数:**
82
+
83
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
84
+ | -------- | ----------- | -------- | ------ | ------------------ |
85
+ | `config` | MySQLConfig | 是 | - | 数据库连接配置对象 |
86
+
87
+ **返回值:**
88
+
89
+ | 类型 | 描述 |
90
+ | ------ | ------------ |
91
+ | `bool` | 是否连接成功 |
92
+
93
+ **示例:**
94
+
95
+ ```python
96
+ from kuaijs import mysql
97
+
98
+ success = mysql.connect({
99
+ "host": "localhost",
100
+ "port": 3306,
101
+ "username": "root",
102
+ "password": "password",
103
+ "database": "test_db",
104
+ "charset": "utf8mb4",
105
+ })
106
+
107
+ if success:
108
+ print("数据库连接成功")
109
+ else:
110
+ print("数据库连接失败")
111
+ ```
112
+
113
+ #### disconnect - 断开数据库连接
114
+
115
+ ```python
116
+ def disconnect() -> None
117
+ ```
118
+
119
+ **示例:**
120
+
121
+ ```python
122
+ from kuaijs import mysql
123
+
124
+ mysql.disconnect()
125
+ print("数据库连接已断开")
126
+ ```
127
+
128
+ #### isConnected - 检查连接状态
129
+
130
+ ```python
131
+ def isConnected() -> bool
132
+ ```
133
+
134
+ **返回值:**
135
+
136
+ | 类型 | 描述 |
137
+ | ------ | ---------- |
138
+ | `bool` | 是否已连接 |
139
+
140
+ **示例:**
141
+
142
+ ```python
143
+ from kuaijs import mysql
144
+
145
+ if mysql.isConnected():
146
+ print("数据库已连接")
147
+ else:
148
+ print("数据库未连接")
149
+ ```
150
+
151
+ ### 数据操作
152
+
153
+ #### query - 执行查询操作
154
+
155
+ 执行 SELECT 查询操作,用于数据检索。
156
+
157
+ ```python
158
+ def query(sql: str, params: List[Any] = []) -> MySQLResult
159
+ ```
160
+
161
+ **参数:**
162
+
163
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
164
+ | -------- | --------- | -------- | ------ | ------------------ |
165
+ | `sql` | str | 是 | - | SQL 查询语句 |
166
+ | `params` | List[Any] | 否 | [] | 查询参数数组,可选 |
167
+
168
+ **返回值:**
169
+
170
+ | 类型 | 描述 |
171
+ | ------------- | ------------ |
172
+ | `MySQLResult` | 查询结果对象 |
173
+
174
+ **示例:**
175
+
176
+ ```python
177
+ from kuaijs import mysql
178
+
179
+ # 简单查询
180
+ result1 = mysql.query("SELECT * FROM users")
181
+ if result1.success:
182
+ print(f"查询到 {len(result1.rows)} 条用户记录")
183
+ for user in result1.rows:
184
+ print(f"用户: {user.get('name')}, 邮箱: {user.get('email')}")
185
+
186
+ # 带参数查询
187
+ result2 = mysql.query("SELECT * FROM users WHERE age > ? AND city = ?", [18, "北京"])
188
+ if result2.success:
189
+ print(f"找到 {len(result2.rows)} 个符合条件的用户")
190
+ else:
191
+ print(f"查询失败: {result2.error}")
192
+ ```
193
+
194
+ #### execute - 执行更新操作
195
+
196
+ 执行 CREATE、INSERT、UPDATE、DELETE 等数据修改操作。
197
+
198
+ ```python
199
+ def execute(sql: str, params: List[Any] = []) -> MySQLResult
200
+ ```
201
+
202
+ **参数:**
203
+
204
+ | 参数名 | 类型 | 是否必填 | 默认值 | 描述 |
205
+ | -------- | --------- | -------- | ------ | -------------- |
206
+ | `sql` | str | 是 | - | SQL 语句 |
207
+ | `params` | List[Any] | 否 | [] | 参数数组,可选 |
208
+
209
+ **返回值:**
210
+
211
+ | 类型 | 描述 |
212
+ | ------------- | ------------ |
213
+ | `MySQLResult` | 执行结果对象 |
214
+
215
+ **示例:**
216
+
217
+ ```python
218
+ from kuaijs import mysql
219
+
220
+ # 创建表
221
+ create_res = mysql.execute("""
222
+ CREATE TABLE IF NOT EXISTS users (
223
+ id INT AUTO_INCREMENT PRIMARY KEY,
224
+ name VARCHAR(255),
225
+ email VARCHAR(255),
226
+ age INT
227
+ )
228
+ """)
229
+ if create_res.success:
230
+ print("用户表创建成功")
231
+ else:
232
+ print(f"用户表创建失败: {create_res.error}")
233
+
234
+ # 插入数据
235
+ insert_res = mysql.execute(
236
+ "INSERT INTO users (name, email, age) VALUES (?, ?, ?)",
237
+ ["张三", "zhangsan@example.com", 25]
238
+ )
239
+ if insert_res.success:
240
+ print(f"用户插入成功,ID: {insert_res.insertId}")
241
+ print(f"影响行数: {insert_res.affectedRows}")
242
+
243
+ # 更新数据
244
+ update_res = mysql.execute("UPDATE users SET age = ? WHERE name = ?", [26, "张三"])
245
+ if update_res.success:
246
+ print(f"更新了 {update_res.affectedRows} 条记录")
247
+
248
+ # 删除数据
249
+ delete_res = mysql.execute("DELETE FROM users WHERE age < ?", [18])
250
+ if delete_res.success:
251
+ print(f"删除了 {delete_res.affectedRows} 条记录")
252
+ else:
253
+ print(f"删除失败: {delete_res.error}")
254
+ ```
255
+
256
+ ### 事务管理
257
+
258
+ #### beginTransaction - 开始事务
259
+
260
+ ```python
261
+ def beginTransaction() -> bool
262
+ ```
263
+
264
+ **返回值:**
265
+
266
+ | 类型 | 描述 |
267
+ | ------ | ---------------- |
268
+ | `bool` | 是否成功开始事务 |
269
+
270
+ **示例:**
271
+
272
+ ```python
273
+ from kuaijs import mysql
274
+
275
+ if mysql.beginTransaction():
276
+ print("事务开始")
277
+ else:
278
+ print("事务开始失败")
279
+ ```
280
+
281
+ #### commit - 提交事务
282
+
283
+ ```python
284
+ def commit() -> bool
285
+ ```
286
+
287
+ **返回值:**
288
+
289
+ | 类型 | 描述 |
290
+ | ------ | ---------------- |
291
+ | `bool` | 是否成功提交事务 |
292
+
293
+ **示例:**
294
+
295
+ ```python
296
+ from kuaijs import mysql
297
+
298
+ if mysql.commit():
299
+ print("事务提交成功")
300
+ else:
301
+ print("事务提交失败")
302
+ ```
303
+
304
+ #### rollback - 回滚事务
305
+
306
+ ```python
307
+ def rollback() -> bool
308
+ ```
309
+
310
+ **返回值:**
311
+
312
+ | 类型 | 描述 |
313
+ | ------ | ---------------- |
314
+ | `bool` | 是否成功回滚事务 |
315
+
316
+ **示例:**
317
+
318
+ ```python
319
+ from kuaijs import mysql
320
+
321
+ if mysql.rollback():
322
+ print("事务回滚成功")
323
+ else:
324
+ print("事务回滚失败")
325
+ ```
326
+
327
+ ## 完整使用示例
328
+
329
+ ### 基本数据库操作
330
+
331
+ ```python
332
+ from kuaijs import mysql
333
+
334
+ # 1. 创建连接配置
335
+ db_config = {
336
+ "host": "localhost",
337
+ "port": 3306,
338
+ "username": "root",
339
+ "password": "password",
340
+ "database": "my_app",
341
+ "charset": "utf8mb4"
342
+ }
343
+
344
+ # 2. 连接数据库
345
+ if mysql.connect(db_config):
346
+ print("数据库连接成功")
347
+
348
+ # 3. 查询数据
349
+ users = mysql.query("SELECT * FROM users WHERE status = ?", ["active"])
350
+ if users.success:
351
+ print(f"找到 {len(users.rows)} 个活跃用户")
352
+
353
+ # 4. 插入新用户
354
+ new_user = mysql.execute(
355
+ "INSERT INTO users (name, email, status) VALUES (?, ?, ?)",
356
+ ["新用户", "newuser@example.com", "active"]
357
+ )
358
+ if new_user.success:
359
+ print(f"新用户创建成功,ID: {new_user.insertId}")
360
+
361
+ # 5. 断开连接
362
+ mysql.disconnect()
363
+ else:
364
+ print("数据库连接失败")
365
+ ```
366
+
367
+ ### 事务处理示例
368
+
369
+ ```python
370
+ from kuaijs import mysql
371
+
372
+ # 转账操作示例
373
+ def transfer_money(from_user_id, to_user_id, amount):
374
+ if not mysql.beginTransaction():
375
+ print("事务开始失败")
376
+ return False
377
+
378
+ try:
379
+ # 扣除转出账户余额
380
+ debit_result = mysql.execute(
381
+ "UPDATE accounts SET balance = balance - ? WHERE user_id = ? AND balance >= ?",
382
+ [amount, from_user_id, amount]
383
+ )
384
+
385
+ if not debit_result.success or debit_result.affectedRows == 0:
386
+ raise Exception("余额不足或扣款失败")
387
+
388
+ # 增加转入账户余额
389
+ credit_result = mysql.execute(
390
+ "UPDATE accounts SET balance = balance + ? WHERE user_id = ?",
391
+ [amount, to_user_id]
392
+ )
393
+
394
+ if not credit_result.success or credit_result.affectedRows == 0:
395
+ raise Exception("转入账户不存在或转账失败")
396
+
397
+ # 记录转账日志
398
+ log_result = mysql.execute(
399
+ "INSERT INTO transfer_logs (from_user, to_user, amount, created_at) VALUES (?, ?, ?, NOW())",
400
+ [from_user_id, to_user_id, amount]
401
+ )
402
+
403
+ if not log_result.success:
404
+ raise Exception("转账日志记录失败")
405
+
406
+ # 提交事务
407
+ if mysql.commit():
408
+ print(f"转账成功: {from_user_id} -> {to_user_id}, 金额: {amount}")
409
+ return True
410
+ else:
411
+ raise Exception("事务提交失败")
412
+
413
+ except Exception as error:
414
+ # 回滚事务
415
+ mysql.rollback()
416
+ print(f"转账失败: {error}")
417
+ return False
418
+
419
+ # 使用示例
420
+ if mysql.isConnected():
421
+ success = transfer_money(1, 2, 100.0)
422
+ if success:
423
+ print("转账操作完成")
424
+ ```
425
+
426
+ ## 注意事项
427
+
428
+ 1. **连接管理**: 使用全局单例连接,确保在应用生命周期内正确管理连接状态
429
+ 2. **参数绑定**: 始终使用参数化查询来防止 SQL 注入攻击
430
+ 3. **事务处理**: 在事务中发生错误时,确保调用 `rollback()` 来回滚事务
431
+ 4. **错误处理**: 检查每个操作的 `success` 字段,并适当处理错误信息
432
+ 5. **资源清理**: 在应用结束时调用 `disconnect()` 来释放数据库连接资源