var FPY_workbenchFun = function (KDApi, $, _) {
    let curIndex = '0';  // 当前内容显示下标 0, 1, 2, 3
    let model;
    let billNoMap;
    // 开票申请单-数据
    const billParam = {
        billNo: '',
        buyerName: '',
        deviceNo: '',
        billMerger: false,
        itemMerger: false
    };
    const rowKey = 'id'; // 开票申请单-单据rowkey
    let deviceNoList = []; // 开票申请单-设备编号
    let limitAmounts = {}; // 开票申请单-拆分限额
    let billList = []; // 开票申请单-单据列表
    // let selectedRowKeys = []; // 开票申请单-已选列表

    // 单据明细处理-数据
    const treatmentSync = ['buyername', 'buyertaxno', 'buyeraddr', 'buyerbank', 'buyeremail', 'buyerphone', 'applyreason']; // 明细处理-能同步的字段
    let treatmentIndex = 0; // 明细处理-当前下标
    let treatmentSplitRule = []; // 明细处理-所有拆分方案-数组
    const treatmentSplitRuleDict = {}; // 明细处理-所有拆分方案-对象
    let treatmentShowBillList = []; // 明细处理-显示的单据列表
    let treatmentInvoiceList = {}; // 明细处理-发票对象 以单据id为key值
    let treatmentInvoiceRelationMap = {}; // 明细处理-发票关系对象 以单据id为key值
    let treatmentRemainingItems = {}; // 明细处理-按明细处理剩余明细对象 以单据id为key值

    // 发票预览-数据
    let previewIndex = 0; // 发票预览单据-当前下标
    let previewInvoiceIndex = 0; // 发票预览单据-当前下标

    // 开票结果-数据
    let resultTimer; // 开票结果-计时器
    let resultTotal = 0; // 开票结果-发票总张数
    let resultList = []; // 开票结果-开票结果列表
    let resultOpenType = 'normal'; // 开票结果-开票类型

    //发票预览页是否保存数据标记
    let previewDataSave = false;
    let infocodechoose = '';

    // JQ对象缓存
    const $workbench = $('#imc_invoiceWorkbench');

    // 头部
    const $head = $workbench.find('.head');
    const $head_item = $head.find('.item');
    const $head_bill_value = $head.find('.bill').find('.value');
    const $head_treatment_value = $head.find('.treatment').find('.value');
    const $head_preview_value = $head.find('.preview').find('.value');
    const $head_result_value = $head.find('.result').find('.value');

    const $content = $workbench.find('.content');
    // 开票申请单
    const $bill = $workbench.find('.bill');
    const $bill_table = $bill.find('.bill-table');
    const $bill_footer_span = $bill.find('.footer').find('span');
    // 单据明细处理
    const $treatment = $workbench.find('.treatment');
    const $treatment_solutions = $treatment.find('.solutions');
    const $treatment_bill = $treatment.find('.bill-detail');
    const $treatment_invoice = $treatment.find('.invoice-detail');
    // 发票预览
    const $preview = $workbench.find('.preview');
    const $preview_bill = $preview.find('.bill-list');
    const $preview_box = $preview.find('.invoice-box');
    const $preview_prev = $preview.find('.invoice-box').find('.prev');
    const $preview_next = $preview.find('.invoice-box').find('.next');
    const $preview_invoice = $preview.find('.invoice');
    const $preview_invoiceType = $preview.find('.invoiceType');
    const $preview_buer = $preview_invoice.find('.buyer').find('.value');
    const $preview_saler = $preview_invoice.find('.saler').find('.value');
    const $preview_jshjje = $preview_invoice.find('.jshjje');
    const $preview_bz = $preview_invoice.find('.bz');
    const $preview_item = $preview_invoice.find('.label').find('.item');
    const $preview_detail = $preview_invoice.find('.detail');
    const $preview_operator = $preview_invoice.find('.operator').find('.value');
    // 开票结果
    const $result = $workbench.find('.result');
    const $result_progress = $result.find('.progress');
    const $result_progress_percent = $result_progress.find('.percent');
    const $result_progress_text = $result_progress.find('.text');
    const $result_fail = $result.find('.fail');
    const $result_success = $result.find('.success');
    const $result_detail = $result.find('.detail');
    const $result_detail_table = $('#imc_invoiceWorkbench_detail_table');

    function setInitData(props) {
        $content.show();

        curIndex = props.currentDisplay || 0;
        // 顶部需要的数据加载

        billParam.billMerger = props.isMergeBill || false;
        billParam.itemMerger = props.isMergeDetail || false;
        deviceNoList = props.jqbhs || [];
        billParam.deviceNo = props.currentJqbh || '';
        billList = props.bills || [];
        treatmentSplitRule = props.splitrule || [];
        billNoMap = props.billNoMap || {};

        for (let i = 0; i < treatmentSplitRule.length; i++) {
            const curData = treatmentSplitRule[i];
            treatmentSplitRuleDict['k' + curData.ruleCode] = curData.ruleName;
        }
        if (props.mergeBill) {
            treatmentMergeBillRelation = props.mergeBill.mergeBillRelation || {};
            treatmentShowBillList = formatTreatmentBill(props.mergeBill.bills || []);
        }
        if (props.invoiceList) {
            treatmentInvoiceList = props.invoiceList || [];
            treatmentInvoiceRelationMap = props.invoiceRelationMap || {};
        }
        if (props.limitAmounts) {
            limitAmounts = props.limitAmounts;
        }

        if (curIndex === 2) {
            updateBillHeader();
            updateTreatmentHeader();
        }
        setCurrentDisplay(curIndex);
    }

    function setCurrentDisplay(index) {
        curIndex = index;
        $head_item.removeClass('actived hack').eq(index).addClass('hack');
        for (let i = 0; i <= index; i++) {
            $head_item.eq(i).addClass('actived');
        }
        $content.find('.content-item').hide().eq(index).show();
        // 头部
        switch (index) {
        case 0:
            showBill();
            break;
        case 1:
            showTreatment();
            break;
        case 2:
            showPreview();
            break;
        case 3:
            showResult();
            break;
        default:
            break;
        }
    }

    // 开票申请单
    function showBill() {
        showBillTable();
        showBillParam();
        updateBillHeader();
    }

    // 开票申请单-列表 筛选显示
    function showBillTable() {
        let tableData = JSON.parse(JSON.stringify(billList));
        if (billParam.billNo) {
            tableData = tableData.filter(o => o.billno.indexOf(billParam.billNo) !== -1);
        }
        if (billParam.buyerName) {
            tableData = tableData.filter(o => o.buyername.indexOf(billParam.buyerName) !== -1);
        }
        Table().init({
            id: 'imc_invoiceWorkbench_bill_table',
            rowKey,
            columns: [
                {
                    title: '序号',
                    width: 40,
                    render: (t, r, i) => Number(i) + 1
                },
                {
                    align: 'left',
                    title: '单据编号',
                    dataIndex: 'billno',
                    ellipsis: true,
                    width: 200,
                    render: (t, r) => `<a href='javascript:;' data-name="detail" data-key=${r.id}>${t}</a>`
                },
                {
                    align: 'left',
                    title: '购方名称',
                    dataIndex: 'buyername',
                    ellipsis: true,
                    width: 205
                },
                {
                    title: '单据日期',
                    dataIndex: 'billdate',
                    width: 138
                },
                {
                    title: '发票种类',
                    dataIndex: 'invoicetype',
                    width: 100,
                    render: t => INVOICE_TYPES_DICT['k' + t] || t
                },
                {
                    title: '单据性质',
                    dataIndex: 'billproperties',
                    render: t => t === '-1' ? '负数' : '正数',
                    width: 80
                },
                {
                    title: '单据金额（元）',
                    dataIndex: 'totalamount',
                    width: 165,
                    render: t => Number(t).toFixed(2)
                },
                {
                    title: '可开票金额（元）',
                    dataIndex: 'totalamount',
                    width: 177,
                    render: t => Number(t).toFixed(2)
                },
                {
                    title: '操作',
                    dataIndex: 'id',
                    width: 40,
                    render: (t, r, i) => `<a href='javascript:;' data-name="del" data-key=${i}>移除</a>`
                }
            ],
            scroll: tableData.length > 12 ? { y: 400 } : {},
            dataSource: tableData
        });
    }

    // 开票申请单-参数
    function showBillParam() {
        $bill.find('.billMerger').attr('checked', billParam.billMerger);
        $bill.find('.itemMerger').attr('checked', billParam.itemMerger);
        const deviceNos = [];
        for (const o in deviceNoList) {
            deviceNos.push({
                key: deviceNoList[o],
                value: o
            });
        }
        console.log(billParam.deviceNo);
        const _html = [`<option value="" disabled>请选择设备编号</option>`];
        for (let i = 0; i < deviceNos.length; i++) {
            _html.push(`<option value="${deviceNos[i].key}" title="${deviceNos[i].value}">${deviceNos[i].value}</option>`);
        }
        $bill.find('.deviceNo').empty().html(_html.join('')).val(billParam.deviceNo);
    }

    // 开票申请单-更新头部
    function updateBillHeader() {
        const _data = billList.reduce((all, b) => all + Number(b.totalamount), 0);
        $head_bill_value.eq(0).text(billList.length + '个');
        $head_bill_value.eq(1).text(_data.toFixed(2) + '元');
        $bill_footer_span.eq(0).text(billList.length + '个');
        $bill_footer_span.eq(1).text(_data.toFixed(2) + '元');
    }

    // 单据明细处理
    function showTreatment() {
        showTreatmentSolutions();
        showTreatmentBill();
        showTreatmentInvoice();
        updateTreatmentHeader();
    }

    // 单据明细处理-拆分方案
    function showTreatmentSolutions() {
        const splitRule = treatmentShowBillList[treatmentIndex].splitrule;
        const disabled = treatmentShowBillList[treatmentIndex].totalamount < 0;
        // 拆分方案
        const value = treatmentSplitRuleDict['k' + splitRule] || '';
        $treatment_solutions.find('.cur-solutions').text(value).prop('title', value);
        // 常用拆分方案
        const otherSolutions = treatmentSplitRule.filter(o => o.ruleCode !== splitRule);
        const allLength = otherSolutions.length;
        const _length = allLength > 3 ? 3 : allLength;
        const _html = [];
        for (let i = 0; i < _length; i++) {
            const obj = otherSolutions[i];
            _html.push(`<div class="solutions-item truncateText ${disabled ? 'disabled' : ''}" data-id="${obj.ruleCode}" title="${obj.ruleName}">${obj.ruleName}</div>`);
        }
        $treatment_solutions.find('.common-solutions').html(_html.join(''));
        // more
        if (allLength > 3) {
            $treatment_solutions.find('.more-box').show();
            if (disabled) {
                $treatment_solutions.find('.btn').addClass('disabled');
            } else {
                $treatment_solutions.find('.btn').removeClass('disabled');
                const _html = [];
                for (let i = 3; i < allLength; i++) {
                    const obj = otherSolutions[i];
                    _html.push(`<div class="solutions-item truncateText ${disabled ? 'disabled' : ''}" data-id="${obj.ruleCode}" title="${obj.ruleName}">${obj.ruleName}</div>`);
                }
                $treatment_solutions.find('.more-solutions').html(_html.join(''));
            }
        } else {
            $treatment_solutions.find('.more-box').hide();
        }
    }

    // 单据明细处理-单据
    function showTreatmentBill() {
        const _html = [];
        for (let i = 0; i < treatmentShowBillList.length; i++) {
            const obj = treatmentShowBillList[i];
            // 是否按明细拆分
            const isDetailSplit = obj.splitrule === 'imc_split_by_detail';
            const difference = fpy_Minus(obj.maintaxdeviation || 0, obj.adjustedData || 0);
            _html.push(`<div class="item ${i === treatmentIndex ? 'actived' : ''}" data-index="${i}">
                <div class="title">
                    <div class="name truncateText" title="${obj.billno}">单据编号：${obj.billno}</div>
                    <div class="statu">信息待补充</div>
                    ${difference != 0 ? `<div class="error">税额尾差：${Number(difference).toFixed(2)}</div>` : ''}
                    ${isDetailSplit ? `<div class="sure primary ${obj.remainingDisabled ? 'disabled' : ''}">确认选取</div>` : ''}
                </div>
                <div id="imc_invoiceWorkbench_treatment_bill${obj.id}" class="table-box"></div>
            </div>`);
        }
        $treatment_bill.empty().html(_html.join(''));
        for (let i = 0; i < treatmentShowBillList.length; i++) {
            const obj = treatmentShowBillList[i];
            let _dataSource = obj.sim_original_bill_item;
            let _selectedRowKeys = false;
            let _disabled = false;
            // 按明细拆分
            if (obj.splitrule === 'imc_split_by_detail') {
                _dataSource = treatmentRemainingItems[obj.id].items;
                _selectedRowKeys = treatmentRemainingItems[obj.id].selectedRowKeys;
                _disabled = o => o.remainvalidamount == 0;
            }
            const total = _dataSource.reduce((all, b) => [all[0] + Number(b.remainvalidnum), all[1] + Number(b.remainvalidamount)], [0, 0]);
            const zeroList = _dataSource.filter(o => o.taxunitprice == 0);
            Table().init({
                id: 'imc_invoiceWorkbench_treatment_bill' + obj.id,
                rowKey,
                columns: [
                    {
                        align: 'left',
                        title: '开票项目',
                        dataIndex: 'goodsname',
                        ellipsis: true,
                        width: 100,
                        totalName: '合计'
                    },
                    {
                        align: 'left',
                        title: '可申请数量',
                        dataIndex: 'remainvalidnum',
                        ellipsis: true,
                        width: 90,
                        render: (t, r) => r.taxunitprice != 0 ? fpy_toFixedNoZero(t, 8) : '',
                        totalName: zeroList.length === _dataSource.length ? '' : fpy_toFixedNoZero(total[0], 8)
                    },
                    {
                        align: 'left',
                        title: '可申请金额(含税)',
                        dataIndex: 'remainvalidamount',
                        ellipsis: true,
                        width: 110,
                        render: t => Number(t).toFixed(2),
                        totalName: total[1].toFixed(2)
                    }
                ],
                scroll: _dataSource.length > 3 ? { y: 78 } : {},
                dataSource: _dataSource,
                selectedRowKeys: _selectedRowKeys,
                disabled: _disabled,
                headerColor: '#666',
                headerBgColor: '#ebeef3',
                rowHeight: 26,
                showTotal: true
            });
            testTreatmentBillFinished(i);
        }
    }

    // 单据明细处理-格式化单据
    function formatTreatmentBill(data) {
        return data.map(o => {
            return {
                ...o,
                hadBuyername: !!o.buyername,
                hadBuyertaxno: !!o.buyertaxno,
                hadHzxxbm: !!o.infocode,
                hadBlueInvoice: !!o.blueinvoicecode
            };
        });
    }

    // 单据明细处理-发票
    function showTreatmentInvoice() {
        // 发票
        const bill = treatmentShowBillList[treatmentIndex];
        const _data = treatmentInvoiceList[bill.id];
        const _length = _data.length;
        const _html = [];
        for (let i = 0; i < _length; i++) {
            const obj = _data[i];
            if (obj.totalamount < 0) {
                if (obj.invoicetype === '028' || obj.invoicetype === '004') {
                    _html.push(`<div class="item" data-index="${i}">
                        <div class="info" data-all="${_length}">
                            <div class="text">
                                <div class="name">发票类型</div>
                                <div class="value">
                                    <div class="invoiceType actived" data-key="${obj.invoicetype}">${INVOICE_TYPES_DICT['k' + obj.invoicetype] || obj.invoicetype}</div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">购方名称</div>
                                <div class="value search">
                                    <input class="searchInput" type="text" name="buyername" maxlength="100" value="${obj.buyername}" disabled>
                                    <div data-name="buyername" class="search-btn disabled"></div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">纳税人识别号</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="buyertaxno" maxlength="20" value="${obj.buyertaxno}" disabled>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">地址及电话</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="buyeraddr" maxlength="100" value="${obj.buyeraddr}">
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">开户行及账号</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="buyerbank" maxlength="100" value="${obj.buyerbank}">
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">申请方类型</div>
                                <div class="value">
                                    <input type="radio" name="applicant" value="2" ${obj.applicant === '2' ? 'checked' : ''}>
                                    <span class="mgl5">销方申请</span>
                                    <input type="radio" name="applicant" value="1" ${obj.applicant !== '2' ? 'checked' : ''}>
                                    <span class="mgl5">购方申请</span>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">红字信息表</div>
                                <div class="value search">
                                    <input class="searchInput" type="text" name="infocode" maxlength="24" value="${obj.infocode}" ${bill.hadHzxxbm ? 'disabled' : ''}>
                                    <div data-name="infocode" class="search-btn ${bill.hadHzxxbm ? 'disabled' : ''}"></div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">原蓝票代码</div>
                                <div class="value search">
                                    <input class="searchInput" type="text" name="originalinvoicecode" maxlength="12" value="${obj.originalinvoicecode}" ${obj.applicant !== '2' || bill.hadHzxxbm || bill.hadBlueInvoice ? 'disabled' : ''}>
                                    <div data-name="originalinvoicecode" class="search-btn ${obj.applicant !== '2' || bill.hadHzxxbm || bill.hadBlueInvoice ? 'disabled' : ''}"></div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">原蓝票号码</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="originalinvoiceno" maxlength="8" value="${obj.originalinvoiceno}" ${obj.applicant !== '2' || bill.hadHzxxbm || bill.hadBlueInvoice ? 'disabled' : ''}>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">原蓝票开票日期</div>
                                <div class="value">
                                    <input class="searchInput" type="date" name="originalissuetime" value="${(obj.originalissuetime || '').substring(0, 10)}" ${obj.applicant !== '2' || bill.hadHzxxbm || bill.hadBlueInvoice ? 'disabled' : ''}>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">备注</div>
                                <div class="value">
                                    <textarea name="applyreason" maxlength="100">${obj.applyreason}</textarea>
                                </div>
                            </div>
                        </div>
                        <div id="imc_invoiceWorkbench_treatment_invoice${obj.id}" class="table-box"></div>
                        <div class="total">
                            <span class="total-item">税额合计：<span class="warning val">${Number(obj.totaltax).toFixed(2)}</span>元</span>
                            <span class="total-item">不含税额金额合计：<span class="warning val">${Number(obj.invoiceamount).toFixed(2)}</span>元</span>
                            <span class="total-item">价税合计：<span class="warning val">${Number(obj.totalamount).toFixed(2)}</span>元</span>
                        </div>
                    </div>`);
                } else {
                    _html.push(`<div class="item" data-index="${i}">
                        <div class="info" data-all="${_length}">
                            <div class="text">
                                <div class="name">发票类型</div>
                                <div class="value">
                                    <div class="invoiceType actived" data-key="${obj.invoicetype}">${INVOICE_TYPES_DICT['k' + obj.invoicetype] || obj.invoicetype}</div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">购方名称</div>
                                <div class="value search">
                                    <input class="searchInput" type="text" name="buyername" maxlength="100" value="${obj.buyername}" disabled>
                                    <div data-name="buyername" class="search-btn disabled"></div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name ${obj.buyerproperty === '0' ? 'requiredFields' : ''}"">纳税人识别号</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="buyertaxno" maxlength="20" value="${obj.buyertaxno}" disabled>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">地址及电话</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="buyeraddr" maxlength="100" value="${obj.buyeraddr}">
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">开户行及账号</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="buyerbank" maxlength="100" value="${obj.buyerbank}">
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">原蓝票代码</div>
                                <div class="value search">
                                    <input class="searchInput" type="text" name="originalinvoicecode" maxlength="12" value="${obj.originalinvoicecode}" ${bill.hadBlueInvoice ? 'disabled' : ''}>
                                    <div data-name="originalinvoicecode" class="search-btn ${bill.hadBlueInvoice ? 'disabled' : ''}"></div>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name requiredFields">原蓝票号码</div>
                                <div class="value">
                                    <input class="searchInput" type="text" name="originalinvoiceno" maxlength="8" value="${obj.originalinvoiceno}" ${bill.hadBlueInvoice ? 'disabled' : ''}>
                                </div>
                            </div>
                            <div class="text">
                                <div class="name">备注</div>
                                <div class="value">
                                    <textarea name="remark" maxlength="230">${obj.remark}</textarea>
                                </div>
                            </div>
                        </div>
                        <div id="imc_invoiceWorkbench_treatment_invoice${obj.id}" class="table-box"></div>
                        <div class="total">
                            <span class="total-item">税额合计：<span class="warning val">${Number(obj.totaltax).toFixed(2)}</span>元</span>
                            <span class="total-item">不含税额金额合计：<span class="warning val">${Number(obj.invoiceamount).toFixed(2)}</span>元</span>
                            <span class="total-item">价税合计：<span class="warning val">${Number(obj.totalamount).toFixed(2)}</span>元</span>
                        </div>
                    </div>`);
                }
            } else {
                _html.push(`<div class="item" data-index="${i}">
                    <div class="info" data-all="${_length}">
                        <div class="text">
                            <div class="name">发票类型</div>
                            <div class="value">
                                <div class="invoiceType actived" data-key="${obj.invoicetype}">${INVOICE_TYPES_DICT['k' + obj.invoicetype] || obj.invoicetype}</div>
                            </div>
                        </div>
                        <div class="text">
                            <div class="name requiredFields">购方名称</div>
                            <div class="value search">
                                <input class="searchInput" type="text" name="buyername" maxlength="100" value="${obj.buyername}" ${bill.hadBuyername ? 'disabled' : ''}>
                                <div data-name="buyername" class="search-btn ${bill.hadBuyername ? 'disabled' : ''}"></div>
                            </div>
                        </div>
                        <div class="text">
                            <div class="name ${obj.buyerproperty === '0' || obj.invoicetype === '028' || obj.invoicetype === '004' ? 'requiredFields' : ''}">纳税人识别号</div>
                            <div class="value">
                                <input class="searchInput" type="text" name="buyertaxno" maxlength="20" value="${obj.buyertaxno}" ${bill.hadBuyertaxno ? 'disabled' : ''}>
                            </div>
                        </div>
                        <div class="text">
                            <div class="name ${obj.invoicetype === '028' || obj.invoicetype === '004' ? 'requiredFields' : ''}">地址及电话</div>
                            <div class="value">
                                <input class="searchInput" type="text" name="buyeraddr" maxlength="100" value="${obj.buyeraddr}">
                            </div>
                        </div>
                        <div class="text">
                            <div class="name ${obj.invoicetype === '028' || obj.invoicetype === '004' ? 'requiredFields' : ''}">开户行及账号</div>
                            <div class="value">
                                <input class="searchInput" type="text" name="buyerbank" maxlength="100" value="${obj.buyerbank}">
                            </div>
                        </div>
                        <div class="text">
                            <div class="name">收票邮箱</div>
                            <div class="value">
                                <input class="searchInput" type="text" name="buyeremail" maxlength="100" value="${obj.buyeremail}">
                            </div>
                        </div>
                        <div class="text">
                            <div class="name">收票手机号</div>
                            <div class="value">
                                <input class="searchInput" type="text" name="buyerphone" maxlength="11" value="${obj.buyerphone}">
                            </div>
                        </div>
                        <div class="text">
                            <div class="name">备注</div>
                            <div class="value">
                                <textarea name="remark" maxlength="230">${obj.remark}</textarea>
                            </div>
                        </div>
                        <div class="text set">
                            <div class="set-item">
                                <span class="set-name">强制清单</span>
                                <div class="checkbox">
                                    <input type="checkbox" name="inventorymark" ${obj.inventorymark === '1' ? 'checked' : ''}>
                                    <div class="label"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div id="imc_invoiceWorkbench_treatment_invoice${obj.id}" class="table-box"></div>
                    <div class="total">
                        <span class="total-item">税额合计：<span class="warning val">${Number(obj.totaltax).toFixed(2)}</span>元</span>
                        <span class="total-item">不含税额金额合计：<span class="warning val">${Number(obj.invoiceamount).toFixed(2)}</span>元</span>
                        <span class="total-item">价税合计：<span class="warning val">${Number(obj.totalamount).toFixed(2)}</span>元</span>
                    </div>
                </div>`);
            }
        }
        // 是否按明细拆分
        const isDetailSplit = bill.splitrule === 'imc_split_by_detail';
        $treatment_invoice.empty().html(_html.join(''));
        for (let i = 0; i < _data.length; i++) {
            const obj = _data[i];
            const columns = [
                {
                    title: '序号',
                    width: 40,
                    render: (t, r, i) => Number(i) + 1
                },
                {
                    title: '开票项目',
                    dataIndex: 'goodsname',
                    ellipsis: true,
                    width: 100
                },
                {
                    title: '数量',
                    dataIndex: 'num',
                    width: 80,
                    render: (t, r, i) => {
                        const val = r.taxunitprice != 0 ? fpy_toFixedNoZero(t, 8) : '';
                        return (
                            r.taxunitprice != 0
                                ? (isDetailSplit
                                    ? `<input class='input' name="num" data-index="${i}" value="${val}" title="${val}">`
                                    : `<span title="${val}">${val}</span>`)
                                : '');
                    }
                },
                {
                    title: `单价(${obj.hsbz === '1' ? '' : '不'}含税)`,
                    dataIndex: obj.hsbz === '1' ? 'taxunitprice' : 'unitprice',
                    width: 80,
                    render: t => {
                        const val = fpy_toFixedTwoEight(t);
                        return t ? `<span class="xmdj" title="${val}">${val}</span>` : '';
                    }
                },
                {
                    title: '税率',
                    dataIndex: 'taxrate',
                    width: 55,
                    render: t => t * 100 + '%'
                },
                {
                    title: '不含税金额',
                    dataIndex: 'amount',
                    width: 90,
                    render: t => {
                        const val = Number(t).toFixed(2);
                        return `<span class="amount" title="${val}">${val}</span>`;
                    }
                },
                {
                    title: '税额',
                    dataIndex: 'tax',
                    width: 80,
                    render: (t, r, i) => {
                        const val = Number(t).toFixed(2);
                        return (
                            bill.maintaxdeviation && bill.maintaxdeviation != 0
                                ? `<input class='input' name="tax" data-index="${i}" value="${val}" title="${val}">`
                                : `<span class="tax" title="${val}">${val}</span>`
                        );
                    }
                },
                {
                    title: '含税金额',
                    dataIndex: 'taxamount',
                    width: 90,
                    render: (t, r, i) => {
                        const val = Number(t).toFixed(2);
                        return (
                            isDetailSplit
                                ? `<input class='input' name="taxamount" data-index="${i}" value="${val}" title="${val}">`
                                : `<span title="${val}">${val}</span>`
                        );
                    }
                }
            ];
            if (isDetailSplit) {
                columns.push({
                    title: '操作',
                    width: 40,
                    render: (t, r, i) => `<a class="del" href="javascript:;" data-index="${i}">删除</a>`
                });
            }
            Table().init({
                id: 'imc_invoiceWorkbench_treatment_invoice' + obj.id,
                rowKey,
                columns,
                scroll: obj.items.length > 8 ? { y: 208 } : {},
                dataSource: obj.items,
                headerColor: '#666',
                headerBgColor: '#eee',
                rowHeight: 26
            });
        }
    }

    // 单据明细处理-更新头部
    function updateTreatmentHeader(hide) {
        let text = '- -';
        if (!hide) {
            const _data = [...new Set(treatmentShowBillList.map(o => treatmentSplitRuleDict['k' + o.splitrule] || ''))];
            text = _data.join('，');
        }
        $head_treatment_value.text(text);
    }

    // 单据明细处理-更新单据数据
    function updateTreatmentBill(index, name, value) {
        treatmentShowBillList[index][name] = value;
    }

    // 单据明细处理-更新发票数据
    function updateTreatmentInvoice(invoiceIndex, name, value) {
        const invoiceList = treatmentInvoiceList[treatmentShowBillList[treatmentIndex].id];
        // 是否能同步修改的字段
        const canSync = treatmentSync.indexOf(name) !== -1;
        for (let i = 0; i < invoiceList.length; i++) {
            if (i === invoiceIndex) {
                invoiceList[i][name] = value;
                // 性能优化
                if (!canSync) break;
            } else {
                if (canSync) invoiceList[i][name] = invoiceList[i][name] === '' ? value : invoiceList[i][name];
            }
        }
        testTreatmentBillFinished(treatmentIndex);
    }

    // 单据明细处理-单据信息完整度
    function testTreatmentBillFinished(index) {
        const invoiceList = treatmentInvoiceList[treatmentShowBillList[index].id];
        let isComplete = true;
        for (let i = 0; i < invoiceList.length; i++) {
            const obj = invoiceList[i];
            // 正数票
            if (obj.totalamount > 0) {
                if (!obj.buyername) {
                    isComplete = false;
                    break;
                }
                // 企业
                if (obj.buyerproperty === '0' && !obj.buyertaxno) {
                    isComplete = false;
                    break;
                }
                if (obj.invoicetype === '028' || obj.invoicetype === '004') {
                    if (!obj.buyertaxno) {
                        isComplete = false;
                        break;
                    }
                    if (!obj.buyeraddr) {
                        isComplete = false;
                        break;
                    }
                    if (!obj.buyerbank) {
                        isComplete = false;
                        break;
                    }
                }
            } else {
                // 负数票 购方名称与购方税号不允许修改
                // 专票
                if (obj.invoicetype === '028' || obj.invoicetype === '004') {
                    if (!obj.buyeraddr) {
                        isComplete = false;
                        break;
                    }
                    if (!obj.buyerbank) {
                        isComplete = false;
                        break;
                    }
                    if (!obj.applicant) {
                        isComplete = false;
                        break;
                    }
                    // 销方申请
                    if (obj.applicant === '2') {
                        // 无红字信息编码并且有原发票代码号码日期 或者 有红字信息编码 就ok
                        if (!((!obj.infocode && obj.originalinvoicecode && obj.originalinvoiceno && obj.originalissuetime) || obj.infocode)) {
                            isComplete = false;
                            break;
                        }
                    }
                    // 购方申请
                    if (obj.applicant !== '2' && !obj.infocode) {
                        isComplete = false;
                        break;
                    }
                } else {
                    if (!obj.originalinvoicecode) {
                        isComplete = false;
                        break;
                    }
                    if (!obj.originalinvoiceno) {
                        isComplete = false;
                        break;
                    }
                }
            }
        }
        const dom = $treatment_bill.find('.item').eq(index).find('.statu');
        if (isComplete) {
            if (!dom.hasClass('finished')) dom.addClass('finished').text('信息已补充');
        } else {
            if (dom.hasClass('finished')) dom.removeClass('finished').text('信息待补充');
        }
        updateTreatmentBill(index, 'isComplete', isComplete);
    }

    // 单据明细处理-按明细开票 检测正常行
    function testTreatmentBillIsNormal() {
        let isNormal = true;
        const items = treatmentShowBillList[treatmentIndex].sim_original_bill_item;
        for (let i = 0; i < items.length; i++) {
            if (items[i].rowtype !== '2') {
                isNormal = false;
            }
        }
        return isNormal;
    }

    // 单据明细处理-按明细开票 剩余明细初始化
    function initTreatmentRemainingItems() {
        const id = treatmentShowBillList[treatmentIndex].id;
        // 确认选取状态
        treatmentShowBillList[treatmentIndex].remainingDisabled = false;
        treatmentInvoiceList = { ...treatmentInvoiceList, [id]: [] };
        treatmentInvoiceRelationMap = { ...treatmentInvoiceRelationMap, [id]: [] };
        const _items = treatmentShowBillList[treatmentIndex].sim_original_bill_item.map(o => {
            return {
                ...o,
                originalXmsl: o.remainvalidnum,
                originalXmdj: o.unitprice,
                originalTaxXmdj: o.taxunitprice,
                originalSe: o.remainvalidtax,
                originalJshjje: o.remainvalidamount
            };
        });
        treatmentRemainingItems = {
            ...treatmentRemainingItems,
            [id]: {
                selectedRowKeys: _items.map(o => o.id),
                items: _items
            }
        };
        showTreatmentBill();
        showTreatmentInvoice();
    }

    // 单据明细处理-按明细开票 剩余明细移除
    function removeTreatmentRemainingItems() {
        const id = treatmentShowBillList[treatmentIndex].id;
        delete treatmentRemainingItems[id];
    }

    // 单据明细处理-按明细开票 剩余明细更新
    function updateTreatmentRemainingItems() {
        const obj = treatmentShowBillList[treatmentIndex];
        const { id, sim_original_bill_item = [] } = JSON.parse(JSON.stringify(obj));
        const invoiceList = treatmentInvoiceList[id];

        const invoiceItems = invoiceList.reduce((accumulator, o) => {
            return accumulator.concat(o.items);
        }, []);

        const _remainingItems = sim_original_bill_item.map(m => {
            // 获取当前明细
            const curInvoiceItems = invoiceItems.filter(o => m.id === o.billItemId);
            if (curInvoiceItems.length) {
                // 原始数据
                const { remainvalidnum, unitprice, taxunitprice, remainvalidtax, remainvalidamount } = m;

                let _num = remainvalidnum;
                let _tax = remainvalidtax;
                let _taxamount = remainvalidamount;

                // 反算可开含税金额，可开数量
                for (const n of curInvoiceItems) {
                    _num = taxunitprice ? fpy_toFixedNoZero(fpy_Minus(_num, n.num), 8) : '';
                    _tax = fpy_Minus(_tax, n.tax).toFixed(2);
                    _taxamount = fpy_Minus(_taxamount, n.taxamount).toFixed(2);
                }

                // 明细金额误差不能超过0.01
                // 若超需反算单价
                let _unitprice = unitprice; // 不含税
                let _taxunitprice = taxunitprice; // 含税
                // 是否过反算过单价 isInverseXmdj 默认false未反算
                let isInverseXmdj = false;
                if (taxunitprice && Math.abs((_num * _taxunitprice - _taxamount).toFixed(2)) > 0.01) {
                    // 反算单价
                    _unitprice = fpy_toFixedTwoEight(fpy_accDiv(fpy_Minus(_taxamount, _tax), _num));
                    _taxunitprice = fpy_toFixedTwoEight(fpy_accDiv(_taxamount, _num));
                    isInverseXmdj = true;
                }

                // 存在单价时的极端异常处理
                if (taxunitprice) {
                    // 金额不为0，数量为0
                    if (_taxamount != 0 && _num == 0) {
                        _num = fpy_toFixedNoZero(fpy_accDiv(_taxamount, taxunitprice), 8);
                    }
                    // 金额为0，数量不为0
                    if (_taxamount == 0 && _num != 0) {
                        _num = '0';
                    }
                }

                return {
                    ...m,
                    isInverseXmdj,
                    remainvalidnum: _num,
                    unitprice: _unitprice,
                    taxunitprice: _taxunitprice,
                    remainvalidtax: _tax,
                    remainvalidamount: _taxamount,
                    originalXmsl: m.remainvalidnum,
                    originalXmdj: m.unitprice,
                    originalTaxXmdj: m.taxunitprice,
                    originalSe: m.remainvalidtax,
                    originalJshjje: m.remainvalidamount
                };
            } else {
                return {
                    ...m,
                    originalXmsl: m.remainvalidnum,
                    originalXmdj: m.unitprice,
                    originalTaxXmdj: m.taxunitprice,
                    originalSe: m.remainvalidtax,
                    originalJshjje: m.remainvalidamount
                };
            }
        });

        const adjustedData = invoiceItems.reduce((all, a) => fpy_Add(all, a.adjustedData || 0), 0);

        // 确认选取状态
        const effectiveList = _remainingItems.filter(o => {
            return treatmentRemainingItems[id].selectedRowKeys.indexOf(o[rowKey]) !== -1 && o.remainvalidamount != 0;
        });

        treatmentShowBillList[treatmentIndex].adjustedData = adjustedData;
        treatmentShowBillList[treatmentIndex].remainingDisabled = !effectiveList.length;
        treatmentRemainingItems[id].items = _remainingItems;
        showTreatmentBill();
    }

    // 单据明细处理-按明细开票 确认选取
    function confirmSelectTreatmentRemainingItems() {
        const obj = treatmentShowBillList[treatmentIndex];
        const { id, hsbz } = obj;
        const selectedRowKeys = treatmentRemainingItems[id].selectedRowKeys;
        let invoiceList = treatmentInvoiceList[id];

        if (!selectedRowKeys.length) {
            // common/tip
            model.invoke("common/tip", '请选择单据明细！');
            return;
        }

        const _items = treatmentRemainingItems[id].items.filter(o => {
            return selectedRowKeys.indexOf(o[rowKey]) !== -1 && o.remainvalidamount != 0;
        }).map(o => {
            return {
                "id": 'items' + fpy_getUUId(), // 明细id 方法生成
                "seq": o.seq, // seq
                "goodscode": o.goodscode, //税收分类编码 goodscode
                "specification": o.specification, //规格型号 specification
                "unit": o.unit, //单位 unit
                "num": o.remainvalidnum, //数量 remainvalidnum
                "unitprice": o.unitprice, //单价 unitprice
                "amount": fpy_Minus(o.remainvalidamount, o.remainvalidtax).toFixed(2), //金额 amount
                "tax": o.remainvalidtax, //税额 remainvalidtax
                "zerotaxmark": "", // 忽略
                "taxpremark": o.policylogo, // policylogo
                "zzstsgl": o.policycontants, // policycontants
                "zxbm": "", // 忽略
                "taxflag": "0", // 忽略
                "simplegoodsname": o.goodssimplename, // goodssimplename
                "goodsname": o.goodsname, //商品名称 goodsname
                "taxrate": o.taxrate, //税率 taxrate
                "rowtype": "0", // 行性质,0明细行，1折扣行，2被折扣行 rowtype 只支持0明细行
                "taxunitprice": o.taxunitprice, //含税单价 taxunitprice
                "taxamount": o.remainvalidamount, //价税合计 remainvalidamount
                "billsourceid": o.billsourceid, // 应收单明细 id
                "discountamount": 0, // 忽略
                "discountrate": 0, // 忽略
                "spbm": o.spbm, // spbm
                billItemId: o.id, // 单据明细 id 自己使用
                originalXmsl: o.originalXmsl,
                originalXmdj: o.originalXmdj,
                originalTaxXmdj: o.originalTaxXmdj,
                originalSe: o.originalSe,
                originalJshjje: o.originalJshjje
            };
        });
        console.log(selectedRowKeys, _items);
        // 更改发票的合计
        let invoice_hjbhsje = '';
        let invoice_kphjse = '';
        let invoice_jshjje = '';
        for (let i = 0; i < _items.length; i++) {
            const o = _items[i];
            // 明细税额误差不能超过0.06
            let difference = ''; // 误差
            let allApportionedValue = 0; // 分摊的值
            let needApportionedValue = 0; // 需分摊的值
            if (hsbz === '0') {
                difference = fpy_Minus(o.tax, fpy_accMul(o.amount, o.taxrate).toFixed(2));
                allApportionedValue =
                needApportionedValue =
                Math.abs(difference) <= 0.06 ? 0 : difference > 0 ? fpy_Minus(difference, 0.06).toFixed(2) : fpy_Add(difference, 0.06).toFixed(2);
                console.log('需分摊的值', needApportionedValue);
                // 是否需要分摊
                if (needApportionedValue != 0) {
                    invoiceList = invoiceList.map(m => {
                        // 是否分摊完成
                        if (needApportionedValue != 0) {
                            // 计算发票的总税额误差
                            const invoiceSeError = m.items.reduce((accumulator, b) => {
                                return fpy_Add(accumulator, fpy_Minus(b.tax, fpy_accMul(b.amount, b.taxrate).toFixed(2)));
                            }, 0);
                            console.log('发票总税额误差', invoiceSeError);
                            // 发票总税额误差不能超过1.27
                            if (Math.abs(invoiceSeError) > 1.27) {
                                return m;
                            } else {
                                let hadApportionedValue = 0; // 被分摊的值
                                const invoiceItems = m.items.map(n => {
                                    // 是否相同单据明细
                                    if (o.billItemId === n.billItemId) {
                                        // 明细行的误差 0.01
                                        const _difference = fpy_Minus(n.tax, fpy_accMul(n.amount, n.taxrate).toFixed(2));
                                        // 计算被分摊的值
                                        if (needApportionedValue > 0) {
                                            // needApportionedValue 0.01
                                            // 明细可以加上的税额 0.06 - 0.01 = 0.05
                                            hadApportionedValue = fpy_Minus(0.06, _difference).toFixed(2);
                                            // 被分摊的值是否大于需要分摊的值 0.05 > 0.01
                                            hadApportionedValue = hadApportionedValue >= needApportionedValue ? needApportionedValue : hadApportionedValue;
                                        } else {
                                            // needApportionedValue -0.01
                                            // 明细可以减去的税额 0.01 + 0.06 = 0.07 转换为-0.07
                                            hadApportionedValue = -fpy_Add(_difference, 0.06).toFixed(2);
                                            // 负数 被分摊的值是否小于需要分摊的值 -0.07 < -0.01
                                            hadApportionedValue = hadApportionedValue <= needApportionedValue ? needApportionedValue : hadApportionedValue;
                                        }

                                        // 是否可以分摊
                                        if (hadApportionedValue) {
                                            // 更新需分摊的值
                                            needApportionedValue = fpy_Minus(needApportionedValue, hadApportionedValue).toFixed(2);

                                            // 更新明细的税额，合计税额，价税合计
                                            return {
                                                ...n,
                                                tax: fpy_Add(n.tax, hadApportionedValue).toFixed(2),
                                                taxamount: fpy_Add(n.taxamount, hadApportionedValue).toFixed(2)
                                            };
                                        } else {
                                            return n;
                                        }
                                    } else {
                                        return n;
                                    }
                                });
                                // 更新发票的税额，合计税额，价税合计
                                return (!hadApportionedValue
                                    ? m
                                    : {
                                        ...m,
                                        items: invoiceItems,
                                        totaltax: fpy_Add(m.totaltax, hadApportionedValue).toFixed(2),
                                        totalamount: fpy_Add(m.totalamount, hadApportionedValue).toFixed(2)
                                    }
                                );
                            }
                        } else {
                            return m;
                        }
                    });
                }
            } else {
                difference = fpy_Minus(o.tax, fpy_Minus(o.taxamount, fpy_accDiv(o.taxamount, fpy_Add(1, o.taxrate)).toFixed(2)));
                allApportionedValue =
                needApportionedValue =
                Math.abs(difference) <= 0.06 ? 0 : difference > 0 ? fpy_Minus(difference, 0.06).toFixed(2) : fpy_Add(difference, 0.06).toFixed(2);
                console.log('需分摊的值', needApportionedValue);
                // 是否需要分摊
                if (needApportionedValue != 0) {
                    invoiceList = invoiceList.map(m => {
                        // 是否分摊完成
                        if (needApportionedValue != 0) {
                            // 计算发票的总税额误差
                            const invoiceSeError = m.items.reduce((accumulator, b) => {
                                return fpy_Add(accumulator, fpy_Minus(b.tax, fpy_Minus(b.taxamount, fpy_accDiv(b.taxamount, fpy_Add(1, b.taxrate)).toFixed(2))));
                            }, 0);
                            console.log('发票总税额误差', invoiceSeError);
                            // 发票总税额误差不能超过1.27
                            if (Math.abs(invoiceSeError) > 1.27) {
                                return m;
                            } else {
                                let hadApportionedValue = 0; // 被分摊的值
                                const invoiceItems = m.items.map(n => {
                                    // 是否相同明细
                                    if (o.billItemId === n.billItemId) {
                                        // 明细行的误差 0.01
                                        const _difference = fpy_Minus(n.tax, fpy_Minus(n.taxamount, fpy_accDiv(n.taxamount, fpy_Add(1, n.taxrate)).toFixed(2)));
                                        // 计算被分摊的值
                                        if (needApportionedValue > 0) {
                                            // needApportionedValue 0.01
                                            // 明细可以加上的税额 0.06 - 0.01 = 0.05
                                            hadApportionedValue = fpy_Minus(0.06, _difference).toFixed(2);
                                            // 被分摊的值是否大于需要分摊的值 0.05 > 0.01
                                            hadApportionedValue = hadApportionedValue >= needApportionedValue ? needApportionedValue : hadApportionedValue;
                                        } else {
                                            // needApportionedValue -0.01
                                            // 明细可以减去的税额 0.01 + 0.06 = 0.07 转换为-0.07
                                            hadApportionedValue = -fpy_Add(_difference, 0.06).toFixed(2);
                                            // 负数 被分摊的值是否小于需要分摊的值 -0.07 < -0.01
                                            hadApportionedValue = hadApportionedValue <= needApportionedValue ? needApportionedValue : hadApportionedValue;
                                        }

                                        // 是否可以分摊
                                        if (hadApportionedValue) {
                                            // 更新需分摊的值
                                            needApportionedValue = fpy_Minus(needApportionedValue, hadApportionedValue).toFixed(2);

                                            // 更新明细的项目数量，项目金额，税额，合计税额，价税合计
                                            const _xmje = fpy_Add(n.taxamount, hadApportionedValue).toFixed(2);
                                            // 反算数量
                                            const _xmsl = n.taxunitprice ? fpy_toFixedNoZero(fpy_accDiv(_xmje, n.taxunitprice), 8) : '';
                                            return {
                                                ...n,
                                                num: _xmsl,
                                                tax: fpy_Add(n.tax, hadApportionedValue).toFixed(2),
                                                taxamount: _xmje
                                            };
                                        } else {
                                            return n;
                                        }
                                    } else {
                                        return n;
                                    }
                                });
                                // 更新发票的税额，合计税额，价税合计
                                return (!hadApportionedValue
                                    ? m
                                    : {
                                        ...m,
                                        items: invoiceItems,
                                        totaltax: fpy_Add(m.totaltax, hadApportionedValue).toFixed(2),
                                        totalamount: fpy_Add(m.totalamount, hadApportionedValue).toFixed(2)
                                    }
                                );
                            }
                        } else {
                            return m;
                        }
                    });
                }
            }

            // 最终调整值 防止调整失败
            const finalAdjustmentValue = fpy_Minus(allApportionedValue, needApportionedValue).toFixed(2);

            // 分摊后调整的税额，价税合计
            const _jshjje = fpy_Minus(o.taxamount, finalAdjustmentValue).toFixed(2);
            // 赋值
            _items[i].tax = fpy_Minus(o.tax, finalAdjustmentValue).toFixed(2);
            _items[i].taxamount = _jshjje;
            // 有调整值且含税，需调整项目数量
            if (finalAdjustmentValue != 0 && hsbz === '1') {
                // 反算数量
                const _xmsl = o.taxunitprice ? fpy_toFixedNoZero(fpy_accDiv(_jshjje, o.taxunitprice), 8) : '';
                _items[i].num = _xmsl;
            }

            // 使用调整后的值
            invoice_hjbhsje = fpy_Add(invoice_hjbhsje, o.amount);
            invoice_kphjse = fpy_Add(invoice_kphjse, o.tax);
            invoice_jshjje = fpy_Add(invoice_jshjje, o.taxamount);
        }

        const invoiceData = {
            "id": 'items' + fpy_getUUId(), // 发票id 方法生成
            "createtime": "", // 忽略
            "invoicecode": "", // 忽略
            "invoiceno": "", // 忽略
            "checkcode": "", // 忽略
            "originalinvoicecode": obj.blueinvoicecode, // blueinvoicecode
            "originalinvoiceno": obj.blueinvoiceno, // blueinvoiceno
            "orderno": fpy_getUUId(), //流水号 32位uuid
            "buyername": obj.buyername, // 购方名称 buyername
            "buyertaxno": obj.buyertaxno, // 购方税号 buyertaxno
            "buyeraddr": obj.buyeraddr, // 购方地址电话 buyeraddr
            "buyertelno": "", // 忽略
            "buyerbank": obj.buyerbank, // 购方银行账号 buyerbank
            "buyerbankacc": "", // 忽略
            "saleraddr": obj.saleraddr, //销方地址电话 saleraddr
            "salertelno": "", // 忽略
            "salerbank": obj.salerbank, //销方开户行账号 salerbank
            "salerbankacc": "", // 忽略
            "payee": obj.payee, //收款人 payee
            "reviewer": obj.reviewer, //复核人 reviewer
            "drawer": obj.drawer, //开票人 drawer
            "specialtype": obj.specialtype, // specialtype
            "salername": obj.salername, //销方名称 salername
            "salertaxno": obj.salertaxno, //销方税号 salertaxno
            "remark": obj.invoiceremark, //备注 invoiceremark
            "deduction": obj.deduction, //扣除额 deduction
            "buyeremail": obj.buyeremail, // 购方邮箱 buyeremail
            "buyerphone": obj.buyerphone, // 购方手机 buyerphone
            "hsbz": obj.hsbz, //含税标志 hsbz
            "taxedtype": "0", // 忽略
            "issuetype": "0", // 0蓝票 1红票 固定0
            "buyertype": "4", // 固定4
            "inventorymark": "0", // 清单标识 0无 1有
            "result": "", // 忽略
            "datahash": "", // 忽略
            "invalider": "", // 忽略
            "invoicetype": obj.invoicetype, //发票种类 invoicetype
            "fileurl": "", // 忽略
            "snapshoturl": "", // 忽略
            "jqbh": obj.jqbh, //设备编号 jqbh
            "remainredamount": 0, // 忽略
            "billno": obj.billno, //单据编号 billno
            "systemsource": obj.systemsource, // systemsource
            "canredtaxamount": 0, // 忽略
            "terminalno": obj.terminalno, // terminalno
            "redreason": "", // 忽略
            "infocode": obj.infocode, // infocode
            "skm": "", // 忽略
            "wxid": obj.wxid, // wxid
            "reorderno": "", // 忽略
            "orgid": obj.orgid, // orgid
            "abolishreason": "",
            "buyerproperty": obj.buyerproperty, //购方企业类型，0企业，1个人 buyerproperty
            "billdate": obj.billdate, // billdate
            "batchbelong": obj.batchbelong, // batchbelong
            "issuestatus": "2", // 固定2
            "invoiceamount": invoice_hjbhsje.toFixed(2), //金额 计算
            "totaltax": invoice_kphjse.toFixed(2), //税额 计算
            "totalamount": invoice_jshjje.toFixed(2), //价税合计 计算
            items: _items
        };

        treatmentInvoiceList[id] = invoiceList.concat(invoiceData);

        // 检测是否超限额
        testForOverLimit(invoice_hjbhsje, invoiceData.invoicetype, invoiceList.length + 1);

        showTreatmentInvoice();
        updateTreatmentRemainingItems();
    }

    // 单据明细处理-按明细开票 检测是否超限额
    function testForOverLimit(v, type, i) {
        let quota = '';
        switch (type) {
        case '026':
            quota = limitAmounts.ecLimitAmt || 0;
            break;
        case '028':
            quota = limitAmounts.esLimitAmt || 0;
            break;
        case '007':
            quota = limitAmounts.pcLimitAmt || 0;
            break;
        case '004':
            quota = limitAmounts.psLimitAmt || 0;
            break;
        }
        if (Number(v) > Number(quota)) {
            // common/tip
            model.invoke("common/tip", `待开发票${i}已超过发票限额${quota}，请修改！`);
        }
    }

    // 单据明细处理-按明细开票 修改数量
    function treatmentChangeXmsl(v, invoiceIndex, itemIndex, whetherToTest) {
        const { id, hsbz, maintaxdeviation } = treatmentShowBillList[treatmentIndex];
        const invoiceList = treatmentInvoiceList[id];
        const invoice = invoiceList[invoiceIndex];
        const { items } = invoiceList[invoiceIndex];
        const { num, amount, tax, taxamount, originalXmsl, originalXmdj, originalTaxXmdj, originalSe, originalJshjje, billItemId } = items[itemIndex];
        const tableDom = $('#imc_invoiceWorkbench_treatment_invoice' + invoice.id).find('tbody').find('tr').eq(itemIndex);

        const value = v.trim();
        if (isNaN(value) || value < 0) {
            tableDom.find(`input[name=num]`).val(num);
            // common/tip
            model.invoke("common/tip", '请输入非负数！');
            return;
        }

        const remainingItems = treatmentRemainingItems[id].items;

        // 百分比计算
        const _xmsl = value;
        const percent = _xmsl / originalXmsl;
        const _se = fpy_accMul(percent, originalSe).toFixed(2);
        const _jshjje = fpy_accMul(percent, originalJshjje).toFixed(2);
        const _hjbhsje = fpy_Minus(_jshjje, _se).toFixed(2);

        // 校验可开的发票明细
        let txable_xmsl = num;
        let txable_se = tax;
        let txable_hjbhsje = amount;
        let txable_jshjje = taxamount;
        for (const o of remainingItems) {
            if (o.id === billItemId) {
                txable_xmsl = fpy_toFixedNoZero(Number(txable_xmsl) + Number(o.remainvalidnum), 8);
                txable_se = (Number(txable_se) + Number(o.remainvalidtax)).toFixed(2);
                txable_hjbhsje = (Number(txable_hjbhsje) + fpy_Minus(o.remainvalidamount, o.remainvalidtax)).toFixed(2);
                txable_jshjje = (Number(txable_jshjje) + Number(o.remainvalidamount)).toFixed(2);
                break;
            }
        }
        // 根据数量判断
        if (Number(txable_xmsl) < Number(_xmsl)) {
            tableDom.find(`input[name=num]`).val(items[itemIndex].num);
            // common/tip
            model.invoke("common/tip", `明细剩余可开数量为${txable_xmsl}，输入不可超过该数值！`);
            return;
        } else if (Number(txable_xmsl) === Number(_xmsl) || txable_jshjje === _jshjje) {
            // 相等，使用可开明细
            items[itemIndex].num = txable_xmsl;
            items[itemIndex].tax = txable_se;
            items[itemIndex].amount = txable_hjbhsje;
            items[itemIndex].taxamount = txable_jshjje;
            // 明细金额误差不能超过0.01
            // 若超需反算单价
            let txable_xmdj = originalXmdj;
            let txable_tax_xmdj = originalTaxXmdj;
            // 是否过反算过单价 isInverseXmdj 默认false未反算
            let isInverseXmdj = false;
            if (hsbz === '0') {
                if (txable_xmdj && Math.abs((txable_xmsl * txable_xmdj - txable_hjbhsje).toFixed(2)) > 0.01) {
                    // 反算单价
                    txable_xmdj = fpy_toFixedTwoEight(fpy_accDiv(txable_hjbhsje, txable_xmsl));
                    isInverseXmdj = true;
                }
            } else {
                if (originalTaxXmdj && Math.abs((txable_xmsl * txable_tax_xmdj - txable_jshjje).toFixed(2)) > 0.01) {
                    // 反算单价
                    txable_tax_xmdj = fpy_toFixedTwoEight(fpy_accDiv(txable_jshjje, txable_xmsl));
                    isInverseXmdj = true;
                }
            }
            items[itemIndex].unitprice = txable_xmdj;
            items[itemIndex].taxunitprice = txable_tax_xmdj;
            items[itemIndex].isInverseXmdj = isInverseXmdj;
        } else {
            // 不等，使用反算明细
            items[itemIndex].num = _xmsl;
            items[itemIndex].tax = _se;
            items[itemIndex].amount = _hjbhsje;
            items[itemIndex].taxamount = _jshjje;
            // 编辑后需将单价调整回原始单价originalXmdj，并将isInverseXmdj改为false
            items[itemIndex].unitprice = originalXmdj;
            items[itemIndex].taxunitprice = originalTaxXmdj;
            items[itemIndex].isInverseXmdj = false;
        }

        // 更改发票的合计
        let invoice_hjbhsje = '';
        let invoice_kphjse = '';
        let invoice_jshjje = '';
        for (let i = 0; i < items.length; i++) {
            invoice_hjbhsje = fpy_Add(invoice_hjbhsje, items[i].amount);
            invoice_kphjse = fpy_Add(invoice_kphjse, items[i].tax);
            invoice_jshjje = fpy_Add(invoice_jshjje, items[i].taxamount);
        }
        invoiceList[invoiceIndex].invoiceamount = invoice_hjbhsje.toFixed(2);
        invoiceList[invoiceIndex].totaltax = invoice_kphjse.toFixed(2);
        invoiceList[invoiceIndex].totalamount = invoice_jshjje.toFixed(2);

        updateTreatmentRemainingItems();

        // 检测是否超限额
        if (whetherToTest) testForOverLimit(invoice_hjbhsje, invoiceList[invoiceIndex].invoicetype, invoiceIndex + 1);

        // 赋值
        tableDom.find('input[name=num]').val(items[itemIndex].num).prop('title', items[itemIndex].num);
        if (maintaxdeviation && maintaxdeviation != 0) {
            tableDom.find('input[name=tax]').val(items[itemIndex].tax).prop('title', items[itemIndex].tax);
        } else {
            tableDom.find('.tax').text(items[itemIndex].tax).prop('title', items[itemIndex].tax);
        }
        tableDom.find('input[name=taxamount]').val(items[itemIndex].taxamount).prop('title', items[itemIndex].taxamount);
        tableDom.find('.amount').text(items[itemIndex].amount).prop('title', items[itemIndex].amount);
        if (originalTaxXmdj) {
            const val = fpy_toFixedTwoEight(hsbz === '1' ? items[itemIndex].taxunitprice : items[itemIndex].unitprice);
            tableDom.find('.xmdj').text(val).prop('title', val);
        }
        // 合计
        const totalDom = $treatment_invoice.find('.item').eq(invoiceIndex).find('.total').find('.val');
        totalDom.eq(0).text(invoiceList[invoiceIndex].totaltax);
        totalDom.eq(1).text(invoiceList[invoiceIndex].invoiceamount);
        totalDom.eq(2).text(invoiceList[invoiceIndex].totalamount);
    }

    // 单据明细处理-按明细开票 修改金额 失去焦点
    function treatmentBlurXmsl(v, invoiceIndex, itemIndex) {
        v = fpy_toFixedNoZero(Number(v), 8);
        if (v === '0') {
            treatmentDeleteItem(invoiceIndex, itemIndex);
        } else {
            treatmentChangeXmsl(v, invoiceIndex, itemIndex, true);
        }
    }

    // 单据明细处理-按明细开票 修改金额
    function treatmentChangeJshjje(v, invoiceIndex, itemIndex, whetherToTest) {
        const { id, hsbz, maintaxdeviation } = treatmentShowBillList[treatmentIndex];
        const invoiceList = treatmentInvoiceList[id];
        const invoice = invoiceList[invoiceIndex];
        const { items } = invoiceList[invoiceIndex];
        const { num, amount, tax, taxamount, originalXmsl, originalXmdj, originalTaxXmdj, originalSe, originalJshjje, billItemId } = items[itemIndex];
        const tableDom = $('#imc_invoiceWorkbench_treatment_invoice' + invoice.id).find('tbody').find('tr').eq(itemIndex);

        const value = v.trim();
        if (isNaN(value) || value < 0) {
            tableDom.find(`input[name=taxamount]`).val(taxamount);
            // common/tip
            model.invoke("common/tip", '请输入非负数！');
            return;
        }

        const remainingItems = treatmentRemainingItems[id].items;

        // 百分比计算
        const _jshjje = value;
        const percent = _jshjje / originalJshjje;
        const _xmsl = originalTaxXmdj ? fpy_toFixedNoZero(fpy_accMul(percent, originalXmsl), 8) : '';
        const _se = fpy_accMul(percent, originalSe).toFixed(2);
        const _hjbhsje = fpy_Minus(_jshjje, _se).toFixed(2);

        // 校验可开的发票明细
        let txable_xmsl = num;
        let txable_se = tax;
        let txable_hjbhsje = amount;
        let txable_jshjje = taxamount;
        for (const o of remainingItems) {
            if (o.id === billItemId) {
                txable_xmsl = fpy_toFixedNoZero(Number(txable_xmsl) + Number(o.remainvalidnum), 8);
                txable_se = (Number(txable_se) + Number(o.remainvalidtax)).toFixed(2);
                txable_hjbhsje = (Number(txable_hjbhsje) + fpy_Minus(o.remainvalidamount, o.remainvalidtax)).toFixed(2);
                txable_jshjje = (Number(txable_jshjje) + Number(o.remainvalidamount)).toFixed(2);
                break;
            }
        }
        // 根据含税金额判断
        if (Number(txable_jshjje) < Number(_jshjje)) {
            tableDom.find(`input[name=taxamount]`).val(items[itemIndex].taxamount);
            // common/tip
            model.invoke("common/tip", `明细剩余可开含税金额为${txable_jshjje}，输入不可超过该数值！`);
            return;
        } else if (Number(txable_jshjje) === Number(_jshjje) || (originalTaxXmdj && txable_xmsl === _xmsl)) {
            // 相等，使用可开明细
            items[itemIndex].num = txable_xmsl;
            items[itemIndex].tax = txable_se;
            items[itemIndex].amount = txable_hjbhsje;
            items[itemIndex].taxamount = txable_jshjje;
            // 明细金额误差不能超过0.01
            // 若超需反算单价
            let txable_xmdj = originalXmdj;
            let txable_tax_xmdj = originalTaxXmdj;
            // 是否过反算过单价 isInverseXmdj 默认false未反算
            let isInverseXmdj = false;
            if (hsbz === '0') {
                if (txable_xmdj && Math.abs((txable_xmsl * txable_xmdj - txable_hjbhsje).toFixed(2)) > 0.01) {
                    // 反算单价
                    txable_xmdj = fpy_toFixedTwoEight(fpy_accDiv(txable_hjbhsje, txable_xmsl));
                    isInverseXmdj = true;
                }
            } else {
                if (originalTaxXmdj && Math.abs((txable_xmsl * txable_tax_xmdj - txable_jshjje).toFixed(2)) > 0.01) {
                    // 反算单价
                    txable_tax_xmdj = fpy_toFixedTwoEight(fpy_accDiv(txable_jshjje, txable_xmsl));
                    isInverseXmdj = true;
                }
            }
            items[itemIndex].unitprice = txable_xmdj;
            items[itemIndex].taxunitprice = txable_tax_xmdj;
            items[itemIndex].isInverseXmdj = isInverseXmdj;
        } else {
            // 不等，使用反算明细
            items[itemIndex].num = _xmsl;
            items[itemIndex].tax = _se;
            items[itemIndex].amount = _hjbhsje;
            items[itemIndex].taxamount = _jshjje;
            // 编辑后需将单价调整回原始单价originalXmdj，并将isInverseXmdj改为false
            items[itemIndex].unitprice = originalXmdj;
            items[itemIndex].taxunitprice = originalTaxXmdj;
            items[itemIndex].isInverseXmdj = false;
        }

        // 更改发票的合计
        let invoice_hjbhsje = '';
        let invoice_kphjse = '';
        let invoice_jshjje = '';
        for (let i = 0; i < items.length; i++) {
            invoice_hjbhsje = fpy_Add(invoice_hjbhsje, items[i].amount);
            invoice_kphjse = fpy_Add(invoice_kphjse, items[i].tax);
            invoice_jshjje = fpy_Add(invoice_jshjje, items[i].taxamount);
        }
        invoiceList[invoiceIndex].invoiceamount = invoice_hjbhsje.toFixed(2);
        invoiceList[invoiceIndex].totaltax = invoice_kphjse.toFixed(2);
        invoiceList[invoiceIndex].totalamount = invoice_jshjje.toFixed(2);

        // 检测是否超限额
        if (whetherToTest) testForOverLimit(invoice_hjbhsje, invoiceList[invoiceIndex].invoicetype, invoiceIndex + 1);

        updateTreatmentRemainingItems();

        // 赋值
        tableDom.find('input[name=num]').val(items[itemIndex].num).prop('title', items[itemIndex].num);
        if (maintaxdeviation && maintaxdeviation != 0) {
            tableDom.find('input[name=tax]').val(items[itemIndex].tax).prop('title', items[itemIndex].tax);
        } else {
            tableDom.find('.tax').text(items[itemIndex].tax).prop('title', items[itemIndex].tax);
        }
        tableDom.find('input[name=taxamount]').val(items[itemIndex].taxamount).prop('title', items[itemIndex].taxamount);
        tableDom.find('.amount').text(items[itemIndex].amount).prop('title', items[itemIndex].amount);
        if (originalTaxXmdj) {
            const val = fpy_toFixedTwoEight(hsbz === '1' ? items[itemIndex].taxunitprice : items[itemIndex].unitprice);
            tableDom.find('.xmdj').text(val).prop('title', val);
        }
        // 合计
        const totalDom = $treatment_invoice.find('.item').eq(invoiceIndex).find('.total').find('.val');
        totalDom.eq(0).text(invoiceList[invoiceIndex].totaltax);
        totalDom.eq(1).text(invoiceList[invoiceIndex].invoiceamount);
        totalDom.eq(2).text(invoiceList[invoiceIndex].totalamount);
    }

    // 单据明细处理-按明细开票 修改金额 失去焦点
    function treatmentBlurJshjje(v, invoiceIndex, itemIndex) {
        v = Number(v).toFixed(2);
        if (v === '0.00') {
            treatmentDeleteItem(invoiceIndex, itemIndex);
        } else {
            treatmentChangeJshjje(v, invoiceIndex, itemIndex, true);
        }
    }

    // 单据明细处理-按明细开票 修改税额 失去焦点
    function treatmentBlurSe(v, invoiceIndex, itemIndex) {
        // maintaxdeviation 税额尾差 原单据税额减去按规则拆分后的税额 大于0，票需补上；小于0，票需减去
        const { id, hsbz, maintaxdeviation = 0, adjustedData = 0 } = treatmentShowBillList[treatmentIndex];
        const invoiceList = treatmentInvoiceList[id];
        const invoice = invoiceList[invoiceIndex];
        const { items } = invoiceList[invoiceIndex];
        const { num, unitprice, amount, tax, taxrate } = items[itemIndex];
        const tableDom = $('#imc_invoiceWorkbench_treatment_invoice' + invoice.id).find('tbody').find('tr').eq(itemIndex);

        const _tax = Number(tax).toFixed(2);
        let value = v.trim();
        if (isNaN(value) || value < 0) {
            tableDom.find(`input[name=tax]`).val(_tax).prop('title', _tax);
            // common/tip
            model.invoke("common/tip", '请输入非负数！');
            return;
        }
        value = Number(value).toFixed(2);

        const difference = fpy_Minus(value, tax); // 税额调整值
        let isError = false;
        const remainingTotalError = fpy_Minus(maintaxdeviation, adjustedData);
        if (remainingTotalError > 0) {
            if (difference > remainingTotalError) {
                isError = '无法修改，所改税额已超出总尾差范围，请重新修改！';
            } else if (difference < 0) {
                isError = '单据税额大于待开发票税额，请增加发票税额！';
            }
        } else if (remainingTotalError < 0) {
            if (difference < remainingTotalError) {
                isError = '无法修改，所改税额已超出总尾差范围，请重新修改！';
            } else if (difference > 0) {
                isError = '单据税额小于待开发票税额，请减少发票税额！';
            }
        } else {
            isError = '当前无税额尾差，无需修改！';
        }

        if (isError) {
            tableDom.find('input[name=tax]').val(_tax).prop('title', _tax);
            // common/tip
            model.invoke("common/tip", isError);
        } else {
            const _amount = fpy_Minus(amount, difference).toFixed(2);
            if (hsbz === '0') {
                if (Math.abs(fpy_Minus(value, fpy_accMul(_amount, taxrate).toFixed(2))) > 0.06) {
                    isError = '待开发票的明细税额误差超过±0.06，请重新修改!';
                } else if (unitprice && Math.abs((num * unitprice - _amount).toFixed(2)) > 0.01) {
                    isError = '待开发票的明细金额误差超过±0.01，请重新修改!';
                }
            } else {
                isError = '无法修改，含税单据不支持调整税额尾差!';
            }
            if (isError) {
                tableDom.find('input[name=tax]').val(_tax).prop('title', _tax);
                // common/tip
                model.invoke("common/tip", isError);
            } else {
                let targetBillItemId;
                // 非按明细拆分方案 更新发票关联关系
                treatmentInvoiceRelationMap[id] = treatmentInvoiceRelationMap[id].map(o => {
                    // 关联关系的发票明细id等于当前明细id
                    if (o.tdetailid === items[itemIndex].id) {
                        // 标记目标单据明细Id
                        targetBillItemId = o.sdetailid;
                        return {
                            ...o,
                            tax: value,
                            amount: _amount
                        };
                    } else {
                        return o;
                    }
                });

                // 更新税额调整值
                treatmentShowBillList[treatmentIndex].adjustedData = fpy_Add(adjustedData, difference);
                treatmentShowBillList[treatmentIndex].sim_original_bill_item = treatmentShowBillList[treatmentIndex].sim_original_bill_item.map(o => {
                    // 根据目标单据明细Id
                    if (targetBillItemId === o.id) {
                        return {
                            ...o,
                            adjustedData: fpy_Add(o.adjustedData || 0, difference)
                        };
                    } else {
                        return o;
                    }
                });

                // 赋值
                items[itemIndex].adjustedData = difference;
                items[itemIndex].tax = value;
                items[itemIndex].amount = _amount;
                tableDom.find(`input[name=tax]`).val(value).prop('title', value);
                tableDom.find('.amount').text(_amount).prop('title', _amount);

                // 更改发票的合计
                let invoice_hjbhsje = '';
                let invoice_kphjse = '';
                for (let i = 0; i < items.length; i++) {
                    invoice_hjbhsje = fpy_Add(invoice_hjbhsje, items[i].amount);
                    invoice_kphjse = fpy_Add(invoice_kphjse, items[i].tax);
                }
                invoiceList[invoiceIndex].invoiceamount = invoice_hjbhsje.toFixed(2);
                invoiceList[invoiceIndex].totaltax = invoice_kphjse.toFixed(2);

                // 合计
                const totalDom = $treatment_invoice.find('.item').eq(invoiceIndex).find('.total').find('.val');
                totalDom.eq(0).text(invoiceList[invoiceIndex].totaltax);
                totalDom.eq(1).text(invoiceList[invoiceIndex].invoiceamount);
                // 刷新单据
                showTreatmentBill();
            }
        }
    }

    // 单据明细处理-按明细开票 删除明细·
    function treatmentDeleteItem(invoiceIndex, itemIndex) {
        const id = treatmentShowBillList[treatmentIndex].id;
        const invoiceList = treatmentInvoiceList[id];
        const { items } = invoiceList[invoiceIndex];
        items.splice(itemIndex, 1);
        if (items.length) {
            // 更改发票的合计
            let invoice_hjbhsje = '';
            let invoice_kphjse = '';
            let invoice_jshjje = '';
            for (let i = 0; i < items.length; i++) {
                invoice_hjbhsje = fpy_Add(invoice_hjbhsje, items[i].amount);
                invoice_kphjse = fpy_Add(invoice_kphjse, items[i].tax);
                invoice_jshjje = fpy_Add(invoice_jshjje, items[i].taxamount);
            }
            invoiceList[invoiceIndex].invoiceamount = invoice_hjbhsje.toFixed(2);
            invoiceList[invoiceIndex].totaltax = invoice_kphjse.toFixed(2);
            invoiceList[invoiceIndex].totalamount = invoice_jshjje.toFixed(2);
        } else {
            invoiceList.splice(invoiceIndex, 1);
        }
        // 涉及到删除，需刷新页面
        updateTreatmentRemainingItems();
        showTreatmentInvoice();
    }

    // 发票预览
    function showPreview() {
        showPreviewBill();
        showPreviewInvoice();
        updatePreviewHeader();
    }

    // 发票预览-单据
    function showPreviewBill() {
        const _html = [];
        for (let i = 0; i < treatmentShowBillList.length; i++) {
            const obj = treatmentShowBillList[i];
            const difference = fpy_Minus(obj.maintaxdeviation || 0, obj.adjustedData || 0);
            _html.push(`<div class="item ${i === previewIndex ? 'actived' : ''}" data-index="${i}">
                <div class="text truncateText">单据编号：<span class="primary" title="${obj.billno}">${obj.billno}</span></div>
                <div class="text">不含税金额：<span class="warning">${Number(obj.invoiceamount).toFixed(2)}</span></div>
                <div class="text">税额：<span class="warning">${Number(obj.totaltax).toFixed(2)}</span></div>
                <div class="text">价税合计：<span class="warning">${Number(obj.totalamount).toFixed(2)}</span></div>
                ${difference != 0 ? `<div class="text">税额尾差：<span class="warning">${Number(difference).toFixed(2)}</span></div>` : ''}
            </div>`);
        }
        $preview_bill.empty().html(_html.join(''));
    }

    // 发票预览-发票
    function showPreviewInvoice() {
        const invoiceList = treatmentInvoiceList[treatmentShowBillList[previewIndex].id];
        const length = invoiceList.length;
        // 防止连续点击出错
        if (previewInvoiceIndex < 0) previewInvoiceIndex = 0;
        if (previewInvoiceIndex >= length) previewInvoiceIndex = length - 1;
        // 切换按钮
        if (previewInvoiceIndex === 0) {
            if (!$preview_prev.hasClass('disabled')) $preview_prev.addClass('disabled');
        } else {
            if ($preview_prev.hasClass('disabled')) $preview_prev.removeClass('disabled');
        }
        if (previewInvoiceIndex === length - 1) {
            if (!$preview_next.hasClass('disabled')) $preview_next.addClass('disabled');
        } else {
            if ($preview_next.hasClass('disabled')) $preview_next.removeClass('disabled');
        }
        const obj = invoiceList[previewInvoiceIndex];
        $preview_invoice.attr('data-info', `发票（${previewInvoiceIndex + 1}/${length}）`);
        $preview_invoiceType.text(`增值税${INVOICE_TYPES_DICT['k' + obj.invoicetype] || obj.invoicetype}`);
        $preview_buer.eq(0).text(obj.buyername).prop('title', obj.buyername);
        $preview_buer.eq(1).text(obj.buyertaxno).prop('title', obj.buyertaxno);
        $preview_buer.eq(2).text(obj.buyeraddr).prop('title', obj.buyeraddr);
        $preview_buer.eq(3).text(obj.buyerbank).prop('title', obj.buyerbank);
        $preview_buer.eq(4).text(obj.buyerphone).prop('title', obj.buyerphone);
        $preview_buer.eq(5).text(obj.buyeremail).prop('title', obj.buyeremail);
        $preview_jshjje.text(`￥${Number(obj.totalamount).toFixed(2)}`);
        $preview_saler.eq(0).text(obj.salername).prop('title', obj.salername);
        $preview_saler.eq(1).text(obj.salertaxno).prop('title', obj.salertaxno);
        $preview_saler.eq(2).text(obj.saleraddr).prop('title', obj.saleraddr);
        $preview_saler.eq(3).text(obj.salerbank).prop('title', obj.salerbank);
        $preview_bz.text(obj.totalamount < 0 && (obj.invoicetype === '028' || obj.invoicetype === '004') ? obj.applyreason : obj.remark);
        $preview_item.eq(4).text(`单价（${obj.hsbz === '1' ? '' : '不'}含税）`);
        $preview_item.eq(5).text(`金额（${obj.hsbz === '1' ? '' : '不'}含税）`);
        const _html = [];
        for (let i = 0; i < obj.items.length; i++) {
            const cur = obj.items[i];
            const xmsl = cur.num ? fpy_toFixedNoZero(cur.num, 8) : '';
            let xmdj = obj.hsbz === '1' ? cur.taxunitprice : cur.unitprice;
            xmdj = xmdj ? fpy_toFixedTwoEight(xmdj) : '';
            const xmje = Number(obj.hsbz === '1' ? cur.taxamount : cur.amount).toFixed(2);
            const sl = (cur.taxrate || '') * 100 + '%';
            const se = Number(cur.tax).toFixed(2);
            _html.push(`<div class="line">
                <div class="item truncateText" title="${cur.goodsname}">${cur.goodsname}</div>
                <div class="item truncateText" title="${cur.specification}">${cur.specification}</div>
                <div class="item truncateText" title="${cur.unit}">${cur.unit}</div>
                <div class="item truncateText" title="${xmsl}">${xmsl}</div>
                <div class="item truncateText" title="${xmdj}">${xmdj}</div>
                <div class="item truncateText" title="${xmje}">${xmje}</div>
                <div class="item truncateText" title="${sl}">${sl}</div>
                <div class="item truncateText" title="${se}">${se}</div>
            </div>`);
        }
        $preview_detail.html(_html.join(''));
        $preview_operator.eq(0).text(obj.payee);
        $preview_operator.eq(1).text(obj.reviewer);
        $preview_operator.eq(2).text(obj.drawer);
    }

    // 发票预览-更新头部
    function updatePreviewHeader(hide) {
        let num = '- -';
        let jshj = '- -';
        if (!hide) {
            let _data = [0, 0];
            for (const i in treatmentInvoiceList) {
                const ary = treatmentInvoiceList[i];
                _data = ary.reduce((all, b) => [all[0] + 1, all[1] + Number(b.totalamount)], _data);
            }
            num = _data[0];
            jshj = _data[1];
        }
        $head_preview_value.eq(0).text(`${num}张`);
        if (jshj !== '- -') jshj = jshj.toFixed(2);
        $head_preview_value.eq(1).text(`${jshj}元`);
    }

    // 开票结果
    function showResult() {
        resultTotal = 0;
        for (const i in treatmentInvoiceList) {
            resultTotal += treatmentInvoiceList[i].length;
        }
        console.log('获取billList是：', billList);
        const _data = billList.map(o => o.id);
        // 设置头部 发票张数
        $head_result_value.eq(0).text(resultTotal);
        // 开票中显示
        $result_detail.show();
        // 先渲染一次页面
        showProgressTable();
        // 开票中轮询
        clearInterval(resultTimer);
        resultTimer = setInterval(() => {
            console.log('轮询获取发票结果，更新resultList数据再调用showProgressTable方法', _data);
            model.invoke("issue/showDetail", _data);
        }, 1000);
    }

    // 开票结果-进度条Table
    function showProgressTable() {
        // 已开具
        const openedList = resultList.filter(o => o.issuestatus !== '1');
        let openedLength = openedList.length;
        openedLength = openedLength >= resultTotal ? resultTotal : openedLength;
        // 更新进度条
        const percent = (openedLength / resultTotal * 100).toFixed(2) + '%';
        $result_progress_percent.css({ width: percent });

        const failList = resultList.filter(o => o.issuestatus === '3');
        $result_progress_text.text(`共${resultTotal}张发票，已开具${openedLength}张，失败${failList.length}张，剩余${resultTotal - openedLength}张`);
        updateResultHeader();
        Table().init({
            id: 'imc_invoiceWorkbench_detail_table',
            rowKey,
            columns: [
                {
                    title: '序号',
                    width: 40,
                    render: (t, r, i) => Number(i) + 1
                },
                {
                    align: 'left',
                    title: '单据编号',
                    dataIndex: 'billno',
                    ellipsis: true,
                    width: 145
                },
                {
                    align: 'left',
                    title: '发票代码',
                    dataIndex: 'invoicecode',
                    width: 100
                },
                {
                    align: 'left',
                    title: '发票号码',
                    dataIndex: 'invoiceno',
                    width: 100
                },
                {
                    align: 'left',
                    title: '价税合计（元）',
                    dataIndex: 'totalamount',
                    ellipsis: true,
                    width: 100,
                    render: t => Number(t).toFixed(2)
                },
                {
                    title: '发票类型',
                    dataIndex: 'invoicetype',
                    render: t => INVOICE_TYPES_DICT['k' + t] || t,
                    width: 100
                },
                {
                    align: 'left',
                    title: '购方名称',
                    dataIndex: 'buyername',
                    ellipsis: true,
                    width: 200
                },
                {
                    title: '开票状态',
                    dataIndex: 'issuestatus',
                    width: 80,
                    render: t => `<span class="${t === '1' ? 'primary' : t === '3' ? 'error' : ''}">${ISSUE_STATUS_DICT['k' + t] || t}</span>`
                },
                {
                    align: 'left',
                    title: '开票说明',
                    dataIndex: 'result',
                    width: 150,
                    render: (t, r) => {
                        return (
                            `<span class="${r.issuestatus === '1' ? 'primary' : r.issuestatus === '3' ? 'error' : ''}">
                                ${r.issuestatus === '1' ? '正在开票，请勿关闭或刷新页面' : t}
                            </span>`
                        );
                    }
                }
            ],
            scroll: resultList.length > 15 ? { y: 365 } : {},
            dataSource: resultList,
            headerColor: '#666',
            headerBgColor: '#eee',
            rowHeight: 26
        });
        const dom = $result_detail_table.find('.workbench-scroll');
        dom.scrollTop(dom.find('table').height());

        // 判断是否开票完成
        if (openedLength >= resultTotal) {
            // 清除计时器
            clearInterval(resultTimer);
            setTimeout(() => {
                $result_progress.hide();
                $result_detail.hide();

                const failList = resultList.filter(o => o.issuestatus === '3');
                const successList = resultList.filter(o => o.issuestatus !== '3');
                const paperInvoiceList = successList.filter(o => o.issuestatus === '0' && (o.invoicetype === '007' || o.invoicetype === '004'));
                // 纸票打印
                if (paperInvoiceList.length) $result.find('.footer').find('.print').show();
                // 一键重开
                if (failList.length) $result.find('.footer').find('.reopen').show();
                showClassTable(failList, successList);
            }, 1000);
        }
    }

    // 开票结果-结果分类
    function resultClass() {
        if (resultOpenType === 'reopen') {
            const failList = resultList.filter(o => o.issuestatus === '3' || o.issuestatus === '1');
            const successList = resultList.filter(o => !(o.issuestatus === '3' || o.issuestatus === '1'));
            const openingList = resultList.filter(o => o.issuestatus === '1');
            const paperInvoiceList = successList.filter(o => o.issuestatus === '0' && (o.invoicetype === '007' || o.invoicetype === '004'));
            if (!openingList.length) {
                // 清除计时器
                clearInterval(resultTimer);
                if (paperInvoiceList.length) $result.find('.footer').find('.print').removeClass('disabled').show();
                if (failList.length) {
                    $result.find('.footer').find('.reopen').removeClass('disabled');
                } else {
                    $result.find('.footer').find('.reopen').hide();
                }
            }
            updateResultHeader();
            showClassTable(failList, successList);
        } else {
            showProgressTable();
        }
    }


    // 开票结果-分类Table
    function showClassTable(failList, successList) {
        const failNum = failList.length;
        const failJshj = failList.reduce((all, b) => all + Number(b.totalamount), 0);
        const successNum = successList.length;
        const successJshj = successList.reduce((all, b) => all + Number(b.totalamount), 0);
        let successY = 0;
        let scrollNum = 0;
        switch (failNum) {
        case 0:
            scrollNum = 16;
            successY = 417;
            break;
        case 1:
            scrollNum = 11;
            successY = 287;
            break;
        case 2:
            scrollNum = 10;
            successY = 261;
            break;
        default:
            scrollNum = 9;
            successY = 234;
            break;
        }
        if (failNum) {
            $result_fail.show();
            Table().init({
                id: 'imc_invoiceWorkbench_fail_table',
                rowKey,
                columns: [
                    {
                        title: '序号',
                        width: 40,
                        render: (t, r, i) => Number(i) + 1
                    },
                    {
                        align: 'left',
                        title: '单据编号',
                        dataIndex: 'billno',
                        ellipsis: true,
                        width: 150
                    },
                    {
                        align: 'left',
                        title: '价税合计（元）',
                        dataIndex: 'totalamount',
                        ellipsis: true,
                        width: 100,
                        render: t => Number(t).toFixed(2)
                    },
                    {
                        title: '发票类型',
                        dataIndex: 'invoicetype',
                        render: t => INVOICE_TYPES_DICT['k' + t] || t,
                        width: 100
                    },
                    {
                        align: 'left',
                        title: '购方名称',
                        dataIndex: 'buyername',
                        ellipsis: true,
                        width: 200
                    },
                    {
                        align: 'left',
                        title: '开票状态',
                        dataIndex: 'issuestatus',
                        width: 80,
                        render: t => `<span class="${t === '1' ? 'primary' : t === '3' ? 'error' : ''}">${ISSUE_STATUS_DICT['k' + t] || t}</span>`
                    },
                    {
                        align: 'left',
                        title: '开票说明',
                        dataIndex: 'result',
                        width: 150,
                        render: (t, r) => {
                            return (
                                `<span class="${r.issuestatus === '1' ? 'primary' : r.issuestatus === '3' ? 'error' : ''}">
                                    ${r.issuestatus === '1' ? '正在开票，请勿关闭或刷新页面' : t}
                                </span>`
                            );
                        }
                    },
                    {
                        align: 'center',
                        title: '操作',
                        dataIndex: 'id',
                        width: 80,
                        render: (t, r) => r.issuestatus === '3' ? `<a href="javascript:;" data-key="${t}">重新开票</a>` : ''
                    }
                ],
                scroll: failList.length > 3 ? { y: 79 } : {},
                dataSource: failList,
                headerColor: '#666',
                headerBgColor: '#eee',
                rowHeight: 26
            });
            $result_fail.find('.text').text(`（共${failNum}张，合计：${failJshj.toFixed(2)}元）`);
            const dom = $result_fail.find('.workbench-scroll');
            dom.scrollTop(dom.find('table').height());
        } else {
            $result_fail.hide();
        }
        if (successNum) {
            $result_success.show();
            Table().init({
                id: 'imc_invoiceWorkbench_success_table',
                rowKey,
                columns: [
                    {
                        title: '序号',
                        width: 40,
                        render: (t, r, i) => Number(i) + 1
                    },
                    {
                        align: 'left',
                        title: '单据编号',
                        dataIndex: 'billno',
                        ellipsis: true,
                        width: 150
                    },
                    {
                        align: 'center',
                        title: '发票代码',
                        dataIndex: 'invoicecode',
                        width: 100
                    },
                    {
                        align: 'center',
                        title: '发票号码',
                        dataIndex: 'invoiceno',
                        width: 100
                    },
                    {
                        align: 'left',
                        title: '价税合计（元）',
                        dataIndex: 'totalamount',
                        ellipsis: true,
                        width: 100,
                        render: t => Number(t).toFixed(2)
                    },
                    {
                        title: '发票类型',
                        dataIndex: 'invoicetype',
                        render: t => INVOICE_TYPES_DICT['k' + t] || t,
                        width: 100
                    },
                    {
                        align: 'left',
                        title: '购方名称',
                        dataIndex: 'buyername',
                        ellipsis: true,
                        width: 200
                    },
                    {
                        title: '开票状态',
                        dataIndex: 'issuestatus',
                        width: 80,
                        render: t => `<span class="success">${ISSUE_STATUS_DICT['k' + t] || t}</span>`
                    }
                ],
                scroll: successList.length > scrollNum ? { y: successY } : {},
                dataSource: successList,
                headerColor: '#666',
                headerBgColor: '#eee',
                rowHeight: 26
            });
            $result_success.find('.text').text(`（共${successNum}张，合计：${successJshj.toFixed(2)}元）`);
        }
    }

    // 开票结果-更新头部
    function updateResultHeader() {
        const successList = resultList.filter(o => o.issuestatus === '0');
        const jshj = successList.reduce((all, b) => all + Number(b.totalamount), 0);
        $head_result_value.eq(0).text(`${successList.length}张`);
        $head_result_value.eq(1).text(`${jshj.toFixed(2)}元`);
    }

    // 开票结果-重开
    function resultReOpen() {
        const _data = billList.map(o => o.id);
        // 重开轮询
        clearInterval(resultTimer);
        resultTimer = setInterval(() => {
            console.log('轮询获取发票结果，更新resultList数据');
            model.invoke("issue/showDetail", _data);
        }, 1000);
    }

    // 退出工作台
    $workbench.on('click', '.quit', function() {
        // 清除计时器 避免开票中关闭弹窗导致内存泄漏
        clearInterval(resultTimer);
        console.log('退出工作台');
        let request = {
            "pks": billList.map(o => o.id),
            "curIndex": curIndex
        };
        model.invoke("close", request);
    });

    // 开票申请单-输入
    $bill.on('input', '.searchForm input', function() {
        const name = $(this).prop('name');
        const value = $(this).val().trim();
        if ($(this).prop('type') !== 'checkbox') {
            $(this).val(value);
            billParam[name] = value;
        } else {
            billParam[name] = $(this).is(':checked');
        }
    });

    // 开票申请单-失去焦点
    $bill.on('blur', '.searchForm input', function() {
        showBillTable();
    });

    // 开票申请单-下拉选择
    $bill.on('change', '.searchForm select', function() {
        const name = $(this).prop('name');
        const value = $(this).val();
        model.invoke("bill/changeJqbh", value);
        billParam[name] = value;
    });

    // 开票申请单-查询
    $bill.on('click', '.searchForm .btn', function() {
        showBillTable();
    });

    // 开票申请单-table选择
    // $bill_table.on('input', 'input', function () {
    //     const type = $(this).attr('data-type');
    //     const checked = $(this).is(':checked');
    //     const index = $(this).attr('data-index');
    //     if (type === 'all') {
    //         if (checked) {
    //             selectedRowKeys = billList.map(o => o[rowKey]);
    //         } else {
    //             selectedRowKeys = [];
    //         }
    //         $bill_table.find('input').prop('checked', checked);
    //     } else {
    //         if (checked) {
    //             selectedRowKeys.push(billList[index][rowKey]);
    //         } else {
    //             const cur = selectedRowKeys.indexOf(billList[index][rowKey]);
    //             selectedRowKeys.splice(cur, 1);
    //         }
    //         $bill_table.find('input[data-type=all]').prop('checked', selectedRowKeys.length === billList.length);
    //     }
    // });

    // 开票申请单-table行点击
    // $bill_table.on('click', 'tbody tr', function (e) {
    //     const dom = $(this).find('input');
    //     const index = dom.attr('data-index');
    //     const checked = dom.is(':checked');
    //     if ($(e.target).is('a')) {
    //         const key = $(e.target).attr('data-key');
    //         if (checked) selectedRowKeys = selectedRowKeys.filter(o => o !== key);
    //         billList.splice(index, 1);
    //         showBillTable(billList);
    //         updateBillHeader();
    //     } else if (!$(e.target).is('input')) {
    //         dom.prop('checked', !checked);
    //         if (!checked) {
    //             selectedRowKeys.push(billList[index][rowKey]);
    //         } else {
    //             const cur = selectedRowKeys.indexOf(billList[index][rowKey]);
    //             selectedRowKeys.splice(cur, 1);
    //         }
    //         $bill_table.find('input[data-type=all]').prop('checked', selectedRowKeys.length === billList.length);
    //     }
    // })

    // 开票申请单-table点击
    $bill_table.on('click', 'tbody tr', function(e) {
        if ($(e.target).is('a')) {
            const key = $(e.target).attr('data-key');
            const name = $(e.target).attr('data-name');
            switch (name) {
            case 'detail':
                console.log('查看详情', key);
                model.invoke("bill/showOriginalBill", key);
                break;
            case 'del':
                billList.splice(key, 1);
                showBillTable();
                updateBillHeader();
                break;
            default:
                break;
            }
        }
    });

    // 开票申请单-下一步
    $bill.find('.footer').on('click', '.next', function () {
        const ids = billList.map(o => o.id);
        console.log('下一步', ids, billParam);

        var request = {
            "mergeBill": billParam["billMerger"],
            "mergeBillDetail": billParam["itemMerger"],
            "deviceNo": billParam["deviceNo"],
            "pks": ids
        };
        model.invoke("bill/mergebill", request)
    });

    // 单据明细处理-选择单据 确认选取 复选框
    // 为兼容js单线程无法同事触发blur与click事件，改用mouseup
    $treatment_bill.on('mouseup', '.item', function(e) {
        const index = Number($(this).attr('data-index'));
        if (index !== treatmentIndex) {
            treatmentIndex = index;
            $treatment_bill.find('.item').removeClass('actived').eq(index).addClass('actived');
            showTreatmentSolutions();
            showTreatmentInvoice();
        }
        const id = treatmentShowBillList[treatmentIndex].id;
        if ($(e.target).hasClass('sure')) {
            const disabled = $(e.target).hasClass('disabled');
            if (!disabled) confirmSelectTreatmentRemainingItems();
        } else if ($(e.target).is('input')) {
            let selectedRowKeys = treatmentRemainingItems[id].selectedRowKeys;
            const remainingItems = treatmentRemainingItems[id].items;
            const type = $(e.target).attr('data-type');
            // click事件中checked是点击后的状态 mousedown事件与mouseup事件中checked是点击前的状态
            const checked = !$(e.target).is(':checked');
            const disabled = $(e.target).prop('disabled');
            const itemIndex = $(e.target).attr('data-index');
            if (!disabled) {
                const dom = $('#imc_invoiceWorkbench_treatment_bill' + id);
                // 复选框
                if (type === 'all') {
                    if (checked) {
                        selectedRowKeys = remainingItems.map(o => o[rowKey]);
                    } else {
                        selectedRowKeys = [];
                    }
                    dom.find('input[data-type!=all]').prop('checked', checked);
                } else {
                    if (checked) {
                        selectedRowKeys.push(remainingItems[itemIndex][rowKey]);
                    } else {
                        const cur = selectedRowKeys.indexOf(remainingItems[itemIndex][rowKey]);
                        selectedRowKeys.splice(cur, 1);
                    }
                    dom.find('input[data-type=all]').prop('checked', selectedRowKeys.length === remainingItems.length);
                }
                treatmentRemainingItems[id].selectedRowKeys = selectedRowKeys;

                const effectiveList = remainingItems.filter(o => {
                    return selectedRowKeys.indexOf(o[rowKey]) !== -1 && o.remainvalidamount != 0;
                });
                const sureDom = $(this).find('.sure');
                if (effectiveList.length) {
                    if (sureDom.hasClass('disabled')) sureDom.removeClass('disabled');
                } else {
                    if (!sureDom.hasClass('disabled')) sureDom.addClass('disabled');
                }
            }
        }
    });

    // 单据明细处理-拆分方案更多
    $treatment_solutions.on('mouseover mouseout', '.more', function(e) {
        if (e.type === 'mouseover') {
            if (!$(this).find('.btn').hasClass('disabled')) $(this).find('.more-pop').show();
        } else if (e.type === 'mouseout') {
            $(this).find('.more-pop').hide();
        }
    });

    // 单据明细处理-拆分方案切换 按明细拆分需单独判断是否可以切换
    $treatment_solutions.on('click', '.solutions-item', function() {
        const disabled = $(this).hasClass('disabled');
        const id = $(this).attr('data-id');
        if (!disabled) {
            console.log('拆分方案切换', id);
            if (id === 'imc_split_by_detail') {
                // 不支持差额单据
                if (treatmentShowBillList[treatmentIndex].deduction) {
                    // common/tip
                    model.invoke("common/tip", '按明细拆分不支持含有差额的单据！');
                    return;
                }
                // 需检测明细行类型，只支持正常行
                if (!testTreatmentBillIsNormal()) {
                    // common/tip
                    model.invoke("common/tip", '按明细拆分只支持明细为正常行的单据！');
                    return;
                }
                model.invoke("common/tip", "本单据已切换为按明细拆分，请在本单据中选取明细生成发票");
                
                // 清空税额尾差调整值
                treatmentShowBillList[treatmentIndex].adjustedData = 0;
                treatmentShowBillList[treatmentIndex].sim_original_bill_item = treatmentShowBillList[treatmentIndex].sim_original_bill_item.map(o => {
                    return {
                        ...o,
                        adjustedData: 0
                    };
                });

                updateTreatmentBill(treatmentIndex, 'splitrule', id);
                initTreatmentRemainingItems();
                showTreatmentSolutions();
            } else {
                // 清空税额尾差调整值
                treatmentShowBillList[treatmentIndex].adjustedData = 0;
                treatmentShowBillList[treatmentIndex].sim_original_bill_item = treatmentShowBillList[treatmentIndex].sim_original_bill_item.map(o => {
                    return {
                        ...o,
                        adjustedData: 0
                    };
                });

                removeTreatmentRemainingItems();
                var request = {
                    "id": treatmentShowBillList[treatmentIndex].id,
                    "ruleCode": id,
                    "ruleName": $(this).html(),
                    "jqbh": billParam.deviceNo,
                    "billNoMap": billNoMap
                };
                model.invoke("process/changeSplitRule", request);
            }
        }
    });

    // 单据明细处理-输入
    $treatment_invoice.on('input', 'input', function() {
        const invoiceIndex = Number($(this).parents('.item').attr('data-index'));
        const itemIndex = $(this).attr('data-index');
        const name = $(this).prop('name');
        const type = $(this).prop('type');
        const maxlength = $(this).prop('maxlength');
        let value = type === 'checkbox' ? $(this).is(':checked') : $(this).prop('value');
        // 输入校验
        switch (name) {
        case 'buyername':
        case 'buyeraddr':
        case 'buyerbank':
        case 'applyreason':
            value = fpy_getTextByMaxLength(value.fpy_filterSpecialChar(), maxlength);
            break;
        case 'buyertaxno':
            value = fpy_getTextByMaxLength(value.fpy_toUpperLetterNum(), maxlength);
            break;
        case 'buyerphone':
        case 'infocode':
        case 'originalinvoicecode':
        case 'originalinvoiceno':
            value = fpy_getTextByMaxLength(value.fpy_onlyNum(), maxlength);
            break;
        case 'buyeremail':
            value = fpy_getTextByMaxLength(value.fpy_onlyEmali(), maxlength);
            break;
        case 'inventorymark':
            value = value ? '1' : '0';
            break;
        case 'num':
            treatmentChangeXmsl(value, invoiceIndex, itemIndex);
            break;
        case 'taxamount':
            treatmentChangeJshjje(value, invoiceIndex, itemIndex);
            break;
        default:
            break;
        }
        // 非明细数量，税额，价税合计输入
        if (!(name === 'num' || name === 'tax' || name === 'taxamount')) {
            $(this).val(value);
            updateTreatmentInvoice(invoiceIndex, name, value);
        }
        // 切换申请类型
        if (name === 'applicant') showTreatmentInvoice();
    });

    // 单据明细处理-输入失去焦点 去除前后空格
    $treatment_invoice.on('blur', 'input', function() {
        const invoiceIndex = Number($(this).parents('.item').attr('data-index'));
        const itemIndex = $(this).attr('data-index');
        const invoicetype = treatmentInvoiceList[treatmentShowBillList[treatmentIndex].id][invoiceIndex].invoicetype;
        const buyerproperty = treatmentInvoiceList[treatmentShowBillList[treatmentIndex].id][invoiceIndex].buyerproperty;
        const name = $(this).prop('name');
        const type = $(this).prop('type');
        const value = $(this).prop('value').trim();
        if (type === 'text') {
            // 错误提示
            switch (name) {
            case 'buyername':
                if (!value) model.invoke("common/tip", "请输入购方名称！");
                break;
            case 'buyertaxno':
                if ((buyerproperty === '0' || invoicetype === '028' || invoicetype === '004') && !value) model.invoke("common/tip", "请输入纳税人识别号！");
                break;
            case 'buyeraddr':
                if ((invoicetype === '028' || invoicetype === '004') && !value) model.invoke("common/tip", "请输入地址及电话！");
                break;
            case 'buyerbank':
                if ((invoicetype === '028' || invoicetype === '004') && !value) model.invoke("common/tip", "请输入开户行及账号！");
                break;
            case 'buyeremail':
                if (value) {
                    const emails = value.split(';').filter(o => o);
                    if (emails.length > 3) {
                        model.invoke("common/tip", "邮箱不能超过3个!");
                    }
                    for (const o of emails) {
                        if (o && !o.fpy_isEmail()) model.invoke("common/tip", "请输入正确的邮箱！");
                    }
                }
                break;
            case 'buyerphone':
                if (value && !value.fpy_isPhone()) model.invoke("common/tip", "请输入正确的手机号码！");
                break;
            case 'num':
                treatmentBlurXmsl(value, invoiceIndex, itemIndex);
                break;
            case 'taxamount':
                treatmentBlurJshjje(value, invoiceIndex, itemIndex);
                break;
            case 'tax':
                treatmentBlurSe(value, invoiceIndex, itemIndex);
                break;
            default:
                break;
            }
            if (!(name === 'num' || name === 'tax' || name === 'taxamount')) {
                $(this).val(value);
                updateTreatmentInvoice(invoiceIndex, name, value);
            }
        }
    });

    // 单据明细处理-输入textarea
    $treatment_invoice.on('input', 'textarea', function() {
        const invoiceIndex = Number($(this).parents('.item').attr('data-index'));
        const name = $(this).prop('name');
        const maxlength = $(this).prop('maxlength');
        let value = $(this).prop('value');
        // 输入校验
        switch (name) {
        case 'remark':
        case 'applyreason':
            value = fpy_getTextByMaxLength(value.fpy_filterSpecialChar(), maxlength);
            break;
        default:
            break;
        }
        $(this).text(value);
        updateTreatmentInvoice(invoiceIndex, name, value);
    });

    // 单据明细处理-输入textarea失去焦点 去除前后空格
    $treatment_invoice.on('blur', 'textarea', function() {
        const invoiceIndex = Number($(this).parents('.item').attr('data-index'));
        const itemIndex = $(this).attr('data-index');
        const name = $(this).prop('name');
        const value = $(this).prop('value').trim();
        $(this).text(value);
        updateTreatmentInvoice(invoiceIndex, name, value);
    });

    // 单据明细处理-选择发票类型 下一个版本支持
    // $treatment_invoice.on('click', '.invoiceType', function () {
    //     const invoiceIndex = $(this).parents('.item').attr('data-index');
    //     const value = $(this).attr('data-key');
    //     console.log('选择发票类型', value);
    //     updateTreatmentInvoice(invoiceIndex, 'invoicetype', value);
    // });

    // 单据明细处理-发票信息搜索
    $treatment_invoice.on('click', '.search-btn', function() {
        const invoiceIndex = $(this).parents('.item').attr('data-index');
        const name = $(this).attr('data-name');
        const disabled = $(this).hasClass('disabled');
        console.log('搜索', invoiceIndex, name, disabled);
        const obj = treatmentInvoiceList[treatmentShowBillList[treatmentIndex].id][invoiceIndex];
        console.log('发票数据：' + obj);
	
        let request = {
            "treatmentInvoiceList": treatmentInvoiceList,
            "thisinvoceid": treatmentShowBillList[treatmentIndex].id,
            "invoiceindex": invoiceIndex,
            "buyertaxno": obj.buyertaxno,
            "disabled": disabled,
            "applicant": obj.applicant,
            "invoicetype": obj.invoicetype,
            "invoiceamount": obj.invoiceamount,
            "totaltax": obj.totaltax,
			"billNoMap": billNoMap,
			"jqbh": billParam.deviceNo,
			"infocodechoose" : infocodechoose
        }
        if (name === "buyername") {
            model.invoke("process/openbuyerlist", request);
        } else if (name === "infocode") {
            model.invoke("process/openredinfolist", request);
        } else if (name === "originalinvoicecode") {
            model.invoke("process/openblueinfolist", request);
        }
    });

    // 单据明细处理-发票明细删除
    $treatment_invoice.on('click', '.del', function() {
        const invoiceIndex = $(this).parents('.item').attr('data-index');
        const itemIndex = $(this).attr('data-index');
        treatmentDeleteItem(invoiceIndex, itemIndex);
    });

    // 单据明细处理-上一步
    $treatment.find('.footer').on('click', '.prev', function() {
        let request = {
            "pks": billList.map(o => o.id)
        };
        model.invoke("process/prestep", request);
    });

    // 单据明细处理-下一步
    $treatment.find('.footer').on('click', '.next', function() {
        console.log('下一步');
        // 检测单据按明细拆分是否完成
        const unfinishedSplitId = [];
        for (const i in treatmentRemainingItems) {
            const obj = treatmentRemainingItems[i];
            for (const o of obj.items) {
                if (o.remainvalidamount != 0) {
                    unfinishedSplitId.push(i);
                    break;
                }
            }
        }
        const bills = treatmentShowBillList.filter(o => unfinishedSplitId.indexOf(o.id) !== -1).map(o => o.billno);
        if (bills.length) {
            // common/tip
            model.invoke("common/tip", `单据${bills.join('，')}可申请金额未拆分完成，请拆分！`);
            return;
        }
        // 按明细开票的单据 关联关系，在操作下一步之前生成
        for (let i = 0; i < treatmentShowBillList.length; i++) {
            if (treatmentShowBillList[i].splitrule === 'imc_split_by_detail') {
                const _id = treatmentShowBillList[i].id;
                const _billno = treatmentShowBillList[i].billno;
                const _invoiceList = treatmentInvoiceList[_id];
                let _invoiceRelationMap = [];
                for (let m = 0; m < _invoiceList.length; m++) {
                    const _invoice = _invoiceList[m];
                    _invoiceRelationMap = _invoiceRelationMap.concat(_invoice.items.map(o => {
                        return {
                            "sbillid": _id, // 单据id
                            "sbillno": _billno,
                            "sdetailid": o.billItemId, // 单据明细id
                            "tbillid": _invoice.id, // 发票id
                            "tbillno": _billno, // 目标单单据编号
                            "tdetailid": o.id, // 发票明细id
                            "amount": o.amount,
                            "tax": o.tax,
                            "num": o.num,
                            "price": o.unitprice,
                            "ttable": "sim_vatinvoice", // 目标单类型， 发票为sim_vatinvoice
                            "pushtype": "1", // 下推类型， 1下推，-1关联
                            "detailmergerflag": "-1" // 固定
                        };
                    }));
                    treatmentInvoiceRelationMap[_id] = _invoiceRelationMap;
                }
            }
        }
        let request = {
            "data": treatmentInvoiceList
        };
        model.invoke("process/processnextstep", request);

        //setCurrentDisplay(2);
    });

    // 发票预览-单据切换
    $preview_bill.on('click', '.item', function() {
        const index = Number($(this).attr('data-index'));
        if (index !== previewIndex) {
            $preview_bill.find('.item').removeClass('actived').eq(index).addClass('actived');
            previewIndex = index;
            previewInvoiceIndex = 0;
            showPreviewBill();
            showPreviewInvoice();
        }
    });

    // 发票预览-按钮显示
    $preview_box.on('mouseover mouseout', function(e) {
        if (e.type === 'mouseover') {
            $preview_prev.show();
            $preview_next.show();
        } else if (e.type === 'mouseout') {
            $preview_prev.hide();
            $preview_next.hide();
        }
    });

    // 发票预览-上一张
    $preview_prev.on('click', function() {
        const disabled = $(this).hasClass('disabled');
        if (!disabled) {
            $preview_invoice.addClass('actived');
            setTimeout(() => $preview_invoice.removeClass('actived'), 200);
            previewInvoiceIndex--;
            showPreviewInvoice();
        }
    });

    // 发票预览-下一张
    $preview_next.on('click', function() {
        const disabled = $(this).hasClass('disabled');
        if (!disabled) {
            $preview_invoice.addClass('actived');
            setTimeout(() => $preview_invoice.removeClass('actived'), 200);
            previewInvoiceIndex++;
            showPreviewInvoice();
        }
    });

    // 发票预览-上一步
    $preview.find('.footer').on('click', '.prev', function() {
        console.log('上一步');
        if (previewDataSave) {
            var requst = {
                "previewDataSave": previewDataSave,
            };
            model.invoke("preview/previewback", requst)
        } else {
            updatePreviewHeader(true);
            setCurrentDisplay(1);
        }
    });

    // 发票预览-保存数据
    $preview.find('.footer').on('click', '.save', function() {
        console.log('保存数据');
        var requst = {
            "treatmentShowBillList": treatmentShowBillList,
            "billNoMap": billNoMap,
            "invoices": treatmentInvoiceList,
            "splitrule": treatmentSplitRule,
            "invBill": billList,
            "previewDataSave": previewDataSave,
            "invRealtion": treatmentInvoiceRelationMap,
            "jqbh": billParam.deviceNo
        };
        model.invoke("preview/save_data", requst)
    });

    // 发票预览-确认开票
    $preview.find('.footer').on('click', '.next', function() {
        console.log('确认开票');
        var requst = {
            "treatmentShowBillList": treatmentShowBillList,
            "billNoMap": billNoMap,
            "invoices": treatmentInvoiceList,
            "previewDataSave": previewDataSave,
            "splitrule": treatmentSplitRule,
            "invBill": billList,
            "invRealtion": treatmentInvoiceRelationMap,
            "jqbh": billParam.deviceNo,
        };
        model.invoke("preview/confirm_issues", requst)
    });

    // 开票结果-重新开票
    $result_fail.on('click', 'a', function() {
        resultOpenType = 'reopen';
        const key = $(this).attr('data-key');
        $result.find('.footer').find('.print').addClass('disabled');
        console.log('操作', key);
        model.invoke("issue/reIssue", [key]);
        resultReOpen();
    });

    // 开票结果-纸票一键打印
    $result.find('.footer').on('click', '.print', function() {
        const disabled = $(this).hasClass('disabled');
        if (!disabled) {
            const _data = resultList.map(o => o.id);
            model.invoke("issue/paperInvPrint", _data);
            console.log('纸票一键打印', _data);
        }
    });

    // 开票结果-一键重开
    $result.find('.footer').on('click', '.reopen', function() {
        const disabled = $(this).hasClass('disabled');
        if (!disabled) {
            resultOpenType = 'reopen';
            const _data = resultList.filter(o => o.issuestatus === '3').map(o => o.id);
            $result.find('.footer').find('.print').addClass('disabled');
            $result.find('.footer').find('.reopen').addClass('disabled');
            console.log('一键重开', _data);
            model.invoke("issue/reIssue", _data);
            resultReOpen();
        }
    });

    this.initWorkbench = function (_model, props) {
        var popsData = {};
        if (props != null && props.data != null) {
            popsData = props.data;
        }
        model = _model;
        initEvent(model, props);
        setInitData(popsData);
    };

    this.updateWorkbench = function (_model, props) {
        model = _model;
        var popsData = {};
        if (props != null && props.data != null) {
            popsData = props.data;
        }
        var eventKey = popsData["eventKey"];
        switch (eventKey) {
            case "bill/mergebill":
                treatmentShowBillList = formatTreatmentBill(popsData.mergeBill.bills || []);
                treatmentInvoiceList = popsData.invoiceList;
                treatmentInvoiceRelationMap = popsData.invoiceRelationMap;
                billNoMap = popsData.billNoMap;
                billList = popsData.bills;
                setCurrentDisplay(1);
                break;
            case "process/prestep":
                updateTreatmentHeader(true);
                setCurrentDisplay(0);
                break;
            case "process/changeSplitRule":
                updateTreatmentBill(treatmentIndex, 'splitrule', popsData.ruleCode);
                showTreatmentBill();
                updateTreatmentHeader();
                showTreatmentSolutions();
                treatmentInvoiceList = {...treatmentInvoiceList, ...popsData["invoiceList"]};
                treatmentInvoiceRelationMap = {...treatmentInvoiceRelationMap, ...popsData["invoiceRelationMap"]};
                showTreatmentInvoice();
				if("undefined" != typeof popsData.infocodechoose && "" != popsData.infocodechoose){
					infocodechoose = popsData.infocodechoose;
				}
                break;
            case "issue/showDetail":
                resultList = popsData.result;
				resultClass();
                break;
            case "preview/save_data":
                previewDataSave = true;
                treatmentInvoiceList = popsData["invoiceList"];
                treatmentInvoiceRelationMap = popsData["invoiceRelationMap"];
                break;
            case "process/blueinvoice":
                //填充蓝票
                treatmentInvoiceList = {...treatmentInvoiceList, ...popsData.data};
                showTreatmentInvoice();
                testTreatmentBillFinished(treatmentIndex);
                break;
            case "process/nextstepcheck":
                if (popsData.data === 'success') {
                    //填充备注
                    treatmentInvoiceList = popsData.treatmentInvoiceList;
                    setCurrentDisplay(2);
                }
                break;
            case "process/openredinfolist":
                //填充红字信息
                treatmentInvoiceList = {...treatmentInvoiceList, ...popsData.data};
                showTreatmentInvoice();
                testTreatmentBillFinished(treatmentIndex);
                break;
            case "bill/changeJqbh":
                limitAmounts = popsData.limitAmounts;
                break;
            case "preview/confirm_issues":
                setCurrentDisplay(3);
                break;
        }
        console.log(popsData);
    };

    var initEvent = function (model, props) {

    };
};