CategoryService.coffee 7.6 KB

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