You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

389 lines
14 KiB

  1. {% extends "layout.html" %}
  2. {% block content %}
  3. <!-- Right Side Navigation Dots -->
  4. <div class="slide-labels" id="slideLabels">
  5. <div class="slide-label active" data-index="0"><span class="dot"></span><span class="txt">首页</span></div>
  6. <div class="slide-label" data-index="1"><span class="dot"></span><span class="txt">数据公示</span></div>
  7. <div class="slide-label" data-index="2"><span class="dot"></span><span class="txt">公益项目</span></div>
  8. <div class="slide-label" data-index="3"><span class="dot"></span><span class="txt">新闻动态</span></div>
  9. <div class="slide-label" data-index="4"><span class="dot"></span><span class="txt">合作伙伴</span></div>
  10. </div>
  11. <!-- Swiper Fullpage -->
  12. <div class="swiper swiper-fullpage" id="fullpageSwiper">
  13. <div class="swiper-wrapper">
  14. <!-- Slide 1: Banner -->
  15. <div class="swiper-slide">
  16. <div class="slide-banner">
  17. <div class="swiper banner-swiper" id="bannerSwiper">
  18. <div class="swiper-wrapper">
  19. {% for banner in banners %}
  20. <div class="swiper-slide">
  21. <div class="banner-slide-bg" style="background-image:url('{{banner.image}}')"></div>
  22. <div class="banner-slide-content pos-{{banner.position | default('left')}}{% if banner.glass %} glass-on{% endif %}">
  23. <h1>{{banner.title}}{% if banner.subtitle %}<br>{{banner.subtitle}}{% endif %}</h1>
  24. {% if banner.description %}
  25. <p class="desc">{{banner.description}}</p>
  26. {% endif %}
  27. <div class="btns">
  28. {% if banner.btn1_show %}
  29. <a href="{{banner.btn1_link}}" class="btn-primary">{{banner.btn1_text}}</a>
  30. {% endif %}
  31. {% if banner.btn2_show %}
  32. <a href="{{banner.btn2_link}}" class="btn-ghost">{{banner.btn2_text}}</a>
  33. {% endif %}
  34. </div>
  35. </div>
  36. </div>
  37. {% endfor %}
  38. </div>
  39. <div class="swiper-pagination"></div>
  40. </div>
  41. <div class="scroll-hint">
  42. <div class="mouse"></div>
  43. <span>SCROLL</span>
  44. </div>
  45. </div>
  46. </div>
  47. <!-- Slide 2: Donation Data -->
  48. <div class="swiper-slide">
  49. <div class="slide-donation">
  50. <div class="donation-wrap">
  51. <div class="section-head">
  52. <h2>捐赠及支出公示</h2>
  53. <div class="en">Every Penny, Tracked with Integrity</div>
  54. </div>
  55. <div class="data-cards">
  56. <div class="data-card">
  57. <div class="label">历年公益捐赠收入</div>
  58. <div class="amount"><span class="countup" data-target="{{donationStat.total_income | default(0)}}">0</span><span class="unit">元</span></div>
  59. <div class="note">截至今日</div>
  60. </div>
  61. <div class="data-card">
  62. <div class="label">本年度捐赠收入</div>
  63. <div class="amount"><span class="countup" data-target="{{donationStat.year_income | default(0)}}">0</span><span class="unit">元</span></div>
  64. <div class="note">本年度</div>
  65. </div>
  66. <div class="data-card">
  67. <div class="label">历年公益支出</div>
  68. <div class="amount"><span class="countup" data-target="{{donationStat.total_expense | default(0)}}">0</span><span class="unit">元</span></div>
  69. <div class="note">截至今日</div>
  70. </div>
  71. </div>
  72. <div class="donation-tables">
  73. <div class="dtable">
  74. <h3>捐赠收入明细</h3>
  75. <div class="dtable-table-wrap">
  76. <table class="dtable-head">
  77. <colgroup><col><col style="width:140px;"></colgroup>
  78. <thead><tr><th>捐赠方</th><th class="td-r">金额</th></tr></thead>
  79. </table>
  80. <div class="dtable-scroll-wrap donation-scroll">
  81. <div class="dtable-scroll-inner">
  82. <table>
  83. <colgroup><col><col style="width:140px;"></colgroup>
  84. <tbody>
  85. {% for item in donationIncome %}
  86. <tr><td>{{item.name}}</td><td class="td-r">{{item.amount}}</td></tr>
  87. {% endfor %}
  88. {% for item in donationIncome %}
  89. <tr><td>{{item.name}}</td><td class="td-r">{{item.amount}}</td></tr>
  90. {% endfor %}
  91. </tbody>
  92. </table>
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. <div class="dtable">
  98. <h3>公益支出明细</h3>
  99. <div class="dtable-table-wrap">
  100. <table class="dtable-head">
  101. <colgroup><col><col style="width:140px;"></colgroup>
  102. <thead><tr><th>支付对象</th><th class="td-r">金额</th></tr></thead>
  103. </table>
  104. <div class="dtable-scroll-wrap donation-scroll">
  105. <div class="dtable-scroll-inner">
  106. <table>
  107. <colgroup><col><col style="width:140px;"></colgroup>
  108. <tbody>
  109. {% for item in donationExpense %}
  110. <tr><td>{{item.name}}</td><td class="td-r">{{item.amount}}</td></tr>
  111. {% endfor %}
  112. {% for item in donationExpense %}
  113. <tr><td>{{item.name}}</td><td class="td-r">{{item.amount}}</td></tr>
  114. {% endfor %}
  115. </tbody>
  116. </table>
  117. </div>
  118. </div>
  119. </div>
  120. </div>
  121. <div class="dtable dtable-drug">
  122. <h3>药品援助公示</h3>
  123. <div class="dtable-table-wrap">
  124. <table>
  125. <thead><tr><th>发放日期</th><th>患者姓名</th><th>地区</th><th>药品名称</th></tr></thead>
  126. </table>
  127. <div class="drug-scroll-wrap">
  128. <div class="drug-scroll-inner">
  129. <table>
  130. <tbody>
  131. {% for item in medicines %}
  132. <tr>
  133. <td>{{item.distribute_date}}</td>
  134. <td>{{item.person}}</td>
  135. <td>{{item.region}}</td>
  136. <td class="drug-name">{{item.name}}</td>
  137. </tr>
  138. {% endfor %}
  139. {% for item in medicines %}
  140. <tr>
  141. <td>{{item.distribute_date}}</td>
  142. <td>{{item.person}}</td>
  143. <td>{{item.region}}</td>
  144. <td class="drug-name">{{item.name}}</td>
  145. </tr>
  146. {% endfor %}
  147. </tbody>
  148. </table>
  149. </div>
  150. </div>
  151. </div>
  152. </div>
  153. </div>
  154. </div>
  155. </div>
  156. </div>
  157. <!-- Slide 3: Projects -->
  158. <div class="swiper-slide">
  159. <div class="slide-projects" id="slideProjects">
  160. <!-- Background images -->
  161. {% for proj in projects %}
  162. <div class="proj-bg{% if loop.index == 1 %} active{% endif %}" style="background-image:url('{{proj.cover}}')"></div>
  163. {% endfor %}
  164. <!-- Info card -->
  165. <div class="proj-info-card" id="projInfoCard">
  166. <div class="card-label">项目介绍</div>
  167. <h3 id="projTitle">{% if projects[0] %}{{projects[0].title}}{% endif %}</h3>
  168. <div class="card-divider"></div>
  169. <p id="projDesc">{% if projects[0] %}{{projects[0].summary}}{% endif %}</p>
  170. <a href="#" class="card-btn" id="projLink">了解详情 →</a>
  171. </div>
  172. <!-- Bottom tabs -->
  173. <div class="proj-tabs" id="projTabs">
  174. {% for proj in projects %}
  175. <div class="proj-tab{% if loop.index == 1 %} active{% endif %}" data-index="{{loop.index0}}">{{proj.title}}</div>
  176. {% endfor %}
  177. </div>
  178. <a href="/project.html" class="proj-more-link">查看全部项目</a>
  179. </div>
  180. </div>
  181. <!-- Slide 4: News -->
  182. <div class="swiper-slide">
  183. <div class="slide-news">
  184. <div class="news-wrap">
  185. <div class="section-head">
  186. <h2>新闻 &amp; 动态</h2>
  187. <div class="en">Latest News and Updates</div>
  188. </div>
  189. <div class="news-grid">
  190. {% if newsList[0] %}
  191. <a href="/news/detail/{{newsList[0].id}}.html" class="news-featured">
  192. <img src="{{newsList[0].cover}}" alt="{{newsList[0].title}}">
  193. <div class="overlay">
  194. <h3>{{newsList[0].title}}</h3>
  195. <div class="date">{{newsList[0].publish_date}}</div>
  196. </div>
  197. </a>
  198. {% endif %}
  199. <div class="news-list">
  200. {% for news in newsList %}
  201. {% if loop.index > 1 %}
  202. <a href="/news/detail/{{news.id}}.html" class="news-item">
  203. <div class="date-box">
  204. <div class="day">{{news.publish_day}}</div>
  205. <div class="ym">{{news.publish_ym}}</div>
  206. </div>
  207. <div class="text">
  208. <h4>{{news.title}}</h4>
  209. <p>{{news.summary}}</p>
  210. </div>
  211. </a>
  212. {% endif %}
  213. {% endfor %}
  214. <div style="text-align:right;padding-top:12px;">
  215. <a href="/news.html" class="more-link">更多新闻 →</a>
  216. </div>
  217. </div>
  218. </div>
  219. </div>
  220. </div>
  221. </div>
  222. <!-- Slide 5: Partners + Footer -->
  223. <div class="swiper-slide">
  224. <div class="slide-footer">
  225. <div class="partners-section">
  226. <div class="section-head">
  227. <h2>合作伙伴</h2>
  228. <div class="en">Thank You for Your Cooperation on the Way to Charity</div>
  229. </div>
  230. <div class="partners-grid">
  231. {% for partner in partners %}
  232. <div class="partner-item">
  233. {% if partner.link %}
  234. <a href="{{partner.link}}" target="_blank"><img src="{{partner.image}}" alt="{{partner.title}}"></a>
  235. {% else %}
  236. <img src="{{partner.image}}" alt="{{partner.title}}">
  237. {% endif %}
  238. </div>
  239. {% endfor %}
  240. </div>
  241. </div>
  242. {% include "common/_footer.html" %}
  243. </div>
  244. </div>
  245. </div>
  246. </div>
  247. {% endblock %}
  248. {% block js %}
  249. <script>
  250. // Project data for tab switching
  251. var projData = [
  252. {% for proj in projects %}
  253. { title: '{{proj.title}}', desc: '{{proj.summary}}', link: '/project/detail/{{proj.id}}.html' }{% if not loop.last %},{% endif %}
  254. {% endfor %}
  255. ];
  256. (function(){
  257. var labels = document.getElementById('slideLabels');
  258. var labelItems = labels.querySelectorAll('.slide-label');
  259. function updateLabels(index) {
  260. labelItems.forEach(function(el, i) {
  261. el.classList.toggle('active', i === index);
  262. });
  263. var lightSlides = [1, 3, 4];
  264. labels.classList.toggle('light', lightSlides.indexOf(index) > -1);
  265. }
  266. // Project tab switching
  267. var projBgs = document.querySelectorAll('.proj-bg');
  268. var projTabs = document.querySelectorAll('.proj-tab');
  269. var projTitle = document.getElementById('projTitle');
  270. var projDesc = document.getElementById('projDesc');
  271. var projLink = document.getElementById('projLink');
  272. var currentProj = 0;
  273. function switchProject(idx) {
  274. projBgs.forEach(function(bg, i) { bg.classList.toggle('active', i === idx); });
  275. projTabs.forEach(function(tab, i) { tab.classList.toggle('active', i === idx); });
  276. if (projData[idx]) {
  277. projTitle.textContent = projData[idx].title;
  278. projDesc.textContent = projData[idx].desc;
  279. projLink.href = projData[idx].link;
  280. }
  281. }
  282. projTabs.forEach(function(tab) {
  283. tab.addEventListener('click', function() {
  284. currentProj = parseInt(this.dataset.index);
  285. switchProject(currentProj);
  286. startProjAuto();
  287. });
  288. });
  289. // Auto-rotate projects
  290. var projTimer = null;
  291. function startProjAuto() {
  292. stopProjAuto();
  293. projTimer = setInterval(function() {
  294. currentProj = (currentProj + 1) % projData.length;
  295. switchProject(currentProj);
  296. }, 5000);
  297. }
  298. function stopProjAuto() { if(projTimer){clearInterval(projTimer);projTimer=null;} }
  299. // Banner Swiper
  300. var bannerSwiper = new Swiper('#bannerSwiper', {
  301. direction: 'horizontal',
  302. loop: true,
  303. speed: 1000,
  304. autoplay: { delay: 5000, disableOnInteraction: false },
  305. effect: 'fade',
  306. fadeEffect: { crossFade: true },
  307. pagination: {
  308. el: '#bannerSwiper .swiper-pagination',
  309. clickable: true,
  310. },
  311. nested: true,
  312. });
  313. // Fullpage Swiper
  314. var fullpage = new Swiper('#fullpageSwiper', {
  315. direction: 'vertical',
  316. speed: 800,
  317. mousewheel: {
  318. sensitivity: 1,
  319. thresholdDelta: 30,
  320. },
  321. keyboard: { enabled: true },
  322. on: {
  323. slideChange: function() {
  324. updateLabels(this.activeIndex);
  325. if(this.activeIndex === 2) { startProjAuto(); } else { stopProjAuto(); }
  326. if(this.activeIndex === 0) { bannerSwiper.autoplay.start(); } else { bannerSwiper.autoplay.stop(); }
  327. if(this.activeIndex === 1) triggerCountUp();
  328. },
  329. init: function() {
  330. updateLabels(0);
  331. }
  332. }
  333. });
  334. // Click labels to navigate
  335. labelItems.forEach(function(el) {
  336. el.addEventListener('click', function() {
  337. fullpage.slideTo(parseInt(this.dataset.index));
  338. });
  339. });
  340. // CountUp animation
  341. function animateCountUp(el) {
  342. var target = parseFloat(el.dataset.target) || 0;
  343. var duration = 2000;
  344. var startTime = performance.now();
  345. var easeOut = function(t) { return 1 - Math.pow(1 - t, 3); };
  346. function update(now) {
  347. var elapsed = now - startTime;
  348. var progress = Math.min(elapsed / duration, 1);
  349. var value = Math.floor(easeOut(progress) * target);
  350. el.textContent = value.toLocaleString();
  351. if (progress < 1) requestAnimationFrame(update);
  352. }
  353. requestAnimationFrame(update);
  354. }
  355. var countUpDone = false;
  356. function triggerCountUp() {
  357. if (countUpDone) return;
  358. countUpDone = true;
  359. document.querySelectorAll('.countup').forEach(function(el) { animateCountUp(el); });
  360. }
  361. })();
  362. </script>
  363. {% endblock %}