sgj
2026-02-25 23ba8d87f56be44209687ee03c8bda3e351412d1
添加地磅抓拍记录页面
已修改2个文件
已添加7个文件
1138 ■■■■■ 文件已修改
fzzy-igdss-core/src/main/java/com/fzzy/igds/domain/WeighbridgeSnap.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/mapper/WeighbridgeSnapMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/EventInfoService.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/WeighbridgeSnapService.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/security/WeighbridgeSnapController.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/java/com/fzzy/security/manager/WeighbridgeSnapManager.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/weighbridgeSnap/weighbridgeSnap-style.css 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/static/security/weighbridgeSnap/weighbridgeSnap.js 432 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-web/src/main/resources/templates/security/weighbridgeSnap.html 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
fzzy-igdss-core/src/main/java/com/fzzy/igds/domain/WeighbridgeSnap.java
@@ -1,13 +1,11 @@
package com.fzzy.igds.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fzzy.igds.constant.WarnStatus;
import com.ruoyi.common.annotation.Excel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.persistence.*;
import javax.persistence.Column;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Date;
@@ -16,14 +14,13 @@
 *
 * @author sgj
 * @since 2026/02/25
 */
@Data
//@Entity
//@Table(name = "d_weighbridge_snap")
//@TableName("d_weighbridge_snap")
//@EqualsAndHashCode(callSuper = false)
public class WeighbridgeSnap  extends BizBaseEntity implements Serializable {
public class WeighbridgeSnap extends BizBaseEntity implements Serializable {
    /**
@@ -84,7 +81,7 @@
    @Column(name = "tags", columnDefinition = "varchar(100) COMMENT '标签(包含车牌和车辆类型)'")
    @TableField("tags")
    private String tags ;
    private String tags;
    @Column(name = "food_variety", columnDefinition = "varchar(7) COMMENT '粮食品种'")
    @TableField("food_variety")
fzzy-igdss-core/src/main/java/com/fzzy/igds/mapper/WeighbridgeSnapMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,8 @@
package com.fzzy.igds.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzzy.igds.domain.WeighbridgeSnap;
public interface WeighbridgeSnapMapper extends BaseMapper<WeighbridgeSnap> {
}
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/EventInfoService.java
@@ -2,14 +2,11 @@
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzzy.igds.data.BaseResp;
import com.fzzy.igds.data.IgdsBaseParam;
import com.fzzy.igds.domain.EventInfo;
import com.fzzy.igds.domain.SnapRecord;
import com.fzzy.igds.mapper.EventInfoMapper;
import com.fzzy.igds.utils.ContextUtil;
import com.fzzy.igds.utils.DateUtil;
import com.fzzy.work.domain.WorkOrder;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -81,7 +78,7 @@
     * @return
     */
    public List<EventInfo> getListByParam(IgdsBaseParam param) {
        if (null == param){
        if (null == param) {
            param = new IgdsBaseParam();
        }
@@ -104,13 +101,14 @@
    /**
     * æŒä¹…化保存
     *
     * @param info
     */
    public void addData(EventInfo info) {
        if(StringUtils.isBlank(info.getId())){
        if (StringUtils.isBlank(info.getId())) {
            info.setId(ContextUtil.generateId());
        }
        if(StringUtils.isBlank(info.getCompanyId())){
        if (StringUtils.isBlank(info.getCompanyId())) {
            info.setCompanyId(ContextUtil.getCompanyId());
        }
fzzy-igdss-core/src/main/java/com/fzzy/igds/service/WeighbridgeSnapService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,135 @@
package com.fzzy.igds.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzzy.igds.data.IgdsBaseParam;
import com.fzzy.igds.domain.WeighbridgeSnap;
import com.fzzy.igds.mapper.WeighbridgeSnapMapper;
import com.fzzy.igds.utils.ContextUtil;
import com.fzzy.igds.utils.DateUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
 * åœ°ç£…抓拍服务类
 *
 * @author sgj
 * @since 2026/02/25
 */
@Slf4j
@Service
public class WeighbridgeSnapService {
    @Resource
    private WeighbridgeSnapMapper weighbridgeSnapMapper;
    /**
     * åˆ†é¡µèŽ·å–åœ°ç£…æŠ“æ‹æ•°æ®
     *
     * @param page  åˆ†é¡µå¯¹è±¡
     * @param param æŸ¥è¯¢å‚æ•°
     * @author sgj
     * @since 2026/02/25
     */
    public void listPage(Page<WeighbridgeSnap> page, IgdsBaseParam param) {
        QueryWrapper<WeighbridgeSnap> queryWrapper = getQueryWrapper(param);
        weighbridgeSnapMapper.selectPage(page, queryWrapper);
    }
    /**
     *
     *
     * @author sgj
     * @since 2026/02/25
     */
    public QueryWrapper<WeighbridgeSnap> getQueryWrapper(IgdsBaseParam param) {
        QueryWrapper<WeighbridgeSnap> queryWrapper = new QueryWrapper<>();
        param.setCompanyId(ContextUtil.getCompanyId());
        queryWrapper.eq("company_id", param.getCompanyId());
        //库区检索
        if (StringUtils.isNotBlank(param.getDeptId())) {
            queryWrapper.eq("dept_id", param.getDeptId());
        }
        //仓库检索
        if (StringUtils.isNotBlank(param.getDepotId())) {
            queryWrapper.eq("depot_id", param.getDepotId());
        }
        // æ”¶å‚¨å…¬å¸æ£€ç´¢
        if (StringUtils.isNotBlank(param.getKey())) {
            queryWrapper.likeRight("dept_id", param.getKey());
        }
        //抓拍时间检索
        if (null != param.getStart()) {
            queryWrapper.ge("time", param.getStart());
        }
        if (null != param.getEnd()) {
            queryWrapper.le("time", param.getEnd());
        }
        //抓拍名称
        if (StringUtils.isNotBlank(param.getName())) {
            queryWrapper.like("name", param.getName());
        }
        queryWrapper.orderByDesc("create_time");
        return queryWrapper;
    }
    /**
     *
     * @param param
     * @return
     */
    public List<WeighbridgeSnap> getListByParam(IgdsBaseParam param) {
        if (null == param) {
            param = new IgdsBaseParam();
        }
        QueryWrapper<WeighbridgeSnap> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(param.getCompanyId())) {
            queryWrapper.eq("company_id", param.getCompanyId());
        }
        if (StringUtils.isNotBlank(param.getDeptId())) {
            queryWrapper.likeRight("dept_id", param.getDeptId());
        }
        if (null != param.getStart()) {
            queryWrapper.ge("time", DateUtil.getCurZero(param.getStart()));
        }
        if (null != param.getEnd()) {
            queryWrapper.le("time", DateUtil.getNextZero(param.getEnd()));
        }
        return weighbridgeSnapMapper.selectList(queryWrapper);
    }
    /**
     * æŒä¹…化保存
     *
     * @param info
     */
    public void addData(WeighbridgeSnap info) {
        if (StringUtils.isBlank(info.getId())) {
            info.setId(ContextUtil.generateId());
        }
        if (StringUtils.isBlank(info.getCompanyId())) {
            info.setCompanyId(ContextUtil.getCompanyId());
        }
        info.setUpdateBy(ContextUtil.getLoginUserName());
        info.setUpdateTime(new Date());
        info.setCreateBy(ContextUtil.getLoginUserName());
        info.setCreateTime(new Date());
        weighbridgeSnapMapper.insert(info);
    }
}
fzzy-igdss-web/src/main/java/com/fzzy/security/WeighbridgeSnapController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,126 @@
package com.fzzy.security;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzzy.common.manager.CommonManager;
import com.fzzy.igds.constant.Constant;
import com.fzzy.igds.constant.RespCodeEnum;
import com.fzzy.igds.constant.WarnType;
import com.fzzy.igds.data.IgdsBaseParam;
import com.fzzy.igds.data.PageResponse;
import com.fzzy.igds.domain.Company;
import com.fzzy.igds.domain.Dept;
import com.fzzy.igds.domain.WeighbridgeSnap;
import com.fzzy.igds.utils.ContextUtil;
import com.fzzy.security.manager.WeighbridgeSnapManager;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Controller
@RequestMapping("/security/weighbridgeSnap")
public class WeighbridgeSnapController {
    private static final String prefix = "security";
    @Resource
    private WeighbridgeSnapManager weighbridgeSnapManager;
    @Resource
    private CommonManager commonManager;
    /**
     * èŽ·å–åœ°ç£…æŠ“æ‹é¡µé¢
     *
     * @param viewType
     * @param model
     * @author sgj
     * @since 2026/02/25
     */
    @GetMapping
    public String getWeighbridgeSnap(@RequestParam(value = "viewType", required = false) String viewType, Model model) {
        //获取当前登录人
        SysUser user = ContextUtil.getLoginUser();
        //获取公司数据
        List<Company> companies = commonManager.listCompanyData();
        String defaultCompany = "";
        if (companies != null && !companies.isEmpty()) {
            defaultCompany = companies.get(0).getId();
        }
        //获取库区数据
        List<Dept> depts = new ArrayList<>();
        String defaultDeptId = "";
        if (Constant.USER_TYPE_30.equals(user.getUserType())) {
            depts = commonManager.listDeptData(null);
            defaultDeptId = user.getDeptId() + "";
        } else {
            depts = commonManager.listDeptData(defaultCompany);
            //在首位添加所有选项
            Dept all = new Dept();
            all.setId("");
            all.setKqmc("所有");
            depts.add(0, all);
        }
        IgdsBaseParam param = new IgdsBaseParam();
        param.setPage(1);
        param.setLimit(8);
        param.setKey(defaultCompany);
        param.setDeptId(defaultDeptId);
        Page<WeighbridgeSnap> events = weighbridgeSnapManager.pageData(param);
        model.addAttribute("weighbridgeSnapList", events.getRecords());
        model.addAttribute("currentPage", events.getCurrent());
        model.addAttribute("totalItems", events.getTotal());
        model.addAttribute("pageSize", events.getSize());
        if (StringUtils.isEmpty(viewType)) {
            // 1 å®‰é˜²é¡µé¢  2 ç›‘管页面
            viewType = "1";
        }
        //页面展示类型
        model.addAttribute("viewType", viewType);
        //设备数据
        model.addAttribute("cameraList", commonManager.listCameraData());
        //库区数据
        model.addAttribute("deptList", depts);
        model.addAttribute("defaultDeptId", defaultDeptId);
        //业务类型数据
        List<Map<String, String>> bizTypeList = new ArrayList<>();
        for (WarnType type : WarnType.values()) {
            Map<String, String> item = new HashMap<>();
            item.put("code", type.getCode());
            item.put("msg", type.getMsg());
            bizTypeList.add(item);
        }
        model.addAttribute("bizTypeList", bizTypeList);
        //公司数据
        model.addAttribute("companyList", companies);
        model.addAttribute("defaultCompany", defaultCompany);
        return prefix + "/weighbridgeSnap";
    }
    /**
     * åˆ†é¡µèŽ·å–æ•°æ®
     *
     * @param param
     * @return
     */
    @RequestMapping("/pageData")
    @ResponseBody
    public PageResponse<Page<WeighbridgeSnap>> pageData(@RequestBody IgdsBaseParam param) {
        Page<WeighbridgeSnap> weighbridgeSnapPage = weighbridgeSnapManager.pageData(param);
        return new PageResponse<>(RespCodeEnum.CODE_0000, weighbridgeSnapPage);
    }
}
fzzy-igdss-web/src/main/java/com/fzzy/security/manager/WeighbridgeSnapManager.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
package com.fzzy.security.manager;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fzzy.common.manager.CommonManager;
import com.fzzy.igds.data.IgdsBaseParam;
import com.fzzy.igds.domain.Camera;
import com.fzzy.igds.domain.WeighbridgeSnap;
import com.fzzy.igds.service.SecCameraService;
import com.fzzy.igds.service.WeighbridgeSnapService;
import com.fzzy.igds.utils.ContextUtil;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Component
public class WeighbridgeSnapManager {
    @Resource
    private WeighbridgeSnapService weighbridgeSnapService;
    @Resource
    private CommonManager commonManager;
    @Resource
    private SecCameraService secCameraService;
    /**
     * åˆ†é¡µèŽ·å–åœ°ç£…æŠ“æ‹æ•°æ®
     *
     * @param param
     * @author sgj
     * @since 2026/02/25
     */
    public Page<WeighbridgeSnap> pageData(IgdsBaseParam param) {
        if (StringUtils.isEmpty(param.getCompanyId())) {
            param.setCompanyId(ContextUtil.getCompanyId());
        }
        Page<WeighbridgeSnap> corePage = new Page<>(param.getPage(), param.getLimit());
        weighbridgeSnapService.listPage(corePage, param);
        if (null == corePage.getRecords() || corePage.getRecords().isEmpty()) {
            return corePage.setRecords(new ArrayList<>());
        }
        //获取监控设备
        List<Camera> cameras = secCameraService.listCamera(ContextUtil.getCompanyId(), null);
        //判断文件是否存在
        for (WeighbridgeSnap record : corePage.getRecords()) {
            record.setImgName(commonManager.isImgExit(record.getImgName(), null));
            //映射监控设备名称
            List<Camera> collect = cameras.stream().filter(camera -> camera.getId().equals(record.getSerId())).collect(Collectors.toList());
            if (!collect.isEmpty()) {
                record.setSerId(collect.get(0).getName());
            }
        }
        return corePage;
    }
}
fzzy-igdss-web/src/main/resources/static/security/weighbridgeSnap/weighbridgeSnap-style.css
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,203 @@
/* å›¾ç‰‡é¢„览层样式 */
.img-preview {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.9);
    z-index: 1000;
    justify-content: center;
    align-items: center;
}
.preview-content {
    max-width: 90%;
    max-height: 90%;
    position: relative;
}
.preview-img {
    max-width: 100%;
    max-height: 90vh;
    border-radius: 4px;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.close-preview {
    position: absolute;
    top: -40px;
    right: -10px;
    color: white;
    font-size: 2rem;
    cursor: pointer;
    background: rgba(0, 0, 0, 0.5);
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    transition: all 0.3s ease;
}
.close-preview:hover {
    background: rgba(255, 255, 255, 0.2);
    transform: scale(1.1);
}
/* å›¾ç‰‡ç½‘格样式 */
.gallery-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
    gap: 20px;
    margin-bottom: 5px;
}
.gallery-item {
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    transition: all 0.3s ease;
}
.gallery-item:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.12);
}
.gallery-img {
    width: 100%;
    height: 229px;
    object-fit: cover;
    cursor: pointer;
    transition: all 0.3s ease;
}
.gallery-img:hover {
    opacity: 0.95;
}
.gallery-info {
    padding: 15px;
}
.gallery-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}
.gallery-title {
    font-size: 1.5rem;
    font-weight: 600;
    color: #333;
    margin: 0;
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.gallery-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.meta-item {
    display: flex;
    align-items: center;
    font-size: 1.3rem;
    color: #666;
}
.meta-item i {
    width: 16px;
    margin-right: 6px;
    color: #999;
    font-size: 1.25rem;
}
.gallery-filename i {
    margin-right: 5px;
    font-size: 0.7rem;
}
/* æ ‡ç­¾æ ·å¼ */
.gallery-tags {
    display: flex;
    flex-wrap: wrap;
    margin-left: auto;
    gap: 3px;
    /*margin: 12px 0;*/
}
/* åˆ†é¡µæ ·å¼ */
.pagination-container {
    display: flex;
    justify-content: flex-end;
    width: 100%;
    /*margin-top: 40px;*/
}
/* ç©ºçŠ¶æ€æ ·å¼ */
.empty-state {
    grid-column: 1 / -1;
    text-align: center;
    padding: 60px 20px;
    color: #999;
}
.empty-state i {
    font-size: 4rem;
    margin-bottom: 20px;
    color: #ddd;
}
.empty-state h3 {
    font-size: 1.5rem;
    margin-bottom: 10px;
    color: #666;
}
/* å“åº”式设计 */
@media (max-width: 992px) {
    .gallery-grid {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
        gap: 25px;
    }
}
@media (max-width: 768px) {
    .main-nav li {
        margin: 0 10px;
    }
    .gallery-grid {
        grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
        gap: 20px;
    }
    .gallery-img {
        height: 180px;
    }
}
@media (max-width: 576px) {
    .gallery-grid {
        grid-template-columns: 1fr;
    }
    .gallery-img {
        height: 200px;
    }
}
fzzy-igdss-web/src/main/resources/static/security/weighbridgeSnap/weighbridgeSnap.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,432 @@
var layer;
var laypage;
// ç›‘听收储公司 Select2 å˜åŒ–
$(document).ready(function() {
    // ç›‘听收储公司下拉框变化
    $('select[name="key"]').on('change', function() {
        var selectedParentId = $(this).val();
        if(selectedParentId) {
            getSelectData(selectedParentId);
        } else {
            // å¦‚果清空了收储公司选择,也清空库区选项
            var $deptSelect = $('select[name="deptId"]');
            $deptSelect.empty()
                .append('<option value="">所有</option>')
                .select2({
                    placeholder: "请选择库区",
                    allowClear: true,
                    width: 'resolve'
                });
        }
    });
    // åœ¨ç‚¹å‡»åº“区下拉框时,仅验证而不发起新请求
    $('select[name="deptId"]').on('select2:opening', function(e) {
        var selectedParentId = $('select[name="key"]').val();
        if(!selectedParentId) {
            e.preventDefault();
            layer.msg('请先选择收储公司');
            return false;
        }
        // ä¸åœ¨æ­¤å¤„发起请求,依赖 change äº‹ä»¶æ—¶çš„预加载
        return true;
    });
});
$(function () {
    // åˆå§‹åŒ–分页
    layui.use(['laypage', 'layer'], function () {
        layer = layui.layer;
        laypage = layui.laypage;
        // åˆå§‹åŒ–分页组件
        initPagination();
    });
    // åˆå§‹åŒ–图片预览功能
    initImagePreview();
});
// ä¿®æ”¹ getSelectData å‡½æ•°ï¼Œæ”¯æŒ Select2 çš„æ•°æ®æ ¼å¼
function getSelectData(parentId) {
    if(!parentId) {
        return layer.msg('请选择收储公司');
    }
    $.ajax({
        url: "../../system/dept-new/getDeptByUserType",
        type: 'POST',
        dataType: "json",
        contentType: "application/json;charset=UTF-8",
        data: parentId,
        success: function (response) {
            if (response) {
                deptList = response;
                // é‡æ–°åˆå§‹åŒ– Select2 æˆ–更新选项
                updateDeptSelect2Options(deptList);
            } else {
                layer.msg(response.msg || '数据加载失败');
            }
        },
        error: function (xhr, status, error) {
            layer.msg('数据加载失败');
        }
    });
}
// æ›´æ–° Select2 ä¸‹æ‹‰æ¡†é€‰é¡¹
function updateDeptSelect2Options(deptList) {
    var $deptSelect = $('select[name="deptId"]');
    // ä¿å­˜å½“前选中的值
    var currentVal = $deptSelect.val();
    // æ¸…空现有选项
    $deptSelect.empty();
    // æ·»åŠ "所有"选项
    $deptSelect.append('<option value="">所有</option>');
    // æ·»åŠ åŠ¨æ€æ•°æ®é€‰é¡¹
    if(deptList && deptList.length > 0) {
        deptList.forEach(function(dept) {
            $deptSelect.append('<option value="' + dept.id + '">' + dept.kqmc + '</option>');
        });
    }
    // é‡æ–°åˆå§‹åŒ– Select2
    $deptSelect.select2({
        placeholder: "请选择库区",
        allowClear: true,
        width: 'resolve'
    });
    // æ¢å¤ä¹‹å‰çš„选择
    if(currentVal) {
        $deptSelect.val(currentVal).trigger('change');
    }
}
/**
 * åˆå§‹åŒ–分页组件
 */
function initPagination() {
    laypage.render({
        elem: 'pagination',
        count: typeof totalItems !== 'undefined' ? totalItems : 0,
        limit: typeof pageSize !== 'undefined' ? pageSize : 6,
        curr: typeof currentPage !== 'undefined' ? currentPage : 1,
        layout: ['prev','page', 'next'],
        // prev: '<i class="layui-icon layui-icon-left"></i>',
        // next: '<i class="layui-icon layui-icon-right"></i>',
        jump: function (obj, first) {
            if (!first) {
                searchRecord(obj.curr, obj.limit)
            }
        }
    });
}
/**
 * é‡æ–°åˆå§‹åŒ–分页组件
 * @param {number} totalCount - æ€»è®°å½•æ•°
 * @param {number} pageSize - æ¯é¡µå¤§å°
 * @param {number} currentPage - å½“前页码
 */
function reinitPagination(totalCount, pageSize, currentPage) {
    laypage.render({
        elem: 'pagination',
        count: totalCount,
        limit: pageSize,
        curr: currentPage,
        layout: ['prev', 'page','next'],
        // prev: '<i class="layui-icon layui-icon-left"></i>',
        // next: '<i class="layui-icon layui-icon-right"></i>',
        jump: function (obj, first) {
            if (!first) {
                searchRecord(obj.curr, obj.limit)
            }
        }
    });
}
/**
 * èŽ·å–äº‹ä»¶è®°å½•æ•°æ®
 * @param {Object} params - æŸ¥è¯¢å‚数对象
 * @param {Function} callback - å›žè°ƒå‡½æ•°
 */
function fetchWeighbridgeSnapData(params, callback) {
    $.ajax({
        url: '../../security/weighbridgeSnap/pageData',
        type: 'POST',
        dataType: "json",
        contentType: "application/json;charset=UTF-8",
        data: JSON.stringify(params),
        success: function (response) {
            if (response.code === '0000') {
                callback(null, response.data);
            } else {
                callback(new Error(response.msg || '数据加载失败'), null);
            }
        },
        error: function (xhr, status, error) {
            callback(new Error('请求失败,请稍后重试'), null);
        }
    });
}
/**
 * æž„建查询参数
 * @param {number} page - é¡µç 
 * @param {number} size - æ¯é¡µå¤§å°
 * @returns {Object} æŸ¥è¯¢å‚数对象
 */
function buildQueryParams(page, size) {
    var params = {
        page: page,
        limit: size
    };
    // æ·»åŠ è¡¨å•æŸ¥è¯¢æ¡ä»¶
    var form = document.getElementById('weighbridgeSnap-form');
    if (form) {
        // å¤„理普通输入框和选择框,排除隐藏域
        var inputs = form.querySelectorAll('input[name]:not([type="hidden"]), select[name]');
        inputs.forEach(function(input) {
            if (input.value) { // åªæ·»åŠ éžç©ºå€¼
                params[input.name] = input.value;
            }
        });
    }
    return params;
}
/**
 * æ›´æ–°äº‹ä»¶ç”»å»Šå†…容
 * @param {Array} records - äº‹ä»¶è®°å½•数据
 */
function updateGallery(records) {
    var container = document.getElementById('gallery-container');
    if (!container) return;
    // æ¸…空现有内容
    container.innerHTML = '';
    if (!records || records.length === 0) {
        // æ˜¾ç¤ºç©ºçŠ¶æ€
        container.innerHTML = `
            <div class="empty-state">
                <i class="fa-solid fa-bell-slash"></i>
                <h3>暂无抓拍记录</h3>
                <p>当前没有可展示的地磅抓拍数据</p>
            </div>
        `;
        // éšè—åˆ†é¡µ
        $('.pagination-container').hide();
        return;
    }
    // æ˜¾ç¤ºåˆ†é¡µ
    $('.pagination-container').show();
    // ç”Ÿæˆäº‹ä»¶å¡ç‰‡
    var html = '';
    records.forEach(function(record) {
        // æ ‡ç­¾å±•示
        var tagsHtml = '';
        if (record.tags) {
            var tags = record.tags.split(',');
            tags.forEach(function(tag) {
                tagsHtml += `
            <span class="tag-person">
                <i class="layui-icon layui-icon-note"></i>
                <span>${tag.trim()}</span>
            </span>
        `;
            });
        }
        html += `
            <div class="gallery-item">
                <img src="${record.imgName || '/logo-sm.png'}" alt="${record.id}"
                    data-url="${record.imgName || '/logo-sm.png'}" data-id="${record.id}"
                     class="gallery-img" onclick="showWeighbridgeSnapPreview(this.getAttribute('data-url'))">
                <div class="gallery-info">
                    <div class="gallery-header">
                        <h3 class="gallery-title">${record.name || record.id}</h3>
                        <div class="gallery-tags">
                            ${tagsHtml}
                        </div>
                    </div>
                    <div class="gallery-meta">
                        <div style="display: flex; align-items: center; gap: 15px;width: 100%">
                            <div class="meta-item" style="width: 50%">
                                <i class="layui-icon layui-icon-video"></i>
                                <span>${getCameraName(record.serId) || record.serId || ''}</span>
                            </div>
                            <div class="meta-item" style="width: 50%">
                                <i class="layui-icon layui-icon-date"></i>
                                <span>${formatDate(record.time)}</span>
                            </div>
                        </div>
                        <div class="meta-item">
                            <i class="layui-icon layui-icon-component"></i>
                            <span>${getTypeName(record.bizType) || record.bizType || ''}</span>
                        </div>
                    </div>
                </div>
            </div>
        `;
    });
    container.innerHTML = html;
}
/**
 * æ ¹æ®æ‘„像头ID获取摄像头名称
 * @param {string} serId - æ‘„像头ID
 * @returns {string|null} æ‘„像头名称或null
 */
function getCameraName(serId) {
    // ç¡®ä¿cameraList存在且为数组
    if (typeof cameraList !== 'undefined' && Array.isArray(cameraList) && serId) {
        // æŸ¥æ‰¾åŒ¹é…çš„æ‘„像头对象
        var camera = cameraList.find(function(item) {
            return item.id === serId;
        });
        // è¿”回摄像头名称,如果找不到则返回null
        return camera ? camera.name : null;
    }
    return null;
}
/**
 * æ ¹æ®ä¸šåŠ¡ç±»åž‹ç¼–ç èŽ·å–ä¸šåŠ¡ç±»åž‹åç§°
 * @param {string} bizType - ä¸šåŠ¡ç±»åž‹ç¼–ç 
 * @returns {string|null} ä¸šåŠ¡ç±»åž‹åç§°æˆ–null
 */
function getTypeName(bizType) {
    if (typeof bizTypeList !== 'undefined' && Array.isArray(bizTypeList) && bizType) {
        // æŸ¥æ‰¾åŒ¹é…çš„业务类型对象
        var type = bizTypeList.find(function(item) {
            return item.code === bizType;
        });
        // è¿”回业务类型名称,如果找不到则返回null
        return type ? type.msg : null;
    }
    return null;
}
/**
 * æ ¼å¼åŒ–日期
 * @param {string|number} date - æ—¥æœŸå­—符串或时间戳
 */
function formatDate(date) {
    if (!date) return '';
    var d = new Date(date);
    return d.getFullYear() + '-' +
        String(d.getMonth() + 1).padStart(2, '0') + '-' +
        String(d.getDate()).padStart(2, '0') + ' ' +
        String(d.getHours()).padStart(2, '0') + ':' +
        String(d.getMinutes()).padStart(2, '0');
}
/**
 * åˆå§‹åŒ–图片预览功能
 */
function initImagePreview() {
    var preview = document.getElementById('imgPreview');
    var previewImg = document.getElementById('previewImg');
    var closeBtn = document.getElementById('closePreview');
    // å¦‚果预览元素不存在,则不初始化
    if (!preview || !previewImg) {
        return;
    }
    // å…³é—­æŒ‰é’®ç‚¹å‡»äº‹ä»¶
    if (closeBtn) {
        closeBtn.addEventListener('click', closePreview);
    }
    // ç‚¹å‡»é¢„览区域外关闭
    preview.addEventListener('click', function (e) {
        if (e.target === preview) {
            closePreview();
        }
    });
    // é”®ç›˜äº‹ä»¶ç›‘听
    document.addEventListener('keydown', function (e) {
        if (e.key === 'Escape' && preview.style.display === 'flex') {
            closePreview();
        }
    });
    // å…³é—­é¢„览函数
    function closePreview() {
        preview.style.display = 'none';
        previewImg.src = '';
    }
}
/**
 * æ˜¾ç¤ºå›¾ç‰‡é¢„览
 * @param {string} imgUrl å›¾ç‰‡URL
 */
function showWeighbridgeSnapPreview(imgUrl) {
    var preview = document.getElementById('imgPreview');
    var previewImg = document.getElementById('previewImg');
    if (preview && previewImg) {
        previewImg.src = imgUrl;
        preview.style.display = 'flex';
    }
}
/**
 * è¯»å–事件记录
 */
function searchRecord(page, size) {
    var pageNumber = 1;
    var sizeNumber = 6;
    if (pageSize && pageSize > 0){
        size = pageSize;
    }
    if (size && size > 0){
        sizeNumber = size;
    }
    if (page && page > 0){
        pageNumber = page;
    }
    // æž„造查询参数,从第一页开始
    var queryParams = buildQueryParams(pageNumber, sizeNumber);
    // æ˜¾ç¤ºloading
    var loadingIndex = layer.load(1, {shade: [0.1, '#fff']});
    // è°ƒç”¨æ•°æ®è¯·æ±‚方法
    fetchWeighbridgeSnapData(queryParams, function(error, data) {
        // å…³é—­loading
        layer.close(loadingIndex);
        if (error) {
            layer.msg(error.message);
            return;
        }
        // æ›´æ–°é¡µé¢æ•°æ®
        updateGallery(data.records);
        // é‡æ–°åˆå§‹åŒ–分页组件
        reinitPagination(data.total, data.size, data.current);
    });
}
fzzy-igdss-web/src/main/resources/templates/security/weighbridgeSnap.html
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="renderer" content="webkit">
    <th:block th:include="include :: header('地磅抓拍管理')"/>
    <link rel="stylesheet" type="text/css" th:href="@{/ajax/libs/layui/css/layui.css}"/>
    <link rel="stylesheet" th:href="@{/security/weighbridgeSnap/weighbridgeSnap-style.css}">
    <th:block th:include="include :: select2-css"/>
    <style>
        .select-list .select2-container--bootstrap {
            width: 280px !important;
            display: inline-block;
        }
    </style>
</head>
<body class="gray-bg">
<div class="container-div">
    <div class="row">
        <div class="col-sm-12 search-collapse"
             style="display: flex; justify-content: space-between; align-items: center;">
            <form id="weighbridgeSnap-form">
                <div class="select-list">
                    <ul>
                        <li>
                            æ”¶å‚¨å…¬å¸ï¼š<select class="form-control" name="key">
                            <option th:each="company : ${companyList}" th:value="${company.id}"
                                    th:text="${company.dwmc}"
                                    th:selected="${company.id == defaultCompany}">
                            </option>
                        </select>
                        </li>
                        <li>
                            æ‰€é€‰åº“区:<select class="form-control" name="deptId" >
                            <option th:each="dept : ${deptList}" th:value="${dept.id}" th:text="${dept.kqmc}"
                                    th:selected="${dept.id == defaultDeptId}">
                            </option>
                        </select>
                        </li>
                        <li class="select-time">
                            <label style="width: 100px">抓拍时间: </label>
                            <input type="text" class="time-input" style="width: 140px;" id="start"
                                   placeholder="开始时间" name="start"/>
                            <span>-</span>
                            <input type="text" class="time-input" style="width: 140px;" id="end" placeholder="结束时间"
                                   name="end"/>
                        </li>
                        <li>
                            <a class="btn btn-primary btn-rounded btn-sm" onclick="searchRecord()"><i
                                    class="fa fa-search"></i>&nbsp;搜索</a>
                            <a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i
                                    class="fa fa-refresh"></i>&nbsp;重置</a>
                        </li>
                    </ul>
                </div>
            </form>
        </div>
        <div class="col-sm-12 " style="padding-top: 10px;background: #FFFFFF;margin-top: 10px;">
            <!-- äº‹ä»¶ç½‘æ ¼ -->
            <div class="gallery-grid" id="gallery-container">
                <!-- äº‹ä»¶ä¸ºç©ºæ—¶æ˜¾ç¤º -->
                <div th:if="${#lists.isEmpty(weighbridgeSnapList)}" class="empty-state">
                    <i class="fa-solid fa-bell-slash"></i>
                    <h3>暂无抓拍记录</h3>
                    <p>当前没有可展示的地磅抓拍数据</p>
                </div>
                <!-- äº‹ä»¶å¡ç‰‡ -->
                <div th:each="weighbridgeSnap : ${weighbridgeSnapList}" class="gallery-item">
                    <img th:src="${weighbridgeSnap.imgName ?: '/logo-sm.png'}" th:alt="${weighbridgeSnap.id}"
                         th:data-url="${weighbridgeSnap.imgName ?: '/logo-sm.png'}" th:data-id="${weighbridgeSnap.id}"
                         class="gallery-img" onclick="showWeighbridgeSnapPreview(this.getAttribute('data-url'))">
                    <div class="gallery-info">
                        <div class="gallery-header">
                            <h3 class="gallery-title" th:text="${weighbridgeSnap.name}"></h3>
                            <div class="gallery-tags">
                                <span th:each="tag : ${#strings.arraySplit(weighbridgeSnap.tags, ',')}" class="tag-person">
                                    <i class="layui-icon layui-icon-note"></i>
                                    <span th:text="${tag}"></span>
                                </span>
                            </div>
                        </div>
                        <div class="gallery-meta">
                            <div style="display: flex; align-items: center; gap: 15px;width: 100%">
                                <div class="meta-item" style="width: 50%">
                                    <i class="layui-icon layui-icon-video"></i>
                                    <span th:text="${weighbridgeSnap.serId}"></span>
                                </div>
                                <div class="meta-item" style="width: 50%">
                                    <i class="layui-icon layui-icon-date"></i>
                                    <span th:text="${weighbridgeSnap.time != null ? #dates.format(weighbridgeSnap.time, 'yyyy-MM-dd HH:mm') : '无时间'}"></span>
                                </div>
                            </div>
                            <div class="meta-item">
                                <i class="layui-icon layui-icon-component"></i>
                                <th:block th:with="matchedTypes=${bizTypeList.?[code == #root.weighbridgeSnap.bizType]}">
                                    <th:block th:if="${!#lists.isEmpty(matchedTypes)}">
                                        <span th:text="${matchedTypes[0].msg}"></span>
                                    </th:block>
                                    <th:block th:if="${#lists.isEmpty(matchedTypes)}">
                                        <span th:text="${weighbridgeSnap.bizType}"></span>
                                    </th:block>
                                </th:block>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!-- åˆ†é¡µæŽ§ä»¶ -->
            <div class="pagination-container" th:if="${not #lists.isEmpty(weighbridgeSnapList)}">
                <div id="pagination"></div>
            </div>
        </div>
    </div>
    <!-- å›¾ç‰‡é¢„览层 -->
    <div class="img-preview" id="imgPreview">
        <div class="preview-content">
            <img src="" alt="预览图片" class="preview-img" id="previewImg">
            <div class="close-preview" id="closePreview">
                <i class="layui-icon layui-icon-clear"></i>
            </div>
        </div>
    </div>
</div>
<th:block th:include="include :: footer"/>
<script th:src="@{/ajax/libs/layui/layui.js}"></script>
<th:block th:include="include :: select2-js"/>
<script th:src="@{/security/weighbridgeSnap/weighbridgeSnap.js}"></script>
<script th:inline="javascript">
    var cameraList = [[${cameraList}]];
    var deptList = [[${deptList}]];
    var bizTypeList = [[${bizTypeList}]];
    var companyList = [[${companyList}]];
    var currentPage = [[${currentPage}]];
    var totalItems = [[${totalItems}]];
    var pageSize = [[${pageSize}]];
</script>
</body>
</html>