PageSourceSearch

https://qhbio.ac.cn/static/javascripts/picgalleryNew.js

js qhbio.ac.cn collected 2026-10-07 22:53:07 UTC 14,934 bytes, 371 lines download raw bytes

1/**
2 * @Author zhangying
3 * @Date 2024/06
4 * @前置操作:先用image_resize_v5.js把所有图片进行裁剪,然后用list2excel.js把文件夹名称生成excel后导入数据库
5 * 后台读取数据库,获得文件夹总数,即数据量,用于分页
6 * 读取对象存储里的文件夹后,通过遍历,再把每个文件夹里的下一级目录,即文件夹里的图片对象数据写入数组,然后通过渲染写入data-lgallery属性中
7 * 这样只需要执行一次AJAX,避免了因为AJAX循环嵌套导致的图片插件(initLG())不可用问题
8 **/
9layui.use(function () {
10  var laypage = layui.laypage;
11  $.ajax({
12    type: "GET",
13    url: "/api/CurlRequest4AnimalsV2",
14    data: {
15      page: 0, // 当前页码
16      size: 9, // 每页数量(3行展示)
17    },
18    success: function (result) {
19      if (result.code === 200) {
20        // layer.msg(result.count);
21        let files = result.data;
22        let dataCount = result.dataCount;
23        laypage.render({
24          elem: "layui_page",
25          count: dataCount,
26          limit: 9, //每页显示的条数(3行展示)
27          jump: function (obj, first) {
28            //设置每页显示的内容
29            var thisData = files.concat().splice(obj.curr * obj.limit - obj.limit, obj.limit);
30            // console.log(thisData)
31            $("#pic_gallery_container").empty();
32            for (i = 0; i < thisData.length; i++) {
33              // 原逻辑:遍历 files 数组
34              // let data_lgallery = [];
35              // for(j=0;j<thisData[i].files.length;j++){
36              //   let url = thisData[i].files[j].download_url.replace("http://", "https://");
37              //   data_lgallery.push(url);
38              // }
39              // $("#pic_gallery_container").append('<div class="TemplateLgallery layui-col-lg3 layui-col-md3" data-lgallery="' + data_lgallery + '" data-lghover="300">' + '<div class="TemplateLgallery-Item">' + '<img src="' + thisData[i].files[0].download_url.replace("http://", "https://") + '" alt="" />' + '</div>' + '<button class="layui-btn layui-btn-fluid">' + thisData[i].spename + '</button>' + '</div>');
40
41              // 新逻辑:后端 V2 返回字段为 download_url(数组),而非 files
42              var urls = Array.isArray(thisData[i].download_url) ? thisData[i].download_url : [];
43              if (urls.length === 0) {
44                continue;
45              }
46              var data_lgallery = urls.map(function (u) {
47                return u.replace("http://", "https://");
48              });
49              var cover = data_lgallery[0];
50              $("#pic_gallery_container").append(
51                '<div class="TemplateLgallery layui-col-lg3 layui-col-md3" data-lgallery="' +
52                  data_lgallery +
53                  '" data-lghover="300">' +
54                  '<div class="TemplateLgallery-Item">' +
55                  '<img src="' +
56                  cover +
57                  '" alt="" />' +
58                  "</div>" +
59                  '<button class="layui-btn layui-btn-fluid">' +
60                  thisData[i].spename +
61                  "</button>" +
62                  "</div>",
63              );
64            }
65            slowScrolling();
66            let x = initLG();
67            if (!first) {
68              // 这里可以发起AJAX请求,获取对应页码的数据
69              console.log("跳转到第 " + obj.curr + " 页,每页显示 " + obj.limit + " 条。");
70              $.ajax({
71                url: "/api/CurlRequest4AnimalsV2",
72                type: "GET",
73                data: {
74                  page: obj.curr, //当前页码
75                  size: obj.limit, //每页数量
76                },
77                success: function (res) {
78                  console.log(res);
79                  let thisData = res.data;
80                  let dataCount = result.dataCount;
81                  //设置每页显示的内容
82                  // var thisData = files.concat().splice(obj.curr*obj.limit - obj.limit, obj.limit);
83                  $("#pic_gallery_container").empty();
84                  for (i = 0; i < thisData.length; i++) {
85                    // 原逻辑:遍历 files 数组
86                    // let data_lgallery = [];
87                    // for(j=0;j<thisData[i].files.length;j++){
88                    //     let url = thisData[i].files[j].download_url.replace("http://", "https://");
89                    //     data_lgallery.push(url);
90                    // }
91                    // $("#pic_gallery_container").append('<div class="TemplateLgallery layui-col-lg3 layui-col-md3" data-lgallery="' + data_lgallery + '" data-lghover="300">' + '<div class="TemplateLgallery-Item">' + '<img src="' + thisData[i].files[0].download_url.replace("http://", "https://") + '" alt="" />' + '</div>' + '<button class="layui-btn layui-btn-fluid">' + thisData[i].spename + '</button>' + '</div>');
92
93                    // 新逻辑:V2 返回 download_url 字段
94                    var urls = Array.isArray(thisData[i].download_url) ? thisData[i].download_url : [];
95                    if (urls.length === 0) {
96                      continue;
97                    }
98                    var data_lgallery = urls.map(function (u) {
99                      return u.replace("http://", "https://");
100                    });
101                    var cover = data_lgallery[0];
102                    $("#pic_gallery_container").append(
103                      '<div class="TemplateLgallery layui-col-lg3 layui-col-md3" data-lgallery="' +
104                        data_lgallery +
105                        '" data-lghover="300">' +
106                        '<div class="TemplateLgallery-Item">' +
107                        '<img src="' +
108                        cover +
109                        '" alt="" />' +
110                        "</div>" +
111                        '<button class="layui-btn layui-btn-fluid">' +
112                        thisData[i].spename +
113                        "</button>" +
114                        "</div>",
115                    );
116                  }
117                  slowScrolling();
118                  let x = initLG();
119                },
120                error: function (err) {
121                  //处理错误
122                  console.log("Error:" + err);
123                },
124              });
125            }
126          },
127        });
128      }
129    },
130    error: function () {
131      alert("获取数据列表失败!");
132    },
133  });
134});
135
136$.ajax({
137  url: "/api/GetAnimalsPicName",
138  type: "GET",
139  success: function (data) {
140    var result = data;
141    $("#piclistFilter_table").dataTable({
142      // "searching": false,
143      paging: true,
144      pageLength: 15,
145      // "ordering": false,
146      // "info": false,
147      language: {
148        sProcessing: "处理中...",
149        sLengthMenu: "显示 _MENU_ 项结果",
150        sZeroRecords: "没有匹配结果",
151        sInfo: "共 _TOTAL_ 种",
152        sInfoEmpty: "共 0 种",
153        sInfoFiltered: "(由 _MAX_ 项结果过滤)",
154        sInfoPostFix: "",
155        sSearch: "物种搜索:",
156        sUrl: "",
157        sEmptyTable: "表中数据为空",
158        sLoadingRecords: "载入中...",
159        sInfoThousands: ",",
160        oPaginate: {
161          sFirst: "<<",
162          sPrevious: "<",
163          sNext: ">",
164          sLast: ">>",
165        },
166        oAria: {
167          sSortAscending: ": 以升序排列此列",
168          sSortDescending: ": 以降序排列此列",
169        },
170      },
171      pagingType: "full_numbers",
172      columns: [
173        {
174          data: "name",
175          title: "物种名称",
176        },
177        {
178          data: "category",
179          title: "物种类别",
180          render: function (cat) {
181            if (cat === "animals") return "脊椎动物";
182            if (cat === "plants") return "维管植物";
183            if (cat === "fungi") return "大型真菌";
184            return cat || "-";
185          },
186        },
187      ],
188      data: result.data,
189      rowCallback: function (row, data, index) {
190        // 为每一行添加点击事件
191        $(row)
192          .off("click")
193          .on("click", function () {
194            // 1. 高亮选中行
195            $("#piclistFilter_table tbody tr").removeClass("selected-row");
196            $(row).addClass("selected-row");
197            // 2. 显示选中物种名
198            var catLabel = (function (cat) {
199              if (cat === "animals") return "脊椎动物";
200              if (cat === "plants") return "维管植物";
201              if (cat === "fungi") return "大型真菌";
202              return cat || "-";
203            })(data.category);
204            var showName = (data.name || "") + "(" + catLabel + ")";
205            if ($("#selected_species_name").length === 0) {
206              $(".picGallery_right_div").prepend('<div id="selected_species_name" style="font-size:16px;font-weight:bold;margin-bottom:10px;display:none;"></div>');
207            }
208            $("#selected_species_name").text(showName).show();
209            // 3. 调用图片加载
210            showSpePicsTask(data.raw_name || data.name, data.category || "animals");
211          });
212      },
213    });
214    // 初始不自动切换到单物种展示,保留右侧12物种网格
215    // if (Array.isArray(result.data) && result.data.length > 0) {
216    //   showSpePicsTask(result.data[0].name);
217    // }
218  },
219  error: function (jqXHR, textStatus, errorThrown) {
220    console.log("请求失败:", textStatus);
221  },
222});
223
224function slowScrolling() {
225  let anchors = document.querySelectorAll('a[href*="#"]');
226
227  for (let anchor of anchors) {
228    anchor.addEventListener("click", function (e) {
229      e.preventDefault();
230
231      let blockID = anchor.getAttribute("href");
232
233      document.querySelector("" + blockID).scrollIntoView({
234        behavior: "smooth",
235        block: "start",
236      });
237    });
238  }
239}
240
241function showSpePicsTask(spename, category) {
242  $.ajax({
243    url: "/api/startCurlRequest4Animals",
244    type: "GET",
245    data: { cname: spename, category: category || "animals" },
246    success: function (res) {
247      var files = [];
248      if (res && Array.isArray(res.files)) {
249        files = res.files.map(function (it) {
250          return String(it.download_url).replace("http://", "https://");
251        });
252      } else if (res && Array.isArray(res.data)) {
253        files = res.data.map(function (u) {
254          return String(u).replace("http://", "https://");
255        });
256      }
257      // 1. 保持选中物种名显示
258      if ($("#selected_species_name").length > 0) {
259        $("#selected_species_name").show();
260      }
261      // 2. 图片为0时提示
262      if (files.length === 0) {
263        $("#pic_gallery_container").empty().append('<div style="color:#d32f2f;font-size:15px;padding:20px 0;">该物种图片数量暂无</div>');
264        $("#layui_page").empty();
265        return;
266      }
267      // 3. 正常渲染图片
268      $("#pic_gallery_container").empty();
269      $("#layui_page").empty();
270      $("#pic_gallery_container").append(`
271        <div id="image-gallery">
272            <div class="gallery-container">
273                <div class="image-list"></div>
274            </div>
275            <div class="spe_pagination"></div>
276            <div class="modal" id="imageModal">
277                <span class="close" id="closeModal">&times;</span>
278                <div class="modal-content-wrapper">
279                    <img class="modal-content" id="img01">
280                    <div class="nav-buttons">
281                        <button class="prev" id="prevBtn" disabled>&lt;</button>
282                        <button class="next" id="nextBtn">&gt;</button>
283                    </div>
284                </div>
285            </div>
286        </div>
287      `);
288      const imagesPerPage = 12;
289      let currentPage = 1;
290      let totalPages = 1;
291      let currentModalIndex = -1;
292      let images = files.slice();
293      let totalCount = files.length;
294      totalPages = Math.ceil(totalCount / imagesPerPage);
295      renderImages(currentPage);
296      setupPagination();
297      function renderImages(page) {
298        const startIndex = (page - 1) * imagesPerPage;
299        const endIndex = startIndex + imagesPerPage;
300        const pageImages = images.slice(startIndex, endIndex);
301        const imageList = document.querySelector(".image-list");
302        imageList.innerHTML = "";
303        pageImages.forEach((img, index) => {
304          const imgElement = document.createElement("img");
305          imgElement.src = img;
306          imgElement.dataset.index = startIndex + index;
307          imgElement.addEventListener("click", showModal);
308          imageList.appendChild(imgElement);
309        });
310      }
311      function setupPagination() {
312        const pagination = document.querySelector(".spe_pagination");
313        pagination.innerHTML = "";
314        for (let i = 1; i <= totalPages; i++) {
315          const button = document.createElement("button");
316          button.textContent = i;
317          button.addEventListener("click", () => {
318            currentPage = i;
319            renderImages(currentPage);
320          });
321          pagination.appendChild(button);
322        }
323      }
324      function showModal(event) {
325        const modal = document.getElementById("imageModal");
326        const modalImg = document.getElementById("img01");
327        const index = parseInt(event.target.dataset.index, 10);
328        currentModalIndex = index;
329        updateModalButtons();
330        modal.style.display = "block";
331        modalImg.src = images[index];
332      }
333      function updateModalButtons() {
334        const prevBtn = document.getElementById("prevBtn");
335        const nextBtn = document.getElementById("nextBtn");
336        prevBtn.disabled = currentModalIndex === 0;
337        nextBtn.disabled = currentModalIndex === images.length - 1;
338      }
339      document.getElementById("prevBtn").addEventListener("click", function () {
340        if (currentModalIndex > 0) {
341          currentModalIndex--;
342          document.getElementById("img01").src = images[currentModalIndex];
343          updateModalButtons();
344        }
345      });
346      document.getElementById("nextBtn").addEventListener("click", function () {
347        if (currentModalIndex < images.length - 1) {
348          currentModalIndex++;
349          document.getElementById("img01").src = images[currentModalIndex];
350          updateModalButtons();
351        }
352      });
353      const span = document.getElementsByClassName("close")[0];
354      span.addEventListener("click", function () {
355        document.getElementById("imageModal").style.display = "none";
356        currentModalIndex = -1;
357        updateModalButtons();
358      });
359      window.onclick = function (event) {
360        if (event.target == document.getElementById("imageModal")) {
361          document.getElementById("imageModal").style.display = "none";
362          currentModalIndex = -1;
363          updateModalButtons();
364        }
365      };
366    },
367    error: function (err) {
368      console.log("Error:", err);
369    },
370  });
371}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.