download.blade.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. @extends('library.layouts.app')
  2. @section('title', __('labels.home'))
  3. @section('content')
  4. <div class="page-body">
  5. <div class="container-xl">
  6. <div class="page-header d-print-none">
  7. <div class="row align-items-center">
  8. <div class="col">
  9. <h2 class="page-title">下载</h2>
  10. <div class="text-muted mt-1">APP 离线数据包</div>
  11. </div>
  12. <div class="col-auto ms-auto">
  13. <span class="badge bg-blue-lt fs-6">{{ count($packets) }} 个数据包</span>
  14. </div>
  15. </div>
  16. </div>
  17. <div class="card">
  18. <div class="card-header">
  19. <h3 class="card-title">
  20. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-archive me-2" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  21. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  22. <path d="M3 4m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z" />
  23. <path d="M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10" />
  24. <path d="M10 12l2 2l2 -2" />
  25. </svg>
  26. 离线数据包
  27. </h3>
  28. </div>
  29. @php
  30. function formatFilesize(int $size): string {
  31. if ($size >= 1048576) return number_format($size / 1048576, 2) . ' MB';
  32. if ($size >= 1024) return number_format($size / 1024, 1) . ' KB';
  33. return $size . ' B';
  34. }
  35. @endphp
  36. @if(empty($packets))
  37. {{-- ── Empty state ── --}}
  38. <div class="card-body">
  39. <div class="empty">
  40. <div class="empty-icon">
  41. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-inbox-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  42. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  43. <path d="M8 4h11a2 2 0 0 1 2 2v9m-1.172 2.821a2 2 0 0 1 -.828 .179h-14a2 2 0 0 1 -2 -2v-9a2 2 0 0 1 1.172 -1.821" />
  44. <path d="M4 12h4l3 3h2l3 -3h1" />
  45. <path d="M3 3l18 18" />
  46. </svg>
  47. </div>
  48. <p class="empty-title">暂无数据包</p>
  49. <p class="empty-subtitle text-muted">当前没有可用的离线数据包。</p>
  50. </div>
  51. </div>
  52. @else
  53. {{-- ════════════════════════════════════════════
  54. ① 桌面端 Table ≥ md (768px)
  55. ════════════════════════════════════════════ --}}
  56. <div class="d-none d-md-block table-responsive">
  57. <table class="table table-vcenter card-table table-hover">
  58. <thead>
  59. <tr>
  60. <th>数据包名称</th>
  61. <th class="text-center" style="width:90px">文件大小</th>
  62. <th class="text-center" style="width:90px">最低版本</th>
  63. <th class="text-center" style="width:160px">创建时间</th>
  64. <th style="min-width:240px">下载链接</th>
  65. </tr>
  66. </thead>
  67. <tbody>
  68. @foreach($packets as $packet)
  69. <tr>
  70. {{-- 名称 --}}
  71. <td>
  72. <div class="d-flex align-items-center">
  73. <span class="avatar avatar-sm me-3 bg-blue-lt text-blue">
  74. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-zip" width="20" height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  75. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  76. <path d="M6 20.735a2 2 0 0 1 -1 -1.735v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-1" />
  77. <path d="M11 17a2 2 0 0 1 2 2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-2a2 2 0 0 1 2 -2z" />
  78. <path d="M11 5l-1 0" />
  79. <path d="M13 7l-1 0" />
  80. <path d="M11 9l-1 0" />
  81. <path d="M13 11l-1 0" />
  82. <path d="M11 13l-1 0" />
  83. <path d="M13 15l-1 0" />
  84. </svg>
  85. </span>
  86. <div>
  87. <div class="fw-semibold text-body">{{ $packet['title'] ?? $packet['id'] }}</div>
  88. <div class="text-muted small font-monospace">{{ $packet['filename'] ?? '' }}</div>
  89. </div>
  90. </div>
  91. </td>
  92. {{-- 大小 --}}
  93. <td class="text-center">
  94. <span class="badge bg-azure-lt text-azure">
  95. {{ formatFilesize((int)($packet['filesize'] ?? 0)) }}
  96. </span>
  97. </td>
  98. {{-- 最低版本 --}}
  99. <td class="text-center">
  100. @if(!empty($packet['min_app_ver']))
  101. <span class="badge bg-lime-lt text-lime">v{{ $packet['min_app_ver'] }}</span>
  102. @else
  103. <span class="text-muted">—</span>
  104. @endif
  105. </td>
  106. {{-- 创建时间 --}}
  107. <td class="text-center text-muted small">
  108. {{ $packet['create_at'] ?? '—' }}
  109. </td>
  110. {{-- 下载链接 --}}
  111. <td>
  112. @if(!empty($packet['url']) && is_array($packet['url']))
  113. <div class="d-flex flex-wrap gap-2">
  114. @foreach($packet['url'] as $index => $urlItem)
  115. <a href="{{ $urlItem['link'] }}"
  116. class="btn btn-sm {{ $index === 0 ? 'btn-primary' : 'btn-outline-secondary' }}"
  117. target="_blank" rel="noopener noreferrer"
  118. title="{{ $urlItem['hostname'] ?? '' }}">
  119. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-download me-1" width="16" height="16" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  120. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  121. <path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2" />
  122. <path d="M7 11l5 5l5 -5" />
  123. <path d="M12 4l0 12" />
  124. </svg>
  125. {{ $urlItem['hostname'] ?? '下载' }}
  126. </a>
  127. @endforeach
  128. </div>
  129. @else
  130. <span class="text-muted">暂无链接</span>
  131. @endif
  132. </td>
  133. </tr>
  134. @endforeach
  135. </tbody>
  136. </table>
  137. </div>
  138. {{-- ════════════════════════════════════════════
  139. ② 移动端 Card list < md (768px)
  140. ════════════════════════════════════════════ --}}
  141. <div class="d-md-none">
  142. <div class="list-group list-group-flush">
  143. @foreach($packets as $packet)
  144. <div class="list-group-item p-3">
  145. {{-- 顶部:图标 + 标题 + 大小 badge --}}
  146. <div class="d-flex align-items-start gap-3">
  147. <span class="avatar avatar-md bg-blue-lt text-blue flex-shrink-0">
  148. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-file-zip" width="22" height="22" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  149. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  150. <path d="M6 20.735a2 2 0 0 1 -1 -1.735v-14a2 2 0 0 1 2 -2h7l5 5v11a2 2 0 0 1 -2 2h-1" />
  151. <path d="M11 17a2 2 0 0 1 2 2v2a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-2a2 2 0 0 1 2 -2z" />
  152. <path d="M11 5l-1 0" />
  153. <path d="M13 7l-1 0" />
  154. <path d="M11 9l-1 0" />
  155. <path d="M13 11l-1 0" />
  156. <path d="M11 13l-1 0" />
  157. <path d="M13 15l-1 0" />
  158. </svg>
  159. </span>
  160. <div class="flex-fill min-w-0 overflow-hidden">
  161. <div class="fw-semibold text-body text-truncate">{{ $packet['title'] ?? $packet['id'] }}</div>
  162. <div class="text-muted small font-monospace text-truncate">
  163. {{ $packet['filename'] ?? '' }}
  164. </div>
  165. </div>
  166. <span class="badge bg-azure-lt text-azure flex-shrink-0">
  167. {{ formatFilesize((int)($packet['filesize'] ?? 0)) }}
  168. </span>
  169. </div>
  170. {{-- 中部:时间 + 最低版本 --}}
  171. <div class="d-flex flex-wrap align-items-center gap-2 mt-2 ps-1">
  172. <span class="text-muted small">
  173. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar me-1" width="14" height="14" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  174. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  175. <path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12z" />
  176. <path d="M16 3v4" />
  177. <path d="M8 3v4" />
  178. <path d="M4 11h16" />
  179. <path d="M11 15h1" />
  180. <path d="M12 15v3" />
  181. </svg>
  182. {{ $packet['create_at'] ?? '—' }}
  183. </span>
  184. @if(!empty($packet['min_app_ver']))
  185. <span class="badge bg-lime-lt text-lime">
  186. 最低版本 v{{ $packet['min_app_ver'] }}
  187. </span>
  188. @endif
  189. </div>
  190. {{-- 底部:下载按钮,全宽竖排 --}}
  191. @if(!empty($packet['url']) && is_array($packet['url']))
  192. <div class="d-flex flex-column gap-2 mt-3">
  193. @foreach($packet['url'] as $index => $urlItem)
  194. <a href="{{ $urlItem['link'] }}"
  195. class="btn btn-sm {{ $index === 0 ? 'btn-primary' : 'btn-outline-secondary' }} w-100"
  196. target="_blank" rel="noopener noreferrer">
  197. <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-download me-1" width="16" height="16" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
  198. <path stroke="none" d="M0 0h24v24H0z" fill="none" />
  199. <path d="M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-2" />
  200. <path d="M7 11l5 5l5 -5" />
  201. <path d="M12 4l0 12" />
  202. </svg>
  203. {{ $urlItem['hostname'] ?? '下载' }}
  204. </a>
  205. @endforeach
  206. </div>
  207. @endif
  208. </div>{{-- /.list-group-item --}}
  209. @endforeach
  210. </div>
  211. </div>
  212. @endif
  213. </div>{{-- /.card --}}
  214. </div>
  215. </div>
  216. @endsection