laiguoran 3 лет назад
Родитель
Сommit
394bfbf7eb

+ 11 - 4
app/controller/change_controller.js

@@ -342,8 +342,8 @@ module.exports = app => {
                     whiteList,
                     auditList,
                     changeList,
-                    tpUnit: change.tp_decimal ? change.tp_decimal : ctx.tender.info.decimal.tp,
-                    upUnit: change.up_decimal ? change.up_decimal : ctx.tender.info.decimal.up,
+                    tpUnit: change.tp_decimal !== null ? change.tp_decimal : ctx.tender.info.decimal.tp,
+                    upUnit: change.up_decimal !== null ? change.up_decimal : ctx.tender.info.decimal.up,
                     authMobile: auth_mobile,
                     shenpiConst,
                 };
@@ -792,7 +792,7 @@ module.exports = app => {
                         responseData.data = await ctx.service.changeAuditList.batchAdd(data);
                         break;
                     case 'del':
-                        await ctx.service.changeAuditList.del(data.id);
+                        await ctx.service.changeAuditList.del(data);
                         break;
                     case 'update':
                         await ctx.service.changeAuditList.save(data.updateData);
@@ -803,7 +803,7 @@ module.exports = app => {
                         responseData.data = await ctx.service.changeAuditList.getList(ctx.change.cid);
                         break;
                     case 'ledger_list':
-                        await ctx.service.changeAuditList.saveLedgerListDatas(data.updateData);
+                        await ctx.service.changeAuditList.saveLedgerListDatas(data.updateData, data.postData);
                         // 取所有工料表
                         responseData.data = { changeList: await ctx.service.changeAuditList.getList(ctx.change.cid),
                             usedList: await ctx.service.stageChange.getFinalUsedData(ctx.tender.id, ctx.change.cid) };
@@ -843,6 +843,13 @@ module.exports = app => {
                     case 'update_tp':
                         await ctx.service.change.saveInfo({ total_price: data.updateData });
                         break;
+                    case 'order_by':
+                        const result = await ctx.service.change.saveOrderBy(data.updateData, data.newLedgerList);
+                        responseData.data = result;
+                        break;
+                    case 'changeOrder':
+                        await ctx.service.changeAuditList.changeOrder(data.postData);
+                        break;
                     default: throw '参数有误';
                 }
 

+ 375 - 25
app/public/js/change_information_set.js

@@ -187,41 +187,185 @@ $(document).ready(() => {
             changeSpreadSheet.setValue(changeSpreadSheet.getRowCount() - 1, 9, cSum !== 0 ? cSum : null);
         },
         add: function () {
-            postData(window.location.pathname + '/save', {type: 'add'}, function (result) {
+            let select = null;
+            if (changeOrder) {
+                select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+            }
+            postData(window.location.pathname + '/save', {type: 'add', postData: select ? select.order : null}, function (result) {
                 if (result) {
-                    changeList.push(result);
-                    changeSpreadSheet.addRows(changeList.length - 1, 1);
-                    SpreadJsObj.reLoadRowData(changeSpreadSheet, changeList.length - 1);
+                    if (changeOrder === 1 && select) {
+                        // 批量更新changeList的order值
+                        _.forEach(changeList, function (item) {
+                            item.order = item.order > select.order ? item.order + 1 : item.order;
+                        });
+                        changeList.splice(select.order, 0, result);
+                        changeSpreadSheet.addRows(select.order, 1);
+                        SpreadJsObj.reLoadRowData(changeSpreadSheet, select.order);
+                        changeSpreadSheet.setSelection(select.order, 0, 1, 1);
+                        console.log(changeList);
+                    } else {
+                        changeList.push(result);
+                        changeSpreadSheet.addRows(changeList.length - 1, 1);
+                        SpreadJsObj.reLoadRowData(changeSpreadSheet, changeList.length - 1);
+                        changeSpreadSheet.setSelection(changeList.length - 1, 0, 1, 1);
+                    }
                     changeSpreadSheet.setStyle(changeSpreadSheet.getRowCount() - 1, -1, style1);
-                    changeSpreadSheet.setSelection(changeList.length - 1, 0, 1, 1);
                     changeSpreadObj.resetXmjSpread();
+                    changeSpreadObj.refreshActn();
                 }
             });
         },
         batchAdd: function(num) {
-            postData(window.location.pathname + '/save', {type: 'batchadd', num}, function (result) {
+            let select = null;
+            if (changeOrder) {
+                select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+            }
+            postData(window.location.pathname + '/save', {type: 'batchadd', num, postData: select ? select.order : null}, function (result) {
                 if (result) {
-                    changeList = _.concat(changeList, result);
+                    changeList = result;
                     SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
                     changeSpreadObj.makeSjsFooter();
                     changeSpreadObj.resetXmjSpread();
+                    changeSpreadObj.refreshActn();
                 }
             });
         },
         del: function () {
-            const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
-            const index = changeList.indexOf(select);
-            if (index > -1 && !_.find(changeUsedData, { cbid: select.id })) {
-                postData(window.location.pathname + '/save', {type: 'del', id: select.id}, function (result) {
-                    changeList.splice(index, 1);
-                    changeSpreadSheet.deleteRows(index, 1);
+            const selection = changeSpreadSheet.getSelections();
+            const sel = selection ? selection[0] : changeSpreadSheet.getSelections()[0];
+            const row = sel && sel.row !== undefined ? sel.row : -1;
+            if (readOnly || row === -1 || sel.row + sel.rowCount > changeList.length) {
+                return false;
+            }
+            const delList = [];
+            let lastSelect = null;
+            let hadTaiZhang = false;
+            for (let r = 0; r < sel.rowCount; r++) {
+                const select = changeList[row + r];
+                if(!select || _.find(changeUsedData, { cbid: select.id })) {
+                    return false;
+                }
+                if (r === sel.rowCount - 1 && changeOrder) {
+                    lastSelect = select;
+                }
+                if (select.lid != 0) {
+                    hadTaiZhang = true;
+                }
+                delList.push(select.id);
+            }
+            console.log(lastSelect, delList);
+            if (delList.length) {
+                postData(window.location.pathname + '/save', {type: 'del', ids: delList, postData: lastSelect ? lastSelect.order : null}, function (result) {
+                    changeList.splice(row, delList.length);
+                    changeSpreadSheet.deleteRows(row, delList.length);
                     const sel = changeSpreadSheet.getSelections();
                     changeSpreadSheet.setSelection(0, 0, 1, 1);
                     changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
-                    if (select.lid != 0) {
+                    if (hadTaiZhang) {
                         tableDataRemake(changeListData);
                     }
                     changeSpreadObj.countSum();
+                    changeSpreadObj.refreshActn();
+                });
+            }
+            // const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+            // const index = changeList.indexOf(select);
+            // if (index > -1 && !_.find(changeUsedData, { cbid: select.id })) {
+                // postData(window.location.pathname + '/save', {type: 'del', id: select.id}, function (result) {
+                //     changeList.splice(index, 1);
+                //     changeSpreadSheet.deleteRows(index, 1);
+                //     const sel = changeSpreadSheet.getSelections();
+                //     changeSpreadSheet.setSelection(0, 0, 1, 1);
+                //     changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
+                //     if (select.lid != 0) {
+                //         tableDataRemake(changeListData);
+                //     }
+                //     changeSpreadObj.countSum();
+                //     changeSpreadObj.refreshActn();
+                // });
+            // }
+        },
+        upMove: function () {
+            const data = {
+                type: 'changeOrder',
+                postData: [],
+            };
+            const selection = changeSpreadSheet.getSelections();
+            const row = selection[0].row, count = selection[0].rowCount;
+            const first = changeSpreadSheet.zh_data[row];
+            if (!first) {
+                changeSpreadObj.refreshActn();
+                return false;
+            }
+            const pre = changeSpreadSheet.zh_data[row - 1], preUpdate = {id: pre.id};
+            for (let iRow = 0; iRow < count; iRow++) {
+                const posData = changeSpreadSheet.zh_data[iRow + row];
+                if (posData) {
+                    data.postData.push({id: posData.id, order: changeSpreadSheet.zh_data[iRow + row - 1].order});
+                    preUpdate.order = posData.order;
+                }
+            }
+            data.postData.push(preUpdate);
+            console.log(data);
+            if (data.postData.length > 0) {
+                postData(window.location.pathname + '/save', data, function () {
+                    _.forEach(data.postData, function (item) {
+                        const cl = _.find(changeList, { id: item.id });
+                        cl.order = item.order;
+                    });
+                    changeList.sort(function (a, b) {
+                        return a.order - b.order
+                    });
+                    SpreadJsObj.reLoadSheetData(changeSpreadSheet);
+                    changeSpreadObj.makeSjsFooter();
+                    const sel = selection[0];
+                    if (sel) {
+                        changeSpreadSheet.setSelection(changeSpreadSheet.zh_data.indexOf(first), sel.col, sel.rowCount, sel.colCount);
+                    }
+                    changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
+                    changeSpreadObj.refreshActn();
+                });
+            }
+        },
+        downMove: function () {
+            const data = {
+                type: 'changeOrder',
+                postData: [],
+            };
+            const selection = changeSpreadSheet.getSelections();
+            const row = selection[0].row, count = selection[0].rowCount;
+            const first = changeSpreadSheet.zh_data[row];
+            if (!first) {
+                changeSpreadObj.refreshActn();
+                return false;
+            }
+            const next = changeSpreadSheet.zh_data[row + count], nextUpdate = {id: next.id};
+            for (let iRow = count - 1; iRow >= 0; iRow--) {
+                const posData = changeSpreadSheet.zh_data[iRow + row];
+                if (posData) {
+                    data.postData.push({id: posData.id, order: changeSpreadSheet.zh_data[iRow + row + 1].order});
+                    nextUpdate.order = posData.order;
+                }
+            }
+            data.postData.push(nextUpdate);
+            console.log(data);
+            if (data.postData.length > 0) {
+                postData(window.location.pathname + '/save', data, function () {
+                    _.forEach(data.postData, function (item) {
+                        const cl = _.find(changeList, { id: item.id });
+                        cl.order = item.order;
+                    });
+                    changeList.sort(function (a, b) {
+                        return a.order - b.order
+                    });
+                    SpreadJsObj.reLoadSheetData(changeSpreadSheet);
+                    changeSpreadObj.makeSjsFooter();
+                    const sel = selection[0];
+                    if (sel) {
+                        changeSpreadSheet.setSelection(changeSpreadSheet.zh_data.indexOf(first), sel.col, sel.rowCount, sel.colCount);
+                    }
+                    changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
+                    changeSpreadObj.refreshActn();
                 });
             }
         },
@@ -244,6 +388,36 @@ $(document).ready(() => {
                 changeSpreadObj.del();
             }
             changeSpreadObj.resetXmjSpread(data);
+            changeSpreadObj.refreshActn();
+        },
+        refreshActn: function (rowCount = 1) {
+            const setObjEnable = function (obj, enable) {
+                if (enable) {
+                    obj.removeClass('disabled');
+                } else {
+                    obj.addClass('disabled');
+                }
+            };
+            // const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+            // 还需判断是否已被调差清单调用
+            const selection = changeSpreadSheet.getSelections();
+            const sel = selection ? selection[0] : changeSpreadSheet.getSelections()[0];
+            const row = sel ? sel.row : -1;
+            const first = changeList[row];
+            let last = first;
+            if (sel.rowCount > 1 && first) {
+                for (let r = 1; r < sel.rowCount; r++) {
+                    const rNode = changeList[sel.row + r];
+                    if (!rNode) break;
+                    last = rNode;
+                }
+            }
+            const preNode = changeList[row - 1];
+
+            setObjEnable($('#up-move'), !readOnly && first && preNode && changeList.indexOf(last) > 0 && sel.row + sel.rowCount <= changeList.length);
+            setObjEnable($('#down-move'), !readOnly && first && changeList.indexOf(last) < changeList.length - 1 && sel.row + sel.rowCount <= changeList.length);
+            // setObjEnable($('#open-list-modal'), !readOnly && select && changeList.indexOf(select) !== -1);
+            // setObjEnable($('#add-white-btn'), !readOnly && select && changeList.indexOf(select) !== -1);
         },
         deletePress: function (sheet) {
             return;
@@ -529,10 +703,13 @@ $(document).ready(() => {
         // filter.sortColumn(0, true);
         changeSpreadObj.makeSjsFooter();
         changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
+        changeSpreadObj.refreshActn();
     });
 
     if (!readOnly) {
         $('#add-white-btn').click(changeSpreadObj.add);
+        $('#up-move').click(changeSpreadObj.upMove);
+        $('#down-move').click(changeSpreadObj.downMove);
         changeSpread.bind(spreadNS.Events.EditEnded, changeSpreadObj.editEnded);
         changeSpread.bind(spreadNS.Events.SelectionChanged, changeSpreadObj.selectionChanged);
         changeSpread.bind(spreadNS.Events.ClipboardPasted, changeSpreadObj.clipboardPasted);
@@ -578,6 +755,9 @@ $(document).ready(() => {
                 'createList': {
                     name: '添加台账清单',
                     icon: 'fa-sign-in',
+                    visible: function () {
+                        return changeOrder === 0;
+                    },
                     callback: function (key, opt) {
                         $('#addlist').modal('show');
                     },
@@ -585,6 +765,9 @@ $(document).ready(() => {
                 'createAdd': {
                     name: '添加空白清单',
                     icon: 'fa-sign-in',
+                    visible: function () {
+                        return changeOrder === 0;
+                    },
                     callback: function (key, opt) {
                         changeSpreadObj.add(changeSpreadSheet);
                     },
@@ -594,6 +777,9 @@ $(document).ready(() => {
                     type: 'batchInsert',
                     value: '2',
                     icon: 'fa-sign-in',
+                    visible: function () {
+                        return changeOrder === 0;
+                    },
                     batchInsert: function (obj, root) {
                         if (_.toNumber(obj.value) > _.toNumber(obj.max)) {
                             obj.value = obj.max;
@@ -608,6 +794,81 @@ $(document).ready(() => {
                         }
                     },
                 },
+                'createList1': {
+                    name: '插入台账清单',
+                    icon: 'fa-sign-in',
+                    visible: function () {
+                        return changeOrder === 1;
+                    },
+                    // disabled: function (key, opt) {
+                    //     const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+                    //     const sel = changeSpreadSheet.getSelections()[0];
+                    //     changeSpreadObj.resetXmjSpread(select);
+                    //     // console.log(select, sel);
+                    //     if (!readOnly && select && sel.row !== changeSpreadSheet.getRowCount() - 1) {
+                    //         return false;
+                    //     } else {
+                    //         return true;
+                    //     }
+                    // },
+                    callback: function (key, opt) {
+                        $('#addlist').modal('show');
+                    },
+                },
+                'createAdd1': {
+                    name: '插入空白清单',
+                    icon: 'fa-sign-in',
+                    visible: function () {
+                        return changeOrder === 1;
+                    },
+                    // disabled: function (key, opt) {
+                    //     const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+                    //     const sel = changeSpreadSheet.getSelections()[0];
+                    //     changeSpreadObj.resetXmjSpread(select);
+                    //     // console.log(select, sel);
+                    //     if (!readOnly && select && sel.row !== changeSpreadSheet.getRowCount() - 1) {
+                    //         return false;
+                    //     } else {
+                    //         return true;
+                    //     }
+                    // },
+                    callback: function (key, opt) {
+                        changeSpreadObj.add(changeSpreadSheet);
+                    },
+                },
+                'batchInsert1': {
+                    name: '批量插入空白清单',
+                    type: 'batchInsert',
+                    value: '2',
+                    icon: 'fa-sign-in',
+                    visible: function () {
+                        return changeOrder === 1;
+                    },
+                    // disabled: function (key, opt) {
+                    //     const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+                    //     const sel = changeSpreadSheet.getSelections()[0];
+                    //     changeSpreadObj.resetXmjSpread(select);
+                    //     // console.log(select, sel);
+                    //     if (!readOnly && select && sel.row !== changeSpreadSheet.getRowCount() - 1) {
+                    //         return false;
+                    //     } else {
+                    //         return true;
+                    //     }
+                    // },
+                    batchInsert: function (obj, root) {
+                        if (_.toNumber(obj.value) > _.toNumber(obj.max)) {
+                            obj.value = obj.max;
+                            toastr.warning('批量插入不可多于' + obj.max);
+                        } else if(_.toNumber(obj.value) < _.toNumber(obj.min)) {
+                            obj.value = obj.min;
+                            toastr.warning('批量插入不可少于' + obj.min);
+                        } else {
+                            // treeOperationObj.addNode(ledgerSpread.getActiveSheet(), parseInt(obj.value));
+                            changeSpreadObj.batchAdd(obj.value);
+                            root.$menu.trigger('contextmenu:hide');
+                        }
+                    },
+                },
                 'delete': {
                     name: '删除',
                     icon: 'fa-remove',
@@ -615,15 +876,29 @@ $(document).ready(() => {
                         changeSpreadObj.del(changeSpreadSheet);
                     },
                     disabled: function (key, opt) {
-                        const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
-                        const sel = changeSpreadSheet.getSelections()[0];
-                        changeSpreadObj.resetXmjSpread(select);
-                        // console.log(select, sel);
-                        if (!readOnly && select && sel.row !== changeSpreadSheet.getRowCount() - 1 && !_.find(changeUsedData, { cbid: select.id })) {
-                            return false;
-                        } else {
+                        // const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+                        // const sel = changeSpreadSheet.getSelections()[0];
+                        // changeSpreadObj.resetXmjSpread(select);
+                        // // console.log(select, sel);
+                        // if (!readOnly && select && sel.row !== changeSpreadSheet.getRowCount() - 1 && !_.find(changeUsedData, { cbid: select.id })) {
+                        //     return false;
+                        // } else {
+                        //     return true;
+                        // }
+                        const selection = changeSpreadSheet.getSelections();
+                        const sel = selection ? selection[0] : changeSpreadSheet.getSelections()[0];
+                        const row = sel && sel.row !== undefined ? sel.row : -1;
+                        if (readOnly || row === -1 || sel.row + sel.rowCount > changeList.length) {
                             return true;
                         }
+                        let isUsed = false;
+                        for (let r = 0; r < sel.rowCount; r++) {
+                            const select = changeList[row + r];
+                            if(!select || _.find(changeUsedData, { cbid: select.id })) {
+                                isUsed = true;
+                            }
+                        }
+                        return isUsed;
                     }
                 },
             }
@@ -637,6 +912,7 @@ $(document).ready(() => {
         $(this).addClass('table-warning');
         const isCheck = $(this).hasClass('table-success') ? true : false;
         const data_bwmx = $(this).attr('data-bwmx').split('$#$');
+        const data_charu = $(this).attr('data-charu') ? $(this).attr('data-charu').split('$#$') : [];
         const isDeal = $(this).data('gcl') !== undefined ? true : false;
         let codeHtml = '<tr quantity="'+ $(this).children('td').eq(5).text() +'" gcl_id="" mx_id=""><td class="text-center">1</td><td colspan="7" class="colspan_1">&nbsp;</td><td class="colspan_2"><input type="checkbox"></td></tr>';
         if (isDeal) {
@@ -661,7 +937,11 @@ $(document).ready(() => {
                     'checked' : '';
                 const existGcl = _.find(changeList, {gcl_id: leaf.gcl_id, bwmx: (bwmx ? bwmx : leaf.jldy ? leaf.jldy : ''), oamount: leaf.quantity});
                 const isUsed = existGcl ? _.find(changeUsedData, { cbid: existGcl.id }) : null;
-                const isDisabled = isUsed ? 'disabled ' : '';
+                const isOldChaRu = changeOrder && isChecked && data_charu.indexOf(leaf.code + '!_!' + (leaf.jldy ? leaf.jldy : '') + '!_!' +
+                    (leaf.dwgc ? leaf.dwgc : '') + '!_!' + (leaf.fbgc ? leaf.fbgc : '') + '!_!' + (leaf.fxgc ? leaf.fxgc : '')
+                    + '!_!' + (leaf.gcl_id ? leaf.gcl_id : '0') + '!_!' + (leaf.mx_id ? leaf.mx_id : '') + '!_!' +
+                    (bwmx !== undefined ? bwmx : leaf.jldy ? leaf.jldy : '') + '*;*' + quantity) === -1;
+                const isDisabled = isUsed || isOldChaRu ? 'disabled ' : '';
                 codeHtml += '<tr quantity="' + quantity + '" gcl_id="' + gcl_id + '" mx_id="' + mx_id + '">' +
                     '<td class="text-center">' + (index+1) + (leaf.cid ? '<i class="text-danger" style="font-weight: 900">*</i>' : '') + '</td>' +
                     '<td>' + leaf.code + '</td>' +
@@ -688,6 +968,7 @@ $(document).ready(() => {
     // 右边项目节选择
     $('body').on('click', '#code-list input', function () {
         let index = $('#code-list').attr('data-index');
+        // 判断是否是自定义排序,是则另外保存一份到tr中,和data-bwmx不相通,最后提交再清除所有的data-charu清单
         if ($(this).is(':checked')) {
             // 去除其它可能已选的checked
             // $('#code-list input').prop('checked', false);
@@ -696,6 +977,7 @@ $(document).ready(() => {
             $('#table-list-select tr[data-index="' + index + '"]').addClass('table-success');
             // 去除部分data-detail值
             let data_bwmx = [];
+            let data_charu = [];
             $('#code-list input:checked').each(function () {
                 const tr = $(this).parents('tr');
                 const length = tr.children('td').length;
@@ -711,14 +993,22 @@ $(document).ready(() => {
                 const quantity = tr.attr('quantity');
                 const de_qu = bwmx + '*;*' + quantity;
                 data_bwmx.push(de_qu);
+                if (changeOrder && $(this).prop('disabled') !== true) {
+                    data_charu.push(de_qu);
+                }
             });
             data_bwmx = data_bwmx.join('$#$');
             $('#table-list-select tr[data-index="' + index + '"]').attr('data-bwmx', data_bwmx);
+            if (changeOrder) {
+                data_charu = data_charu.join('$#$');
+                $('#table-list-select tr[data-index="' + index + '"]').attr('data-charu', data_charu);
+            }
         } else {
             // 判断还有无选中项目节编号
             if ($('#code-list input').is(':checked')) {
                 // 去除部分data-detail值
                 let data_bwmx = [];
+                let data_charu = [];
                 $('#code-list input:checked').each(function () {
                     const tr = $(this).parents('tr');
                     const length = tr.children('td').length;
@@ -734,12 +1024,22 @@ $(document).ready(() => {
                     const quantity = tr.attr('quantity');
                     const de_qu = bwmx + '*;*' + quantity;
                     data_bwmx.push(de_qu);
+                    if (changeOrder && $(this).prop('disabled') !== true) {
+                        data_charu.push(de_qu);
+                    }
                 });
                 data_bwmx = data_bwmx.join('$#$');
                 $('#table-list-select tr[data-index="' + index + '"]').attr('data-bwmx', data_bwmx);
+                if (changeOrder) {
+                    data_charu = data_charu.join('$#$');
+                    $('#table-list-select tr[data-index="' + index + '"]').attr('data-charu', data_charu);
+                }
             } else {
                 $('#table-list-select tr[data-index="' + index + '"]').removeClass('table-success');
                 $('#table-list-select tr[data-index="' + index + '"]').attr('data-bwmx', '');
+                if (changeOrder) {
+                    $('#table-list-select tr[data-index="' + index + '"]').attr('data-charu', '');
+                }
             }
         }
         checkSelectAll();
@@ -747,17 +1047,30 @@ $(document).ready(() => {
 
     // 添加空白清单or签约清单
     $('.add-list-btn').on('click', function () {
+        let select = null;
+        if (changeOrder) {
+            select = SpreadJsObj.getSelectObject(changeSpreadSheet);
+        }
         const newLedgerList = remakeChangeSpread();
+        console.log(newLedgerList, select);
         // 更新至服务器
-        postData(window.location.pathname + '/save', { type:'ledger_list', updateData: newLedgerList }, function (result) {
+        postData(window.location.pathname + '/save', { type:'ledger_list', updateData: newLedgerList, postData: select ? select.order : null }, function (result) {
             changeList = result.changeList;
             changeUsedData = result.usedList;
             SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
             changeSpreadObj.makeSjsFooter();
             const select = SpreadJsObj.getSelectObject(changeSpreadSheet);
             changeSpreadObj.resetXmjSpread(select);
+            changeSpreadObj.refreshActn();
+            $('#table-list-select tr').attr('data-charu', '');
+            if(changeOrder) {
+                $('#code-list input:checked').each(function () {
+                    $(this).attr('disabled', true);
+                })
+            }
             $('#addlist').modal('hide');
         }, function () {
+            $('#table-list-select tr').attr('data-charu', '');
             $('#addlist').modal('hide');
         });
 
@@ -908,6 +1221,7 @@ $(document).ready(() => {
             if ($('#code-list input').is(':checked')) {
                 // 去除部分data-detail值
                 let data_bwmx = [];
+                let data_charu = [];
                 $('#code-list input:checked').each(function () {
                     const tr = $(this).parents('tr');
                     const length = tr.children('td').length;
@@ -923,13 +1237,23 @@ $(document).ready(() => {
                     const quantity = tr.attr('quantity');
                     const de_qu = bwmx + '*;*' + quantity;
                     data_bwmx.push(de_qu);
+                    if (changeOrder && $(this).prop('disabled') !== true) {
+                        data_charu.push(de_qu);
+                    }
                 });
                 data_bwmx = data_bwmx.join('$#$');
                 $('#table-list-select tr[data-index="' + index + '"]').attr('data-bwmx', data_bwmx);
+                if (changeOrder) {
+                    data_charu = data_charu.join('$#$');
+                    $('#table-list-select tr[data-index="' + index + '"]').attr('data-charu', data_charu);
+                }
                 $('#table-list-select tr[data-index="' + index + '"]').addClass('table-success');
             } else {
                 $('#table-list-select tr[data-index="' + index + '"]').removeClass('table-success');
                 $('#table-list-select tr[data-index="' + index + '"]').attr('data-bwmx', '');
+                if (changeOrder) {
+                    $('#table-list-select tr[data-index="' + index + '"]').attr('data-charu', '');
+                }
             }
         }
     });
@@ -1002,6 +1326,31 @@ $(document).ready(() => {
         }
         toastr.success('已还原到上次保存状态');
     });
+
+    $('.dropdown-menu input[name="paixu"]').on('click', function () {
+        const newChangeOrder = parseInt($(this).val());
+        if (newChangeOrder !== changeOrder) {
+            const newLedgerList = changeOrder ? remakeChangeSpread(0) : [];
+            // 更新至服务器
+            postData(window.location.pathname + '/save', { type:'order_by', updateData: newChangeOrder, newLedgerList }, function (result) {
+                if (newChangeOrder === 0) {
+                    $('#bpaixu').text('清单排序:清单编号');
+                    $('#upAndMoveBtn').attr('style', 'display: none !important');
+                    $('.order_text').text('添加');
+                    changeOrder = newChangeOrder;
+                } else if (newChangeOrder === 1) {
+                    $('#bpaixu').text('清单排序:添加顺序');
+                    $('#upAndMoveBtn').show();
+                    $('.order_text').text('插入');
+                    changeOrder = newChangeOrder;
+                }
+                changeList = result;
+                SpreadJsObj.loadSheetData(changeSpreadSheet, SpreadJsObj.DataType.Data, changeList);
+                changeSpreadObj.makeSjsFooter();
+                changeSpreadObj.resetXmjSpread(SpreadJsObj.getSelectObject(changeSpreadSheet));
+            });
+        }
+    });
 });
 function checkSelectAll() {
     let check = $('#code-list tr').length > 0 ? true : false;
@@ -1072,6 +1421,7 @@ function tableDataRemake(changeListData) {
     $('#table-list-select tr').removeClass('table-warning');
     $('#table-list-select tr').removeClass('table-success');
     $('#table-list-select tr').attr('data-bwmx', '');
+    $('#table-list-select tr').attr('data-charu', '');
     $('#code-list').html('');
     $('#code-list').attr('data-index', '');
     $('#code-input').val('');
@@ -1274,7 +1624,7 @@ function makeCodeTable(search = '') {
     }
 }
 
-function remakeChangeSpread() {
+function remakeChangeSpread(cOrder = changeOrder) {
     const newTableList = [];
     // 获取选中的签约清单判断并插入到原有清单中
     $('#table-list-select .table-success').each(function(){
@@ -1293,7 +1643,7 @@ function remakeChangeSpread() {
         let lid = $(this).data('lid');
         let lindex = $(this).data('index');
         // 原清单和数量改变
-        let data_bwmx = $(this).attr('data-bwmx').split('$#$');
+        let data_bwmx = cOrder ? ($(this).attr('data-charu') ? $(this).attr('data-charu').split('$#$') : []) : $(this).attr('data-bwmx').split('$#$');
 
         for (const b of data_bwmx) {
             const oamount = b.split('*;*')[1] != '' ? b.split('*;*')[1] : 0;

+ 42 - 0
app/service/change.js

@@ -696,6 +696,48 @@ module.exports = app => {
         }
 
         /**
+         * 保存变更信息
+         * @param {int} order_by - 表单提交的数据
+         * @return {void}
+         */
+        async saveOrderBy(order_by, newLedgerList = []) {
+            const transaction = await this.db.beginTransaction();
+            let result = [];
+            try {
+                const postData = { order_by };
+                let changeList = await this.ctx.service.changeAuditList.getList(this.ctx.change.cid);
+                if (order_by) {
+                    let i = 1;
+                    const updateArray = [];
+                    for (const cl of changeList) {
+                        updateArray.push({
+                            id: cl.id,
+                            order: i,
+                        });
+                        cl.order = i;
+                        i++;
+                    }
+                    if (updateArray.length > 0) await transaction.updateRows(this.ctx.service.changeAuditList.tableName, updateArray);
+                } else {
+                    await this.ctx.service.changeAuditList.saveLedgerListDatas(newLedgerList, null, order_by);
+                    changeList = await this.ctx.service.changeAuditList.getList(this.ctx.change.cid, order_by);
+                }
+                const options = {
+                    where: {
+                        cid: this.ctx.change.cid,
+                    },
+                };
+                await transaction.update(this.tableName, postData, options);
+                await transaction.commit();
+                result = changeList;
+            } catch (error) {
+                await transaction.rollback();
+                result = false;
+            }
+            return result;
+        }
+
+        /**
          * 审批通过
          * @param {Number} pid 项目id
          * @param {int} postData - 表单提交的数据

+ 205 - 84
app/service/change_audit_list.js

@@ -27,63 +27,63 @@ module.exports = app => {
          * 取出变更令清单列表,并按台账清单在前,空白清单在后排序
          * @return {void}
          */
-        async getList(cid) {
+        async getList(cid, order_by = this.ctx.change.order_by) {
+            if (order_by) {
+                return await this.getAllDataByCondition({ where: { cid }, orders: [['order', 'asc']] });
+            }
             const sql = 'SELECT * FROM ?? WHERE `cid` = ? ORDER BY `lid` = "0", `id` asc';
             const sqlParam = [this.tableName, cid];
             return await this.db.query(sql, sqlParam);
         }
 
         /**
-         * 添加空白变更清单
-         * @return {void}
+         * 移除清单时,同步其后清单order
+         * @param transaction - 事务
+         * @param {Number} cid - 变更cid
+         * @param {Number} order - order之后的
+         * @return {Promise<*>}
+         * @private
          */
-        async add(data) {
-            if (!this.ctx.tender || !this.ctx.change) {
-                throw '数据错误';
-            }
-            const insertData = {
-                tid: this.ctx.tender.id,
-                cid: this.ctx.change.cid,
-                lid: '0',
-                code: '',
-                name: '',
-                bwmx: '',
-                unit: '',
-                unit_price: null,
-                oamount: 0,
-                camount: 0,
-                samount: '',
-                detail: '',
-                spamount: 0,
-                xmj_code: null,
-                xmj_jldy: null,
-                xmj_dwgc: null,
-                xmj_fbgc: null,
-                xmj_fxgc: null,
-                gcl_id: '',
-            };
-            // 新增工料
-            const result = await this.db.insert(this.tableName, insertData);
-            if (result.affectedRows === 0) {
-                throw '新增空白清单数据失败';
-            }
-            return await this.getDataById(result.insertId);
+        async _syncOrder(transaction, cid, order, selfOperate = '-', num = 1) {
+            this.initSqlBuilder();
+            this.sqlBuilder.setAndWhere('cid', {
+                value: this.db.escape(cid),
+                operate: '=',
+            });
+            this.sqlBuilder.setAndWhere('order', {
+                value: order,
+                operate: '>=',
+            });
+            this.sqlBuilder.setUpdateData('order', {
+                value: num,
+                selfOperate,
+            });
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
+            const data = await transaction.query(sql, sqlParam);
+            return data;
         }
 
         /**
-         * 批量添加空白变更清单
+         * 添加空白变更清单
          * @return {void}
          */
-        async batchAdd(data) {
+        async add(data) {
             if (!this.ctx.tender || !this.ctx.change) {
                 throw '数据错误';
             }
-            const num = data.num ? parseInt(data.num) : 0;
-            if (num < 1 || num > 100) {
-                throw '批量添加的空白清单数目不能小于1或大于100';
-            }
-            const insertArray = [];
-            for (let i = 0; i < num; i++) {
+            const transaction = await this.db.beginTransaction();
+            try {
+                let order = null;
+                if (this.ctx.change.order_by) {
+                    if (data) {
+                        order = parseInt(data) + 1;
+                        // order以下的清单+1
+                        await this._syncOrder(transaction, this.ctx.change.cid, order, '+');
+                    } else {
+                        order = await this.count({ cid: this.ctx.change.cid });
+                        order = order ? order + 1 : 1;
+                    }
+                }
                 const insertData = {
                     tid: this.ctx.tender.id,
                     cid: this.ctx.change.cid,
@@ -104,19 +104,88 @@ module.exports = app => {
                     xmj_fbgc: null,
                     xmj_fxgc: null,
                     gcl_id: '',
+                    order,
                 };
-                insertArray.push(insertData);
+                // 新增工料
+                const result = await transaction.insert(this.tableName, insertData);
+                if (result.affectedRows === 0) {
+                    throw '新增空白清单数据失败';
+                }
+                await transaction.commit();
+                return await this.getDataById(result.insertId);
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
             }
-            // 新增工料
-            const result = await this.db.insert(this.tableName, insertArray);
-            if (result.affectedRows !== num) {
-                throw '批量添加空白清单数据失败';
+        }
+
+        /**
+         * 批量添加空白变更清单
+         * @return {void}
+         */
+        async batchAdd(data) {
+            if (!this.ctx.tender || !this.ctx.change) {
+                throw '数据错误';
             }
-            // 获取刚批量添加的所有list
-            for (let j = 0; j < num; j++) {
-                insertArray[j].id = result.insertId + j;
+            const transaction = await this.db.beginTransaction();
+            try {
+                const num = data.num ? parseInt(data.num) : 0;
+                if (num < 1 || num > 100) {
+                    throw '批量添加的空白清单数目不能小于1或大于100';
+                }
+                let order = null;
+                if (this.ctx.change.order_by) {
+                    if (data) {
+                        order = parseInt(data.postData) + 1;
+                        // order以下的清单+1
+                        await this._syncOrder(transaction, this.ctx.change.cid, order, '+', num);
+                    } else {
+                        order = await this.count({ cid: this.ctx.change.cid });
+                        order = order ? order + 1 : 1;
+                    }
+                }
+                const insertArray = [];
+                for (let i = 0; i < num; i++) {
+                    const insertData = {
+                        tid: this.ctx.tender.id,
+                        cid: this.ctx.change.cid,
+                        lid: '0',
+                        code: '',
+                        name: '',
+                        bwmx: '',
+                        unit: '',
+                        unit_price: null,
+                        oamount: 0,
+                        camount: 0,
+                        samount: '',
+                        detail: '',
+                        spamount: 0,
+                        xmj_code: null,
+                        xmj_jldy: null,
+                        xmj_dwgc: null,
+                        xmj_fbgc: null,
+                        xmj_fxgc: null,
+                        gcl_id: '',
+                        order: order ? order + i : null,
+                    };
+                    insertArray.push(insertData);
+                }
+                // 新增工料
+                const result = await transaction.insert(this.tableName, insertArray);
+                if (result.affectedRows !== num) {
+                    throw '批量添加空白清单数据失败';
+                }
+                await transaction.commit();
+                // // 获取刚批量添加的所有list
+                // for (let j = 0; j < num; j++) {
+                //     insertArray[j].id = result.insertId + j;
+                // }
+                // return insertArray;
+                return await this.getList(this.ctx.change.cid);
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
             }
-            return insertArray;
         }
 
         /**
@@ -124,14 +193,18 @@ module.exports = app => {
          * @param {int} id 清单id
          * @return {void}
          */
-        async del(id) {
+        async del(data) {
             if (!this.ctx.tender || !this.ctx.change) {
                 throw '数据错误';
             }
             const transaction = await this.db.beginTransaction();
             try {
                 // 判断是否可删
-                await transaction.delete(this.tableName, { id });
+                await transaction.delete(this.tableName, { id: data.ids });
+                // // order以下的清单-1
+                if (this.ctx.change.order_by) {
+                    await this._syncOrder(transaction, this.ctx.change.cid, data.postData, '-', data.ids.length);
+                }
                 // 重新算变更令总额
                 await this.calcCamountSum(transaction);
                 await transaction.commit();
@@ -202,7 +275,7 @@ module.exports = app => {
          * @param {Object} datas 内容
          * @return {void}
          */
-        async saveLedgerListDatas(datas) {
+        async saveLedgerListDatas(datas, data = null, order_by = this.ctx.change.order_by) {
             if (!this.ctx.tender || !this.ctx.change) {
                 throw '数据错误';
             }
@@ -210,47 +283,63 @@ module.exports = app => {
             // 判断t_type是否为费用
             const transaction = await this.db.beginTransaction();
             try {
-                const sql1 = 'SELECT a.* FROM ?? as b LEFT JOIN ?? as a ON b.cbid = a.id WHERE b.cid = ? GROUP BY b.cbid';
-                const sqlParam1 = [this.ctx.service.stageChange.tableName, this.tableName, this.ctx.change.cid];
-                const usedList = await transaction.query(sql1, sqlParam1);
-                // 先删除原本的台账清单数据
-                const sql = 'DELETE FROM ?? WHERE cid = ? and lid != "0"';
-                const sqlParam = [this.tableName, this.ctx.change.cid];
-                await transaction.query(sql, sqlParam);
+                let order = null;
+                if (order_by) {
+                    if (data) {
+                        order = parseInt(data) + 1;
+                        // order以下的清单+1
+                        await this._syncOrder(transaction, this.ctx.change.cid, order, '+', datas.length);
+                    } else {
+                        order = await this.count({ cid: this.ctx.change.cid });
+                        order = order ? order + 1 : 1;
+                    }
+                } else {
+                    // 先删除原本的台账清单数据
+                    const sql = 'DELETE FROM ?? WHERE cid = ? and lid != "0"';
+                    const sqlParam = [this.tableName, this.ctx.change.cid];
+                    await transaction.query(sql, sqlParam);
+                }
                 const insertDatas = [];
                 for (const data of datas) {
                     data.tid = this.ctx.tender.id;
                     data.cid = this.ctx.change.cid;
                     data.spamount = data.camount;
                     data.samount = '';
+                    data.order = order ? order : null;
+                    order = order ? order + 1 : null;
                     insertDatas.push(data);
                 }
                 if (insertDatas.length > 0) await transaction.insert(this.tableName, insertDatas);
                 await this.calcCamountSum(transaction);
-                // 更新stage_change和stage_change_final的cbid
-                if (usedList.length > 0) {
-                    const updateList = [];
-                    const sql2 = 'SELECT * FROM ?? WHERE `cid` = ? AND `lid` != "0"';
-                    const sqlParam2 = [this.tableName, this.ctx.change.cid];
-                    const newList = await transaction.query(sql2, sqlParam2);
-                    // const newList = await transaction.select(this.tableName, { where: { cid: this.ctx.change.cid } });
-                    for (const used of usedList) {
-                        const newone = this._.find(newList, { code: used.code, lid: used.lid, gcl_id: used.gcl_id, bwmx: used.bwmx });
-                        if (newone) {
-                            updateList.push({
-                                row: {
-                                    cbid: newone.id,
-                                },
-                                where: {
-                                    cid: this.ctx.change.cid,
-                                    cbid: used.id,
-                                },
-                            });
+                if (!order_by) {
+                    const sql1 = 'SELECT a.* FROM ?? as b LEFT JOIN ?? as a ON b.cbid = a.id WHERE b.cid = ? GROUP BY b.cbid';
+                    const sqlParam1 = [this.ctx.service.stageChange.tableName, this.tableName, this.ctx.change.cid];
+                    const usedList = await transaction.query(sql1, sqlParam1);
+                    // 更新stage_change和stage_change_final的cbid
+                    if (usedList.length > 0) {
+                        const updateList = [];
+                        const sql2 = 'SELECT * FROM ?? WHERE `cid` = ? AND `lid` != "0"';
+                        const sqlParam2 = [this.tableName, this.ctx.change.cid];
+                        const newList = await transaction.query(sql2, sqlParam2);
+                        // const newList = await transaction.select(this.tableName, { where: { cid: this.ctx.change.cid } });
+                        for (const used of usedList) {
+                            const newone = this._.find(newList, { code: used.code, lid: used.lid, gcl_id: used.gcl_id, bwmx: used.bwmx });
+                            if (newone) {
+                                updateList.push({
+                                    row: {
+                                        cbid: newone.id,
+                                    },
+                                    where: {
+                                        cid: this.ctx.change.cid,
+                                        cbid: used.id,
+                                    },
+                                });
+                            }
+                        }
+                        if (updateList.length > 0) {
+                            await transaction.updateRows(this.ctx.service.stageChange.tableName, updateList);
+                            await transaction.updateRows(this.ctx.service.stageChangeFinal.tableName, updateList);
                         }
-                    }
-                    if (updateList.length > 0) {
-                        await transaction.updateRows(this.ctx.service.stageChange.tableName, updateList);
-                        await transaction.updateRows(this.ctx.service.stageChangeFinal.tableName, updateList);
                     }
                 }
                 await transaction.commit();
@@ -890,6 +979,38 @@ module.exports = app => {
                 await transaction.query(pSql, []);
             }
         }
+
+        /**
+         * 交换两个清单的顺序
+         * @param {Number} id1 - 工料1的id
+         * @param {Number} id2 - 工料2的id
+         * @returns {Promise<void>}
+         */
+        async changeOrder(datas) {
+            if (!this.ctx.tender || !this.ctx.change) {
+                throw '数据错误';
+            }
+            // const bill1 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id1 });
+            // const bill2 = await this.getDataByCondition({ tid: this.ctx.tender.id, id: id2 });
+            // if (!bill1 || !bill2) {
+            //     throw '数据错误';
+            // }
+
+            const transaction = await this.db.beginTransaction();
+            try {
+                // const order = bill1.order;
+                // bill1.order = bill2.order;
+                // bill2.order = order;
+                // await transaction.update(this.tableName, { id: bill1.id, order: bill1.order });
+                // await transaction.update(this.tableName, { id: bill2.id, order: bill2.order });
+                await transaction.updateRows(this.tableName, datas);
+                await transaction.commit();
+                return true;
+            } catch (err) {
+                await transaction.rollback();
+                throw err;
+            }
+        }
     }
 
     return ChangeAuditList;

+ 27 - 2
app/view/change/information.ejs

@@ -11,10 +11,33 @@
                 <% } %>
                 <% if (auditStatus === 1 || auditStatus === 2 || auditStatus === 9) { %>
                     <div class="d-inline-block">
-                        <a href="#addlist" data-toggle="modal" class="btn btn-sm btn-light text-primary" id="open-list-modal" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="添加清单"><i class="fa fa-plus" aria-hidden="true"></i> 添加台账清单</a>
+                        <a href="#addlist" data-toggle="modal" class="btn btn-sm btn-light text-primary" id="open-list-modal" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="添加清单"><i class="fa fa-plus" aria-hidden="true"></i> <span class="order_text"><% if (change.order_by === 0) { %>添加<% } else { %>插入<% } %></span>台账清单</a>
+                    </div>
+                    <div class="d-inline-block mr-1">
+                        <a href="javascript:void(0);" class="btn btn-sm btn-light text-primary" id="add-white-btn" data-original-title="添加清单"><i class="fa fa-plus" aria-hidden="true"></i> <span class="order_text"><% if (change.order_by === 0) { %>添加<% } else { %>插入<% } %></span>空白清单</a>
                     </div>
                     <div class="d-inline-block mr-3">
-                        <a href="javascript:void(0);" class="btn btn-sm btn-light text-primary" id="add-white-btn" data-original-title="添加清单"><i class="fa fa-plus" aria-hidden="true"></i> 添加空白清单</a>
+                        <button type="button" class="btn btn-sm btn-light text-primary dropdown-toggle" data-toggle="dropdown" id="bpaixu">清单排序:<% if (change.order_by === 0) { %>清单编号<% } else { %>添加顺序<% } %></button>
+                        <div class="dropdown-menu" aria-labelledby="bpaixu">
+                            <ul class="list-unstyled px-3 mb-0">
+                                <li class="mb-2">
+                                    <div class="custom-control custom-radio">
+                                        <input type="radio" class="custom-control-input" name="paixu" id="order_0" value="0" <% if (change.order_by === 0) { %>checked<% } %>>
+                                        <label class="custom-control-label" for="order_0">清单编号</label>
+                                    </div>
+                                </li>
+                                <li class="mb-2">
+                                    <div class="custom-control custom-radio">
+                                        <input type="radio" class="custom-control-input" name="paixu" id="order_1" value="1" <% if (change.order_by === 1) { %>checked<% } %>>
+                                        <label class="custom-control-label" for="order_1">添加顺序</label>
+                                    </div>
+                                </li>
+                            </ul>
+                        </div>
+                    </div>
+                    <div class="d-inline-block mr-3" id="upAndMoveBtn" <% if (change.order_by === 0) { %>style="display: none!important;" <% } %>>
+                        <a href="javascript:void(0)" id="up-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="上移"><i class="fa fa-arrow-up" aria-hidden="true"></i></a>
+                        <a href="javascript:void(0)" id="down-move" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="下移"><i class="fa fa-arrow-down" aria-hidden="true"></i></a>
                     </div>
                 <% } %>
                 <div class="d-inline-block">
@@ -414,6 +437,7 @@
     const changeSpreadSheet = changeSpread.getActiveSheet();
     const xmjSpread = SpreadJsObj.createNewSpread($('#xmj-spread')[0]);
     let changeList = JSON.parse(unescape('<%- escape(JSON.stringify(changeList)) %>'));
+    console.log(changeList);
     const style1 = new GC.Spread.Sheets.Style();
     style1.locked = true;
 </script>
@@ -451,6 +475,7 @@
     };
     let changeInfo = Object.assign({}, back_changeInfo);
     let changeUsedData = JSON.parse(unescape('<%- escape(JSON.stringify(changeUsedData)) %>'));
+    let changeOrder = parseInt('<%- change.order_by %>');
     console.log(changeUsedData);
 </script>
 <script src="/public/js/change_information_set.js?202001181"></script>