@wangjs-jacky/ticktick-cli 0.1.0

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 (40) hide show
  1. package/.github/workflows/npm-publish.yml +26 -0
  2. package/CLAUDE.md +34 -0
  3. package/README.md +62 -0
  4. package/README_CN.md +62 -0
  5. package/bin/cli.ts +2 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +1490 -0
  8. package/dist/index.js.map +1 -0
  9. package/docs/oauth-credential-pre-validation.md +253 -0
  10. package/docs/reference/cli-usage-guide.md +587 -0
  11. package/docs/reference/dida365-open-api-zh.md +999 -0
  12. package/docs/reference/dida365-open-api.md +999 -0
  13. package/docs/reference/project-guide.md +63 -0
  14. package/docs/superpowers/plans/2026-04-03-tt-cli-auth.md +1110 -0
  15. package/docs/superpowers/specs/2026-04-03-tt-cli-design.md +142 -0
  16. package/package.json +45 -0
  17. package/skills/tt-cli-guide/SKILL.md +152 -0
  18. package/skills/tt-cli-guide/references/intent-mapping.md +169 -0
  19. package/src/api/client.ts +61 -0
  20. package/src/api/oauth.ts +146 -0
  21. package/src/api/resources.ts +291 -0
  22. package/src/commands/auth.ts +218 -0
  23. package/src/commands/project.ts +303 -0
  24. package/src/commands/task.ts +806 -0
  25. package/src/commands/user.ts +43 -0
  26. package/src/index.ts +46 -0
  27. package/src/types.ts +211 -0
  28. package/src/utils/config.ts +88 -0
  29. package/src/utils/endpoints.ts +22 -0
  30. package/src/utils/format.ts +71 -0
  31. package/src/utils/server.ts +81 -0
  32. package/tests/config.test.ts +87 -0
  33. package/tests/format.test.ts +56 -0
  34. package/tests/oauth.test.ts +42 -0
  35. package/tests/parity-fields.test.ts +89 -0
  36. package/tests/parity-map.ts +184 -0
  37. package/tests/parity.test.ts +101 -0
  38. package/tsconfig.json +22 -0
  39. package/tsup.config.ts +12 -0
  40. package/vitest.config.ts +7 -0
@@ -0,0 +1,999 @@
1
+ # 滴答清单 Open API
2
+
3
+ ## 简介
4
+
5
+ 欢迎使用滴答清单 Open API 文档。滴答清单是一款功能强大的任务管理应用,帮助用户轻松管理和组织日常任务、截止日期和项目。通过滴答清单 Open API,开发者可以将滴答清单的任务管理功能集成到自己的应用中,打造无缝的用户体验。
6
+
7
+ ## 快速开始
8
+
9
+ 使用滴答清单 Open API 前,你需要注册应用并获取 Client ID 和 Client Secret。请访问[滴答清单开发者中心](https://developer.dida365.com/manage)注册应用。注册成功后,你将收到用于请求认证的 Client ID 和 Client Secret。
10
+
11
+ ## 授权
12
+
13
+ ### 获取 Access Token
14
+
15
+ 调用滴答清单 Open API 需要先获取对应用户的 Access Token。滴答清单使用 OAuth2 协议获取 Access Token。
16
+
17
+ #### 第一步
18
+
19
+ 将用户重定向到滴答清单授权页面:`https://dida365.com/oauth/authorize`
20
+
21
+ | 参数名 | 说明 |
22
+ |--------|------|
23
+ | client_id | 应用唯一标识 |
24
+ | scope | 以空格分隔的权限范围,当前可用范围:`tasks:write` `tasks:read` |
25
+ | state | 会原样传递到重定向 URL |
26
+ | redirect_uri | 用户配置的重定向 URL |
27
+ | response_type | 固定值 `code` |
28
+
29
+ 示例:
30
+
31
+ ```
32
+ https://dida365.com/oauth/authorize?scope=scope&client_id=client_id&state=state&redirect_uri=redirect_uri&response_type=code
33
+ ```
34
+
35
+ #### 第二步
36
+
37
+ 用户授权后,滴答清单会将用户重定向回你的应用的 `redirect_uri`,并附带授权码作为查询参数。
38
+
39
+ | 参数名 | 说明 |
40
+ |--------|------|
41
+ | code | 用于后续获取 Access Token 的授权码 |
42
+ | state | 第一步中传递的 state 参数 |
43
+
44
+ #### 第三步
45
+
46
+ 使用授权码换取 Access Token,向 `https://dida365.com/oauth/token` 发送 POST 请求(Content-Type: application/x-www-form-urlencoded):
47
+
48
+ | 参数名 | 说明 |
49
+ |--------|------|
50
+ | client_id | 使用 **Basic Auth** 认证方式放在 **HEADER** 中的用户名 |
51
+ | client_secret | 使用 **Basic Auth** 认证方式放在 **HEADER** 中的密码 |
52
+ | code | 第二步获取的授权码 |
53
+ | grant_type | 授权类型,目前仅支持 `authorization_code` |
54
+ | scope | 以空格分隔的权限范围,当前可用范围:`tasks:write`、`tasks:read` |
55
+ | redirect_uri | 用户配置的重定向 URL |
56
+
57
+ 响应中包含用于 OpenAPI 请求认证的 Access Token:
58
+
59
+ ```json
60
+ {
61
+ "access_token": "access token value"
62
+ }
63
+ ```
64
+
65
+ #### 调用 OpenAPI
66
+
67
+ 在请求头中设置 **Authorization**,值为 **Bearer** `access token value`:
68
+
69
+ ```
70
+ Authorization: Bearer e*****b
71
+ ```
72
+
73
+ ## API 参考
74
+
75
+ 滴答清单 Open API 提供了 RESTful 接口,用于访问和管理用户任务、清单和其他相关资源。API 基于标准 HTTP 协议,支持 JSON 数据格式。
76
+
77
+ ### 任务(Task)
78
+
79
+ #### 根据 Project ID 和 Task ID 获取任务
80
+
81
+ ```
82
+ GET /open/v1/project/{projectId}/task/{taskId}
83
+ ```
84
+
85
+ **参数**
86
+
87
+ | 类型 | 参数名 | 说明 | 数据类型 |
88
+ |------|--------|------|----------|
89
+ | Path | **projectId** *必填* | 项目标识 | string |
90
+ | Path | **taskId** *必填* | 任务标识 | string |
91
+
92
+ **响应**
93
+
94
+ | HTTP 状态码 | 说明 | 数据模型 |
95
+ |-------------|------|----------|
96
+ | 200 | OK | [Task](#task) |
97
+ | 401 | 未授权 | 无内容 |
98
+ | 403 | 禁止访问 | 无内容 |
99
+ | 404 | 未找到 | 无内容 |
100
+
101
+ **示例**
102
+
103
+ 请求:
104
+
105
+ ```http
106
+ GET /open/v1/project/{{projectId}}/task/{{taskId}} HTTP/1.1
107
+ Host: api.dida365.com
108
+ Authorization: Bearer {{token}}
109
+ ```
110
+
111
+ 响应:
112
+
113
+ ```json
114
+ {
115
+ "id": "63b7bebb91c0a5474805fcd4",
116
+ "isAllDay": true,
117
+ "projectId": "6226ff9877acee87727f6bca",
118
+ "title": "任务标题",
119
+ "content": "任务内容",
120
+ "desc": "任务描述",
121
+ "timeZone": "America/Los_Angeles",
122
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
123
+ "startDate": "2019-11-13T03:00:00+0000",
124
+ "dueDate": "2019-11-14T03:00:00+0000",
125
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
126
+ "priority": 1,
127
+ "status": 0,
128
+ "completedTime": "2019-11-13T03:00:00+0000",
129
+ "sortOrder": 12345,
130
+ "items": [
131
+ {
132
+ "id": "6435074647fd2e6387145f20",
133
+ "status": 0,
134
+ "title": "子任务标题",
135
+ "sortOrder": 12345,
136
+ "startDate": "2019-11-13T03:00:00+0000",
137
+ "isAllDay": false,
138
+ "timeZone": "America/Los_Angeles",
139
+ "completedTime": "2019-11-13T03:00:00+0000"
140
+ }
141
+ ]
142
+ }
143
+ ```
144
+
145
+ #### 创建任务
146
+
147
+ ```
148
+ POST /open/v1/task
149
+ ```
150
+
151
+ **参数**
152
+
153
+ | 类型 | 参数名 | 说明 | 数据类型 |
154
+ |------|--------|------|----------|
155
+ | Body | title *必填* | 任务标题 | string |
156
+ | Body | projectId *必填* | 项目 ID | string |
157
+ | Body | content | 任务内容 | string |
158
+ | Body | desc | 清单描述 | string |
159
+ | Body | isAllDay | 是否全天 | boolean |
160
+ | Body | startDate | 开始日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | date |
161
+ | Body | dueDate | 截止日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | date |
162
+ | Body | timeZone | 时间指定的时区 | string |
163
+ | Body | reminders | 任务提醒列表 | list |
164
+ | Body | repeatFlag | 任务重复规则 | string |
165
+ | Body | priority | 任务优先级,默认为 "0" | integer |
166
+ | Body | sortOrder | 任务排序值 | integer |
167
+ | Body | items | 子任务列表 | list |
168
+ | Body | items.title | 子任务标题 | string |
169
+ | Body | items.startDate | 开始日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"` | date |
170
+ | Body | items.isAllDay | 是否全天 | boolean |
171
+ | Body | items.sortOrder | 子任务排序值 | integer |
172
+ | Body | items.timeZone | 开始时间指定的时区 | string |
173
+ | Body | items.status | 子任务完成状态 | integer |
174
+ | Body | items.completedTime | 完成时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | date |
175
+
176
+ **响应**
177
+
178
+ | HTTP 状态码 | 说明 | 数据模型 |
179
+ |-------------|------|----------|
180
+ | 200 | OK | [Task](#task) |
181
+ | 201 | 已创建 | 无内容 |
182
+ | 401 | 未授权 | 无内容 |
183
+ | 403 | 禁止访问 | 无内容 |
184
+ | 404 | 未找到 | 无内容 |
185
+
186
+ **示例**
187
+
188
+ 请求:
189
+
190
+ ```http
191
+ POST /open/v1/task HTTP/1.1
192
+ Host: api.dida365.com
193
+ Content-Type: application/json
194
+ Authorization: Bearer {{token}}
195
+
196
+ {
197
+ "title": "任务标题",
198
+ "projectId": "6226ff9877acee87727f6bca"
199
+ }
200
+ ```
201
+
202
+ 响应:
203
+
204
+ ```json
205
+ {
206
+ "id": "63b7bebb91c0a5474805fcd4",
207
+ "projectId": "6226ff9877acee87727f6bca",
208
+ "title": "任务标题",
209
+ "content": "任务内容",
210
+ "desc": "任务描述",
211
+ "isAllDay": true,
212
+ "startDate": "2019-11-13T03:00:00+0000",
213
+ "dueDate": "2019-11-14T03:00:00+0000",
214
+ "timeZone": "America/Los_Angeles",
215
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
216
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
217
+ "priority": 1,
218
+ "status": 0,
219
+ "completedTime": "2019-11-13T03:00:00+0000",
220
+ "sortOrder": 12345,
221
+ "items": [
222
+ {
223
+ "id": "6435074647fd2e6387145f20",
224
+ "status": 1,
225
+ "title": "子任务标题",
226
+ "sortOrder": 12345,
227
+ "startDate": "2019-11-13T03:00:00+0000",
228
+ "isAllDay": false,
229
+ "timeZone": "America/Los_Angeles",
230
+ "completedTime": "2019-11-13T03:00:00+0000"
231
+ }
232
+ ]
233
+ }
234
+ ```
235
+
236
+ #### 更新任务
237
+
238
+ ```
239
+ POST /open/v1/task/{taskId}
240
+ ```
241
+
242
+ **参数**
243
+
244
+ | 类型 | 参数名 | 说明 | 数据类型 |
245
+ |------|--------|------|----------|
246
+ | Path | **taskId** *必填* | 任务标识 | string |
247
+ | Body | id *必填* | 任务 ID | string |
248
+ | Body | projectId *必填* | 项目 ID | string |
249
+ | Body | title | 任务标题 | string |
250
+ | Body | content | 任务内容 | string |
251
+ | Body | desc | 清单描述 | string |
252
+ | Body | isAllDay | 是否全天 | boolean |
253
+ | Body | startDate | 开始日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | date |
254
+ | Body | dueDate | 截止日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | date |
255
+ | Body | timeZone | 时间指定的时区 | string |
256
+ | Body | reminders | 任务提醒列表 | list |
257
+ | Body | repeatFlag | 任务重复规则 | string |
258
+ | Body | priority | 任务优先级,默认为 "normal" | integer |
259
+ | Body | sortOrder | 任务排序值 | integer |
260
+ | Body | items | 子任务列表 | list |
261
+ | Body | items.title | 子任务标题 | string |
262
+ | Body | items.startDate | 开始日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"` | date |
263
+ | Body | items.isAllDay | 是否全天 | boolean |
264
+ | Body | items.sortOrder | 子任务排序值 | integer |
265
+ | Body | items.timeZone | 开始时间指定的时区 | string |
266
+ | Body | items.status | 子任务完成状态 | integer |
267
+ | Body | items.completedTime | 完成时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | date |
268
+
269
+ **响应**
270
+
271
+ | HTTP 状态码 | 说明 | 数据模型 |
272
+ |-------------|------|----------|
273
+ | 200 | OK | [Task](#task) |
274
+ | 201 | 已创建 | 无内容 |
275
+ | 401 | 未授权 | 无内容 |
276
+ | 403 | 禁止访问 | 无内容 |
277
+ | 404 | 未找到 | 无内容 |
278
+
279
+ **示例**
280
+
281
+ 请求:
282
+
283
+ ```http
284
+ POST /open/v1/task/{{taskId}} HTTP/1.1
285
+ Host: api.dida365.com
286
+ Content-Type: application/json
287
+ Authorization: Bearer {{token}}
288
+
289
+ {
290
+ "id": "{{taskId}}",
291
+ "projectId": "{{projectId}}",
292
+ "title": "任务标题",
293
+ "priority": 1
294
+ }
295
+ ```
296
+
297
+ 响应:
298
+
299
+ ```json
300
+ {
301
+ "id": "63b7bebb91c0a5474805fcd4",
302
+ "projectId": "6226ff9877acee87727f6bca",
303
+ "title": "任务标题",
304
+ "content": "任务内容",
305
+ "desc": "任务描述",
306
+ "isAllDay": true,
307
+ "startDate": "2019-11-13T03:00:00+0000",
308
+ "dueDate": "2019-11-14T03:00:00+0000",
309
+ "timeZone": "America/Los_Angeles",
310
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
311
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
312
+ "priority": 1,
313
+ "status": 0,
314
+ "completedTime": "2019-11-13T03:00:00+0000",
315
+ "sortOrder": 12345,
316
+ "items": [
317
+ {
318
+ "id": "6435074647fd2e6387145f20",
319
+ "status": 1,
320
+ "title": "子任务标题",
321
+ "sortOrder": 12345,
322
+ "startDate": "2019-11-13T03:00:00+0000",
323
+ "isAllDay": false,
324
+ "timeZone": "America/Los_Angeles",
325
+ "completedTime": "2019-11-13T03:00:00+0000"
326
+ }
327
+ ],
328
+ "kind": "CHECKLIST"
329
+ }
330
+ ```
331
+
332
+ #### 完成任务
333
+
334
+ ```
335
+ POST /open/v1/project/{projectId}/task/{taskId}/complete
336
+ ```
337
+
338
+ **参数**
339
+
340
+ | 类型 | 参数名 | 说明 | 数据类型 |
341
+ |------|--------|------|----------|
342
+ | Path | **projectId** *必填* | 项目标识 | string |
343
+ | Path | **taskId** *必填* | 任务标识 | string |
344
+
345
+ **响应**
346
+
347
+ | HTTP 状态码 | 说明 | 数据模型 |
348
+ |-------------|------|----------|
349
+ | 200 | OK | 无内容 |
350
+ | 201 | 已创建 | 无内容 |
351
+ | 401 | 未授权 | 无内容 |
352
+ | 403 | 禁止访问 | 无内容 |
353
+ | 404 | 未找到 | 无内容 |
354
+
355
+ **示例**
356
+
357
+ 请求:
358
+
359
+ ```http
360
+ POST /open/v1/project/{{projectId}}/task/{{taskId}}/complete HTTP/1.1
361
+ Host: api.dida365.com
362
+ Authorization: Bearer {{token}}
363
+ ```
364
+
365
+ #### 删除任务
366
+
367
+ ```
368
+ DELETE /open/v1/project/{projectId}/task/{taskId}
369
+ ```
370
+
371
+ **参数**
372
+
373
+ | 类型 | 参数名 | 说明 | 数据类型 |
374
+ |------|--------|------|----------|
375
+ | Path | **projectId** *必填* | 项目标识 | string |
376
+ | Path | **taskId** *必填* | 任务标识 | string |
377
+
378
+ **响应**
379
+
380
+ | HTTP 状态码 | 说明 | 数据模型 |
381
+ |-------------|------|----------|
382
+ | 200 | OK | 无内容 |
383
+ | 201 | 已创建 | 无内容 |
384
+ | 401 | 未授权 | 无内容 |
385
+ | 403 | 禁止访问 | 无内容 |
386
+ | 404 | 未找到 | 无内容 |
387
+
388
+ **示例**
389
+
390
+ 请求:
391
+
392
+ ```http
393
+ DELETE /open/v1/project/{{projectId}}/task/{{taskId}} HTTP/1.1
394
+ Host: api.dida365.com
395
+ Authorization: Bearer {{token}}
396
+ ```
397
+
398
+ #### 移动任务
399
+
400
+ ```
401
+ POST /open/v1/task/move
402
+ ```
403
+
404
+ 在项目之间移动一个或多个任务。
405
+
406
+ **请求体**
407
+
408
+ JSON 数组,包含任务移动操作。
409
+
410
+ | 类型 | 参数名 | 说明 | 数据类型 |
411
+ |------|--------|------|----------|
412
+ | Body | **fromProjectId** *必填* | 源项目 ID | string |
413
+ | Body | **toProjectId** *必填* | 目标项目 ID | string |
414
+ | Body | **taskId** *必填* | 要移动的任务 ID | string |
415
+
416
+ **响应**
417
+
418
+ | HTTP 状态码 | 说明 | 数据模型 |
419
+ |-------------|------|----------|
420
+ | 200 | OK | 返回移动结果数组,包含任务 ID 和新的 etag |
421
+ | 201 | 已创建 | 无内容 |
422
+ | 401 | 未授权 | 无内容 |
423
+ | 403 | 禁止访问 | 无内容 |
424
+ | 404 | 未找到 | 无内容 |
425
+
426
+ **示例**
427
+
428
+ 请求:
429
+
430
+ ```http
431
+ POST /open/v1/task/move HTTP/1.1
432
+ Host: api.dida365.com
433
+ Authorization: Bearer {{token}}
434
+
435
+ [
436
+ {
437
+ "fromProjectId": "69a850ef1c20d2030e148fdd",
438
+ "toProjectId": "69a850f41c20d2030e148fdf",
439
+ "taskId": "69a850f8b9061f374d54a046"
440
+ }
441
+ ]
442
+ ```
443
+
444
+ 响应:
445
+
446
+ ```json
447
+ [
448
+ {
449
+ "id": "69a850f8b9061f374d54a046",
450
+ "etag": "43p2zso1"
451
+ }
452
+ ]
453
+ ```
454
+
455
+ #### 获取已完成任务列表
456
+
457
+ ```
458
+ POST /open/v1/task/completed
459
+ ```
460
+
461
+ 获取指定项目和时间范围内已标记为完成的任务列表。
462
+
463
+ **请求体**
464
+
465
+ JSON 对象,包含筛选条件。所有字段均为可选,但建议至少提供一个筛选条件以缩小结果范围。
466
+
467
+ | 类型 | 参数名 | 说明 | 数据类型 |
468
+ |------|--------|------|----------|
469
+ | Body | **projectIds** | 项目标识列表 | list |
470
+ | Body | **startDate** | 时间范围起始(包含)。筛选 completedTime >= startDate 的任务 | date |
471
+ | Body | **endDate** | 时间范围截止(包含)。筛选 completedTime <= endDate 的任务 | date |
472
+
473
+ **响应**
474
+
475
+ | HTTP 状态码 | 说明 | 数据模型 |
476
+ |-------------|------|----------|
477
+ | 200 | OK | < [Task](#task) > 数组 |
478
+ | 201 | 已创建 | 无内容 |
479
+ | 401 | 未授权 | 无内容 |
480
+ | 403 | 禁止访问 | 无内容 |
481
+ | 404 | 未找到 | 无内容 |
482
+
483
+ **示例**
484
+
485
+ 请求:
486
+
487
+ ```http
488
+ POST /open/v1/task/completed HTTP/1.1
489
+ Host: api.dida365.com
490
+ Authorization: Bearer {{token}}
491
+
492
+ {
493
+ "projectIds": ["69a850f41c20d2030e148fdf"],
494
+ "startDate": "2026-03-01T00:58:20.000+0000",
495
+ "endDate": "2026-03-05T10:58:20.000+0000"
496
+ }
497
+ ```
498
+
499
+ 响应:
500
+
501
+ ```json
502
+ [
503
+ {
504
+ "id": "69a850f8b9061f374d54a046",
505
+ "projectId": "69a850f41c20d2030e148fdf",
506
+ "sortOrder": -1099511627776,
507
+ "title": "update",
508
+ "content": "",
509
+ "timeZone": "America/Los_Angeles",
510
+ "isAllDay": false,
511
+ "priority": 0,
512
+ "completedTime": "2026-03-04T23:58:20.000+0000",
513
+ "status": 2,
514
+ "etag": "t3kc5m5f",
515
+ "kind": "TEXT"
516
+ }
517
+ ]
518
+ ```
519
+
520
+ #### 筛选任务
521
+
522
+ ```
523
+ POST /open/v1/task/filter
524
+ ```
525
+
526
+ 根据高级筛选条件获取任务列表,包括项目范围、日期范围、优先级、标签和状态。
527
+
528
+ **参数**
529
+
530
+ | 类型 | 参数名 | 说明 | 数据类型 |
531
+ |------|--------|------|----------|
532
+ | Body | **projectIds** | 筛选属于指定项目 ID 的任务 | list |
533
+ | Body | **startDate** | 筛选 startDate >= startDate 的任务 | date |
534
+ | Body | **endDate** | 筛选 startDate <= endDate 的任务 | date |
535
+ | Body | **priority** | 按优先级筛选。有效值:无(0)、低(1)、中(3)、高(5) | list |
536
+ | Body | **tag** | 筛选包含所有指定标签的任务 | list |
537
+ | Body | **status** | 按状态码筛选任务(如 `[0]` 表示未完成,`[2]` 表示已完成) | list |
538
+
539
+ **响应**
540
+
541
+ | HTTP 状态码 | 说明 | 数据模型 |
542
+ |-------------|------|----------|
543
+ | 200 | OK | < [Task](#task) > 数组 |
544
+ | 201 | 已创建 | 无内容 |
545
+ | 401 | 未授权 | 无内容 |
546
+ | 403 | 禁止访问 | 无内容 |
547
+ | 404 | 未找到 | 无内容 |
548
+
549
+ **示例**
550
+
551
+ 请求:
552
+
553
+ ```http
554
+ POST /open/v1/task/filter HTTP/1.1
555
+ Host: api.dida365.com
556
+ Authorization: Bearer {{token}}
557
+
558
+ {
559
+ "projectIds": ["69a850f41c20d2030e148fdf"],
560
+ "startDate": "2026-03-01T00:58:20.000+0000",
561
+ "endDate": "2026-03-06T10:58:20.000+0000",
562
+ "priority": [0],
563
+ "tag": ["urgent"],
564
+ "status": [0]
565
+ }
566
+ ```
567
+
568
+ 响应:
569
+
570
+ ```json
571
+ [
572
+ {
573
+ "id": "69a85785b9061f3c217e9de6",
574
+ "projectId": "69a850f41c20d2030e148fdf",
575
+ "sortOrder": -2199023255552,
576
+ "title": "task1",
577
+ "content": "",
578
+ "desc": "",
579
+ "startDate": "2026-03-05T00:00:00.000+0000",
580
+ "dueDate": "2026-03-05T00:00:00.000+0000",
581
+ "timeZone": "America/Los_Angeles",
582
+ "isAllDay": false,
583
+ "priority": 0,
584
+ "status": 0,
585
+ "tags": ["tag"],
586
+ "etag": "cic6e3cg",
587
+ "kind": "TEXT"
588
+ },
589
+ {
590
+ "id": "69a8ea79b9061f4d803f6b32",
591
+ "projectId": "69a850f41c20d2030e148fdf",
592
+ "sortOrder": -3298534883328,
593
+ "title": "task2",
594
+ "content": "",
595
+ "startDate": "2026-03-05T00:00:00.000+0000",
596
+ "dueDate": "2026-03-05T00:00:00.000+0000",
597
+ "timeZone": "America/Los_Angeles",
598
+ "isAllDay": false,
599
+ "priority": 0,
600
+ "status": 0,
601
+ "tags": ["tag"],
602
+ "etag": "0nvpcxzh",
603
+ "kind": "TEXT"
604
+ }
605
+ ]
606
+ ```
607
+
608
+ ### 项目(Project)
609
+
610
+ #### 获取用户所有项目
611
+
612
+ ```
613
+ GET /open/v1/project
614
+ ```
615
+
616
+ **响应**
617
+
618
+ | HTTP 状态码 | 说明 | 数据模型 |
619
+ |-------------|------|----------|
620
+ | 200 | OK | < [Project](#project) > 数组 |
621
+ | 401 | 未授权 | 无内容 |
622
+ | 403 | 禁止访问 | 无内容 |
623
+ | 404 | 未找到 | 无内容 |
624
+
625
+ **示例**
626
+
627
+ 请求:
628
+
629
+ ```http
630
+ GET /open/v1/project HTTP/1.1
631
+ Host: api.dida365.com
632
+ Authorization: Bearer {{token}}
633
+ ```
634
+
635
+ 响应:
636
+
637
+ ```json
638
+ [
639
+ {
640
+ "id": "6226ff9877acee87727f6bca",
641
+ "name": "项目名称",
642
+ "color": "#F18181",
643
+ "closed": false,
644
+ "groupId": "6436176a47fd2e05f26ef56e",
645
+ "viewMode": "list",
646
+ "permission": "write",
647
+ "kind": "TASK"
648
+ }
649
+ ]
650
+ ```
651
+
652
+ #### 根据 ID 获取项目
653
+
654
+ ```
655
+ GET /open/v1/project/{projectId}
656
+ ```
657
+
658
+ **参数**
659
+
660
+ | 类型 | 参数名 | 说明 | 数据类型 |
661
+ |------|--------|------|----------|
662
+ | Path | **projectId** *必填* | 项目标识 | string |
663
+
664
+ **响应**
665
+
666
+ | HTTP 状态码 | 说明 | 数据模型 |
667
+ |-------------|------|----------|
668
+ | 200 | OK | [Project](#project) |
669
+ | 401 | 未授权 | 无内容 |
670
+ | 403 | 禁止访问 | 无内容 |
671
+ | 404 | 未找到 | 无内容 |
672
+
673
+ **示例**
674
+
675
+ 请求:
676
+
677
+ ```http
678
+ GET /open/v1/project/{{projectId}} HTTP/1.1
679
+ Host: api.dida365.com
680
+ Authorization: Bearer {{token}}
681
+ ```
682
+
683
+ 响应:
684
+
685
+ ```json
686
+ {
687
+ "id": "6226ff9877acee87727f6bca",
688
+ "name": "项目名称",
689
+ "color": "#F18181",
690
+ "closed": false,
691
+ "groupId": "6436176a47fd2e05f26ef56e",
692
+ "viewMode": "list",
693
+ "kind": "TASK"
694
+ }
695
+ ```
696
+
697
+ #### 获取项目及其数据
698
+
699
+ ```
700
+ GET /open/v1/project/{projectId}/data
701
+ ```
702
+
703
+ **参数**
704
+
705
+ | 类型 | 参数名 | 说明 | 数据类型 |
706
+ |------|--------|------|----------|
707
+ | Path | **projectId** *必填* | 项目标识,支持 "inbox" | string |
708
+
709
+ **响应**
710
+
711
+ | HTTP 状态码 | 说明 | 数据模型 |
712
+ |-------------|------|----------|
713
+ | 200 | OK | [ProjectData](#projectdata) |
714
+ | 401 | 未授权 | 无内容 |
715
+ | 403 | 禁止访问 | 无内容 |
716
+ | 404 | 未找到 | 无内容 |
717
+
718
+ **示例**
719
+
720
+ 请求:
721
+
722
+ ```http
723
+ GET /open/v1/project/{{projectId}}/data HTTP/1.1
724
+ Host: api.dida365.com
725
+ Authorization: Bearer {{token}}
726
+ ```
727
+
728
+ 响应:
729
+
730
+ ```json
731
+ {
732
+ "project": {
733
+ "id": "6226ff9877acee87727f6bca",
734
+ "name": "项目名称",
735
+ "color": "#F18181",
736
+ "closed": false,
737
+ "groupId": "6436176a47fd2e05f26ef56e",
738
+ "viewMode": "list",
739
+ "kind": "TASK"
740
+ },
741
+ "tasks": [
742
+ {
743
+ "id": "6247ee29630c800f064fd145",
744
+ "isAllDay": true,
745
+ "projectId": "6226ff9877acee87727f6bca",
746
+ "title": "任务标题",
747
+ "content": "任务内容",
748
+ "desc": "任务描述",
749
+ "timeZone": "America/Los_Angeles",
750
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
751
+ "startDate": "2019-11-13T03:00:00+0000",
752
+ "dueDate": "2019-11-14T03:00:00+0000",
753
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
754
+ "priority": 1,
755
+ "status": 0,
756
+ "completedTime": "2019-11-13T03:00:00+0000",
757
+ "sortOrder": 12345,
758
+ "items": [
759
+ {
760
+ "id": "6435074647fd2e6387145f20",
761
+ "status": 0,
762
+ "title": "子任务标题",
763
+ "sortOrder": 12345,
764
+ "startDate": "2019-11-13T03:00:00+0000",
765
+ "isAllDay": false,
766
+ "timeZone": "America/Los_Angeles",
767
+ "completedTime": "2019-11-13T03:00:00+0000"
768
+ }
769
+ ]
770
+ }
771
+ ],
772
+ "columns": [
773
+ {
774
+ "id": "6226ff9e76e5fc39f2862d1b",
775
+ "projectId": "6226ff9877acee87727f6bca",
776
+ "name": "列名称",
777
+ "sortOrder": 0
778
+ }
779
+ ]
780
+ }
781
+ ```
782
+
783
+ #### 创建项目
784
+
785
+ ```
786
+ POST /open/v1/project
787
+ ```
788
+
789
+ **参数**
790
+
791
+ | 类型 | 参数名 | 说明 | 数据类型 |
792
+ |------|--------|------|----------|
793
+ | Body | name *必填* | 项目名称 | string |
794
+ | Body | color | 项目颜色,如 `"#F18181"` | string |
795
+ | Body | sortOrder | 项目排序值 | integer (int64) |
796
+ | Body | viewMode | 视图模式:`"list"`、`"kanban"`、`"timeline"` | string |
797
+ | Body | kind | 项目类型:`"TASK"`、`"NOTE"` | string |
798
+
799
+ **响应**
800
+
801
+ | HTTP 状态码 | 说明 | 数据模型 |
802
+ |-------------|------|----------|
803
+ | 200 | OK | [Project](#project) |
804
+ | 201 | 已创建 | 无内容 |
805
+ | 401 | 未授权 | 无内容 |
806
+ | 403 | 禁止访问 | 无内容 |
807
+ | 404 | 未找到 | 无内容 |
808
+
809
+ **示例**
810
+
811
+ 请求:
812
+
813
+ ```http
814
+ POST /open/v1/project HTTP/1.1
815
+ Host: api.dida365.com
816
+ Content-Type: application/json
817
+ Authorization: Bearer {{token}}
818
+
819
+ {
820
+ "name": "项目名称",
821
+ "color": "#F18181",
822
+ "viewMode": "list",
823
+ "kind": "task"
824
+ }
825
+ ```
826
+
827
+ 响应:
828
+
829
+ ```json
830
+ {
831
+ "id": "6226ff9877acee87727f6bca",
832
+ "name": "项目名称",
833
+ "color": "#F18181",
834
+ "sortOrder": 0,
835
+ "viewMode": "list",
836
+ "kind": "TASK"
837
+ }
838
+ ```
839
+
840
+ #### 更新项目
841
+
842
+ ```
843
+ POST /open/v1/project/{projectId}
844
+ ```
845
+
846
+ **参数**
847
+
848
+ | 类型 | 参数名 | 说明 | 数据类型 |
849
+ |------|--------|------|----------|
850
+ | Path | projectId *必填* | 项目标识 | string |
851
+ | Body | name | 项目名称 | string |
852
+ | Body | color | 项目颜色 | string |
853
+ | Body | sortOrder | 排序值,默认 0 | integer (int64) |
854
+ | Body | viewMode | 视图模式:`"list"`、`"kanban"`、`"timeline"` | string |
855
+ | Body | kind | 项目类型:`"TASK"`、`"NOTE"` | string |
856
+
857
+ **响应**
858
+
859
+ | HTTP 状态码 | 说明 | 数据模型 |
860
+ |-------------|------|----------|
861
+ | 200 | OK | [Project](#project) |
862
+ | 201 | 已创建 | 无内容 |
863
+ | 401 | 未授权 | 无内容 |
864
+ | 403 | 禁止访问 | 无内容 |
865
+ | 404 | 未找到 | 无内容 |
866
+
867
+ **示例**
868
+
869
+ 请求:
870
+
871
+ ```http
872
+ POST /open/v1/project/{{projectId}} HTTP/1.1
873
+ Host: api.dida365.com
874
+ Content-Type: application/json
875
+ Authorization: Bearer {{token}}
876
+
877
+ {
878
+ "name": "项目名称",
879
+ "color": "#F18181",
880
+ "viewMode": "list",
881
+ "kind": "TASK"
882
+ }
883
+ ```
884
+
885
+ 响应:
886
+
887
+ ```json
888
+ {
889
+ "id": "6226ff9877acee87727f6bca",
890
+ "name": "项目名称",
891
+ "color": "#F18181",
892
+ "sortOrder": 0,
893
+ "viewMode": "list",
894
+ "kind": "TASK"
895
+ }
896
+ ```
897
+
898
+ #### 删除项目
899
+
900
+ ```
901
+ DELETE /open/v1/project/{projectId}
902
+ ```
903
+
904
+ **参数**
905
+
906
+ | 类型 | 参数名 | 说明 | 数据类型 |
907
+ |------|--------|------|----------|
908
+ | Path | **projectId** *必填* | 项目标识 | string |
909
+
910
+ **响应**
911
+
912
+ | HTTP 状态码 | 说明 | 数据模型 |
913
+ |-------------|------|----------|
914
+ | 200 | OK | 无内容 |
915
+ | 401 | 未授权 | 无内容 |
916
+ | 403 | 禁止访问 | 无内容 |
917
+ | 404 | 未找到 | 无内容 |
918
+
919
+ **示例**
920
+
921
+ 请求:
922
+
923
+ ```http
924
+ DELETE /open/v1/project/{{projectId}} HTTP/1.1
925
+ Host: api.dida365.com
926
+ Authorization: Bearer {{token}}
927
+ ```
928
+
929
+ ## 数据模型
930
+
931
+ ### ChecklistItem(清单项)
932
+
933
+ | 字段名 | 说明 | 数据类型 |
934
+ |--------|------|----------|
935
+ | **id** | 子任务标识 | string |
936
+ | **title** | 子任务标题 | string |
937
+ | **status** | 完成状态。正常:`0`,已完成:`1` | integer (int32) |
938
+ | **completedTime** | 完成时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | string (date-time) |
939
+ | **isAllDay** | 是否全天 | boolean |
940
+ | **sortOrder** | 排序值。**示例**:`234444` | integer (int64) |
941
+ | **startDate** | 开始日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | string (date-time) |
942
+ | **timeZone** | 时区。**示例**:`"America/Los_Angeles"` | string |
943
+
944
+ ### Task(任务)
945
+
946
+ | 字段名 | 说明 | 数据类型 |
947
+ |--------|------|----------|
948
+ | **id** | 任务标识 | string |
949
+ | **projectId** | 所属项目 ID | string |
950
+ | **title** | 任务标题 | string |
951
+ | **isAllDay** | 是否全天 | boolean |
952
+ | **completedTime** | 完成时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | string (date-time) |
953
+ | **content** | 任务内容 | string |
954
+ | **desc** | 清单描述 | string |
955
+ | **dueDate** | 截止日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | string (date-time) |
956
+ | **items** | 子任务列表 | < [ChecklistItem](#checklistitem清单项) > 数组 |
957
+ | **priority** | 优先级。无:`0`,低:`1`,中:`3`,高:`5` | integer (int32) |
958
+ | **reminders** | 提醒触发器列表。**示例**:`["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"]` | < string > 数组 |
959
+ | **repeatFlag** | 重复规则。**示例**:`"RRULE:FREQ=DAILY;INTERVAL=1"` | string |
960
+ | **sortOrder** | 排序值。**示例**:`12345` | integer (int64) |
961
+ | **startDate** | 开始日期时间,格式:`"yyyy-MM-dd'T'HH:mm:ssZ"`。**示例**:`"2019-11-13T03:00:00+0000"` | string (date-time) |
962
+ | **status** | 完成状态。正常:`0`,已完成:`2` | integer (int32) |
963
+ | **timeZone** | 时区。**示例**:`"America/Los_Angeles"` | string |
964
+ | **kind** | 类型:`"TEXT"`、`"NOTE"`、`"CHECKLIST"` | string |
965
+
966
+ ### Project(项目)
967
+
968
+ | 字段名 | 说明 | 数据类型 |
969
+ |--------|------|----------|
970
+ | **id** | 项目标识 | string |
971
+ | **name** | 项目名称 | string |
972
+ | **color** | 项目颜色 | string |
973
+ | **sortOrder** | 排序值 | integer (int64) |
974
+ | **closed** | 是否已关闭 | boolean |
975
+ | **groupId** | 项目分组标识 | string |
976
+ | **viewMode** | 视图模式:`"list"`、`"kanban"`、`"timeline"` | string |
977
+ | **permission** | 权限:`"read"`、`"write"` 或 `"comment"` | string |
978
+ | **kind** | 类型:`"TASK"` 或 `"NOTE"` | string |
979
+
980
+ ### Column(列)
981
+
982
+ | 字段名 | 说明 | 数据类型 |
983
+ |--------|------|----------|
984
+ | id | 列标识 | string |
985
+ | projectId | 项目标识 | string |
986
+ | name | 列名称 | string |
987
+ | sortOrder | 排序值 | integer (int64) |
988
+
989
+ ### ProjectData(项目数据)
990
+
991
+ | 字段名 | 说明 | 数据类型 |
992
+ |--------|------|----------|
993
+ | project | 项目信息 | [Project](#project项目) |
994
+ | tasks | 项目下未完成的任务 | < [Task](#task任务) > 数组 |
995
+ | columns | 项目下的列 | < [Column](#column列) > 数组 |
996
+
997
+ ## 反馈与支持
998
+
999
+ 如果你对滴答清单 Open API 文档有任何问题或反馈,请通过 [support@dida365.com](mailto:support@dida365.com) 联系我们。感谢你选择滴答清单!