| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- document.head.insertAdjacentHTML('beforeend','<style type="text/css">'+stylFns['app/pages/Admin/Products/index.styl']+'</style>')
- PouchDB = require 'app/utils/pouch'
- Papa = require 'papaparse'
- module.exports =
- name: 'AdminProducts'
-
- render: (new Function '_ctx', '_cache', renderFns['app/pages/Admin/Products/index.pug'])()
-
- data: ->
- return {
- products: []
- categories: []
- searchQuery: ''
- selectedCategory: ''
- selectedStatus: ''
- showProductModal: false
- showImportModal: false
- editingProduct: null
- selectedFile: null
- importing: false
- importResults: null
- }
-
- computed:
- filteredProducts: ->
- products = @products
-
- # Фильтр по поиску
- if @searchQuery
- query = @searchQuery.toLowerCase()
- products = products.filter (product) =>
- product.name?.toLowerCase().includes(query) ||
- product.sku?.toLowerCase().includes(query)
-
- # Фильтр по категории
- if @selectedCategory
- products = products.filter (product) =>
- product.category == @selectedCategory
-
- # Фильтр по статусу
- if @selectedStatus == 'active'
- products = products.filter (product) => product.active
- else if @selectedStatus == 'inactive'
- products = products.filter (product) => !product.active
-
- return products
-
- methods:
- loadProducts: ->
- PouchDB.queryView('admin', 'products', { include_docs: true })
- .then (result) =>
- @products = result.rows.map (row) -> row.doc
- .catch (error) =>
- console.error 'Ошибка загрузки товаров:', error
- @showNotification 'Ошибка загрузки товаров', 'error'
-
- loadCategories: ->
- PouchDB.queryView('admin', 'categories', { include_docs: true })
- .then (result) =>
- @categories = result.rows.map (row) -> row.doc
- .catch (error) =>
- console.error 'Ошибка загрузки категорий:', error
-
- getCategoryName: (categoryId) ->
- category = @categories.find (cat) -> cat._id == categoryId
- category?.name || 'Без категории'
-
- editProduct: (product) ->
- @editingProduct = product
- @showProductModal = true
-
- toggleProductStatus: (product) ->
- updatedProduct = {
- ...product
- active: !product.active
- updatedAt: new Date().toISOString()
- }
-
- PouchDB.saveToRemote(updatedProduct)
- .then (result) =>
- @loadProducts()
- @showNotification 'Статус товара обновлен'
- .catch (error) =>
- console.error 'Ошибка обновления статуса:', error
- @showNotification 'Ошибка обновления статуса', 'error'
-
- deleteProduct: (productId) ->
- if confirm('Вы уверены, что хотите удалить этот товар?')
- PouchDB.getDocument(productId)
- .then (doc) ->
- PouchDB.saveToRemote({ ...doc, _deleted: true })
- .then (result) =>
- @loadProducts()
- @showNotification 'Товар удален'
- .catch (error) =>
- console.error 'Ошибка удаления товара:', error
- @showNotification 'Ошибка удаления товара', 'error'
-
- onFileSelect: (event) ->
- @selectedFile = event.target.files[0]
- @importResults = null
-
- importProducts: ->
- if !@selectedFile
- @showNotification 'Выберите файл для импорта', 'error'
- return
-
- @importing = true
- @importResults = null
-
- reader = new FileReader()
- reader.onload = (e) =>
- try
- results = Papa.parse e.target.result, {
- header: true
- delimiter: ';'
- skipEmptyLines: true
- encoding: 'UTF-8'
- }
-
- products = results.data.filter (row) =>
- row && row['Артикул*'] && row['Название товара'] && row['Цена, руб.*']
-
- couchProducts = products.map (product, index) =>
- @transformProductData(product, index)
-
- # Пакетное сохранение
- PouchDB.bulkDocs(couchProducts)
- .then (result) =>
- @importResults = { success: true, processed: couchProducts.length }
- @importing = false
- @loadProducts()
- @showNotification "Импортировано #{couchProducts.length} товаров"
- .catch (error) =>
- @importResults = { success: false, error: error.message, processed: 0 }
- @importing = false
- @showNotification "Ошибка импорта: #{error.message}", 'error'
-
- catch error
- @importResults = { success: false, error: error.message, processed: 0 }
- @importing = false
- @showNotification "Ошибка обработки файла: #{error.message}", 'error'
-
- reader.readAsText(@selectedFile, 'UTF-8')
-
- transformProductData: (product, index) ->
- # Базовые поля
- productData = {
- _id: "product:#{Date.now()}-#{index}"
- type: 'product'
- name: product['Название товара']
- sku: product['Артикул*']
- price: parseFloat(product['Цена, руб.*'].replace(/\s/g, '').replace(',', '.')) || 0
- active: true
- createdAt: new Date().toISOString()
- updatedAt: new Date().toISOString()
- }
-
- # Дополнительные поля
- if product['Цена до скидки, руб.']
- productData.oldPrice = parseFloat(product['Цена до скидки, руб.'].replace(/\s/g, '').replace(',', '.'))
-
- if product['Ссылка на главное фото*']
- productData.image = product['Ссылка на главное фото*']
-
- if product['Бренд*']
- productData.brand = product['Бренд*']
-
- if product['Тип*']
- productData.productType = product['Тип*']
-
- # Rich content преобразование
- if product['Rich-контент JSON']
- try
- richContent = JSON.parse(product['Rich-контент JSON'])
- productData.description = @richContentToMarkdown(richContent)
- catch
- productData.description = product['Аннотация'] || ''
- else
- productData.description = product['Аннотация'] || ''
-
- # Домены (все товары доступны на всех доменах по умолчанию)
- productData.domains = @availableDomains?.map((d) -> d.domain) || []
-
- return productData
-
- richContentToMarkdown: (richContent) ->
- # Простое преобразование rich content в markdown
- return JSON.stringify(richContent) # Временная реализация
-
- formatPrice: (price) ->
- return '0 ₽' if !price
- new Intl.NumberFormat('ru-RU', {
- style: 'currency'
- currency: 'RUB'
- minimumFractionDigits: 0
- }).format(price)
-
- getStatusClass: (isActive) ->
- baseClass = 'admin-products__status'
- if isActive
- return "#{baseClass} admin-products__status--active"
- else
- return "#{baseClass} admin-products__status--inactive"
-
- showNotification: (message, type = 'success') ->
- @$root.showNotification?(message, type) || debug.log("#{type}: #{message}")
-
- mounted: ->
- @loadProducts()
- @loadCategories()
|