From 36c506f4bf98af61b9bf4dbb67bca65987559f0a Mon Sep 17 00:00:00 2001 From: nepiedg <806669289@qq.com.com> Date: Fri, 17 Apr 2026 10:33:33 +0000 Subject: [PATCH] feat(note): add audio upload and sharing functionality - Introduced `note_audio` table for storing audio attachments related to notes. - Implemented audio upload endpoint in `Note` controller to handle audio file uploads. - Added sharing functionality with `note_share` table to manage share tokens and view counts. - Updated API routes to include endpoints for audio uploads and share creation. - Enhanced documentation to reflect new audio and sharing features. --- app/note/controller/v1/Meta.php | 2 +- app/note/controller/v1/Note.php | 25 +++ app/note/controller/v1/Share.php | 51 ++++++ app/note/model/NoteAudio.php | 27 +++ app/note/model/NoteShare.php | 36 ++++ app/note/route/app.php | 4 + app/note/service/NoteService.php | 162 ++++++++++++++++++ app/note/service/PlanningService.php | 19 ++ database.sql | 35 ++++ docs/note_api.md | 149 +++++++++++++++- .../00a3e4cf9f27ce67356ad755410d3e08.aac | Bin 0 -> 16349 bytes .../42e8d9f6af7322edc1ac68496957e305.aac | 1 + .../788b3d3555ac0b10f0d8dc1438aebd1a.aac | Bin 0 -> 8959 bytes .../8c3d9502811ecbdb8087f91a64150cce.aac | Bin 0 -> 17396 bytes route/app.php | 4 + 15 files changed, 507 insertions(+), 8 deletions(-) create mode 100644 app/note/controller/v1/Share.php create mode 100644 app/note/model/NoteAudio.php create mode 100644 app/note/model/NoteShare.php create mode 100644 public/storage/note/audio/20260417/00a3e4cf9f27ce67356ad755410d3e08.aac create mode 100644 public/storage/note/audio/20260417/42e8d9f6af7322edc1ac68496957e305.aac create mode 100644 public/storage/note/audio/20260417/788b3d3555ac0b10f0d8dc1438aebd1a.aac create mode 100644 public/storage/note/audio/20260417/8c3d9502811ecbdb8087f91a64150cce.aac diff --git a/app/note/controller/v1/Meta.php b/app/note/controller/v1/Meta.php index c0e6d38..5afdb63 100644 --- a/app/note/controller/v1/Meta.php +++ b/app/note/controller/v1/Meta.php @@ -11,7 +11,7 @@ use think\App; /** * 笔记模块元信息控制器 */ -class Meta extends BaseController +class c extends BaseController { /** * @var PlanningService diff --git a/app/note/controller/v1/Note.php b/app/note/controller/v1/Note.php index e7ba74a..3d263c1 100644 --- a/app/note/controller/v1/Note.php +++ b/app/note/controller/v1/Note.php @@ -8,6 +8,7 @@ use app\note\controller\BaseController; use app\note\service\NoteService; use think\App; use think\exception\ValidateException; +use think\Request; /** * 笔记控制器 @@ -153,4 +154,28 @@ class Note extends BaseController return Response::error($e->getMessage(), $e->getCode() ?: 500); } } + + /** + * 上传笔记录音 + * POST /note/v1/item/audio/:id + */ + public function audio(Request $request, int $id) + { + try { + if ($id <= 0) { + return Response::error('笔记 ID 不正确', 400); + } + + $file = $request->file('audio'); + if (!$file) { + return Response::error('录音文件不能为空', 400); + } + + $durationMs = (int) $request->post('audio_duration_ms', 0); + $result = $this->noteService->uploadAudio($this->getCurrentNoteUserId(), $id, $file, $durationMs); + return Response::success($result, '上传成功'); + } catch (\Throwable $e) { + return Response::error($e->getMessage(), $e->getCode() ?: 500); + } + } } diff --git a/app/note/controller/v1/Share.php b/app/note/controller/v1/Share.php new file mode 100644 index 0000000..c34cbd9 --- /dev/null +++ b/app/note/controller/v1/Share.php @@ -0,0 +1,51 @@ +noteService = new NoteService(); + } + + public function create(int $id) + { + try { + if ($id <= 0) { + return Response::error('笔记 ID 不正确', 400); + } + + $result = $this->noteService->createShare($this->getCurrentNoteUserId(), $id); + return Response::success($result, '分享已生成'); + } catch (\Throwable $e) { + return Response::error($e->getMessage(), $e->getCode() ?: 500); + } + } + + public function read(string $token) + { + try { + if (trim($token) === '') { + return Response::error('分享标识不能为空', 400); + } + + $result = $this->noteService->getSharedDetail(trim($token)); + return Response::success($result); + } catch (\Throwable $e) { + return Response::error($e->getMessage(), $e->getCode() ?: 500); + } + } +} diff --git a/app/note/model/NoteAudio.php b/app/note/model/NoteAudio.php new file mode 100644 index 0000000..ea1759b --- /dev/null +++ b/app/note/model/NoteAudio.php @@ -0,0 +1,27 @@ +order('id', 'desc') + ->find(); + } +} diff --git a/app/note/model/NoteShare.php b/app/note/model/NoteShare.php new file mode 100644 index 0000000..522b65d --- /dev/null +++ b/app/note/model/NoteShare.php @@ -0,0 +1,36 @@ +where('note_user_id', $noteUserId) + ->where('status', 1) + ->order('id', 'desc') + ->find(); + } + + public static function findByToken(string $token): ?self + { + return self::where('share_token', $token) + ->where('status', 1) + ->find(); + } +} diff --git a/app/note/route/app.php b/app/note/route/app.php index 9113e2e..52313dd 100644 --- a/app/note/route/app.php +++ b/app/note/route/app.php @@ -6,6 +6,7 @@ use app\note\controller\v1\Ai; use app\note\controller\v1\Auth; use app\note\controller\v1\Meta; use app\note\controller\v1\Note; +use app\note\controller\v1\Share; /** * note 应用路由 @@ -19,6 +20,7 @@ use app\note\controller\v1\Note; // v1 笔记模块接口规划(公开) Route::get('v1/meta/interfaces', [Meta::class, 'interfaces']); Route::post('v1/auth/wechat-login', [Auth::class, 'wechatLogin']); +Route::get('v1/share/read/:token', [Share::class, 'read']); // v1 笔记模块接口(需登录) Route::group('v1', function () { @@ -30,7 +32,9 @@ Route::group('v1', function () { Route::post('item/update/:id', [Note::class, 'update']); Route::post('item/delete/:id', [Note::class, 'delete']); Route::post('item/transcript/:id', [Note::class, 'transcript']); + Route::post('item/audio/:id', [Note::class, 'audio']); Route::post('ai/summary/:id', [Ai::class, 'summary']); Route::get('ai/summary/:id', [Ai::class, 'readSummary']); + Route::post('share/create/:id', [Share::class, 'create']); })->middleware(\app\api\middleware\Auth::class); diff --git a/app/note/service/NoteService.php b/app/note/service/NoteService.php index 21be883..1731d6b 100644 --- a/app/note/service/NoteService.php +++ b/app/note/service/NoteService.php @@ -3,9 +3,13 @@ declare(strict_types=1); namespace app\note\service; +use app\note\model\NoteAudio; use app\note\model\NoteAiSummary; use app\note\model\NoteItem; +use app\note\model\NoteShare; use app\note\model\NoteTranscript; +use think\File; +use think\facade\Filesystem; /** * note 模块笔记服务 @@ -98,8 +102,10 @@ class NoteService { $note = $this->getOwnedNote($noteUserId, $id); $summary = NoteAiSummary::findLatestByNoteId($id); + $audio = NoteAudio::findLatestByNoteId($id); $result = $this->formatNoteItem($note); + $result['audio'] = $audio ? $this->formatAudio($audio) : null; $result['summary'] = $summary ? [ 'summary_id' => (int) $summary->id, 'summary_type' => (string) $summary->summary_type, @@ -216,6 +222,131 @@ class NoteService ]; } + /** + * 上传录音文件 + * + * @param int $noteUserId + * @param int $id + * @param File $file + * @param int $durationMs + * @return array + * @throws \Exception + */ + public function uploadAudio(int $noteUserId, int $id, File $file, int $durationMs = 0): array + { + $note = $this->getOwnedNote($noteUserId, $id); + $savedPath = str_replace('\\', '/', Filesystem::disk('public')->putFile('note/audio', $file)); + $now = time(); + + $audio = NoteAudio::findLatestByNoteId($id); + if (!$audio) { + $audio = new NoteAudio(); + $audio->note_id = $id; + $audio->created_at = $now; + } + + $audio->disk = 'public'; + $audio->file_path = $savedPath; + $audio->file_url = $this->buildPublicFileUrl($savedPath); + $audio->file_size = (int) $file->getSize(); + $audio->mime_type = (string) $file->getMime(); + $audio->duration_ms = max(0, $durationMs); + $audio->updated_at = $now; + $audio->save(); + + $note->audio_duration_ms = max((int) $note->audio_duration_ms, (int) $audio->duration_ms); + if ($note->source_type === 'text') { + $note->source_type = trim((string) $note->content) !== '' ? 'mix' : 'audio'; + } + $note->updated_at = $now; + $note->save(); + + return $this->formatAudio($audio); + } + + /** + * 创建分享 + * + * @param int $noteUserId + * @param int $id + * @return array + * @throws \Exception + */ + public function createShare(int $noteUserId, int $id): array + { + $note = $this->getOwnedNote($noteUserId, $id); + $share = NoteShare::findActiveByNote($id, $noteUserId); + $now = time(); + + if (!$share) { + $share = new NoteShare(); + $share->note_id = $id; + $share->note_user_id = $noteUserId; + $share->share_token = bin2hex(random_bytes(16)); + $share->view_count = 0; + $share->status = 1; + $share->created_at = $now; + } + + $share->title = (string) $note->title; + $share->updated_at = $now; + $share->save(); + + return [ + 'note_id' => $id, + 'share_token' => (string) $share->share_token, + 'share_path' => '/pages/note/edit?share_token=' . $share->share_token, + 'title' => (string) $note->title, + ]; + } + + /** + * 获取分享详情 + * + * @param string $token + * @return array + * @throws \Exception + */ + public function getSharedDetail(string $token): array + { + $share = NoteShare::findByToken($token); + if (!$share) { + throw new \Exception('分享内容不存在或已失效', 404); + } + + if ((int) $share->expired_at > 0 && (int) $share->expired_at < time()) { + throw new \Exception('分享已过期', 410); + } + + $note = NoteItem::where('id', (int) $share->note_id) + ->where('deleted_at', 0) + ->find(); + if (!$note) { + throw new \Exception('分享内容不存在', 404); + } + + $summary = NoteAiSummary::findLatestByNoteId((int) $note->id); + $audio = NoteAudio::findLatestByNoteId((int) $note->id); + + $share->view_count = (int) $share->view_count + 1; + $share->last_view_time = time(); + $share->save(); + + $result = $this->formatNoteItem($note); + $result['audio'] = $audio ? $this->formatAudio($audio) : null; + $result['summary'] = $summary ? [ + 'summary_text' => (string) $summary->summary_text, + 'status' => (string) $summary->status, + ] : null; + $result['share'] = [ + 'share_token' => (string) $share->share_token, + 'title' => (string) $share->title, + 'view_count' => (int) $share->view_count, + ]; + + return $result; + } + /** * 获取当前用户拥有的笔记 * @@ -258,6 +389,26 @@ class NoteService ]; } + /** + * 格式化音频附件 + * + * @param NoteAudio $audio + * @return array + */ + private function formatAudio(NoteAudio $audio): array + { + return [ + 'audio_id' => (int) $audio->id, + 'disk' => (string) $audio->disk, + 'file_path' => (string) $audio->file_path, + 'audio_url' => (string) $audio->file_url, + 'file_size' => (int) $audio->file_size, + 'mime_type' => (string) $audio->mime_type, + 'duration_ms' => (int) $audio->duration_ms, + 'updated_at' => (int) $audio->updated_at, + ]; + } + /** * 规范化标题 * @@ -291,4 +442,15 @@ class NoteService $decoded = json_decode($value, true); return is_array($decoded) ? $decoded : []; } + + /** + * 拼接公开文件 URL + * + * @param string $savedPath + * @return string + */ + private function buildPublicFileUrl(string $savedPath): string + { + return rtrim((string) request()->domain(), '/') . '/storage/' . ltrim($savedPath, '/'); + } } diff --git a/app/note/service/PlanningService.php b/app/note/service/PlanningService.php index 95d04e7..5d3945e 100644 --- a/app/note/service/PlanningService.php +++ b/app/note/service/PlanningService.php @@ -48,14 +48,19 @@ class PlanningService ['method' => 'POST', 'path' => '/note/v1/item/update/:id', 'desc' => '更新笔记'], ['method' => 'POST', 'path' => '/note/v1/item/delete/:id', 'desc' => '删除笔记'], ['method' => 'POST', 'path' => '/note/v1/item/transcript/:id', 'desc' => '保存实时转写内容'], + ['method' => 'POST', 'path' => '/note/v1/item/audio/:id', 'desc' => '上传录音附件'], ['method' => 'POST', 'path' => '/note/v1/ai/summary/:id', 'desc' => '发起 AI 总结'], ['method' => 'GET', 'path' => '/note/v1/ai/summary/:id', 'desc' => '查看 AI 总结结果'], + ['method' => 'POST', 'path' => '/note/v1/share/create/:id', 'desc' => '生成分享标识'], + ['method' => 'GET', 'path' => '/note/v1/share/read/:token', 'desc' => '读取分享内容'], ], 'suggested_tables' => [ 'note_user', 'note_item', 'note_transcript', 'note_ai_summary', + 'note_audio', + 'note_share', ], 'development_priority' => [ '1. 先落小程序登录,打通微信 openid 与 JWT', @@ -157,6 +162,20 @@ class PlanningService 'audio_duration_ms' => '当前累计录音时长,可选', ], ], + 'audio' => [ + 'route' => 'POST /note/v1/item/audio/:id', + 'request' => [ + 'audio' => '录音文件 multipart 字段,必填', + 'audio_duration_ms' => '录音时长,可选', + ], + ], + 'share' => [ + 'route' => 'POST /note/v1/share/create/:id', + 'response' => [ + 'share_token' => '分享 token', + 'share_path' => '小程序分享路径', + ], + ], ]; } diff --git a/database.sql b/database.sql index d04658c..4d8ad42 100644 --- a/database.sql +++ b/database.sql @@ -103,3 +103,38 @@ CREATE TABLE IF NOT EXISTS `note_ai_summary` ( KEY `idx_status` (`status`), KEY `idx_summary_type` (`summary_type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='note模块-AI总结结果表'; + +-- 笔记录音附件表 +CREATE TABLE IF NOT EXISTS `note_audio` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `note_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'note_item.id', + `disk` varchar(30) NOT NULL DEFAULT 'public' COMMENT '存储磁盘', + `file_path` varchar(255) NOT NULL DEFAULT '' COMMENT '磁盘相对路径', + `file_url` varchar(500) NOT NULL DEFAULT '' COMMENT '公开访问地址', + `file_size` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '文件大小', + `mime_type` varchar(100) NOT NULL DEFAULT '' COMMENT '文件类型', + `duration_ms` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '录音时长', + `created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', + `updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', + PRIMARY KEY (`id`), + KEY `idx_note_id` (`note_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='note模块-录音附件表'; + +-- 笔记分享表 +CREATE TABLE IF NOT EXISTS `note_share` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', + `note_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'note_item.id', + `note_user_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'note_user.id', + `share_token` varchar(64) NOT NULL DEFAULT '' COMMENT '分享 token', + `title` varchar(255) NOT NULL DEFAULT '' COMMENT '分享标题', + `view_count` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '查看次数', + `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:0失效 1有效', + `expired_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '过期时间,0不过期', + `last_view_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '最后查看时间', + `created_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间', + `updated_at` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间', + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_share_token` (`share_token`), + KEY `idx_note_id` (`note_id`), + KEY `idx_note_user_id` (`note_user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='note模块-分享记录表'; diff --git a/docs/note_api.md b/docs/note_api.md index 96b40dd..711a1ff 100644 --- a/docs/note_api.md +++ b/docs/note_api.md @@ -13,7 +13,9 @@ 1. 微信小程序登录 2. 笔记创建、列表、详情、更新、删除 3. 实时转写文本保存 -4. AI 总结生成与查询 +4. 录音文件上传与播放 +5. AI 总结生成与查询 +6. 笔记分享与分享只读访问 路由注册位置: @@ -67,7 +69,7 @@ - [database.sql](/root/work/tp/database.sql#L26) -当前 `note` 模块使用以下 4 张表: +当前 `note` 模块使用以下 6 张表: 1. `note_user` 用于小程序用户登录和用户资料 @@ -81,6 +83,12 @@ 4. `note_ai_summary` AI 总结结果表 +5. `note_audio` + 录音附件表,保存上传后的音频文件地址与时长 + +6. `note_share` + 分享记录表,保存分享 token 与查看次数 + --- ## 5. 接口列表 @@ -435,7 +443,48 @@ --- -### 5.10 生成 AI 总结 +### 5.10 上传录音文件 + +- 方法:`POST` +- 路径:`/note/v1/item/audio/:id` +- 是否鉴权:是 +- Content-Type:`multipart/form-data` + +表单参数: + +| 字段 | 类型 | 必填 | 说明 | +| :--- | :--- | :--- | :--- | +| `audio` | file | 是 | 录音文件 | +| `audio_duration_ms` | int | 否 | 录音时长 | + +说明: + +- 上传成功后会返回可直接播放的 `audio_url` +- 后端会同步写入 `note_audio`,并更新笔记的录音时长 + +成功响应示例: + +```json +{ + "code": 200, + "msg": "上传成功", + "data": { + "audio_id": 2, + "disk": "public", + "file_path": "note/audio/20260417/test.m4a", + "audio_url": "http://127.0.0.1:8000/storage/note/audio/20260417/test.m4a", + "file_size": 20480, + "mime_type": "audio/mp4", + "duration_ms": 18500, + "updated_at": 1710000400 + }, + "time": 1710000400 +} +``` + +--- + +### 5.11 生成 AI 总结 - 方法:`POST` - 路径:`/note/v1/ai/summary/:id` @@ -492,7 +541,7 @@ --- -### 5.11 查看 AI 总结 +### 5.12 查看 AI 总结 - 方法:`GET` - 路径:`/note/v1/ai/summary/:id` @@ -504,6 +553,90 @@ --- +### 5.13 创建分享 + +- 方法:`POST` +- 路径:`/note/v1/share/create/:id` +- 是否鉴权:是 + +成功响应示例: + +```json +{ + "code": 200, + "msg": "分享已生成", + "data": { + "note_id": 10, + "share_token": "7a4d2f2d4a5f1b20f6f9670bb1f4d123", + "share_path": "/pages/note/edit?share_token=7a4d2f2d4a5f1b20f6f9670bb1f4d123", + "title": "会议纪要" + }, + "time": 1710000600 +} +``` + +说明: + +- 返回 `share_token` 和小程序页面路径 +- 小程序可用该路径做转发 + +--- + +### 5.14 读取分享内容 + +- 方法:`GET` +- 路径:`/note/v1/share/read/:token` +- 是否鉴权:否 + +成功响应示例: + +```json +{ + "code": 200, + "msg": "success", + "data": { + "id": 10, + "note_user_id": 1, + "title": "会议纪要", + "content": "今天确认了下周需求排期", + "transcript_text": "今天确认了下周需求排期", + "source_type": "mix", + "status": "draft", + "audio_duration_ms": 18500, + "summary_status": "success", + "last_transcript_time": 1710000300, + "created_at": 1710000000, + "updated_at": 1710000600, + "audio": { + "audio_id": 2, + "disk": "public", + "file_path": "note/audio/20260417/test.m4a", + "audio_url": "http://127.0.0.1:8000/storage/note/audio/20260417/test.m4a", + "file_size": 20480, + "mime_type": "audio/mp4", + "duration_ms": 18500, + "updated_at": 1710000400 + }, + "summary": { + "summary_text": "今天确认了下周需求排期,需要继续跟进接口联调。", + "status": "success" + }, + "share": { + "share_token": "7a4d2f2d4a5f1b20f6f9670bb1f4d123", + "title": "会议纪要", + "view_count": 3 + } + }, + "time": 1710000601 +} +``` + +说明: + +- 用于收件人直接查看分享的笔记内容、录音和 AI 摘要 + +--- + ## 6. 错误码约定 当前模块沿用项目统一返回结构: @@ -537,8 +670,10 @@ 3. 保存返回的 `token` 4. 创建笔记 `POST /note/v1/item/create` 5. 录音转写过程中持续调用 `POST /note/v1/item/transcript/:id` -6. 需要生成总结时调用 `POST /note/v1/ai/summary/:id` -7. 打开详情页时调用 `GET /note/v1/item/:id` +6. 录音停止后上传录音文件 `POST /note/v1/item/audio/:id` +7. 需要生成总结时调用 `POST /note/v1/ai/summary/:id` +8. 分享前调用 `POST /note/v1/share/create/:id` +9. 打开详情页时调用 `GET /note/v1/item/:id` --- @@ -546,4 +681,4 @@ 1. AI 总结目前是规则版,不是大模型版 2. 微信登录依赖服务端已正确配置 `WECHAT_MINI_APPID` 和 `WECHAT_MINI_SECRET` -3. 当前未实现文件音频上传,只实现了“转写文本写回后端”的数据链路 +3. 分享读取接口为公开接口,建议前端仅用于只读展示 diff --git a/public/storage/note/audio/20260417/00a3e4cf9f27ce67356ad755410d3e08.aac b/public/storage/note/audio/20260417/00a3e4cf9f27ce67356ad755410d3e08.aac new file mode 100644 index 0000000000000000000000000000000000000000..aa452aedeab3d13e0f831e293ed10bec67c34a15 GIT binary patch literal 16349 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�bszcnctu9*vGdKTl;r%ynisKdQ*`jv%Q-XDrl;jwC-2PTNvg_d_| z%YOc+nF?*iwBs46&~@wph}Oj~M$K^RXKK+_ifP(s_RK^gZRm#s)iI-X8(t;s;W1J7 zEZeVI^{riC&zGs_A#@Ct-zKm#zu4W=YxnKC9o~I8ng|5w{ou*@=lzas&0yXcv{G=a zscc zj_5r<;L*V=o^ncFDbCw#;%R#)xNy}xoDsh2 zk@%!7!%$-&c;WZ9&jWgfXy~7wAP>4sv3_Kwk8KR*c-!3Mh-|!E6{Z<)&4qR6+pG{G zH~-F=x8DeN70IQ{OPaw>mIcVe0`AE2TU)XC!9AX7ud*3hzY`wmt_OM0yY}J!bqk&( z1p;+sdwb-iHCgN+@eiZ^$?Smfdcsq%xc*#HLZB`0$H%`5;q}SGkH-PBCoj=NWv$vt z1?Vuhdmp1*t_p;`Mv}EL64+`33Z(P>12oENKKQ`px$Tt~J3D?9`-^H=9SFekq}( z4XJ%UtdRuC%(VzjKg863PsS}HkY)+hn{2J!YNm&2hrIKJY9F=Wfk@}1d**iHP;%|7 zzL=Y$x{rJ_>?16prmx0IIFy_K(UZ6I<~5CqPjhaF9cps5u;zOZqC-L0ASW7NKKPf< ze8VP#K0QFK6|!|h1nhnxjA?8;Qcb>%D`I6$%?SC6U^Q3O#GTI zZqA-U-bXF~&=sOMqQ;Q!ohF0E%!&T+1l7EE=m#XR?c4U^3f6R7V?0V^>vDNHbGX2= zi%%i0L_QnlO6LV51U{pMLi{~3Yu2RJ}&jSD-w?_jdb z&90xktc-4z0J9QHZUVM;Z~R;IR1g}%DdD%=iESOx0!GON6GKQ4E&$Q_--A#R0QN;< z;-bVc6DboQ-7A;z`R)F70$+`t{CY_trFR;4Lhi)Tj9-Y#j+a(c9g79qW0<%HYo;TF zTL2Zob-1)Cd<){Q9g{T#2KA7&5<{kpc;f5w$Jny;s70iKiU?HlFS3E%y?k#79r7m+>4j_uKBzlTMzYb%M|Hn*I~Z?Hvpv zR$OamiJKG1xo#K%r(8dy*ycA^Z{hQWYfCx60$wM&gXsZs=(vLFc#r?!Y_9sn1I&=h zkwg-$5ckoV@RjSUWesE*5R{l_=^2g59CsLkMy;XLom~Um{)ZC(~$?HZ|aEH!hEJCKI!OUP(Wo0KkgNh ztN1g66WoMS$ZsUsX*Q>g>&!BQK)C7poXnkkz?oRacDH&~`Y08zaHu$K&KA#%76PZX!4$ARAq6-Mo`)(o& zYV(WDSE>x=1CD;dreYjsG&nn_<6L%Lp2PFvwT`$N_rbO1)h3@0eJ-#KGR=(3Th?jg zC1!&8(fP)cxEBwAs@?d45Q$Xl{m*ulnBS8nR{w;0mT!7!968?<$i%vBqrkT(eu)?wIlGaTtqy}awsTi%SN=~c|WGcV1N)wK@uv| z%3q{zjY+3ywNS($YVB7mXKbXTdsRXTIx*2<@;c$l?p)N$sx#u~u&Bjg&fOcgs>53Noaed91MtOR1K3$?jsxQrGwQSvVGLc&>3 z!<~IPq)wMq)6kRiWO#7FRdio5@eseA{9S?(mq26D8>>}D(~cO-Vwiui{fn{ne*l=Y BfTI8a literal 0 HcmV?d00001 diff --git a/public/storage/note/audio/20260417/42e8d9f6af7322edc1ac68496957e305.aac b/public/storage/note/audio/20260417/42e8d9f6af7322edc1ac68496957e305.aac new file mode 100644 index 0000000..c0e5e88 --- /dev/null +++ b/public/storage/note/audio/20260417/42e8d9f6af7322edc1ac68496957e305.aac @@ -0,0 +1 @@ +uZ \ No newline at end of file diff --git a/public/storage/note/audio/20260417/788b3d3555ac0b10f0d8dc1438aebd1a.aac b/public/storage/note/audio/20260417/788b3d3555ac0b10f0d8dc1438aebd1a.aac new file mode 100644 index 0000000000000000000000000000000000000000..1b5d01f6e29ca9995eab96be42dee6a6a16ee0fa GIT binary patch literal 8959 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 a*g&8c4B&b6E7x5z)KQU`55-c_Qj;fq8cr|( literal 0 HcmV?d00001 diff --git a/route/app.php b/route/app.php index 19aacd9..ee8a4c5 100644 --- a/route/app.php +++ b/route/app.php @@ -10,6 +10,7 @@ use app\note\controller\v1\Ai as NoteAi; use app\note\controller\v1\Auth as NoteAuth; use app\note\controller\v1\Meta as NoteMeta; use app\note\controller\v1\Note as NoteItem; +use app\note\controller\v1\Share as NoteShare; /** * 全局路由入口。 @@ -54,6 +55,7 @@ Route::group('api/v1/video-work', function () { Route::group('note/v1', function () { Route::get('meta/interfaces', [NoteMeta::class, 'interfaces']); Route::post('auth/wechat-login', [NoteAuth::class, 'wechatLogin']); + Route::get('share/read/:token', [NoteShare::class, 'read']); }); // note v1 笔记小程序模块接口(需登录) @@ -66,7 +68,9 @@ Route::group('note/v1', function () { Route::post('item/update/:id', [NoteItem::class, 'update']); Route::post('item/delete/:id', [NoteItem::class, 'delete']); Route::post('item/transcript/:id', [NoteItem::class, 'transcript']); + Route::post('item/audio/:id', [NoteItem::class, 'audio']); Route::post('ai/summary/:id', [NoteAi::class, 'summary']); Route::get('ai/summary/:id', [NoteAi::class, 'readSummary']); + Route::post('share/create/:id', [NoteShare::class, 'create']); })->middleware(\app\api\middleware\Auth::class);