audio.service.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import { Audio, AudioDocument } from '../../models/Audio';
  2. import { User } from '../../models/User';
  3. import { PaginationResult } from '../../types';
  4. import mongoose from 'mongoose';
  5. // 获取用户音频列表
  6. export async function getAudioList(
  7. userId: string,
  8. options: {
  9. page?: number;
  10. pageSize?: number;
  11. isFavorite?: boolean;
  12. keyword?: string;
  13. category?: string;
  14. }
  15. ): Promise<PaginationResult<AudioDocument>> {
  16. const { page = 1, pageSize = 10, isFavorite, keyword, category } = options;
  17. // 验证 userId 是否为有效的 ObjectId
  18. if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
  19. return {
  20. list: [],
  21. total: 0,
  22. page,
  23. pageSize,
  24. totalPages: 0,
  25. };
  26. }
  27. const query: Record<string, unknown> = { userId };
  28. if (isFavorite !== undefined) {
  29. query.isFavorite = isFavorite;
  30. }
  31. if (keyword) {
  32. query.$or = [
  33. { title: { $regex: keyword, $options: 'i' } },
  34. { text: { $regex: keyword, $options: 'i' } },
  35. ];
  36. }
  37. if (category) {
  38. query.category = category;
  39. }
  40. const total = await Audio.countDocuments(query);
  41. const totalPages = Math.ceil(total / pageSize);
  42. const list = await Audio.find(query)
  43. .sort({ createdAt: -1 })
  44. .skip((page - 1) * pageSize)
  45. .limit(pageSize);
  46. return {
  47. list,
  48. total,
  49. page,
  50. pageSize,
  51. totalPages,
  52. };
  53. }
  54. // 获取单个音频
  55. export async function getAudioById(audioId: string, userId: string): Promise<AudioDocument | null> {
  56. // 验证 userId 是否为有效的 ObjectId
  57. if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
  58. return null;
  59. }
  60. return Audio.findOne({ _id: audioId, userId });
  61. }
  62. // 删除音频
  63. export async function deleteAudio(audioId: string, userId: string): Promise<boolean> {
  64. // 验证 userId 是否为有效的 ObjectId
  65. if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
  66. return false;
  67. }
  68. const result = await Audio.findOneAndDelete({ _id: audioId, userId });
  69. return !!result;
  70. }
  71. // 切换收藏状态
  72. export async function toggleFavorite(audioId: string, userId: string): Promise<AudioDocument | null> {
  73. // 验证 userId 是否为有效的 ObjectId
  74. if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
  75. return null;
  76. }
  77. const audio = await Audio.findOne({ _id: audioId, userId });
  78. if (!audio) return null;
  79. audio.isFavorite = !audio.isFavorite;
  80. await audio.save();
  81. return audio;
  82. }
  83. // 更新音频信息
  84. export async function updateAudio(
  85. audioId: string,
  86. userId: string,
  87. data: { title?: string; tags?: string[] }
  88. ): Promise<AudioDocument | null> {
  89. // 验证 userId 是否为有效的 ObjectId
  90. if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
  91. return null;
  92. }
  93. const audio = await Audio.findOne({ _id: audioId, userId });
  94. if (!audio) return null;
  95. if (data.title) audio.title = data.title;
  96. if (data.tags) audio.tags = data.tags;
  97. await audio.save();
  98. return audio;
  99. }
  100. // 获取用户使用统计
  101. export async function getUserStats(userId: string): Promise<{
  102. totalAudios: number;
  103. totalDuration: number;
  104. totalWords: number;
  105. favoriteCount: number;
  106. }> {
  107. // 验证 userId 是否为有效的 ObjectId
  108. if (!userId || !mongoose.Types.ObjectId.isValid(userId)) {
  109. return { totalAudios: 0, totalDuration: 0, totalWords: 0, favoriteCount: 0 };
  110. }
  111. const stats = await Audio.aggregate([
  112. { $match: { userId: userId } },
  113. {
  114. $group: {
  115. _id: null,
  116. totalAudios: { $sum: 1 },
  117. totalDuration: { $sum: '$audioDuration' },
  118. totalWords: { $sum: '$wordCount' },
  119. favoriteCount: {
  120. $sum: { $cond: [{ $eq: ['$isFavorite', true] }, 1, 0] },
  121. },
  122. },
  123. },
  124. ]);
  125. if (stats.length === 0) {
  126. return { totalAudios: 0, totalDuration: 0, totalWords: 0, favoriteCount: 0 };
  127. }
  128. return {
  129. totalAudios: stats[0].totalAudios,
  130. totalDuration: stats[0].totalDuration,
  131. totalWords: stats[0].totalWords,
  132. favoriteCount: stats[0].favoriteCount,
  133. };
  134. }