# app_script_history

id: 674e599c99321d7b83fbaf5f
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 09:06:45.567
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id ,degree) {

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree  );
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        // sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {
            alert(1);
            旋转图片(data.id ,90); 
        },
        // 图片右转
        scan_func: function () {

        },
        // 选择
        scan_func: function () {
               旋转图片(data.id ,-90); 
        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    // console.log('================out')
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e599c99321d7b83fbaf63
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 09:07:13.947
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id ,degree) {

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree  );
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        // sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {
            alert(1);
            旋转图片(data.id ,90); 
        },
        // 图片右转
        scan_func: function () {

               旋转图片(data.id ,-90); 
        },
        // 选择
        scan_func: function () {
        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    // console.log('================out')
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e599c99321d7b83fbaf8d
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 09:08:50.613
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id ,degree) {

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree  );
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        // sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {
            alert(1);
            旋转图片(data.id ,90); 
        },
        // 图片右转
        turn_right_func: function () {

               旋转图片(data.id ,-90); 
        },
        // 选择
        scan_func: function () {
        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    // console.log('================out')
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e599c99321d7b83fbaf93
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:49:32.145
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id ,degree) {

    let sheet= book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree  );
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {
            alert(1);
            旋转图片(data.id ,90); 
        },
        // 图片右转
        scan_func: function () {

        },
        // 选择
        scan_func: function () {
               旋转图片(data.id ,-90); 
        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e599c99321d7b83fbaf97
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:50:14.512
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id ,degree) {

    let sheet= book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree  );
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {
            
            旋转图片(data.id ,90); 
        },
        // 图片右转
        scan_func: function () {

        },
        // 选择
        scan_func: function () {
               旋转图片(data.id ,-90); 
        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e599c99321d7b83fbaf9b
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:50:46.995
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id ,degree) {

    let sheet= book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree  );
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {
            
            旋转图片(data.id ,90); 
        },
        // 图片右转
        scan_func: function () {

旋转图片(data.id ,-90); 
        },
        // 选择
        scan_func: function () {
              
        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbaf9f
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:50:49.900
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        scan_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        scan_func: function () {

        },
        // 放大
        scan_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafa7
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:52:53.631
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");


        brick.addToolButton(2  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-repeat",   // 字符图标
            "旋转图片",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {  //点击后的回调函数

                showInfoPane('*正在旋转图片...');
                setTimeout(function () {
                    //toastr.info(id);  // id 是当前操作的图片对应数据的ID
                    var ret = do_imageRotate(id, "90");
                    if (ret.success) {
                        //把数据中的图片替换，
                        for (let i = 0; i < brick.data.length; i++) {
                            if (brick.data[i].id == id) {
                                //属性从新的属性中替换 
                                for (let prop in brick.data[i]) {
                                    brick.data[i][prop] = ret.data[prop];
                                }
                                break;
                            }
                        }
                        //把缩略图的图片地址替换 ， 

                        let img = $('#' + id).find('.image');
                        img.attr("src", ret.data.url_thumbnail);
                        img.attr('largeimage', ret.data.url_img);

                        hideInfoPane();

                    }
                }, 10);
            }
        );


        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {

        },
        // 放大
        blow_up_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafab
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:54:23.276
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}


function 选中此前(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let found = false;
    for (let i = 0; i < imgs.length; i++) {
        imgPool.setImageSelected(imgs[i].id, !selected);
        if (imgs[i].id == id) return;

    }
}


/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");



        brick.addToolButton(3  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-plus",   // 字符图标
            "选中此前",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {
                let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

                let imgPool = book.sheet1.getBrick("imgPool");
                let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
                let found = false;
                for (let i = 0; i < imgs.length; i++) {
                    imgPool.setImageSelected(imgs[i].id, !selected);
                    if (imgs[i].id == id) return;

                }


            });




        brick.addToolButton(4  //在从右往左数第2个工作栏位置添加一个工具按钮
            , "fa-bolt",   // 字符图标
            "OCR识别",  // 鼠标悬停的提示信息
            "green", //按钮背景色
            function (id) {

                let imgPool = book.sheet1.getBrick("imgPool");
                let data = imgPool.getDataById(id);
                let url = data.url_img;

                buildImageOCRConfig(url, null, function (config) {

                });



            });

    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {

        },
        // 放大
        blow_up_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafaf
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:55:53.608
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}


function 选中此前(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let found = false;
    for (let i = 0; i < imgs.length; i++) {
        imgPool.setImageSelected(imgs[i].id, !selected);
        if (imgs[i].id == id) return;

    }
}

function 当前图片直接OCR识别(data) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');


    let url = data.url_img;

    buildImageOCRConfig(url, null, function (config) {

    });




}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");




    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {

        },
        // 放大
        blow_up_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafb3
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:56:38.079
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}


function 选中此前(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let found = false;
    for (let i = 0; i < imgs.length; i++) {
        imgPool.setImageSelected(imgs[i].id, !selected);
        if (imgs[i].id == id) return;

    }
}

function 当前图片直接OCR识别(data) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');


    let url = data.url_img;

    buildImageOCRConfig(url, null, function (config) {

    });




}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");




    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {
            选中此前(id);
        },
        // 放大
        blow_up_func: function () {
            当前图片直接OCR识别(data);
        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafb7
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:57:54.380
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}


function 选中此前(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let found = false;
    for (let i = 0; i < imgs.length; i++) {
        imgPool.setImageSelected(imgs[i].id, !selected);
        if (imgs[i].id == id) return;

    }
}

function 当前图片直接OCR识别(data) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');


    let url = data.url_img;

    buildImageOCRConfig(url, null, function (config) {

    });




}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");




    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {

        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {
            选中此前(data.id);
        },
        // 放大
        blow_up_func: function () {
            当前图片直接OCR识别(data);
        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafbb
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 10:58:23.169
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}


function 选中此前(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let found = false;
    for (let i = 0; i < imgs.length; i++) {
        imgPool.setImageSelected(imgs[i].id, !selected);
        if (imgs[i].id == id) return;

    }
}

function 当前图片直接OCR识别(data) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');


    let url = data.url_img;

    buildImageOCRConfig(url, null, function (config) {

    });




}

/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");




    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {
            当前图片直接OCR识别(data);
        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {
            选中此前(data.id);
        },
        // 放大
        blow_up_func: function () {

        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


id: 674e720799321d7b83fbafc4
scriptid: 673210829932478770cad2af
tablename: app_template
clientip: 125.119.1.77
username: sa
createdate: 2024.12.03 13:20:01.723
script:
var pathToMonit = "";//当前监控的目录
var electron = null;
var pzh_prefix = ""; // 凭证号前缀
var pzh_len = 0; //凭证号长度
var lastPZH = "";
var fullScreenDiv = null;

/*
$(document).ready(function () {
    var script = $(`<script src="ui/imageEditor/filerobot-image-editor.min.js">
    
    </script>`);
    $(document.body).append(script);
});
*/

function formOpen() {

    $('body').append(`<script src="/resource?code=imgCustomControls.js"></script>`)

    book.getWorkSheet('归档').visible = false;

    book.showTabOnWhere = "none";
    newImgCommingTipVisible(false);


    //是否自动OCR
    let autoOCR = get_auto_ocr();
    book.sheet0.cells("ocr").setValue(autoOCR);

    book.sheet0.popoverContentFlagHiden = true; //不要显示 单元格有悬浮提示的标记

    //加载帐套信息及年月
    var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
    var ym = book.getWorkSheet('main').cells("ym").getValueString();
    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);

    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000001'.substring(8 - pzh_len, 8);
        lastPZH = v;
    });

    // smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
    // });

    book.getWorkSheet('凭证清单').cells("yue").setValue(getMonth(newDate()));


    book.sheet1.getBrick('imgPool').config.promptInfoOnDelete = "确信要将图片放入回收站吗?";

    //收到来自服务器推送的消息
    onPushMessage("electronPushMessage", function (msg) {
        msg = JSON.parse(msg);
        if (msg.cmd == "newFileUploaded") newImgCommingTipVisible(true); //通知有新文件上传了
        if (msg.cmd == "notifyNeedUploadFileCount") notifyNeedUploadFileCount(msg.fileCount); //通知还有多少个文件等待上传
    });


    onPushMessage("autoOCR", function (msg) {
        msg = JSON.parse(msg);
        if (msg.action == 'info') {
            toastr.show(msg.message);
        }
        if (msg.action == 'over') {
            toastr.hide();
        }
    });



    //获取当前的electron接口对象
    electron = getElectron(); //getElectron是系统全局功能函数

    book.sheet1.getBrick('imgPool').selectionMode = 'multi'; //图片设置成多选模式
    book.sheet1.getBrick('imgPool').config.selectedFlagStyle = 'border'; //以亮显边框的方式显示选中状态


    // 追加一些CSS类 ，用于凭证号标记
    $(document.body).append(`<style>
                        .pzh {position:absolute;left:0;bottom:0px; 
                                height:30px; line-height:30px;width:100%; 
                                background-color:#af4040e0; 
                                color:white;font-weight:bold;font-size:20px;text-align:left;}
                        .delete_pzh { position:absolute; right:0; width:40px; height:44px; top:0; text-align:right; 
                                    vertical-align:top; font-size:24px; color:#ffa0a0;padding-right:5px;}      
                        .delete_pzh:hover { color:white;}      
                          
                        </style>
                    `);


    //注册调整缩略图大小的事件

    $('#blockSize').on('input', resetImgPoolBlockSize);


    setTimeout(function () {
        //调取缩略图大小

        //默认显示小图
        imgSizeChange(1);
        /*
                var imgPool = book.sheet1.getBrick('imgPool');
                let blockSize = getImagePoolBlockSize();
                if (blockSize != imgPool.config.blockSize) {
                    $('#blockSize').val(blockSize);
                    resetImgPoolBlockSize(false);
                } 
                */

    }, 1000);




    //调取图片目录设置，注意适当延时
    setTimeout(function () {
        if (electron != null) {
            var hostName = electron.getHostName();
            pathToMonit = getMonitePath(hostName);

            //开启监控
            if (pathToMonit == '') pathToMonit = "c:\\凭证影像采集目录";

            moniteStart(pathToMonit);
            $.alert('请将扫描仪的图片目录指向：' + pathToMonit);
        }

        //显示总共图片数
        getTotalImageCount(function (ret) { book.sheet0.cells('imageCountTotal').setValue('共' + ret + '张') });

    }, 500);



    $(document).on('keydown', function (e) {
        console.info(" kkkkk down");
        if (e.ctrlKey) {
            // fullScreenViewImageOpen();
        }
    });


    $(document).on('keyup', function (e) {
        console.info(" kkkkk up");
        if (!e.ctrlKey) {

            // fullScreenViewImageClose();

        }
    });

    onPushMessage("pz_ocr", function (msg) {
        if (msg.action == 'info') {
            toastr.show(msg);
        }
    });

}

//@comment (group=顶部按钮,caption=图片大小修改,needRightControl=false)
function imgSizeChange(val) {
    book.sheet0.cells('imgsize').setValue(val);

    var imgPool = book.sheet1.getBrick('imgPool');

    resetImgPoolBlockSize(false);
}
//@comment (group=顶部按钮,caption=自动OCR修改,needRightControl=false)
function ocrChange() {
    var val = book.sheet0.cells('ocr').getValue();
    val = (val == '0') ? '1' : '0'
    book.sheet0.cells('ocr').setValue(val);
    set_auto_ocr(val, function () { });
}



// 先保存当前选中状态及设置的凭证号信息

var g_selection;
var g_pzMap;
//@comment (group=图片清单刷新,caption=保存选中状态及凭证标记信息,needRightControl=false)
function saveSelectionAndPZInfo() {

    var imgPool = book.sheet1.getBrick('imgPool');

    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    // 保存设置的凭证号信息
    var pzhMap = {};
    var pzhs = imgPool.dom.find('.pzh');
    for (let i = 0; i < pzhs.length; i++) {
        let id = $(pzhs[i]).parent().attr('id');
        let pzh = $(pzhs[i]).find('.no').text();
        pzhMap[id] = pzh;

    }
    g_selection = selection;
    g_pzMap = pzhMap;
}




//@comment (group=图片清单刷新,caption=还原选中及凭证标记,needRightControl=false)
function restoreSelectionAndPZInfo() {
    var selection = g_selection;
    var pzhMap = g_pzMap;
    var imgPool = book.sheet1.getBrick('imgPool');

    //恢复选中状态
    for (let i = 0; i < selection.length; i++) {
        imgPool.setImageSelected(selection[i].id, true);
    }
    //恢复凭证号
    for (let id in pzhMap) {
        var pzh = pzhMap[id];
        find_pzh(id, true).find('.no').text(pzh);
    }

}

//@comment (group=图片控件,caption=重设小图大小,needRightControl=false)
function resetImgPoolBlockSize(needSaveSetting) {
    if (needSaveSetting == null) needSaveSetting = true;
    var imgPool = book.sheet1.getBrick('imgPool');

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    let v = book.sheet0.cells('imgSize').getValueString();
    var blockSize = v == '1' ? '300' : '510';

    imgPool.config.blockSize = parseInt(blockSize);
    imgPool.rebuildGridly();

    //恢复选中状态
    restoreSelectionAndPZInfo();

    if (needSaveSetting) {
        setTimeout(function () {
            setImagePoolBlockSize(imgPool.getConfig("gguid"), v);
        }, 1000);
    }



}

function resetImageCountInfo() {

    setTimeout(function () {
        book.sheet0.cells("imageCount").setValue("前 " + book.sheet1.getBrick("imgPool").imageCount + " 张");
    }, 300);
}



function 旋转图片(id, degree) {

    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    showInfoPane('*正在旋转图片...');
    setTimeout(function () {
        //toastr.info(id);  // id 是当前操作的图片对应数据的ID
        var ret = do_imageRotate(id, degree);
        if (ret.success) {
            //把数据中的图片替换，
            for (let i = 0; i < brick.data.length; i++) {
                if (brick.data[i].id == id) {
                    //属性从新的属性中替换 
                    for (let prop in brick.data[i]) {
                        brick.data[i][prop] = ret.data[prop];
                    }
                    break;
                }
            }
            //把缩略图的图片地址替换 ， 

            let img = $('#' + id).find('.image');
            img.attr("src", ret.data.url_thumbnail);
            img.attr('largeimage', ret.data.url_img);

            hideInfoPane();

        }
    }, 10);


}


function 选中此前(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');

    let selected = $('#' + id).parent().find('.brickSelected').length > 0; // 可以用 imgPool.isImageSelected( id) 替换，但此时本函数还没有提供，以后可以换成此函数

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let found = false;
    for (let i = 0; i < imgs.length; i++) {
        imgPool.setImageSelected(imgs[i].id, !selected);
        if (imgs[i].id == id) return;

    }
}

function 当前图片直接OCR识别(data) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');


    let url = data.url_img;

    buildImageOCRConfig(url, null, function (config) {

    });



}



function 全屏显示大图(id) {
    let sheet = book.sheet1;
    let brick = sheet.getBrick('imgPool');
    brick.popupShow(id);
}


/**
 * 图片控件初始化完成
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片控件初始化完成)
function imageGridlyInited(sheet, name, data) {


    if (name == "imgPool") {
        resetImageCountInfo()
        //图片都初始化后， 定制右上角的工具栏，最多可加5个工具按 钮
        let brick = sheet.getBrick(name);

        book.sheet0.cells("imageCount").setValue(brick.imageCout + "张图片");




    }
}


/**
 * 图片控件中图片上的删除按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 * @param data  图片的信息
 *
 * @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行删除操作，否则表示终止删除操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上的删除按钮被点击)
function imageOnDelete(sheet, name, data) {



    if (name == 'imgPool') {
        moveImageToRecycle(data.id);
        resetImageCountInfo();
    }
    return { success: true };
}
/**
 * 图片控件中上传按钮被点击
 * @param sheet   所在Sheet
 * @param name  图片控件的名称
 *
 @returns  {object}    返回一个对象 ， 其中  success= boolean 表示继续执行上传操作，否则表示终止上传操作
 *    如果需要显示一个提示信息，则在 属性 message 中指定
 */
//@comment (group=图片控件,caption=图片上传按钮被点击)
function imageOnNewUpload(sheet, name) {


    if (name == 'imgPool') {
        toastr.info("请连接扫描仪，或将图片复制到监控的目录下，图片自动上传");
    }

    if (name == 'FJ') {
        var imgPool = book.sheet1.getBrick('imgPool');
        // 保存当前选中状态及设置的凭证号信息
        var selection = imgPool.getSelectedImageList();
        if (selection.length == 0) {
            toastr.error("至少选中一张图片");
            return { success: false }; // 此返回，阻止了默认的上传操作
        }


        var lastPZ = null;
        for (let i = 0; i < selection.length; i++) {
            var one = selection[i];
            var pzh = getPZH(one.id);
            if (pzh != '') {
                toastr.error("选中的图片中有标记为凭证的，禁止将凭证图片添加到当前凭证中");
                return { success: false }; // 此返回，阻止了默认的上传操作
            }
        }

        var ret = addImageToPZ($one_ds.getString(0, "id"), selection);
        if (ret.success) {
            //刷新图片区
            cb_refresh_onClick();
            //刷新凭证
            loadPZ($one_ds.getString(0, "id"), $one_ds.getString(0, "pzh"), $one_ds.getString(0, "verifiername") != "" ? 1 : 0);
        }

    }


    return { success: false }; // 此返回，阻止了默认的上传操作
}

//先定位 Id的序号， 然后返回它左边的图片的ID
function findLeftImageId(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    if (index > 0) return imgs[index - 1].id;
    return "";
}


//找到左边最近的一张凭证号
//如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
//否则在那个号上加1做为自已的凭证号
function incLeftNearestPZH(id) {
    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    //找到自已的索引号
    let index = 0;
    for (let i = 0; i < imgs.length; i++) {
        if (imgs[i].id == id) {
            index = i;
            break;
        }
    }

    //再从index往左边查到第一张凭证
    for (let i = index - 1; i >= 0; i--) {
        let tid = imgs[i].id;
        let pzh = getPZH(tid);
        if (pzh == '') continue;
        if (i == index - 1) {
            return pzh; // 左边最近的一张凭证号就在自已的左边，那么就意味着自已与左边那张凭证号可能就是一张凭证的不同分页，所以直接返回凭证号
        } else {
            return stringInc(pzh);
        }

    }
    //到这里，都没有找到凭证号，那么直接返回凭证号前缀
    return stringInc(lastPZH);
}

/**
 * 图片控件中鼠标进入某个图片区域
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=鼠标进入图片区域)
function imageOnMouseEnter(sheet, name, data, event) {
    var url = data.url_img;

    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControls({
        // 凭证标记编辑
        sign: '2024112101',
        // 凭证名称编辑
        sign_edit_func: function (val) {
            this.sign = val;
            this.init(); // 控件初始化
        },
        // 凭证名称删除
        sign_del_func: function () {

            this.sign = '';
            this.init(); // 控件初始化
            console.log(this)
        },
        // 凭证标记
        sign_func: function () {

        },
        // 扫描
        scan_func: function () {
            当前图片直接OCR识别(data);
        },
        // 图片左转
        turn_left_func: function () {

            旋转图片(data.id, 90);
        },
        // 图片右转
        turn_right_func: function () {

            旋转图片(data.id, -90);
        },
        // 选择
        select_func: function () {
            选中此前(data.id);
        },
        // 放大
        blow_up_func: function () {
brick.popupShow(data.id);
        }
    });

}
//@comment (group=图片控件,caption=鼠标从图片移开,needRightControl=false)
function imageOnMouseOut(sheet, name, data, event) {
    // 控件移除
    $('.brickInner.brickImage[id="' + data.id + '"]').imgCustomControlsRemove();
}

/**
 * 图片控件中图片顺序变化了
 * @param sheet   所在Sheet
 * @param config  图片控件的配置信息
 *@param ids  调整顺序后的id清单
 *
 */
//@comment (group=图片控件,caption=顺序调整后)
function attachmentOrderChanged(sheet, config, ids) {

    let imgPool = book.sheet1.getBrick("imgPool");
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    reorderImageFileIndex(imgs);

}

/**
 * 图片控件中某个图片被单击
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 * @param event  事件对象
 *
 *
 */
//@comment (group=图片控件,caption=图片被单击)
function imageOnClick(sheet, name, data, event) {

    if (name == 'imgPool') {
        //  if (book.sheet0.cells("clickAction").getValue() == 2) imageOnDBLClick(sheet, name, data, event, false);
    }
}


var g_lastPZH = "";
/**
 * 图片控件中某个图片被双击了
 * @param sheet   所在Sheet
 * @param config  图片控件的名称
 *@param data  该图片的详细信息
 *
 */
//@comment (group=图片控件,caption=图片被双击)
function imageOnDBLClick(sheet, name, data, event, showDlg) {

    if (showDlg == undefined) showDlg = true;


    var pzh = '';
    try {

        pzh = find_pzh(data.id, false).find('.no').text();
    } catch (err) {

    }

    if (pzh == undefined) pzh = "";
    if (pzh == '') {

        //找到左边最近的一张凭证号
        //如果该凭证与自已相临，那么就同号，因为可能是同一个凭证的不同分页
        //否则在那个号上加1做为自已的凭证号
        pzh = incLeftNearestPZH(data.id);
        if (pzh > lastPZH) lastPZH = pzh;


    }

    let $setpzh = function (val) {
        if (val == '') {

            var p = find_pzh(data.id, false);
            if (p) p.remove();
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, false);
            return true;
        } else {
            if (val.length - pzh_prefix.length != pzh_len) {
                toastr.error("凭证号(不含前缀)长度必须是" + pzh_len + "位");
                return false;

            }
            g_lastPZH = val; //记下来
            find_pzh(data.id, true).find('.no').text(val);
            book.sheet1.getBrick("imgPool").setImageSelected(data.id, true);
            return true;
        }
    }

    if (!showDlg) {
        $setpzh(pzh);
        return;
    }

    let dlg = inputBox("标记为凭证", "", pzh, "输入凭证号码",

        function (val) { //确认后的回调

            return $setpzh(val);

        }, false,/*不允许为空*/
        //下面是一些事件的切入
        {
            //输入面板初始化完成后
            onContentReady: function () {

                let input = dlg.$content.find('.name');
                input.on('keyup', function () {
                    if (input.val().indexOf(pzh_prefix) != 0) {
                        input.val(pzh_prefix);
                    }
                });
            }
        }
    );




}


function setLoadImagePoolDataOnceCount() {
    let onceCount = book.sheet0.cells("onceCount").getValueInt();
    if (onceCount < 0) onceCount = 100;
    if (onceCount > 2000) onceCount = 2000;
    setTimeout(function () {
        book.sheet0.cells("onceCount").setValue(onceCount);
        book.sheet1.getBrick("imgPool").config.onceCount = onceCount;
        cb_refresh_onClick();
    }, 1);

}

//@comment (group=凭证号,caption=得到图片的凭证号如果有的话,needRightControl=false)
function getPZH(id) {
    let obj = find_pzh(id, false);
    if (obj == null) return;
    let s = obj.text();
    s = s.replace(/\s/g, '');
    return s;
}

//@comment (group=凭证号,caption=设置图片的凭证号,needRightControl=false)
function setPZH(id, pzh, needDeleteButton) {
    if (needDeleteButton == undefined) needDeleteButton = true
    find_pzh(id, true, needDeleteButton).find('.no').text(pzh);
}

//@comment (group=凭证号,caption=查找或创建凭证号标记对象,needRightControl=false)
function find_pzh(id, create_if_not_exists, needDeleteButton) {

    if (needDeleteButton == undefined) needDeleteButton = true;

    var d = $('#' + id);
    if (!d) {
        $.alert(id + "不存在");
        return null;
    }

    var ret = d.find('.pzh');
    if (ret.length == 0) {
        if (create_if_not_exists) //如果需要创建，则创建它
        {
            d.append(`<div class="pzh" >
                        <div class="no"></div>
                        <div class="delete_pzh"  ${needDeleteButton ? "" : " style='display:none' "} ><i class="fa fa-close" onclick="removePZH('${id}');  event.preventDefault(); event.stopPropagation();"> </i></div>
                      </div>`);
        }
        ret = d.find('.pzh');
    }
    return ret;

}

//@comment (group=图片控件,caption=移除图片看的凭证号标记,needRightControl=false)
function removePZH(id) {
    var p = find_pzh(id, false);
    if (p) p.remove();
}

function cb_selectall_onClick() { doSelect(true); }
function cb_selectnull_onClick() { doSelect(false); }

function doSelect(b) {
    var imgPool = book.sheet1.getBrick('imgPool');
    if (b) {
        imgPool.selectAll();
    } else {
        imgPool.unSelectAll();
    }
}


function cb_path_onClick() {
    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    var path = electron.showOpenDialogSync('');
    if (path == '') return;
    if (!path.endsWith('凭证影像采集目录')) {

        $.alert("目录名必须是：“凭证影像采集目录”，盘符及上级目录随意。");
        return;
    }
    var hostName = electron.getHostName();
    setMonitePath(hostName, path);

    moniteStart(path);


}

//@comment (group=上传相关,caption=开始文件变化监控,needRightControl=false)
function moniteStart(path) {
    pathToMonit = path;
    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit);

    if (electron == null) {
        toastr.error("此功能仅能在客户端APP中执行");
        return;
    }

    book.sheet0.cells('stateBar').setValue("图片目录 " + pathToMonit + " 监控中...");
    electron.ipcSendMessage({ cmd: "moniteStart", path: path });
}

function cb_refresh_onClick() {
    newImgCommingTipVisible(false);

    // 先保存当前选中状态及设置的凭证号信息
    saveSelectionAndPZInfo();

    var imgPool = book.sheet1.getBrick('imgPool');
    imgPool.reInit(restoreSelectionAndPZInfo); //重新初始化 ,并在初始化完成后， 恢复选中状态

    toastr.info("重新加载完成");
}

//@comment (group=上传相关,caption=上传好一个文件后，通知有新文件,needRightControl=false)
//@comment (group=上传相关,caption=上传好一个文件后通知有新文件,needRightControl=false)
function newImgCommingTipVisible(v) {
    book.sheet0.getBrick('shineText').visible = v;

}

//@comment (group=上传相关,caption=刷新当前还有多少文件要上传的提示,needRightControl=false)
function notifyNeedUploadFileCount(fc) {
    var info = fc == 0 ? "" : "【" + fc + "】个文件正准备上传";
    book.sheet0.cells("stateInfo2").setValue(info);
}


//@comment (group=归档,caption=凭证归档,needRightControl=false)
function cb_auto_onClick() {

    var imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    var selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }

    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    let nn = imgs.length - selection.length;
    if (nn > 0) {
        $confirm("提示", "有" + nn + "张图片没有选中，确信要继续吗?", function () {
            do_pack(selection);
        });
    } else {
        do_pack(selection);
    }
}

var pzGroup = [];

//@comment (group=归档,caption=归档操作,needRightControl=false)
function do_pack(selection) {
    pzGroup = [];
    let pzh2Config = {}; //凭证号对应的配置信息 ， 辅助数据
    let lastPZ = null;
    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        let pzh = getPZH(one.id);
        if (pzh == '') {
            if (lastPZ != null) {
                lastPZ.fj.push(one.id);
            }
        } else {
            //新的凭证号
            if (pzh2Config[pzh] == null) {
                lastPZ = {};
                lastPZ.pzh = pzh;
                lastPZ.fj = []; //附件图片
                lastPZ.pz = []; //凭证图片
                pzh2Config[pzh] = lastPZ; //记下凭证号与配置对象的对应关系
                pzGroup.push(lastPZ); //加入到总配置中
            } else {
                //已经存在配置，说明它是该凭证号的更多的分页图片
                //需要检测，它的左边是不是也是同一个号的凭证
                lastPZ = pzh2Config[pzh];

                let leftID = findLeftImageId(one.id); //找到它左边那张图片的ID
                if (leftID == '') {
                    toastr.error("不可能出现的情况");
                    return;
                }
                let leftPZH = getPZH(leftID);
                if (leftPZH != pzh) {
                    $.alert(pzh + '有多张图片，请将它们移动到相邻位置，即同一张凭证的多个分页必须连续相邻，它们之间不要穿插附件图片或其它凭证号图片');
                    return;
                }

            }
            lastPZ.pz.push(one.id); //凭证图片，同一个凭证可能有多个图片 
        }
    }

    if (pzGroup.length == 0) {
        toastr.error("凭证归档操作，至少需要标记一张凭证，并选中它");
        return;
    }

    console.dir();


    do_pzgdqr();



}

//@comment (group=归档,caption=归档确认,needRightControl=false)
function do_pzgdqr() {

    // 整理归档配置信息用于显示
    book.getWorkSheet('归档').paintPermit = false;

    $gd_ds.reset();
    for (let i = 0; i < pzGroup.length; i++) {
        let one = pzGroup[i];
        let row = $gd_ds.insertRow(9999);
        $gd_ds.setValue(row, { pzh: one.pzh, pzs: one.pz.length, fjs: one.fj.length, hj: one.pz.length + one.fj.length });
    }
    book.getWorkSheet('归档').paintPermit = true;

    book.getWorkSheet('归档').popup('fa fa-cog', '归档确认', 450, 450, true, true, {
        action1: {
            text: '确认',
            btnClass: 'btn-green',
            action: function () {
                do_pzgd();
                return true;    //表示关闭弹窗
            }
        },
        cancel: {
            text: '关闭',
            btnClass: 'btn-red',
            action: function () {

                return true;
            }
        }

    });

}
//@comment (group=归档,caption=归档,needRightControl=false)
function do_pzgd() {
    showInfoPane('*正在归档...');
    setButtonsStatus(false); //禁用一些按钮点击
    //alert(JSON.stringify(pzGroup));
    runTask("归档",
        {
            corpid: book.getWorkSheet('归档').cells("corpid").getValueString(),
            ym: book.getWorkSheet('归档').cells("ym").getValueString(),
            pzGroup: pzGroup
        }, function (ret) {
            hideInfoPane();
            ret = JSON.parse(ret);

            if (ret.success) {

                setButtonsStatus(true); //启用一些按钮点击
                smartRetrieve(book.sheet2, "dzpz_pz"); //刷新凭证列表
                //重新检索图片区
                cb_refresh_onClick();
            } else {
                $.alert(ret.message);
            }

        });
}

function setButtonsStatus(b) {

    book.sheet0.getBrick('cb_auto').enabled = b;
}




function cb_trash_onClick() {
    var url = runTask("urlForTrash", {});
    openInMainFrame(url, false, 'fa-trash', '图片回收站');

}

function cb_deleteSelection_onClick() {
    let imgPool = book.sheet1.getBrick('imgPool');
    // 保存当前选中状态及设置的凭证号信息
    let selection = imgPool.getSelectedImageList();
    if (selection.length == 0) {
        toastr.error("至少选中一张图片");
        return;
    }
    let nn = selection.length;
    $confirm("提示", "确信将选中的" + nn + "张图片移入回收站吗?", function () {
        showInfoPane('*正在移和回收站');
        setTimeout(function () {
            do_trush(selection);
            hideInfoPane();
        }, 100);
    });

}

function do_trush(selection) {

    for (let i = 0; i < selection.length; i++) {
        let one = selection[i];
        moveImageToRecycle(one.id);

    }
    cb_refresh_onClick();

}

function cb_size_onClick() {
    let RPM = book.sheet0.RPM;
    let h = RPM.getRowHeight(1);
    if (h > 1) {
        RPM.setRowStretchHeight(1, 0);//弹性高度取消
        RPM.setRowHeight(1, 1);

        RPM.setRowHeight(2, 0);
        book.sheet0.getBrick('dbnav').visible = false;

    } else {

        RPM.setRowStretchHeight(1, 40);//弹性高度取消
        RPM.setRowHeight(1, 300);

        RPM.setRowHeight(2, 30);
        book.sheet0.getBrick('dbnav').visible = true;
    }
}


/**
 * 单元格的值发生了改变
 * @param sheet  所在的工作表
 * @param cell  单元格对象
 * @param oldValue  原先的值
 * @param newValue 变化后的值
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChanged(sheet, cell, oldValue, newValue, innerRow) {

    //通过别名来判断
    if (sheet.name == '凭证清单') {
        if (cell.alias == 'nian' || cell.alias == 'yue') {
            reload_pzh_info();
        };
    }



}

/**
 * 单元格因为被编辑而改变。当用户通过编辑单元的值而让单元格发生值改变时本事件被触发。
 * 注意，当使用脚本 sheet.cells(row,col).setValue ( value) 来改变单元格的值时，本事件并不触发
 * @param sheet
 * @param cell
 * @param newValue
 * @param innerRow   当单元格没有绑定数据库或绑定到单行数据库时，本参数无意义。如果绑定一个
 * 多行数据库，则表示该单元所绑定的字段的第 innerRow行发生变化
 */
function cellValueChangedByEdit(sheet, cell, newValue, innerRow) {

    if (cell.alias == 'onceCount') {
        setLoadImagePoolDataOnceCount();

    }


}



function reload_pzh_info() {
    var sheet = book.getWorkSheet('main');
    //加载帐套信息及年月
    var corpid = sheet.cells("corpid").getValueString();

    var nian = sheet.cells("nian").getValueString();
    var yue = sheet.cells("yue").getValueString();
    var ym = nian + right("00" + yue, 2);

    //得到年月后，获取凭证号相关设置
    pzh_len = getPZHLen(corpid);
    pzh_prefix = getPZHPrefix(corpid, ym);
    getLastPZH(corpid, ym, function (v) {
        if (v == '') v = pzh_prefix + '00000000'.substring(8 - pzh_len, 8);
        lastPZH = v;

    });

    smartRetrieve(sheet, "dzpz_pz"); //刷新凭证列表
}



function cb_ocr_onClick() {
    toastr.show("正在自动识别");
    var imgPool = book.sheet1.getBrick('imgPool');
    let imgs = imgPool.getCurrentSortedImageList();//得到当前排序后的图片清单
    asyncPool(1,  // 最多4个并发执行
        imgs, //需要处理的数据数组，每个元素可以是任意类型的数据
        function (one, array) // item表示当前处理的对象， array就是整个数据数组
        {
            console.info(one.url_img);
            //函数必须返回一个Promise对象
            return new Promise(function (resolve, reject) {

                var corpid = book.getWorkSheet('main').cells("corpid").getValueString();
                var ym = book.getWorkSheet('main').cells("ym").getValue();

                back_ocr({ id: one.id, ocr: one.ocr, corpid: corpid, ym: ym }, function (ret) {


                    if (ret.needWriteback) one.ocr = JSON.stringify(ret.ocrResult);

                    if (ret.pzh != '') {
                        setPZH(one.id, ret.pzh);

                    }
                    resolve(1);
                });





            });
        }).then(function () {  //此时，整个数据数组都已经迭代执行完成 ，通常在此善后
            console.info("over");
            toastr.hide();
            toastr.success("自动识别完成");
            hideInfoPane();
        });

}


