Редактировал(а) Кристина Гришкина 10.10.2025

От версии 3.1
отредактировано Кристина Гришкина
на 10.10.2025
Изменить комментарий: К данной версии нет комментариев
К версии 2.2
отредактировано Alexey Semenihin
на 10.10.2025
Изменить комментарий: Добавлен тег [Создание задачи, редактирование задачи, наблюдатели, карточка задачи, окно задачи, свойства задачи, информация по задаче, создать подзадачу, родительские задачи, согласования по задаче, история изменений, копирование задач, стадии договоров, типы задач, приложить файл к задаче]

Сводка

Подробности

Свойства страницы
Автор документа
... ... @@ -1,1 +1,1 @@
1 -xwiki:XWiki.grishkinakn
1 +xwiki:XWiki.semenihinaa
Содержимое
... ... @@ -1,5 +1,36 @@
1 1  {{velocity}}
2 +## Макрос для отображения подстраниц с отображаемыми именами в алфавитном порядке
3 +#macro(displayDirectChildrenClean)
4 + #set ($currentPage = $doc.fullName)
5 + #set ($children = $xwiki.getDocument($currentPage).getChildren())
6 + #if ($children.size() > 0)
7 + ## Создаем список для хранения пар (отображаемое имя, полное имя)
8 + #set ($childList = [])
9 + #foreach ($child in $children)
10 + #set ($childDoc = $xwiki.getDocument($child))
11 + ## Получаем отображаемое имя (title), если оно не пустое, иначе используем имя документа
12 + #set ($displayName = $childDoc.getPlainTitle())
13 + #if ($displayName == '')
14 + #set ($displayName = $childDoc.getName())
15 + #end
16 + ## Добавляем пару в список
17 + #set ($discard = $childList.add({"displayName": $displayName, "fullName": $child}))
18 + #end
19 + ## Сортируем список по displayName
20 + #set ($sortedChildren = $sorttool.sort($childList, "displayName:asc"))
21 + ## Выводим отсортированный список
22 + #foreach ($item in $sortedChildren)
23 + [[$item.displayName>>$item.fullName]]
24 + #end
25 + #end
26 +#end
27 +## Выводим список
28 +#displayDirectChildrenClean()
29 +{{/velocity}}
2 2  
31 +
32 +{{velocity}}
33 +
3 3  ## Подключаем необходимые JS/CSS для работы вкладок
4 4  $xwiki.jsfx.use('uicomponents/widgets/tabView.js', {'forceSkinAction': true, 'language': 'xwiki/2.1'})
5 5  $xwiki.ssfx.use('uicomponents/widgets/tabView.css', true)
... ... @@ -15,12 +15,6 @@
15 15   attachmentsTab.click();
16 16   }
17 17   // Альтернативный вариант (если не сработал ID):
18 - else {
19 - var tabs = $$('.tab-menu a').find(function(tab) {
20 - return tab.textContent.trim().includes('Вложения');
21 - });
22 - if (tabs && tabs.length > 0) tabs[0].click();
23 - }
24 24  });
25 25  </script>
26 26  {{/html}}
... ... @@ -27,63 +27,227 @@
27 27  {{/velocity}}
28 28  
29 29  {{velocity}}
55 +=== Прикрепите вложения и используйте кнопки для навигации ===
56 +#set($spaceRef = $doc.documentReference.lastSpaceReference.name)
57 +#set($pageName = $doc.documentReference.name)
58 +#set($docFullName = "${spaceRef}.${pageName}")
30 30  #set($attachments = $doc.getAttachmentList())
31 -#foreach($attachment in $attachments)
32 - #set($filename = $attachment.filename)
33 - #set($fileurl = $doc.getAttachmentURL($filename))
34 - #set($fileExt = $filename.substring($filename.lastIndexOf('.') + 1).toLowerCase())
35 -
36 - ## Определяем тип файла
37 - #set($isPdf = $fileExt == 'pdf')
38 - #set($isImage = $fileExt == 'png' || $fileExt == 'jpg' || $fileExt == 'jpeg' || $fileExt == 'gif' || $fileExt == 'bmp' || $fileExt == 'svg')
39 - #set($isOffice = $fileExt == 'doc' || $fileExt == 'docx' || $fileExt == 'xls' || $fileExt == 'xlsx' || $fileExt == 'ppt' || $fileExt == 'pptx' || $fileExt == 'odt' || $fileExt == 'ods' || $fileExt == 'odp')
40 -
41 - ## Обрабатываем только поддерживаемые форматы
42 - #if($isPdf || $isImage || $isOffice)
43 -
44 -
45 - #if($isPdf)
60 +#set($itemsPerPage = 1)
61 +#set($totalPages = ($attachments.size() + $itemsPerPage - 1) / $itemsPerPage)
62 +#set($currentPage = 1)
63 +#if("$!request.page" != "")
64 + #set($currentPage = $mathtool.toInteger($request.page))
65 +#end
66 +#set($startIndex = ($currentPage - 1) * $itemsPerPage)
67 +#set($endIndex = $startIndex + $itemsPerPage - 1)
68 +#if($endIndex >= $attachments.size())
69 + #set($endIndex = $attachments.size() - 1)
70 +#end
71 +
72 +{{html}}
73 +<div class="navigation-controls">
74 + #if($attachments && !$attachments.isEmpty())
75 + <!-- Выпадающий список для выбора вложения -->
76 + <div class="attachment-selector">
77 + <label for="attachment-select">Выберите вложение:</label>
78 + <select id="attachment-select">
79 + #foreach($attachment in $attachments)
80 + <option value="$attachment.filename" #if($velocityCount == $currentPage)selected#end>
81 + $attachment.filename
82 + </option>
83 + #end
84 + </select>
85 + </div>
86 +
87 + <!-- Пагинация -->
88 + <div class="pagination-controls">
89 + #if($currentPage > 1)
90 + #set($prevPage = $currentPage - 1)
91 + <a href="$doc.getURL('view', "page=${prevPage}")" class="btn btn-primary">Назад</a>
92 + #else
93 + <span class="btn btn-disabled">Назад</span>
94 + #end
95 +
96 + <span class="page-info">Страница $currentPage из $totalPages</span>
97 +
98 + #if($currentPage < $totalPages)
99 + #set($nextPage = $currentPage + 1)
100 + <a href="$doc.getURL('view', "page=${nextPage}")" class="btn btn-primary">Далее</a>
101 + #else
102 + <span class="btn btn-disabled">Далее</span>
103 + #end
104 + </div>
105 + #else
106 + <div class="no-attachments-message">
107 + Нет прикрепленных вложений. Пожалуйста, добавьте файлы для просмотра.
108 + </div>
109 + #end
110 +</div>
111 +{{/html}}
112 +
113 +#if($attachments && !$attachments.isEmpty())
114 + #foreach($i in [$startIndex..$endIndex])
115 + #set($attachment = $attachments.get($i))
116 + #set($filename = $attachment.filename)
117 + #set($fileurl = $doc.getAttachmentURL($filename, "download"))
118 + #set($fileExtension = $filename.substring($filename.lastIndexOf('.') + 1).toLowerCase())
119 +
120 + === Документ: $filename ===
121 +
46 46   {{html}}
47 - <div class="pdf-viewer-container">
48 - <iframe
49 - src="/resources/pdfjs/web/viewer.html?file=${fileurl}"
50 - width="100%"
51 - height="600px">
52 - </iframe>
123 + <div class="document-viewer-container" id="document-viewer">
124 + #if($fileExtension == 'pdf')
125 + <!-- PDF Viewer -->
126 + <iframe
127 + id="document-frame"
128 + src="/resources/pdfjs/web/viewer.html?file=${escapetool.url($fileurl)}"
129 + width="100%"
130 + height="600px">
131 + </iframe>
132 + #elseif($fileExtension == 'doc' || $fileExtension == 'docx' || $fileExtension == 'ppt' || $fileExtension == 'pptx' || $fileExtension == 'xls' || $fileExtension == 'xlsx' || $fileExtension == 'mp4')
133 + #if($fileExtension == 'doc' || $fileExtension == 'docx' || $fileExtension == 'ppt' || $fileExtension == 'pptx' || $fileExtension == 'xls' || $fileExtension == 'xlsx')
134 + <!-- Office Viewer -->
135 + #set($officeViewerUrl = "${doc.getURL('view')}?xpage=office&attachment=${escapetool.url($filename)}")
136 + <iframe
137 + id="document-frame"
138 + src="$officeViewerUrl"
139 + width="100%"
140 + height="600px">
141 + </iframe>
142 + #end
143 + #if($fileExtension == 'mp4')
144 + ==ВИДЕО==
145 + <video id="myvideo" width="920" controls>
146 + <source src="${fileurl}" type="video/$fileExtension">
147 + Ваш браузер не поддерживает видео.
148 + </video>
149 + #end
150 + #else
151 + ==Конец==
152 + <div class="unsupported-format">
153 + Формат файла (${fileExtension}) не поддерживается для просмотра.
154 + <a href="${fileurl}">Скачать файл</a>
155 + </div>
156 + #end
53 53   </div>
54 54   {{/html}}
55 -
56 - #elseif($isImage)
57 - [[image:${attachment.filename}]]
58 -
59 - #elseif($isOffice)
60 - {{office attachment="${attachment.filename}" filterStyles="false"/}}
61 -
62 62   #end
63 - #end
160 +#else
161 + {{html}}
162 + <div class="no-attachments-message">
163 + Нет доступных вложений для отображения.
164 + </div>
165 + {{/html}}
64 64  #end
65 65  
66 66  {{html}}
67 67  <style>
68 - .pdf-viewer-container {
170 + .navigation-controls {
171 + display: flex;
172 + flex-direction: column;
173 + gap: 15px;
174 + margin-bottom: 20px;
175 + }
176 + .attachment-selector {
177 + display: flex;
178 + align-items: center;
179 + gap: 10px;
180 + }
181 + .attachment-selector select {
182 + padding: 8px;
183 + border-radius: 4px;
184 + min-width: 300px;
185 + }
186 + .document-viewer-container {
69 69   margin: 20px 0;
70 70   border: 1px solid #eee;
71 71   padding: 10px;
72 72   background: #f9f9f9;
73 73   }
74 -
75 - /* Стили для изображений */
76 - .image-wrapper {
77 - max-width: 100%;
78 - margin: 10px 0;
192 + .pagination-controls {
193 + margin: 20px 0;
194 + display: flex;
195 + justify-content: center;
196 + align-items: center;
197 + gap: 20px;
79 79   }
80 -
81 - /* Стили для офисных документов */
82 - .office-document {
83 - border: 1px solid #ddd;
84 - margin: 15px 0;
85 - min-height: 500px;
199 + .btn {
200 + padding: 8px 16px;
201 + border-radius: 4px;
202 + text-decoration: none;
86 86   }
204 + .btn-primary {
205 + background-color: #3366cc;
206 + color: white;
207 + }
208 + .btn-disabled {
209 + background-color: #eee;
210 + color: #999;
211 + cursor: not-allowed;
212 + }
213 + .page-info {
214 + font-weight: bold;
215 + }
216 + .unsupported-format {
217 + padding: 20px;
218 + text-align: center;
219 + color: #666;
220 + }
221 + .no-attachments-message {
222 + padding: 20px;
223 + text-align: center;
224 + color: #666;
225 + font-style: italic;
226 + border: 1px dashed #ccc;
227 + background-color: #f5f5f5;
228 + }
87 87  </style>
230 +
231 +<script>
232 +//<![CDATA[
233 +document.addEventListener('DOMContentLoaded', function() {
234 + const select = document.getElementById('attachment-select');
235 + const viewerContainer = document.getElementById('document-viewer');
236 +
237 + if (select && viewerContainer) {
238 + select.addEventListener('change', function() {
239 + const filename = this.value;
240 + const fileExtension = filename.split('.').pop().toLowerCase();
241 + const fileurl = "${doc.getURL('download')}" + "/" + encodeURIComponent(filename);
242 + const pdfViewerUrl = "/resources/pdfjs/web/viewer.html?file=" + encodeURIComponent(fileurl);
243 + const baseUrl = "${doc.getURL('view')}";
244 +
245 + let viewerHtml = '';
246 +
247 + if (fileExtension === 'pdf') {
248 + viewerHtml = '<iframe id="document-frame" ' +
249 + 'src="' + pdfViewerUrl + '" ' +
250 + 'width="100%" height="600px"></iframe>';
251 + } else if (['doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx'].indexOf(fileExtension) >= 0) {
252 + viewerHtml = '<iframe id="document-frame" ' +
253 + 'src="' + baseUrl + '?xpage=office&attachment=' + encodeURIComponent(filename) + '" ' +
254 + 'width="100%" height="600px"></iframe>';
255 + } else if (fileExtension === 'mp4'||fileExtension === 'mov') {
256 + viewerHtml = '<video width="920" controls>' +
257 + '<source src="' + fileurl + '" type="video/' + fileExtension + '">' +
258 + 'Ваш браузер не поддерживает видео.</video>';
259 +} else {
260 + viewerHtml = '<div class="unsupported-format">' +
261 + 'Формат файла (' + fileExtension + ') не поддерживается для просмотра. ' +
262 + '<a href="' + fileurl + '">Скачать файл</a></div>';
263 + }
264 +
265 + viewerContainer.innerHTML = viewerHtml;
266 +
267 + // Обновляем заголовок документа
268 + const titleElement = viewerContainer.previousElementSibling;
269 + if (titleElement && titleElement.tagName === 'H3') {
270 + titleElement.textContent = 'Документ: ' + filename;
271 + }
272 + });
273 + }
274 +});
275 +//]]>
276 +</script>
88 88  {{/html}}
89 89  {{/velocity}}