Save all currently accumulated repository changes as a backup snapshot for Gitea so no local work is lost.
22 KiB
22 KiB
🎨 UX ДИЗАЙН: СОЗДАНИЕ И РЕДАКТИРОВАНИЕ ШАБЛОНОВ
🎯 ВОПРОС: ГДЕ РЕДАКТИРОВАТЬ ШАБЛОНЫ?
📋 ВАРИАНТЫ РЕШЕНИЯ
ВАРИАНТ 1: ГИБРИДНЫЙ ПОДХОД (РЕКОМЕНДУЕТСЯ) ✅
Создание шаблона:
- В CRM интерфейсе
- Можно создать пустой шаблон или загрузить существующий файл
Редактирование шаблона:
- Содержимое (DOCX) → в Nextcloud через OnlyOffice
- Метаданные и маппинг → в CRM интерфейсе
Преимущества:
- ✅ Удобно редактировать DOCX в OnlyOffice (богатый редактор)
- ✅ Метаданные в CRM (логика рядом с данными)
- ✅ Гибкость - можно редактировать где удобно
ВАРИАНТ 2: ТОЛЬКО В NEXTCLOUD
Создание/редактирование:
- Все в Nextcloud
- В CRM только настройка маппинга
Недостатки:
- ❌ Нужно переключаться между системами
- ❌ Маппинг отдельно от шаблона
ВАРИАНТ 3: ТОЛЬКО В CRM
Создание/редактирование:
- Все в CRM
- Загрузка файла через интерфейс CRM
Недостатки:
- ❌ Нет удобного редактора DOCX в CRM
- ❌ Дублирование файлов (в CRM и Nextcloud)
🏆 РЕКОМЕНДУЕМЫЙ ПОДХОД: ГИБРИДНЫЙ
📝 СЦЕНАРИЙ 1: СОЗДАНИЕ НОВОГО ШАБЛОНА
В CRM интерфейсе:
┌─────────────────────────────────────────────────────────┐
│ Создание шаблона документа │
├─────────────────────────────────────────────────────────┤
│ │
│ Название шаблона: [________________] │
│ │
│ Модуль: [Project ▼] │
│ │
│ Файл шаблона: │
│ ○ Создать пустой шаблон │
│ ○ Загрузить существующий файл │
│ [Выбрать файл...] │
│ │
│ Имя файла в Nextcloud: [pretenziya.docx] │
│ │
│ [Сохранить и настроить маппинг] │
│ │
└─────────────────────────────────────────────────────────┘
Что происходит:
-
Если "Создать пустой шаблон":
- CRM создает пустой DOCX через PHPWord
- Загружает в Nextcloud
/Templates/pretenziya.docx - Создает запись в
vtiger_doctemplate - Открывает шаблон в OnlyOffice для редактирования
-
Если "Загрузить существующий файл":
- Пользователь выбирает файл
- CRM загружает в Nextcloud
/Templates/ - Создает запись в
vtiger_doctemplate - Переходит к настройке маппинга
📝 СЦЕНАРИЙ 2: РЕДАКТИРОВАНИЕ ШАБЛОНА
В CRM интерфейсе (детальный вид шаблона):
┌─────────────────────────────────────────────────────────┐
│ Шаблон: Претензия [Редактировать] │
├─────────────────────────────────────────────────────────┤
│ │
│ Модуль: Project │
│ Файл: pretenziya.docx │
│ │
│ [📝 Редактировать содержимое в OnlyOffice] │
│ → Откроет файл в Nextcloud для редактирования │
│ │
│ ──────────────────────────────────────────────────── │
│ │
│ Маппинг переменных: │
│ │
│ Переменная шаблона → Поле модуля │
│ ┌─────────────────┐ ┌──────────────────────┐ │
│ │ CLIENT_NAME │ → │ $PROJECT_PROJECTNAME$│ │
│ └─────────────────┘ └──────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌──────────────────────┐ │
│ │ DATE │ → │ $PROJECT_CREATEDTIME$ │ │
│ └─────────────────┘ └──────────────────────┘ │
│ │
│ [+ Добавить переменную] │
│ │
│ ──────────────────────────────────────────────────── │
│ │
│ [💾 Сохранить маппинг] │
│ │
└─────────────────────────────────────────────────────────┘
Кнопка "Редактировать содержимое":
- Открывает файл в OnlyOffice через Nextcloud
- Пользователь редактирует DOCX
- Сохраняет в Nextcloud
- CRM автоматически подхватывает изменения
🔧 РЕАЛИЗАЦИЯ
1. Создание пустого шаблона
class DocTemplate_Template_Model {
/**
* Создать пустой шаблон в Nextcloud
*/
public function createEmptyTemplate($filename) {
// 1. Создать пустой DOCX через PHPWord
$phpWord = new \PhpOffice\PhpWord\PhpWord();
$section = $phpWord->addSection();
$section->addText('Шаблон документа');
$tempFile = tempnam(sys_get_temp_dir(), 'template_') . '.docx';
$writer = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, 'Word2007');
$writer->save($tempFile);
// 2. Загрузить в Nextcloud через WebDAV
$this->uploadToNextcloud($tempFile, $filename);
// 3. Удалить временный файл
unlink($tempFile);
return true;
}
/**
* Загрузка файла в Nextcloud
*/
private function uploadToNextcloud($localFile, $filename) {
$nextcloudUrl = 'https://office.clientright.ru:8443';
$username = 'admin';
$password = 'office';
$path = '/Templates/';
$webdavUrl = $nextcloudUrl . '/remote.php/dav/files/' .
$username . $path . $filename;
$ch = curl_init($webdavUrl);
curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, fopen($localFile, 'r'));
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 201 && $httpCode !== 204) {
throw new Exception("Ошибка загрузки в Nextcloud");
}
}
}
2. Загрузка существующего файла
class DocTemplate_Edit_View {
public function process(Vtiger_Request $request) {
if ($request->has('file_upload')) {
$uploadedFile = $_FILES['template_file'];
// 1. Валидация файла
if ($uploadedFile['type'] !== 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
throw new Exception("Только DOCX файлы");
}
// 2. Загрузить в Nextcloud
$filename = $request->get('filename');
$this->uploadToNextcloud($uploadedFile['tmp_name'], $filename);
// 3. Создать запись в CRM
$templateModel = new DocTemplate_Template_Model();
$templateModel->set('templatename', $request->get('templatename'));
$templateModel->set('filename', $filename);
$templateModel->set('module', $request->get('module'));
$templateModel->save();
// 4. Редирект на редактирование маппинга
header("Location: index.php?module=DocTemplate&view=Edit&record=" . $templateModel->getId());
}
}
}
3. Редактирование содержимого (открытие в OnlyOffice)
class DocTemplate_EditContent_Action {
public function process(Vtiger_Request $request) {
$templateId = $request->get('record');
$template = DocTemplate_Template_Model::getInstanceById($templateId);
// Получить URL для открытия в OnlyOffice
$nextcloudUrl = 'https://office.clientright.ru:8443';
$filename = $template->getFilename();
$path = $template->getNextcloudPath();
// URL для открытия в OnlyOffice
$onlyOfficeUrl = $nextcloudUrl . '/apps/files/?dir=' .
urlencode($path) .
'&openfile=' . urlencode($filename);
// Или через прямой вызов OnlyOffice
$onlyOfficeUrl = $nextcloudUrl . '/apps/onlyoffice/' .
urlencode($path . $filename);
header("Location: " . $onlyOfficeUrl);
exit;
}
}
4. Интерфейс редактирования маппинга
JavaScript:
DocTemplate = {
/**
* Показать редактор маппинга
*/
showMappingEditor: function(templateId, module) {
// 1. Получить список полей модуля (как PDFMaker)
AppConnector.request({
module: 'DocTemplate',
action: 'GetModuleFields',
module_name: module
}).then(function(response) {
// 2. Показать модальное окно с редактором маппинга
DocTemplate.showMappingDialog(response.result.fields, templateId);
});
},
/**
* Диалог редактирования маппинга
*/
showMappingDialog: function(fields, templateId) {
var html = '<div class="mapping-editor">' +
'<table class="table">' +
'<thead><tr><th>Переменная шаблона</th><th>Поле модуля</th><th></th></tr></thead>' +
'<tbody id="mapping-rows"></tbody>' +
'</table>' +
'<button onclick="DocTemplate.addMappingRow()">+ Добавить</button>' +
'</div>';
// Показать модальное окно
// При сохранении → вызвать SaveMapping
},
/**
* Сохранение маппинга
*/
saveMapping: function(templateId, mapping) {
AppConnector.request({
module: 'DocTemplate',
action: 'SaveMapping',
template_id: templateId,
mapping: JSON.stringify(mapping)
}).then(function(response) {
if (response.success) {
Vtiger_Helper_Js.showPnotify('Маппинг сохранен');
}
});
}
};
🎨 UI КОМПОНЕНТЫ
1. Список шаблонов (List View)
┌─────────────────────────────────────────────────────────┐
│ Шаблоны документов [+ Создать] │
├─────────────────────────────────────────────────────────┤
│ │
│ Название │ Модуль │ Файл │ Действия│
│ ───────────────────────────────────────────────────── │
│ Претензия │ Project │ pretenziya.docx │ [✏️][👁️]│
│ Исковое заявл. │ Project │ isk.docx │ [✏️][👁️]│
│ Соглашение │ Contacts │ soglashenie.docx │ [✏️][👁️]│
│ │
└─────────────────────────────────────────────────────────┘
2. Детальный вид шаблона
┌─────────────────────────────────────────────────────────┐
│ Претензия [Редактировать] [×] │
├─────────────────────────────────────────────────────────┤
│ │
│ Модуль: Project │
│ Файл: pretenziya.docx │
│ Путь: /Templates/ │
│ │
│ [📝 Редактировать содержимое в OnlyOffice] │
│ │
│ ──────────────────────────────────────────────────── │
│ │
│ Маппинг переменных: │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Переменная │ Поле модуля │ [×] │ │
│ ├──────────────────────────────────────────────────┤ │
│ │ CLIENT_NAME │ $PROJECT_PROJECTNAME$ │ [×] │ │
│ │ DATE │ $PROJECT_CREATEDTIME$ │ [×] │ │
│ │ AMOUNT │ $PROJECT_CF_1885$ │ [×] │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ [+ Добавить переменную] │
│ │
│ [💾 Сохранить] │
│ │
└─────────────────────────────────────────────────────────┘
3. Диалог добавления переменной
┌─────────────────────────────────────────────────────────┐
│ Добавить переменную │
├─────────────────────────────────────────────────────────┤
│ │
│ Переменная шаблона: │
│ [CLIENT_NAME________________] │
│ │
│ Поле модуля: │
│ [Выбрать поле ▼] │
│ ├─ Прямые поля │
│ │ ├─ $PROJECT_PROJECTNAME$ │
│ │ ├─ $PROJECT_CREATEDTIME$ │
│ │ └─ ... │
│ ├─ Связанные модули │
│ │ ├─ $CONTACTS_LASTNAME$ │
│ │ └─ ... │
│ └─ Функции │
│ ├─ formatDate($PROJECT_CREATEDTIME$) │
│ └─ ... │
│ │
│ [Отмена] [Добавить] │
│ │
└─────────────────────────────────────────────────────────┘
🔄 АЛЬТЕРНАТИВНЫЙ ПОДХОД: ВСТРОЕННЫЙ РЕДАКТОР
Вариант: Редактирование прямо в CRM
Если нужен встроенный редактор в CRM (без перехода в Nextcloud):
// Использовать OnlyOffice Document Server API
// Встроить редактор в iframe
class DocTemplate_EditContent_View {
public function process(Vtiger_Request $request) {
$templateId = $request->get('record');
$template = DocTemplate_Template_Model::getInstanceById($templateId);
// Получить URL для OnlyOffice Document Server
$onlyOfficeUrl = $this->getOnlyOfficeEditorUrl($template);
$viewer = $this->getViewer($request);
$viewer->assign('ONLYOFFICE_URL', $onlyOfficeUrl);
$viewer->assign('TEMPLATE', $template);
$viewer->view('EditContent.tpl', 'DocTemplate');
}
}
Template:
<iframe src="{$ONLYOFFICE_URL}" width="100%" height="800px"></iframe>
✅ РЕКОМЕНДАЦИИ
Для создания шаблона:
- ✅ В CRM интерфейсе
- ✅ Можно создать пустой или загрузить файл
- ✅ Автоматическая загрузка в Nextcloud
Для редактирования содержимого:
- ✅ В Nextcloud через OnlyOffice (богатый редактор)
- ✅ Кнопка "Редактировать содержимое" открывает в новой вкладке
- ✅ После сохранения в Nextcloud - изменения сразу доступны
Для редактирования маппинга:
- ✅ В CRM интерфейсе
- ✅ Визуальный редактор с выбором полей
- ✅ Поддержка формата PDFMaker (
$MODULE_FIELDNAME$)
🚀 ГОТОВ РЕАЛИЗОВАТЬ!
Какой вариант тебе больше нравится?
- Гибридный (содержимое в Nextcloud, маппинг в CRM) - РЕКОМЕНДУЮ ✅
- Только в CRM (встроенный редактор)
- Только в Nextcloud (маппинг отдельно)