自动化立体仓库 - WMS系统
zwl
4 天以前 632bde0f32999a2b319b706e23d90bc1b5dd8cc2
1.新增拍照功能
4个文件已添加
16个文件已修改
545 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/PhotoController.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocDetl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkDetl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/WrkDetlLog.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/WrkDetlLogMapper.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/InboundCameraCaptureService.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/InboundCameraCaptureServiceImpl.java 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/web/WcsController.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocDetlMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkDetlLogMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/WrkDetlMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/sql/20260421_inbound_camera_capture.sql 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/common.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locDetl/locDetl.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locMast/locMast.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/ioWorks/locDetlQuery.html 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locDetl/locDetl.html 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locMast/locMast.html 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pakStore/locDetlCheckQuery.html 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/pakStore/locDetlQuery.html 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/PhotoController.java
New file
@@ -0,0 +1,38 @@
package com.zy.asrs.controller;
import com.core.annotations.ManagerAuth;
import com.core.common.Cools;
import com.core.common.R;
import com.zy.asrs.service.InboundCameraCaptureService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class PhotoController {
    @Autowired
    private InboundCameraCaptureService inboundCameraCaptureService;
    @GetMapping("/photo/loc/auth")
    @ManagerAuth
    public R loc(@RequestParam String locNo) {
        return R.ok(inboundCameraCaptureService.resolveLocPicUrls(locNo));
    }
    @PostMapping("/photo/resolve/auth")
    @ManagerAuth
    public R resolve(@RequestBody(required = false) Map<String, Object> body,
                     @RequestParam(required = false) String pic) {
        String value = pic;
        if (Cools.isEmpty(value) && body != null && body.get("pic") != null) {
            value = String.valueOf(body.get("pic"));
        }
        return R.ok(inboundCameraCaptureService.resolvePicUrls(value));
    }
}
src/main/java/com/zy/asrs/entity/LocDetl.java
@@ -164,6 +164,9 @@
    @ApiModelProperty(value= "备注")
    private String memo;
    @ApiModelProperty(value= "入库抓拍照片")
    private String pic;
    /**
     * 集装箱号
     */
src/main/java/com/zy/asrs/entity/WrkDetl.java
@@ -314,6 +314,12 @@
    private String memo;
    /**
     * 入库抓拍照片
     */
    @ApiModelProperty(value= "入库抓拍照片")
    private String pic;
    /**
     * 备用1
     */
    @ApiModelProperty(value= "备用1")
src/main/java/com/zy/asrs/entity/WrkDetlLog.java
@@ -313,6 +313,12 @@
    private String memo;
    /**
     * 入库抓拍照片
     */
    @ApiModelProperty(value= "入库抓拍照片")
    private String pic;
    /**
     * 备用1
     */
    @ApiModelProperty(value= "备用1")
src/main/java/com/zy/asrs/mapper/WrkDetlLogMapper.java
@@ -2,7 +2,6 @@
import com.zy.asrs.entity.WrkDetlLog;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@@ -14,8 +13,7 @@
@Repository
public interface WrkDetlLogMapper extends BaseMapper<WrkDetlLog> {
    @Insert("insert into asr_wrk_detl_log select * from asr_wrk_detl where wrk_no=#{workNo}")
    int save(Integer workNo);
    int save(@Param("workNo") Integer workNo);
    List<WrkDetlLog> selectWrkDetlLogs(@Param("wrkNo") Integer wrkNo,
                                       @Param("orderNo") String orderNo,
src/main/java/com/zy/asrs/service/InboundCameraCaptureService.java
New file
@@ -0,0 +1,12 @@
package com.zy.asrs.service;
import java.util.List;
public interface InboundCameraCaptureService {
    String capture(Integer sourceStaNo, String locNo, String barcode);
    List<String> resolvePicUrls(String pic);
    List<String> resolveLocPicUrls(String locNo);
}
src/main/java/com/zy/asrs/service/impl/InboundCameraCaptureServiceImpl.java
New file
@@ -0,0 +1,250 @@
package com.zy.asrs.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.LocDetl;
import com.zy.asrs.service.InboundCameraCaptureService;
import com.zy.asrs.service.LocDetlService;
import com.zy.system.entity.Config;
import com.zy.system.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class InboundCameraCaptureServiceImpl implements InboundCameraCaptureService {
    private static final String CONFIG_CODE = "InboundCameraCapture";
    private static final MediaType JSON_MEDIA_TYPE = MediaType.parse("application/json;charset=utf-8");
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .build();
    @Autowired
    private ConfigService configService;
    @Autowired
    private LocDetlService locDetlService;
    @Override
    public String capture(Integer sourceStaNo, String locNo, String barcode) {
        CaptureConfig config = loadConfig();
        if (config == null || !config.enabled) {
            return null;
        }
        if (sourceStaNo == null) {
            log.warn("入库抓拍配置跳过:sourceStaNo为空");
            return null;
        }
        JSONArray cameras = config.stations.getJSONArray(String.valueOf(sourceStaNo));
        if (Cools.isEmpty(cameras)) {
            log.warn("入库抓拍配置缺失:sourceStaNo={}", sourceStaNo);
            return null;
        }
        if (cameras.size() != 2) {
            log.warn("入库抓拍摄像头数量不是2:sourceStaNo={}, count={}", sourceStaNo, cameras.size());
        }
        String baseName = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())
                + "_" + sanitize(String.valueOf(sourceStaNo))
                + "_" + sanitize(locNo)
                + "_" + sanitize(barcode);
        List<String> successPics = new ArrayList<>();
        for (int i = 0; i < cameras.size(); i++) {
            JSONObject camera = cameras.getJSONObject(i);
            if (camera == null) {
                continue;
            }
            String picName = baseName + "-" + (i + 1) + ".jpg";
            if (captureOne(config.captureUrl, sourceStaNo, i + 1, camera, picName)) {
                successPics.add(picName);
            }
        }
        return successPics.isEmpty() ? null : JSON.toJSONString(successPics);
    }
    @Override
    public List<String> resolvePicUrls(String pic) {
        CaptureConfig config = loadConfig();
        String prefix = config == null ? "" : config.imageUrlPrefix;
        Set<String> urls = new LinkedHashSet<>();
        for (String picName : parsePicNames(pic)) {
            if (Cools.isEmpty(picName)) {
                continue;
            }
            if (picName.startsWith("http://") || picName.startsWith("https://")) {
                urls.add(picName);
            } else if (!Cools.isEmpty(prefix)) {
                urls.add(prefix + picName);
            }
        }
        return new ArrayList<>(urls);
    }
    @Override
    public List<String> resolveLocPicUrls(String locNo) {
        if (Cools.isEmpty(locNo)) {
            return new ArrayList<>();
        }
        List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>().eq("loc_no", locNo));
        Set<String> urls = new LinkedHashSet<>();
        for (LocDetl locDetl : locDetls) {
            urls.addAll(resolvePicUrls(locDetl.getPic()));
        }
        return new ArrayList<>(urls);
    }
    private boolean captureOne(String captureUrl, Integer sourceStaNo, int index, JSONObject camera, String picName) {
        String ip = camera.getString("ip");
        if (Cools.isEmpty(ip)) {
            log.warn("入库抓拍摄像头IP为空:sourceStaNo={}, cameraIndex={}", sourceStaNo, index);
            return false;
        }
        JSONObject requestJson = new JSONObject();
        requestJson.put("ip", ip);
        requestJson.put("port", defaultInt(camera.getInteger("port"), 554));
        requestJson.put("user", defaultString(camera.getString("user"), "admin"));
        requestJson.put("password", defaultString(camera.getString("password"), "a327482030"));
        requestJson.put("picName", picName);
        try {
            RequestBody body = RequestBody.create(JSON_MEDIA_TYPE, requestJson.toJSONString());
            Request request = new Request.Builder()
                    .url(captureUrl)
                    .post(body)
                    .build();
            try (Response response = HTTP_CLIENT.newCall(request).execute()) {
                ResponseBody responseBody = response.body();
                String bodyText = responseBody == null ? "" : responseBody.string();
                if (!response.isSuccessful()) {
                    log.warn("入库抓拍HTTP失败:sourceStaNo={}, cameraIndex={}, ip={}, httpCode={}, picName={}",
                            sourceStaNo, index, ip, response.code(), picName);
                    return false;
                }
                JSONObject result = JSON.parseObject(bodyText);
                Integer code = result == null ? null : result.getInteger("code");
                if (code != null && code == 200) {
                    return true;
                }
                String msg = result == null ? bodyText : result.getString("msg");
                log.warn("入库抓拍返回失败:sourceStaNo={}, cameraIndex={}, ip={}, code={}, msg={}, picName={}",
                        sourceStaNo, index, ip, code, msg, picName);
                return false;
            }
        } catch (Exception e) {
            log.warn("入库抓拍异常:sourceStaNo={}, cameraIndex={}, ip={}, picName={}",
                    sourceStaNo, index, ip, picName, e);
            return false;
        }
    }
    private CaptureConfig loadConfig() {
        Config config = configService.selectConfigByCode(CONFIG_CODE);
        if (config == null || Cools.isEmpty(config.getValue())) {
            return null;
        }
        if (config.getStatus() != null && config.getStatus() == 0) {
            return null;
        }
        try {
            JSONObject json = JSON.parseObject(config.getValue());
            CaptureConfig captureConfig = new CaptureConfig();
            Boolean enabled = json.getBoolean("enabled");
            captureConfig.enabled = enabled == null || enabled;
            captureConfig.captureUrl = json.getString("captureUrl");
            captureConfig.imageUrlPrefix = normalizePrefix(json.getString("imageUrlPrefix"), captureConfig.captureUrl);
            captureConfig.stations = json.getJSONObject("stations");
            if (Cools.isEmpty(captureConfig.captureUrl) || captureConfig.stations == null) {
                log.warn("入库抓拍配置不完整:code={}", CONFIG_CODE);
                return null;
            }
            return captureConfig;
        } catch (Exception e) {
            log.warn("入库抓拍配置解析失败:code={}", CONFIG_CODE, e);
            return null;
        }
    }
    private List<String> parsePicNames(String pic) {
        List<String> names = new ArrayList<>();
        if (Cools.isEmpty(pic)) {
            return names;
        }
        try {
            Object parsed = JSON.parse(pic);
            if (parsed instanceof JSONArray) {
                JSONArray array = (JSONArray) parsed;
                for (int i = 0; i < array.size(); i++) {
                    names.add(array.getString(i));
                }
                return names;
            }
            if (parsed instanceof String) {
                names.add((String) parsed);
                return names;
            }
        } catch (Exception ignored) {
            // 兼容旧数据中直接存单个文件名或逗号分隔文件名的情况。
        }
        String[] split = pic.split(",");
        for (String item : split) {
            if (!Cools.isEmpty(item)) {
                names.add(item.trim());
            }
        }
        return names;
    }
    private String normalizePrefix(String imageUrlPrefix, String captureUrl) {
        String prefix = imageUrlPrefix;
        if (Cools.isEmpty(prefix) && !Cools.isEmpty(captureUrl)) {
            int idx = captureUrl.lastIndexOf("/");
            prefix = idx > "http://".length() ? captureUrl.substring(0, idx) + "/image/" : "";
        }
        if (!Cools.isEmpty(prefix) && !prefix.endsWith("/")) {
            prefix = prefix + "/";
        }
        return prefix;
    }
    private String sanitize(String value) {
        if (value == null) {
            return "null";
        }
        return value.replaceAll("[\\\\/:*?\"<>|\\s]+", "_");
    }
    private int defaultInt(Integer value, int defaultValue) {
        return value == null ? defaultValue : value;
    }
    private String defaultString(String value, String defaultValue) {
        return Cools.isEmpty(value) ? defaultValue : value;
    }
    private static class CaptureConfig {
        private boolean enabled;
        private String captureUrl;
        private String imageUrlPrefix;
        private JSONObject stations;
    }
}
src/main/java/com/zy/common/web/WcsController.java
@@ -58,6 +58,8 @@
    private WorkService workService;
    @Autowired
    private StaDescService staDescService;
    @Autowired
    private InboundCameraCaptureService inboundCameraCaptureService;
    @PostMapping("/pakin/loc/v1")
    @ResponseBody
@@ -500,6 +502,7 @@
            if (!res) {
                throw new CoolException("保存工作档失败");
            }
            String pic = inboundCameraCaptureService.capture(devpNo, dto.getLocNo(), barcode);
            // 生成工作档明细
            waitPakins.forEach(waitPakin -> {
                WrkDetl wrkDetl = new WrkDetl();
@@ -509,6 +512,9 @@
                wrkDetl.setAppeTime(now);
                wrkDetl.setModiTime(now);
                wrkDetl.setWeight(wrkMast.getScWeight());
                if (!Cools.isEmpty(pic)) {
                    wrkDetl.setPic(pic);
                }
                if (!wrkDetlService.insert(wrkDetl)) {
                    throw new CoolException("保存工作明细失败");
                }
src/main/resources/mapper/LocDetlMapper.xml
@@ -44,6 +44,7 @@
        <result column="appe_user" property="appeUser" />
        <result column="appe_time" property="appeTime" />
        <result column="memo" property="memo" />
        <result column="pic" property="pic" />
        <result column="container_no" property="containerNo" />
        <result column="teu" property="teu" />
        <result column="plate_no" property="plateNo" />
src/main/resources/mapper/WrkDetlLogMapper.xml
@@ -34,7 +34,7 @@
        <result column="item_num" property="itemNum"/>
        <result column="safe_qty" property="safeQty"/>
        <result column="weight" property="weight"/>
        <result column="length" property="length"/>
        <result column="man_length" property="manLength"/>
        <result column="volume" property="volume"/>
        <result column="three_code" property="threeCode"/>
        <result column="supp" property="supp"/>
@@ -51,6 +51,7 @@
        <result column="appe_user" property="appeUser"/>
        <result column="appe_time" property="appeTime"/>
        <result column="memo" property="memo"/>
        <result column="pic" property="pic"/>
        <result column="standby1" property="standby1" />
        <result column="standby2" property="standby2" />
        <result column="standby3" property="standby3" />
@@ -61,6 +62,28 @@
        <result column="uuid" property="uuid"/>
    </resultMap>
    <insert id="save">
        insert into asr_wrk_detl_log (
            wrk_no, io_time, anfme, zpallet, matnr, maktx, batch, order_no,
            container_no, teu, plate_no, train_no, freq_type, cube_number,
            specs, model, color, brand, unit, price, sku, units, barcode,
            origin, manu, manu_date, item_num, safe_qty, weight, man_length,
            volume, three_code, supp, supp_code, be_batch, dead_time, dead_warn,
            source, inspect, danger, modi_user, modi_time, appe_user, appe_time,
            memo, standby1, standby2, standby3, box_type1, box_type2, box_type3, pic
        )
        select
            wrk_no, io_time, anfme, zpallet, matnr, maktx, batch, order_no,
            container_no, teu, plate_no, train_no, freq_type, cube_number,
            specs, model, color, brand, unit, price, sku, units, barcode,
            origin, manu, manu_date, item_num, safe_qty, weight, man_length,
            volume, three_code, supp, supp_code, be_batch, dead_time, dead_warn,
            source, inspect, danger, modi_user, modi_time, appe_user, appe_time,
            memo, standby1, standby2, standby3, box_type1, box_type2, box_type3, pic
        from asr_wrk_detl
        where wrk_no = #{workNo}
    </insert>
    <sql id="batchSeq">
        <if test="wrkNo != null and wrkNo != ''">
            and a.wrk_no = #{wrkNo}
src/main/resources/mapper/WrkDetlMapper.xml
@@ -51,6 +51,7 @@
        <result column="appe_user" property="appeUser" />
        <result column="appe_time" property="appeTime" />
        <result column="memo" property="memo" />
        <result column="pic" property="pic" />
        <result column="standby1" property="standby1" />
        <result column="standby2" property="standby2" />
        <result column="standby3" property="standby3" />
src/main/resources/sql/20260421_inbound_camera_capture.sql
New file
@@ -0,0 +1,33 @@
IF COL_LENGTH('dbo.asr_wrk_detl', 'pic') IS NULL
BEGIN
    ALTER TABLE [dbo].[asr_wrk_detl]
        ADD [pic] NVARCHAR(MAX) NULL;
END
GO
IF COL_LENGTH('dbo.asr_wrk_detl_log', 'pic') IS NULL
BEGIN
    ALTER TABLE [dbo].[asr_wrk_detl_log]
        ADD [pic] NVARCHAR(MAX) NULL;
END
GO
IF COL_LENGTH('dbo.asr_loc_detl', 'pic') IS NULL
BEGIN
    ALTER TABLE [dbo].[asr_loc_detl]
        ADD [pic] NVARCHAR(MAX) NULL;
END
GO
IF NOT EXISTS (SELECT 1 FROM sys_config WHERE code = N'InboundCameraCapture')
BEGIN
    INSERT INTO sys_config (name, code, value, type, status)
    VALUES (
        N'入库站点抓拍配置',
        N'InboundCameraCapture',
        N'{"enabled":true,"captureUrl":"http://192.168.10.11:8000/startPic","imageUrlPrefix":"http://192.168.10.11:8000/image/","stations":{"101":[{"ip":"10.10.16.13","port":554,"user":"admin","password":"a327482030"},{"ip":"10.10.16.14","port":554,"user":"admin","password":"a327482030"}]}}',
        2,
        1
    );
END
GO
src/main/webapp/static/js/common.js
@@ -284,6 +284,40 @@
    return(false);
}
function showPhotoViewer(layer, urls) {
    if (!urls || urls.length === 0) {
        layer.msg('暂无照片');
        return;
    }
    var html = '<div style="padding:16px;display:flex;flex-wrap:wrap;gap:12px;max-height:70vh;overflow:auto;background:#f7f7f7;">';
    for (var i = 0; i < urls.length; i++) {
        var url = escapePhotoHtml(urls[i]);
        html += '<a href="' + url + '" target="_blank" style="display:block;width:360px;max-width:100%;background:#fff;border:1px solid #e6e6e6;padding:8px;">'
            + '<img src="' + url + '" style="display:block;width:100%;height:auto;max-height:360px;object-fit:contain;" alt="photo">'
            + '</a>';
    }
    html += '</div>';
    layer.open({
        type: 1,
        title: '查看照片',
        area: ['900px', '75%'],
        maxmin: true,
        shadeClose: true,
        content: html
    });
}
function escapePhotoHtml(value) {
    if (value === undefined || value === null) {
        return '';
    }
    return String(value)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}
/**
 * 获取AI助手SVG图标HTML
 * @param {number} width 宽度,默认48
src/main/webapp/static/js/locDetl/locDetl.js
@@ -47,6 +47,7 @@
    cols.push({field: 'modiUser$', align: 'center',title: '修改人员',hide: true}
        ,{field: 'memo', align: 'center',title: '备注', hide: false}
        ,{field: 'modiTime$', align: 'center',title: '修改时间'}
        ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:160}
    )
    return cols;
}
@@ -297,6 +298,29 @@
    table.on('tool(locDetl)', function(obj){
        var data = obj.data;
        switch (obj.event) {
            case 'viewPhoto':
                if (!data.pic) {
                    layer.msg('暂无照片');
                    break;
                }
                $.ajax({
                    url: baseUrl + "/photo/resolve/auth",
                    headers: {'token': localStorage.getItem('token')},
                    data: JSON.stringify({pic: data.pic}),
                    dataType:'json',
                    contentType:'application/json;charset=UTF-8',
                    method: 'POST',
                    success: function (res) {
                        if (res.code === 200) {
                            showPhotoViewer(layer, res.data);
                        } else if (res.code === 403) {
                            top.location.href = baseUrl + "/";
                        } else {
                            layer.msg(res.msg);
                        }
                    }
                });
                break;
            // 详情
            case 'detail':
                layer.open({
src/main/webapp/static/js/locMast/locMast.js
@@ -69,7 +69,7 @@
            ,{field: 'locType2$', align: 'center',title: '宽窄类型', hide:true}
            ,{field: 'locType3$', align: 'center',title: '轻重类型', hide:true}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:100}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:160}
        ]],
        request: {
            pageName: 'curr',
@@ -267,6 +267,23 @@
                    }
                });
                break;
            case 'viewPhoto':
                $.ajax({
                    url: baseUrl + "/photo/loc/auth",
                    headers: {'token': localStorage.getItem('token')},
                    data: {locNo: data.locNo},
                    method: 'GET',
                    success: function (res) {
                        if (res.code === 200) {
                            showPhotoViewer(layer, res.data);
                        } else if (res.code === 403) {
                            top.location.href = baseUrl + "/";
                        } else {
                            layer.msg(res.msg);
                        }
                    }
                });
                break;
            // 编辑
            case 'edit':
                layer.open({
src/main/webapp/views/ioWorks/locDetlQuery.html
@@ -83,6 +83,9 @@
<div class="layui-form">
    <table class="layui-hide" id="stockOut" lay-filter="stockOut"></table>
</div>
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="viewPhoto">查看照片</a>
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
@@ -101,7 +104,8 @@
        ];
        cols.push.apply(cols, detlCols);
        cols.push({field: 'updateBy$', align: 'center',title: '修改人员', hide: true}
            ,{field: 'updateTime$', align: 'center',title: '修改时间'})
            ,{field: 'updateTime$', align: 'center',title: '修改时间'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:110})
        return cols;
    }
@@ -162,6 +166,27 @@
            }
        });
        table.on('tool(stockOut)', function(obj){
            if (obj.event !== 'viewPhoto') {
                return;
            }
            $.ajax({
                url: baseUrl + "/photo/loc/auth",
                headers: {'token': localStorage.getItem('token')},
                data: {locNo: obj.data.locNo},
                method: 'GET',
                success: function (res) {
                    if (res.code === 200) {
                        showPhotoViewer(layer, res.data);
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg);
                    }
                }
            });
        });
        // 搜索栏搜索事件
        form.on('submit(search)', function (data) {
            pageCurr = 1;
src/main/webapp/views/locDetl/locDetl.html
@@ -93,6 +93,7 @@
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">详情</a>
    <a class="layui-btn layui-btn-xs" lay-event="viewPhoto">查看照片</a>
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
src/main/webapp/views/locMast/locMast.html
@@ -112,6 +112,7 @@
<script type="text/html" id="operate">
<!--    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="detail">详情</a>-->
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="viewPhoto">查看照片</a>
    <a class="layui-btn layui-btn-xs btn-edit" lay-event="edit">编辑</a>
</script>
src/main/webapp/views/pakStore/locDetlCheckQuery.html
@@ -118,6 +118,9 @@
<div class="layui-form">
    <table class="layui-hide" id="stockOut" lay-filter="stockOut"></table>
</div>
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="viewPhoto">查看照片</a>
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
@@ -152,7 +155,8 @@
        ];
        cols.push.apply(cols, detlCols);
        cols.push({field: 'modiUser$', align: 'center',title: '修改人员', hide: true}
            ,{field: 'modiTime$', align: 'center',title: '修改时间'})
            ,{field: 'modiTime$', align: 'center',title: '修改时间'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:110})
        return cols;
    }
@@ -242,6 +246,27 @@
            }
        });
        table.on('tool(stockOut)', function(obj){
            if (obj.event !== 'viewPhoto') {
                return;
            }
            $.ajax({
                url: baseUrl + "/photo/loc/auth",
                headers: {'token': localStorage.getItem('token')},
                data: {locNo: obj.data.locNo},
                method: 'GET',
                success: function (res) {
                    if (res.code === 200) {
                        showPhotoViewer(layer, res.data);
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg);
                    }
                }
            });
        });
        // 搜索栏搜索事件
        form.on('submit(search)', function (data) {
            tableReload();
src/main/webapp/views/pakStore/locDetlQuery.html
@@ -113,6 +113,9 @@
<div class="layui-form">
    <table class="layui-hide" id="stockOut" lay-filter="stockOut"></table>
</div>
<script type="text/html" id="operate">
    <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="viewPhoto">查看照片</a>
</script>
<script type="text/javascript" src="../../static/js/jquery/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="../../static/layui/layui.js" charset="utf-8"></script>
@@ -131,7 +134,8 @@
        ];
        cols.push.apply(cols, detlCols);
        cols.push({field: 'modiUser$', align: 'center',title: '修改人员', hide: true}
            ,{field: 'modiTime$', align: 'center',title: '修改时间'})
            ,{field: 'modiTime$', align: 'center',title: '修改时间'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:110})
        return cols;
    }
@@ -223,6 +227,27 @@
            }
        });
        table.on('tool(stockOut)', function(obj){
            if (obj.event !== 'viewPhoto') {
                return;
            }
            $.ajax({
                url: baseUrl + "/photo/loc/auth",
                headers: {'token': localStorage.getItem('token')},
                data: {locNo: obj.data.locNo},
                method: 'GET',
                success: function (res) {
                    if (res.code === 200) {
                        showPhotoViewer(layer, res.data);
                    } else if (res.code === 403) {
                        top.location.href = baseUrl + "/";
                    } else {
                        layer.msg(res.msg);
                    }
                }
            });
        });
        // 搜索栏搜索事件
        form.on('submit(search)', function (data) {
            tableReload();