Изменения документа Инструкция по работе с мобильным приложением X-Lance
Редактировал(а) Кристина Гришкина 10.10.2025
От версии 2.2
отредактировано Alexey Semenihin
на 10.10.2025
на 10.10.2025
Изменить комментарий:
Добавлен тег [Мобильное приложение, Согласование документа, согласование изменений, ссылка на приложение, работа в приложении, вход в приложение, авторизация в приложении]
К версии 3.1
отредактировано Кристина Гришкина
на 10.10.2025
на 10.10.2025
Изменить комментарий:
К данной версии нет комментариев
Сводка
-
Свойства страницы (2 изменено, 0 добавлено, 0 удалено)
Подробности
- Свойства страницы
-
- Автор документа
-
... ... @@ -1,1 +1,1 @@ 1 -xwiki:XWiki. semenihinaa1 +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}}