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

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

Сводка

Подробности

Свойства страницы
Автор документа
... ... @@ -1,1 +1,1 @@
1 -xwiki:XWiki.semenihinaa
1 +xwiki:XWiki.grishkinakn
Содержимое
... ... @@ -1,36 +1,5 @@
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}}
30 30  
31 -
32 -{{velocity}}
33 -
34 34  ## Подключаем необходимые JS/CSS для работы вкладок
35 35  $xwiki.jsfx.use('uicomponents/widgets/tabView.js', {'forceSkinAction': true, 'language': 'xwiki/2.1'})
36 36  $xwiki.ssfx.use('uicomponents/widgets/tabView.css', true)
... ... @@ -46,6 +46,12 @@
46 46   attachmentsTab.click();
47 47   }
48 48   // Альтернативный вариант (если не сработал 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 + }
49 49  });
50 50  </script>
51 51  {{/html}}
... ... @@ -52,227 +52,63 @@
52 52  {{/velocity}}
53 53  
54 54  {{velocity}}
55 -=== Прикрепите вложения и используйте кнопки для навигации ===
56 -#set($spaceRef = $doc.documentReference.lastSpaceReference.name)
57 -#set($pageName = $doc.documentReference.name)
58 -#set($docFullName = "${spaceRef}.${pageName}")
59 59  #set($attachments = $doc.getAttachmentList())
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 -
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)
122 122   {{html}}
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
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>
157 157   </div>
158 158   {{/html}}
55 +
56 + #elseif($isImage)
57 + [[image:${attachment.filename}]]
58 +
59 + #elseif($isOffice)
60 + {{office attachment="${attachment.filename}" filterStyles="false"/}}
61 +
159 159   #end
160 -#else
161 - {{html}}
162 - <div class="no-attachments-message">
163 - Нет доступных вложений для отображения.
164 - </div>
165 - {{/html}}
63 + #end
166 166  #end
167 167  
168 168  {{html}}
169 169  <style>
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 {
68 + .pdf-viewer-container {
187 187   margin: 20px 0;
188 188   border: 1px solid #eee;
189 189   padding: 10px;
190 190   background: #f9f9f9;
191 191   }
192 - .pagination-controls {
193 - margin: 20px 0;
194 - display: flex;
195 - justify-content: center;
196 - align-items: center;
197 - gap: 20px;
74 +
75 + /* Стили для изображений */
76 + .image-wrapper {
77 + max-width: 100%;
78 + margin: 10px 0;
198 198   }
199 - .btn {
200 - padding: 8px 16px;
201 - border-radius: 4px;
202 - text-decoration: none;
203 - }
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 - }
229 -</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 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 - });
81 + /* Стили для офисных документов */
82 + .office-document {
83 + border: 1px solid #ddd;
84 + margin: 15px 0;
85 + min-height: 500px;
273 273   }
274 -});
275 -//]]>
276 -</script>
87 +</style>
277 277  {{/html}}
278 278  {{/velocity}}