Procházet zdrojové kódy

成本报审,财务账面,小数位数相关

MaiXinRong před 1 týdnem
rodič
revize
593aeee7bb

+ 13 - 2
app/controller/cost_controller.js

@@ -385,7 +385,7 @@ module.exports = app => {
                             ledgerC.forEach(l => { delete l.postil; delete l.memo; });
                             const bookC = await ctx.service.costStageBook.getCompareData(ctx.costStage);
                             ctx.helper.assignRelaData(ledgerC, [
-                                { data: bookC, fields: ['pre_in_tp', 'pre_in_excl_tax_tp', 'calc_his', 'postil', 'memo'], prefix: '', relaId: 'ledger_id' },
+                                { data: bookC, fields: ['pre_in_tp', 'pre_in_excl_tax_tp', 'in_tp', 'in_excl_tax_tp', 'calc_his', 'postil', 'memo'], prefix: '', relaId: 'ledger_id' },
                             ]);
                             responseData.data[f] = ledgerC;
                             break;
@@ -406,7 +406,7 @@ module.exports = app => {
                             detailC.forEach(l => { delete l.postil; delete l.memo; });
                             const bookDetailC = await ctx.service.costStageBook.getCompareData(ctx.costStage);
                             ctx.helper.assignRelaData(detailC, [
-                                { data: bookDetailC, fields: ['calc_his', 'postil', 'memo'], prefix: '', relaId: 'detail_id' },
+                                { data: bookDetailC, fields: ['in_tp', 'in_excl_tax_tp', 'calc_his', 'postil', 'memo'], prefix: '', relaId: 'detail_id' },
                             ]);
                             responseData.data[f] = detailC;
                             break;
@@ -617,6 +617,17 @@ module.exports = app => {
                 ctx.ajaxErrorBody('未知期数据类型', '保存数据错误');
             }
         }
+        async setDecimal(ctx) {
+            try {
+                const data = JSON.parse(ctx.request.body.data);
+                const stageTypeInfo = ctx.service.costStage.stageType[ctx.costStage.stage_type];
+                const result = await this.ctx.service[stageTypeInfo.dataService].setDecimal(data.decimal);
+                ctx.body = { err: 0, msg: '', data: result };
+            } catch (err) {
+                this.log(err);
+                ctx.body = this.ajaxErrorBody(err, '设置小数位数错误');
+            }
+        }
 
         async uploadStageFile(ctx) {
             let stream;

+ 23 - 0
app/public/js/cost_stage_book.js

@@ -808,4 +808,27 @@ $(document).ready(function() {
             }, 100);
         });
     })('a[name=showLevel]', billsObj.sheet);
+
+    if (!readOnly) {
+        $('#cost-decimal').on('show.bs.modal', () => {
+            const decimalObjs = [$('#cost-tp'), $('#cost-excl-tax-tp')];
+            for (const obj of decimalObjs) {
+                obj.val(obj.attr('org'));
+            }
+        });
+        $('#cost-decimal-ok').click(() => {
+            const decimal = { tp: parseInt($('#cost-tp').val()), excl_tax_tp: parseInt($('#cost-excl-tax-tp').val()) };
+            postData('decimal', { decimal }, function(result) {
+                if (result.calc) {
+                    const refreshNode = billsObj.tree.loadPostData({ update: result.bills });
+                    billsObj.refreshTree(refreshNode);
+                    detailObj.data.updateDatas(result.detail);
+                    detailObj.reloadDetailData();
+                }
+                $('#cost-tp').attr('org', decimal.tp);
+                $('#cost-excl-tax-tp').attr('org', decimal.excl_tax_tp);
+                $('#cost-decimal').modal('hide');
+            });
+        });
+    }
 });

+ 22 - 0
app/public/js/cost_stage_ledger.js

@@ -1266,6 +1266,28 @@ $(document).ready(function() {
             }
         }
     });
+    if (!readOnly) {
+        $('#cost-decimal').on('show.bs.modal', () => {
+            const decimalObjs = [$('#cost-tp'), $('#cost-excl-tax-tp')];
+            for (const obj of decimalObjs) {
+                obj.val(obj.attr('org'));
+            }
+        });
+        $('#cost-decimal-ok').click(() => {
+            const decimal = { tp: parseInt($('#cost-tp').val()), excl_tax_tp: parseInt($('#cost-excl-tax-tp').val()) };
+            postData('decimal', { decimal }, function(result) {
+                if (result.calc) {
+                    const refreshNode = billsObj.tree.loadPostData({ update: result.bills });
+                    billsObj.refreshTree(refreshNode);
+                    detailObj.data.updateDatas(result.detail);
+                    detailObj.reloadDetailData();
+                }
+                $('#cost-tp').attr('org', decimal.tp);
+                $('#cost-excl-tax-tp').attr('org', decimal.excl_tax_tp);
+                $('#cost-decimal').modal('hide');
+            });
+        });
+    }
 
     const costFile = $.ledger_att({
         selector: '#fujian',

+ 1 - 0
app/router.js

@@ -562,6 +562,7 @@ module.exports = app => {
     app.get('/sp/:id/cost/tender/:tid/:stype/:sorder/compare', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.compare');
     app.post('/sp/:id/cost/tender/:tid/:stype/:sorder/load', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.stageLoad');
     app.post('/sp/:id/cost/tender/:tid/:stype/:sorder/update', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.stageUpdate');
+    app.post('/sp/:id/cost/tender/:tid/:stype/:sorder/decimal', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.setDecimal');
     app.post('/sp/:id/cost/tender/:tid/:stype/:sorder/file/upload', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.uploadStageFile');
     app.post('/sp/:id/cost/tender/:tid/:stype/:sorder/file/delete', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.deleteStageFile');
     app.post('/sp/:id/cost/tender/:tid/:stype/:sorder/stage/tag', sessionAuth, subProjectCheck, tenderCheck, tenderPermissionCheck, costStageCheck, 'costController.tag');

+ 3 - 3
app/service/cost_stage.js

@@ -25,9 +25,9 @@ module.exports = app => {
             super(ctx);
             this.tableName = 'cost_stage';
             this.stageType = {
-                ledger: { key: 'ledger', name: '成本报审', decimal: { tp: 6, tax: 2 }, shenpi_status: 'cost_stage_ledger', push_type: 'costStageLedger', dataService: 'costStageLedger', detailService: 'costStageDetail' },
-                book: { key: 'book', name: '财务账面', decimal: { tp: 6 }, shenpi_status: 'cost_stage_book', push_type: 'costStageBook', dataService: 'costStageBook', detailService: 'costStageBookDetail' },
-                analysis: { key: 'analysis', name: '成本分析', decimal: { tp: 6 }, shenpi_status: 'cost_stage_analysis', push_type: 'costStageAnalysis', dataService: 'costStageAnalysis', detailService: 'costStageAnalysisDetail' },
+                ledger: { key: 'ledger', name: '成本报审', decimal: { tp: 6, tax: 2, excl_tax_tp: 6 }, shenpi_status: 'cost_stage_ledger', push_type: 'costStageLedger', dataService: 'costStageLedger', detailService: 'costStageDetail' },
+                book: { key: 'book', name: '财务账面', decimal: { tp: 6, tax: 2, excl_tax_tp: 6 }, shenpi_status: 'cost_stage_book', push_type: 'costStageBook', dataService: 'costStageBook', detailService: 'costStageBookDetail' },
+                analysis: { key: 'analysis', name: '成本分析', decimal: { tp: 6, tax: 2, excl_tax_tp: 6 }, shenpi_status: 'cost_stage_analysis', push_type: 'costStageAnalysis', dataService: 'costStageAnalysis', detailService: 'costStageAnalysisDetail' },
             };
         }
 

+ 0 - 33
app/service/cost_stage_analysis.js

@@ -664,39 +664,6 @@ module.exports = app => {
             if (updateData.length > 0) await transaction.updateRows(this.tableName, updateData);
         }
 
-        async setDecimal(decimal) {
-            if (!this.ctx.costStage) throw '读取数据错误';
-            if (this.ctx.costStage.stage_order !== this.ctx.costStage.latestOrder) throw '往期不可修改小数位数';
-            if (this.ctx.costStage.audit_status !== auditConst.status.uncheck && this.ctx.costStage.audit_status !== auditConst.status.checkNo) throw '仅原报可修改小数位数';
-            const orgDecimal = this.ctx.costStage.decimal;
-
-            const calcTp = decimal.tp < orgDecimal.tp;
-            this.ctx.costStage.decimal = { tp: decimal.tp, tax: decimal.tax || this.ctx.costStage.decimal.tax };
-
-            const updateData = [];
-            if (calcTp) {
-                const calcData = await this.getAllDataByCondition({ where: {stage_id: this.ctx.costStage.id, tree_is_leaf: 1 } });
-                for (const cd of calcData) {
-                    const nd = { id: cd.id, tree_id: cd.tree_id };
-                    for (const prop of costFields.calcFields) {
-                        nd[prop] = this.ctx.helper.round(nd[prop], decimal.tp);
-                    }
-                    updateData.push(nd);
-                }
-            }
-            const conn = await this.db.beginTransaction();
-            try {
-                await conn.update(this.ctx.service.costStage.tableName, { id: this.ctx.costStage.id, decimal: JSON.stringify(this.ctx.costStage.decimal)});
-                if (updateData.length > 0) await conn.updateRows(this.tableName, updateData);
-                await conn.commit();
-                return { calc: calcTp, update: updateData };
-            } catch(err) {
-                await conn.rollback();
-                return { calc: false, update: [] };
-            }
-
-        }
-
         async getSum(stage) {
             const sumCol = stage.calcTemplate.col_set.find(x => { return x.sum; });
             const field = sumCol.field;

+ 71 - 2
app/service/cost_stage_book.js

@@ -19,6 +19,7 @@ costFields.calcFields = [...costFields.curFields];
 costFields.editQueryFields = [...costFields.baseFields, ...costFields.textFields, ...costFields.preFields, ...costFields.curFields];
 costFields.readQueryFields = [...costFields.baseFields, ...costFields.textFields, ...costFields.preFields, ...costFields.readFields];
 costFields.compareQueryFields = [...costFields.baseFields, ...costFields.textFields, ...costFields.preFields, ...costFields.curFields, 'calc_his'];
+const auditConst = require('../const/audit').costStage;
 
 module.exports = app => {
     class CostStageBook extends app.BaseService {
@@ -129,9 +130,9 @@ module.exports = app => {
                 if (d.in_tp !== undefined ) {
                     nd.in_tp = d.in_tp !== undefined ? this.ctx.helper.round(d.in_tp || 0, this.ctx.costStage.decimal.tp) : (od.in_tp ? od.in_tp : 0);
                     const divNum = this.ctx.helper.add(1, this.ctx.helper.div(cl.tax, 100));
-                    nd.in_excl_tax_tp = this.ctx.helper.div(nd.in_tp, divNum, this.ctx.costStage.decimal.tp);
+                    nd.in_excl_tax_tp = this.ctx.helper.div(nd.in_tp, divNum, this.ctx.costStage.decimal.excl_tax_tp);
                 }
-                if (d.in_excl_tax_tp !== undefined) nd.in_excl_tax_tp = this.ctx.helper.round(d.in_excl_tax_tp, this.ctx.costStage.decimal.tp);
+                if (d.in_excl_tax_tp !== undefined) nd.in_excl_tax_tp = this.ctx.helper.round(d.in_excl_tax_tp, this.ctx.costStage.decimal.excl_tax_tp);
                 if (od) {
                     updateDetail.push(nd);
                 } else {
@@ -198,6 +199,74 @@ module.exports = app => {
             const result = await this.db.queryOne(`SELECT ${sumFields.join(', ')} FROM ${this.tableName} where stage_id = ?`, [stage.id]);
             return result;
         }
+
+        async setDecimal(decimal) {
+            if (!this.ctx.costStage) throw '读取数据错误';
+            if (this.ctx.costStage.stage_order !== this.ctx.costStage.latestOrder) throw '往期不可修改小数位数';
+            if (this.ctx.costStage.audit_status !== auditConst.status.uncheck && this.ctx.costStage.audit_status !== auditConst.status.checkNo) throw '仅原报可修改小数位数';
+            const orgDecimal = this.ctx.costStage.decimal;
+
+            const calcTp = decimal.tp < orgDecimal.tp || decimal.excl_tax_tp !== orgDecimal.excl_tax_tp;
+            this.ctx.costStage.decimal = this.ctx.helper._.assignIn(this.ctx.costStage.typeInfo.decimal, decimal);
+
+            const updateData = [], detailUpdateData = [];
+            let orgLedger, orgDetail;
+            if (calcTp) {
+                const detailCalcData = await this.ctx.service.costStageBookDetail.getAllDataByCondition({ where: { stage_id: this.ctx.costStage.id }});
+                orgDetail = await this.ctx.service.costStageDetail.getAllDataByCondition({ where: { stage_id: this.ctx.costStage.relaStage.id }});
+                for (const cd of detailCalcData) {
+                    const nd = { id: cd.id, ledger_id: cd.ledger_id, detail_id: cd.detail_id };
+                    const cl = orgLedger.find(x => { return x.id === cd.ledger_id });
+                    nd.in_tp = this.ctx.helper.round(cd.in_tp, decimal.tp);
+                    const divNum = cl.tax ? this.ctx.helper.add(1, this.ctx.helper.div(cl.tax, 100)) : 1;
+                    nd.in_excl_tax_tp = this.ctx.helper.div(nd.in_tp !== undefined ? nd.in_tp : nd.in_tp, divNum, decimal.excl_tax_tp);
+                    detailUpdateData.push(nd);
+                }
+                const calcData = await this.getAllDataByCondition({ where: {stage_id: this.ctx.costStage.id } });
+                orgLedger = await this.ctx.service.costStageLedger.getAllDataByCondition({ where: { stage_id: this.ctx.costStage.relaStage.id }});
+                for (const cd of calcData) {
+                    const nd = { id: cd.id, ledger_id: cd.ledger_id };
+                    const relaDetail = detailUpdateData.filter(x => { return x.ledger_id === cd.ledger_id; });
+                    if (relaDetail && relaDetail.length > 0) {
+                        for (const rd of relaDetail) {
+                            for (const prop of costFields.calcFields) {
+                                nd[prop] = this.ctx.helper.add(nd[prop], rd[prop]);
+                            }
+                        }
+                    } else {
+                        const cl = orgLedger.find(x => { return x.id === cd.ledger_id });
+                        nd.in_tp = this.ctx.helper.round(cd.in_tp, decimal.tp);
+                        const divNum = cl.tax ? this.ctx.helper.add(1, this.ctx.helper.div(cl.tax, 100)) : 1;
+                        nd.in_excl_tax_tp = this.ctx.helper.div(nd.in_tp !== undefined ? nd.in_tp : nd.in_tp, divNum, decimal.excl_tax_tp);
+                    }
+                    updateData.push(nd);
+                }
+            }
+
+            const conn = await this.db.beginTransaction();
+            try {
+                await conn.update(this.ctx.service.costStage.tableName, { id: this.ctx.costStage.id, decimal: JSON.stringify(this.ctx.costStage.decimal)});
+                if (updateData.length > 0) await conn.updateRows(this.tableName, updateData);
+                if (detailUpdateData.length > 0) await conn.updateRows(this.ctx.service.costStageBookDetail.tableName, detailUpdateData);
+                await conn.commit();
+            } catch(err) {
+                await conn.rollback();
+                return { calc: false, bills: [], detail: [] };
+            }
+            updateData.forEach(i => {
+                i.book_id = i.id;
+                delete i.id;
+                const cl = orgLedger.find(x => { return x.id === i.ledger_id });
+                i.tree_id = cl.tree_id;
+            });
+            detailUpdateData.forEach(u => {
+                u.book_id = u.id;
+                delete u.id;
+                const cl = orgDetail.find(x => { return x.id === od.detail_id; });
+                i.id = cl.id;
+            });
+            return { calc: calcTp, bills: updateData, detail: detailUpdateData };
+        }
     }
 
     return CostStageBook;

+ 39 - 10
app/service/cost_stage_ledger.js

@@ -461,8 +461,8 @@ module.exports = app => {
                 if (row.tax !== undefined || nData.sf_tp !== undefined || nData.yf_tp !== undefined) {
                     nData.tax = row.tax !== undefined ? helper.round(row.tax || 0, decimal.tax) : oData.tax;
                     const divNum = nData.tax ? helper.add(1, helper.div(nData.tax, 100)) : 1;
-                    nData.yf_excl_tax_tp = helper.div(nData.yf_tp !== undefined ? nData.yf_tp : oData.yf_tp, divNum, decimal.tp);
-                    nData.sf_excl_tax_tp = helper.div(nData.sf_tp !== undefined ? nData.sf_tp : oData.sf_tp, divNum, decimal.tp);
+                    nData.yf_excl_tax_tp = helper.div(nData.yf_tp !== undefined ? nData.yf_tp : oData.yf_tp, divNum, decimal.excl_tax_tp);
+                    nData.sf_excl_tax_tp = helper.div(nData.sf_tp !== undefined ? nData.sf_tp : oData.sf_tp, divNum, decimal.excl_tax_tp);
                 }
                 for (const field of costFields.textFields) {
                     if (row[field] !== undefined) nData[field] = row[field] || '';
@@ -509,31 +509,60 @@ module.exports = app => {
             if (this.ctx.costStage.audit_status !== auditConst.status.uncheck && this.ctx.costStage.audit_status !== auditConst.status.checkNo) throw '仅原报可修改小数位数';
             const orgDecimal = this.ctx.costStage.decimal;
 
-            const calcTp = decimal.tp < orgDecimal.tp;
-            this.ctx.costStage.decimal = { up: decimal.up, tp: decimal.tp, qty: decimal.qty };
+            const calcTp = decimal.tp < orgDecimal.tp || decimal.excl_tax_tp !== orgDecimal.excl_tax_tp;
+            this.ctx.costStage.decimal = this.ctx.helper._.assignIn(this.ctx.costStage.typeInfo.decimal, decimal);
 
-            const updateData = [];
+            const updateData = [], detailUpdateData = [];
             if (calcTp) {
+                const detailCalcData = await this.ctx.service.costStageDetail.getAllDataByCondition({ where: { stage_id: this.ctx.costStage.id }});
+                for (const cd of detailCalcData) {
+                    const nd = { id: cd.id, ledger_id: cd.ledger_id };
+                    nd.tax = this.ctx.helper.round(cd.tax, decimal.tax);
+                    nd.pay_tp = this.ctx.helper.round(cd.pay_tp, decimal.tp);
+                    nd.cut_tp = this.ctx.helper.round(cd.cut_tp, decimal.tp);
+                    nd.yf_tp = this.ctx.helper.round(cd.yf_tp, decimal.tp);
+                    nd.sf_tp = this.ctx.helper.round(cd.sf_tp, decimal.tp);
+                    const divNum = nd.tax ? this.ctx.helper.add(1, this.ctx.helper.div(nd.tax, 100)) : 1;
+                    nd.yf_excl_tax_tp = this.ctx.helper.div(nd.yf_tp !== undefined ? nd.yf_tp : nd.yf_tp, divNum, decimal.excl_tax_tp);
+                    nd.sf_excl_tax_tp = this.ctx.helper.div(nd.sf_tp !== undefined ? nd.sf_tp : nd.sf_tp, divNum, decimal.excl_tax_tp);
+                    detailUpdateData.push(nd);
+                }
                 const calcData = await this.getAllDataByCondition({ where: {stage_id: this.ctx.costStage.id, tree_is_leaf: 1 } });
                 for (const cd of calcData) {
                     const nd = { id: cd.id, tree_id: cd.tree_id };
-                    for (const prop of costFields.curFields) {
-                        nd[prop] = this.ctx.helper.round(nd[prop]);
+                    const relaDetail = detailUpdateData.filter(x => { return x.ledger_id === cd.id; });
+                    if (relaDetail && relaDetail.length > 0) {
+                        for (const rd of relaDetail) {
+                            for (const prop of costFields.calcFields) {
+                                if (prop === 'tax') continue;
+                                nd[prop] = this.ctx.helper.add(nd[prop], rd[prop]);
+                            }
+                        }
+                    } else {
+                        nd.tax = this.ctx.helper.round(cd.tax, decimal.tax);
+                        nd.pay_tp = this.ctx.helper.round(cd.pay_tp, decimal.tp);
+                        nd.cut_tp = this.ctx.helper.round(cd.cut_tp, decimal.tp);
+                        nd.yf_tp = this.ctx.helper.round(cd.yf_tp, decimal.tp);
+                        nd.sf_tp = this.ctx.helper.round(cd.sf_tp, decimal.tp);
+                        const divNum = nd.tax ? this.ctx.helper.add(1, this.ctx.helper.div(nd.tax, 100)) : 1;
+                        nd.yf_excl_tax_tp = this.ctx.helper.div(nd.yf_tp !== undefined ? nd.yf_tp : nd.yf_tp, divNum, decimal.excl_tax_tp);
+                        nd.sf_excl_tax_tp = this.ctx.helper.div(nd.sf_tp !== undefined ? nd.sf_tp : nd.sf_tp, divNum, decimal.excl_tax_tp);
                     }
                     updateData.push(nd);
                 }
             }
+
             const conn = await this.db.beginTransaction();
             try {
                 await conn.update(this.ctx.service.costStage.tableName, { id: this.ctx.costStage.id, decimal: JSON.stringify(this.ctx.costStage.decimal)});
                 if (updateData.length > 0) await conn.updateRows(this.tableName, updateData);
+                if (detailUpdateData.length > 0) await conn.updateRows(this.ctx.service.costStageDetail.tableName, detailUpdateData);
                 await conn.commit();
-                return { calc: calcTp, update: updateData };
+                return { calc: calcTp, bills: updateData, detail: detailUpdateData };
             } catch(err) {
                 await conn.rollback();
-                return { calc: false, update: [] };
+                return { calc: false, bills: [], detail: [] };
             }
-
         }
 
         async getSum(stage) {

+ 5 - 0
app/view/cost/book.ejs

@@ -19,6 +19,11 @@
                     </div>
                 </div>
             </div>
+            <% if (ctx.costStage.create_user_id === ctx.session.sessionUser.accountId) { %>
+            <div class="d-inline-block">
+                <a href="" class="btn btn-sm btn-light text-primary" data-toggle="modal" data-placement="bottom" title="设置" data-target="#cost-decimal"><i class="fa fa-cog" aria-hidden="true"></i></a>
+            </div>
+            <% } %>
             <div class="ml-auto">
             </div>
         </div>

+ 2 - 1
app/view/cost/book_modal.ejs

@@ -1,4 +1,5 @@
 <% include ../shares/delete_hint_modal.ejs %>
 <% include ./audit_modal.ejs %>
 <% include ../shares/upload_att.ejs %>
-<% include ../shares/new_tag_modal.ejs %>
+<% include ../shares/new_tag_modal.ejs %>
+<% include ./cost_decimal.ejs %>

+ 66 - 0
app/view/cost/cost_decimal.ejs

@@ -0,0 +1,66 @@
+
+<div class="modal fade show" id="cost-decimal" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">设置</h5>
+            </div>
+            <div class="modal-body">
+                <div class="form-group mb-3">
+                    <h5>小数位数</h5>
+                    <div class="row">
+                        <div class="col-6">
+                            <div class="input-group input-group-sm">
+                                <div class="input-group-prepend">
+                                    <span class="input-group-text">金额</span>
+                                </div>
+                                <input type="number" id="cost-tp" class="form-control" value="<%- ctx.costStage.decimal.tp %>" org="<%- ctx.costStage.decimal.tp %>" min="0" max="6" maxlength="1" oninput="limitDecimal(this)" <% if (ctx.costStage.readOnly) { %>disabled<% } %>>
+                            </div>
+                        </div>
+                        <div class="col-6">
+                            <div class="input-group input-group-sm">
+                                <div class="input-group-prepend">
+                                    <span class="input-group-text">金额(不含税)</span>
+                                </div>
+                                <input type="number" id="cost-excl-tax-tp" class="form-control" value="<%- ctx.costStage.decimal.excl_tax_tp %>" org="<%- ctx.costStage.decimal.excl_tax_tp %>" min="0" max="6" maxlength="1" oninput="limitDecimal(this)" <% if (ctx.costStage.readOnly) { %>disabled<% } %>>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                <% if (!ctx.costStage.readOnly) { %>
+                <button type="button" class="btn btn-sm btn-primary" id="cost-decimal-ok">确认</button>
+                <% } %>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    // 根据Min Max限制Input输入
+    function limitInputMinMax (obj) {
+        if (_.toNumber(obj.value) > _.toNumber(obj.max)) {
+            obj.value = obj.max;
+        }
+        if(_.toNumber(obj.value) < _.toNumber(obj.min)) {
+            obj.value = obj.min;
+        }
+    }
+    // 根据Maxlength限制input输入
+    function limitMaxLength (obj) {
+        if (obj.value.length > obj.maxLength) {
+            obj.value = obj.value.substr(0, obj.maxLength);
+        }
+    }
+    // 根据正则限制输入
+    function limitReg(obj, reg) {
+        obj.value = obj.value.replace(reg, '');
+    }
+    // 小数位数 input 输入限制
+    function limitDecimal(obj) {
+        limitReg(obj, /[^\d]/g);
+        limitMaxLength(obj);
+        limitInputMinMax(obj);
+    }
+</script>

+ 3 - 0
app/view/cost/ledger.ejs

@@ -27,6 +27,9 @@
                     <a href="javascript: void(0);" name="base-opr" type="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>
                     <a href="javascript: void(0);" name="base-opr" type="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>
                 </div>
+                <div class="d-inline-block">
+                    <a href="" class="btn btn-sm btn-light text-primary" data-toggle="modal" data-placement="bottom" title="设置" data-target="#cost-decimal"><i class="fa fa-cog" aria-hidden="true"></i></a>
+                </div>
                 <% } %>
             </div>
             <div class="ml-auto">

+ 1 - 0
app/view/cost/ledger_modal.ejs

@@ -2,6 +2,7 @@
 <% include ./audit_modal.ejs %>
 <% include ../shares/upload_att.ejs %>
 <% include ../shares/new_tag_modal.ejs %>
+<% include ./cost_decimal.ejs %>
 <div class="modal" id="import-deal-type" data-backdrop="static" aria-modal="true" role="dialog">
     <div class="modal-dialog" role="document">
         <div class="modal-content">