CategoryService.coffee 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # app/services/CategoryService.coffee
  2. { Category } = require 'app/types/data'
  3. class CategoryService
  4. constructor: ->
  5. @pouchService = require 'app/utils/pouch'
  6. @initialized = false
  7. init: ->
  8. return Promise.resolve() if @initialized
  9. try
  10. await @pouchService.init()
  11. @initialized = true
  12. log '✅ CategoryService инициализирован'
  13. return Promise.resolve()
  14. catch error
  15. log '❌ Ошибка инициализации CategoryService: ' + error
  16. return Promise.reject(error)
  17. getAllCategories: ->
  18. await @ensureInit()
  19. try
  20. result = await @pouchService.queryView('categories', 'all_active', {
  21. include_docs: true
  22. })
  23. categories = result.rows.map (row) ->
  24. new Category(row.doc)
  25. # Сортировка по порядку
  26. categories.sort (a, b) -> a.order - b.order
  27. log '📂 Загружены категории: ' + categories.length
  28. return categories
  29. catch error
  30. log '❌ Ошибка загрузки категорий: ' + error
  31. throw error
  32. getCategoryBySlug: (slug) ->
  33. await @ensureInit()
  34. try
  35. result = await @pouchService.queryView('categories', 'by_slug', {
  36. key: slug
  37. include_docs: true
  38. })
  39. if result.rows.length > 0
  40. category = new Category(result.rows[0].doc)
  41. log '📂 Загружена категория по slug: ' + slug
  42. return category
  43. else
  44. log '⚠️ Категория не найдена по slug: ' + slug
  45. return null
  46. catch error
  47. log '❌ Ошибка поиска категории по slug ' + slug + ': ' + error
  48. throw error
  49. getCategoryById: (id) ->
  50. await @ensureInit()
  51. try
  52. doc = await @pouchService.getDocument(id)
  53. category = new Category(doc)
  54. log '📂 Загружена категория по ID: ' + id
  55. return category
  56. catch error
  57. if error.status == 404
  58. log '⚠️ Категория не найдена по ID: ' + id
  59. return null
  60. else
  61. log '❌ Ошибка загрузки категории по ID ' + id + ': ' + error
  62. throw error
  63. getHierarchicalCategories: ->
  64. await @ensureInit()
  65. try
  66. result = await @pouchService.queryView('categories', 'hierarchical', {
  67. include_docs: true
  68. })
  69. categories = result.rows.map (row) ->
  70. new Category(row.doc)
  71. # Построение иерархии
  72. hierarchical = @buildHierarchy(categories)
  73. log '🌳 Построена иерархия категорий'
  74. return hierarchical
  75. catch error
  76. log '❌ Ошибка построения иерархии категорий: ' + error
  77. throw error
  78. buildHierarchy: (categories, parentId = null) ->
  79. hierarchy = []
  80. categories
  81. .filter (cat) -> cat.parent == parentId
  82. .sort (a, b) -> a.order - b.order
  83. .forEach (category) =>
  84. children = @buildHierarchy(categories, category._id)
  85. if children.length > 0
  86. category.children = children
  87. hierarchy.push(category)
  88. return hierarchy
  89. saveCategory: (categoryData) ->
  90. await @ensureInit()
  91. try
  92. # Если переданы данные, создаем объект Category
  93. if categoryData instanceof Category
  94. category = categoryData
  95. else
  96. category = new Category(categoryData)
  97. # Генерация ID если не установлен
  98. if not category._id
  99. category._id = 'category:' + category.slug
  100. # Убедимся, что есть все обязательные поля
  101. category.type = 'category'
  102. category.active = category.active != false
  103. category.domains = category.domains || [window.location.hostname]
  104. category.order = category.order || 0
  105. category.createdAt = category.createdAt || new Date().toISOString()
  106. category.updatedAt = new Date().toISOString()
  107. result = await @pouchService.saveDocument(category)
  108. log '💾 Категория сохранена: ' + category.name + ' (ID: ' + category._id + ')'
  109. return result
  110. catch error
  111. log '❌ Ошибка сохранения категории: ' + error
  112. throw error
  113. bulkSaveCategories: (categories) ->
  114. await @ensureInit()
  115. try
  116. # Преобразуем категории в документы для PouchDB
  117. docs = categories.map (category) =>
  118. if category._id and category._rev
  119. return category
  120. else
  121. # Новая категория
  122. return {
  123. _id: category._id || 'category:' + category.slug
  124. type: 'category'
  125. name: category.name
  126. slug: category.slug
  127. parent: category.parent || null
  128. order: category.order || 0
  129. image: category.image || ''
  130. description: category.description || ''
  131. domains: category.domains || [window.location.hostname]
  132. active: category.active != false
  133. seo: category.seo || {}
  134. createdAt: category.createdAt || new Date().toISOString()
  135. updatedAt: new Date().toISOString()
  136. }
  137. result = await @pouchService.bulkDocs(docs)
  138. success = []
  139. errors = []
  140. result.forEach (item, index) =>
  141. if item.ok
  142. success.push(categories[index])
  143. else
  144. errors.push({
  145. category: categories[index]
  146. error: item.error || 'Unknown error'
  147. index: index
  148. })
  149. log '📦 Пакетное сохранение категорий: успешно ' + success.length + ', ошибок ' + errors.length
  150. return { success, errors }
  151. catch error
  152. log '❌ Ошибка пакетного сохранения категорий: ' + error
  153. throw error
  154. ensureInit: ->
  155. unless @initialized
  156. throw new Error('CategoryService не инициализирован. Вызовите init() сначала.')
  157. module.exports = new CategoryService()