Статьи

Создание простого CRM с REST API за 10 минут

Представьте, что нам нужно хранить деловые контакты и отслеживать их статус. Это типичная функция приложения CRM. Давайте посмотрим, как среда AllcountJS может помочь нам решить эту проблему за 10 минут.

AllcountJS — это среда быстрой разработки приложений с открытым исходным кодом. Он построен поверх стека MEAN (MongoDB, Express, AngularJS, NodeJS). Но «M» можно заменить другой базой данных, в том числе SQL.

Основной частью приложения AllcountJS является файл конфигурации .js с в основном декларативным описанием структуры приложения: сущностей, их полей, отношений, представлений, ролей и разрешений.

Все операции CRUD, представления по умолчанию, функции управления пользователями доступны «из коробки».

Встроенный контроль доступа на основе ролей позволяет управлять правами доступа на основе ролей пользователей.

Пользовательский интерфейс генерируется автоматически с использованием значков AngularJS, Twitter Bootstrap, Jade и Font Awesome.

AllcountJS также предоставляет JSON REST API для выполнения всех операций, доступных пользователям. Если вам нужно добавить некоторые специфические функции в ваше приложение, вы можете использовать механизм Dependency Injection.

Установка и запуск

Вы можете начать работать с AllcountJS несколькими способами: как отдельное приложение, как зависимость от другого приложения Node.js или запустить демонстрационное приложение на allcountjs.com.

Самый простой способ увидеть результат — просто запустить приложение на  демонстрационной странице.

Если вы планируете развернуть приложение на своем сайте, вы должны установить  Node.jsMongoDB  и  Git . Затем установите CLI AllcountJS, вызвав команду «npm install», и выполните init проекта:

npm install -g allcountjs-cli
allcountjs init cusdevcrm-allcount
cd cusdevcrm-allcount
npm install

AllcountJS CLI попросит вас ввести некоторую информацию о вашем проекте, чтобы предварительно заполнить package.json. Затем откройте  app-config/main.js файл в каталоге приложения и замените его содержимое следующим фрагментом кода:

A.app({
  appName: "CusDev CRM",
  appIcon: "phone",
  onlyAuthenticated: true,   
  menuItems: [   
    {    
      name: "Contact",    
      entityTypeId: "Contact",    
      icon: "user"    
    }, {    
      name: "Board",    
      entityTypeId: "FlowBoard",    
      icon: "bars"
    }, {
      name: "Statuses",
      entityTypeId: "Status",
      icon: "sort"
    }
  ],
  entities: function(Fields) {
    return {
      Contact: {
        fields: {
          name: Fields.text("Name").required(),
          company: Fields.text("Company").required(),
          site: Fields.text("Site"),
          email: Fields.text("Email"),
          skype: Fields.text("Skype"),
          phone: Fields.text("Phone"),
          lastContactDate: Fields.date('Last contact date'),  
          status: Fields.fixedReference("Status", "Status")
        },  
        views: {  
          FlowBoard: {
            customView: "board" 
          }
        }
      },
      Status: {
        fields: {
          name: Fields.text("Name").required(),
          order: Fields.integer("Order").required()
        },
        sorting: [['order', 1]],
        referenceName: "name"
      }
    }
  },
  migrations: function (Migrations) { return [
    {
      name: "statuses",
      operation: Migrations.insert("Status", [
        {id: "1", name: "Message Sent", order: 1}, 
        {id: "2", name: "Answered", order: 2},
        {id: "3", name: "Meeting Approved", order: 3}, 
        {id: "4", name: "Meeting Finished", order: 4},
        {id: "5", name: "Rejected", order: 5}
      ])
    },
    {
      name: "demo-contacts",
      operation: Migrations.insert("Contact", [
        {id: "1", name: "John Doe", company: "Acme, Inc.", email: "john@acme.com", site: "acme.com", status: {id: "1"}, lastContactDate: "2015-07-18"},
        {id: "2", name: "Peter Stone", company: "FooBar LLC", email: "peter@foobar.com", status: {id: "2"}, lastContactDate: "2015-07-17"}
      ])
    }
  ]}   
});

Теперь давайте посмотрим, как это работает.

Общие настройки приложения

Имя и значок приложения определяются с  appName и   appIcon свойствами. AllcountJS использует   иконки Font Awesome . Вы можете выбрать любой значок и использовать его, просто ссылаясь на его имя. При обращении к значку необходимо удалить  fa- префикс.

 appName: "CusDev CRM",
 appIcon: "phone",

Настройка аутентификации настраивается  onlyAuthenticated свойством. Он заявляет, что только аутентифицированные пользователи могут использовать это приложение.  

onlyAuthenticated: true

Существует также  menuItems свойство, но мы рассмотрим его после того, как определим сущности и представления.

Контакты и статусы

Теперь мы готовы описать наши бизнес-объекты. Они определены в  entities собственности. Предположим, что у контакта будет два обязательных текстовых поля: Имя и Компания, некоторое текстовое поле с контактными данными, дата последнего контакта и текущий статус.

Поле статуса ссылается на  status объект. Которые могут иметь такие значения, как «Сообщение отправлено», «Отвечено», «Отклонено». Статус сущности имеет  name и  order поля.

entities: function(Fields) {
    return {
      Contact: {   
        fields: {    
          name: Fields.text("Name").required(),    
          company: Fields.text("Company").required(),    
          site: Fields.text("Site"),   
          email: Fields.text("Email"),   
          skype: Fields.text("Skype"),    
          phone: Fields.text("Phone"),
          lastContactDate: Fields.date('Last contact date'),    
          status: Fields.fixedReference("Status", "Status")    
        }
      },    
      Status: {    
        fields: {    
          name: Fields.text("Name").required(),   
          order: Fields.integer("Order").required()    
        },    
        sorting: [['order', 1]],    
        referenceName: "name"    
      }    
    }   
  }

Board View

Каждая сущность может иметь много  views. Представление в AllcountJS похоже на представление SQL: у них нет специального хранилища в базе данных, и вы можете работать с ними, как с сущностями. Наиболее распространенный вариант использования представлений — предоставление настраиваемого поведения, пользовательского интерфейса и прав доступа.

В нашем случае мы будем использовать  views только для предоставления конкретного интерфейса для  Contact. Шаблон пользовательского интерфейса для представления или объекта определяется в  customView свойстве.

views: {    
  FlowBoard: {    
    customView: "board"   
  }   
}

Это относится к  .jade файлу, содержащему исходный код шаблона. AllcountJS использует Jade Template Engine для генерации результирующего HTML для веб-просмотра.

В AllcountJS есть шаблон картона с функцией перетаскивания. Мы будем использовать его с некоторыми настройками. Итак, давайте создадим  board.jade  файл с этим фрагментом кода:

extends project/card-board    
block panelBody    
  .panel-body    
    h4 {{item.name}}    
    p {{item.company}}    
    p {{item.lastContactDate | date}}

Меню

Теперь пришло время описать наше меню приложения. Есть  menuItems свойство приложения. Он состоит из ссылок на сущности приложения.

menuItems: [    
    {    
      name: "Contact",    
      entityTypeId: "Contact",    
      icon: "user"    
    }, {    
      name: "Board",    
      entityTypeId: "FlowBoard",    
      icon: "bars"    
    }, {    
      name: "Statuses",    
      entityTypeId: "Status",    
      icon: "sort"    
    }    
  ]

REST API

Представьте, что у вас есть другое приложение и вы хотите интегрировать его с вашей новой CRM. Это не проблема, потому что все функции приложения могут быть доступны через REST API. Сначала нужно получить токен доступа. Если ваше приложение CRM расположено по адресу  https: // localhost: 9080,  вам нужно отправить запрос HTTP POST на  https: // localhost: 9080 / api / выполнить вход с

{"username": "admin", "password": "admin"}` 

в организме. В ответ вы получите токен вот так:

{"token":"56026b8ad7939dcb552a1668:PSDhU6x_VeIzqPYtIATXzEdMTLE"}

Далее давайте попробуем получить все контакты, хранящиеся в CRM. Отправьте HTTP-запрос GET на  https: // localhost: 9080 / api / entity / FlowBoard или непосредственно на  https: // localhost: 9080 / api / entity / Contact with

X-Access-Token: 56026b8ad7939dcb552a1668:PSDhU6x_VeIzqPYtIATXzEdMTLE

в шапке. И вы получите все ваши контакты в формате JSON. Также вы можете обновлять, создавать, удалять все ваши контакты через API.

Результат

Мы только что создали простое приложение CRM на основе AllcountJS. Как видите, это было легко и не заняло слишком много времени:

Просмотр картона

Этот пример демонстрирует небольшую часть возможностей AllcountJS. Хотите узнать больше? Изучите нашу  документацию  и не стесняйтесь спрашивать о  gitter .