Quellcode durchsuchen

模板配置&计算修改

MaiXinRong vor 4 Wochen
Ursprung
Commit
f8e524ee06

+ 12 - 1
app/controller/template_controller.js

@@ -125,12 +125,23 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
                 const spreadSetting = this.ctx.service.calcTmpl.calcSpreadCache(data.type, data.col_set, data.multi_header);
                 const testData = await this.ctx.service.calcTmpl.getCalcTestData(data.col_set, data.type, 3);
-                ctx.body = { err: 0, msg: '', data: { spreadSetting, testData} };
+                const calc = this.ctx.service.calcTmpl._getCalcExpr(spreadSetting.cols);
+                ctx.body = { err: 0, msg: '', data: { spreadSetting, testData, calc } };
             } catch (error) {
                 ctx.log(error);
                 ctx.ajaxErrorBody(error, '预览失败');
             }
         }
+        async reCalcTemplate(ctx) {
+            try {
+                const templateId = ctx.query.tid;
+                await ctx.service.calcTmpl.reCalcTemplate(templateId, true);
+            } catch(error) {
+                ctx.log(error);
+                ctx.postError(error, '重算模板失败');
+            }
+            ctx.redirect(ctx.request.header.referer);
+        }
         // ---------------------------------------------------
     }
 

+ 1 - 22
app/public/js/cost_tmpl.js

@@ -197,13 +197,6 @@ $(document).ready(() => {
                     } else {
                         select.decimal = num;
                     }
-                } else if (col.field === 'rela_col') {
-                    const exist = self.colSetData.find(x => { return x.type === 'num' && x.calc_code === validText });
-                    if (!exist) {
-                        toastr.warning(`暂无计量单号为${validText}的列,请先配置该数值列`);
-                    } else {
-                        select.rela_col = validText;
-                    }
                 } else {
                     select[col.field] = validText;
                 }
@@ -375,24 +368,10 @@ $(document).ready(() => {
     }
     const detailObj = new TemplateDetailObj();
 
-    let previewSpreadSetting, previewData, previewSpread;
-    $('#preview-calc-grid').on('shown.bs.modal', function () {
-        if (!previewSpread) {
-            previewSpread = SpreadJsObj.createNewSpread($('#preview-spread')[0]);
-        }
-        const previewSheet = previewSpread.getActiveSheet();
-        SpreadJsObj.initSheet(previewSheet, previewSpreadSetting);
-    });
     $('#preview').click(function() {
         const data = { type: 'cost', col_set: detailObj.getCurrentColSet(), multi_header: detailObj.multi_header || detailObj.template.multi_header };
         if (!data.col_set) return;
-
-        postData('preview', data, function(result) {
-            result.spreadSetting.readOnly = true;
-            previewSpreadSetting = result.spreadSetting;
-            previewData = result.testData;
-            $('#preview-calc-grid').modal('show');
-        })
+        calcTemplatePreview.preview(data);
     });
 
     const templateObj = (function(list){

+ 15 - 33
app/public/js/pos_calc_tmpl.js

@@ -16,10 +16,10 @@ $(document).ready(() => {
                     { title: '列名', colSpan: '1', rowSpan: '1', field: 'title', hAlign: 0, width: 130, formatter: '@' },
                     { title: '列宽', colSpan: '1', rowSpan: '1', field: 'width', hAlign: 1, width: 70, type: 'Number' },
                     { title: '单位', colSpan: '1', rowSpan: '1', field: 'unit', hAlign: 1, width: 60, cellType: 'unit' },
-                    { title: '计算代号', colSpan: '1', rowSpan: '1', field: 'calc_code', hAlign: 1, width: 80, cellType: 'customizeCombo', comboItems: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J'], },
+                    { title: '计算代号', colSpan: '1', rowSpan: '1', field: 'calc_code', hAlign: 1, width: 80, cellType: 'customizeCombo', comboItems: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'], },
                     { title: '小数位数', colSpan: '1', rowSpan: '1', field: 'decimal', hAlign: 1, width: 60, type: 'Number' },
                     { title: '规格类型', colSpan: '1', rowSpan: '1', field: 'spec_set', hAlign: 1, width: 80, cellType: 'customizeCombo', cellTypeKey: 'spec', comboItems: specList, },
-                    { title: '关联列代号', colSpan: '1', rowSpan: '1', field: 'rela_col', hAlign: 1, width: 80, cellType: 'customizeCombo', comboItems: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J'], },
+                    { title: '关联列代号', colSpan: '1', rowSpan: '1', field: 'rela_col', hAlign: 1, width: 80, cellType: 'customizeCombo', comboItems: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'], },
                     { title: '计算公式', colSpan: '1', rowSpan: '1', field: 'expr', hAlign: 0, width: 250 },
                 ],
                 emptyRows: 0,
@@ -67,6 +67,7 @@ $(document).ready(() => {
                         toastr.warning('请勿输入重复的计算代号');
                     } else {
                         select.calc_code = validText;
+                        select.field = 'num_' + select.calc_code.toLowerCase();
                     }
                 } else if (col.field === 'width') {
                     select.width = parseInt(validText);
@@ -246,43 +247,24 @@ $(document).ready(() => {
             });
         }
         getCurrentColSet() {
+            for (const col of this.colSetData) {
+                if (col.type === 'num') {
+                    if (!col.calc_code) {
+                        toastr.error(`【${col.title}】未定义计算代号`);
+                        return null;
+                    }
+                }
+            }
             return this.colSetData;
         }
     }
     const detailObj = new TemplateDetailObj();
 
-    let previewSpreadSetting, previewData, previewSpread;
-    $('#preview-calc-grid').on('shown.bs.modal', function () {
-        if (!previewSpread) {
-            previewSpread = SpreadJsObj.createNewSpread($('#preview-spread')[0]);
-        }
-        const previewSheet = previewSpread.getActiveSheet();
-        SpreadJsObj.initSheet(previewSheet, previewSpreadSetting);
-        const qtyCol = previewSpreadSetting.cols.find(x => { return x.field === 'qty'; });
-        if (qtyCol) {
-            for (const pd of previewData) {
-                pd.calcExpr = qtyCol.expr;
-                for (const col of previewSpreadSetting.cols) {
-                    if (col.type !== 'Number' || col.field === 'qty') continue;
-                    pd.calcExpr = pd.calcExpr.replace(new RegExp(col.field, 'gm'), pd[col.field]);
-                }
-                try {
-                    pd.qty = ZhCalc.round(ZhCalc.mathCalcExpr(pd.calcExpr.replace(new RegExp('%', 'gm'), '/100')), qtyCol.decimal);
-                } catch(err) {
-                    pd.qty = 0;
-                }
-            }
-        }
-        SpreadJsObj.loadSheetData(previewSheet, SpreadJsObj.DataType.Data, previewData);
-    });
     $('#preview').click(function() {
         const data = { type: 'posCalc', col_set: detailObj.getCurrentColSet() };
-        postData('preview', data, function(result) {
-            result.spreadSetting.readOnly = true;
-            previewSpreadSetting = result.spreadSetting;
-            previewData = result.testData;
-            $('#preview-calc-grid').modal('show');
-        })
+        if (!data.col_set) return;
+
+        calcTemplatePreview.preview(data);
     });
 
     const templateObj = (function(list){
@@ -292,7 +274,7 @@ $(document).ready(() => {
         const loadTemplateDetail = async function(template) {
             const result = await postDataAsync('load', {filter: 'detail', id: template.id, type: 'posCalc'});
             if (result && result.detail) template.col_set = result.detail.col_set;
-        }
+        };
         const refreshTemplate = async function() {
             if (!curTemplate) {
                 // todo 隐藏模板详细界面

+ 51 - 0
app/public/js/shares/ct_preview.js

@@ -0,0 +1,51 @@
+;
+const calcTemplatePreview = (function(){
+    let previewSpreadSetting, previewData, previewCalc, previewSpread;
+
+    const calcPreviewData = function() {
+        const codeReg = /num_[a-z]{1}/gm;
+        for (const pd of previewData) {
+            for (const pc of previewCalc) {
+                if (!pc.expr) continue;
+
+                let calcExpr = pc.expr;
+                const codeParam = calcExpr.match(codeReg);
+                for (const cp of codeParam) {
+                    calcExpr = calcExpr.replace(new RegExp(cp, 'gm'), pd[cp]);
+                }
+                try {
+                    pd[pc.field] = ZhCalc.round(ZhCalc.mathCalcExpr(calcExpr.replace(new RegExp('%', 'gm'), '/100')), pc.decimal);
+                } catch(err) {
+                    pd[pc.field] = 0;
+                }
+            }
+        }
+    };
+
+    const checkShownListen = function() {
+        let hasListen = $.hasData($('#preview-calc-grid')[0]) && $.hasData($('#preview-calc-grid')[0]).events && $.hasData($('#preview-calc-grid')[0]).events['shown'];
+        if (!hasListen) {
+            $('#preview-calc-grid').on('shown.bs.modal', function () {
+                if (!previewSpread) previewSpread = SpreadJsObj.createNewSpread($('#preview-spread')[0]);
+                const previewSheet = previewSpread.getActiveSheet();
+                SpreadJsObj.initSheet(previewSheet, previewSpreadSetting);
+                SpreadJsObj.loadSheetData(previewSheet, SpreadJsObj.DataType.Data, previewData);
+            });
+        }
+    };
+
+    const preview = function(data) {
+        checkShownListen();
+        postData('preview', data, function(result) {
+            result.spreadSetting.readOnly = true;
+            previewSpreadSetting = result.spreadSetting;
+            previewData = result.testData || [];
+            previewCalc = result.calc || [];
+            calcPreviewData();
+            $('#preview-calc-grid').modal('show');
+        });
+    };
+    return { preview }
+})();
+
+

+ 2 - 0
app/router.js

@@ -625,6 +625,8 @@ module.exports = app => {
     app.post('/sp/:id/template/save', sessionAuth, subProjectCheck, 'templateController.saveTemplate');
     app.post('/sp/:id/template/load', sessionAuth, subProjectCheck, 'templateController.load');
     app.post('/sp/:id/template/preview', sessionAuth, subProjectCheck, 'templateController.preview');
+    app.get('/sp/:id/template/reCalc', sessionAuth, subProjectCheck, 'templateController.reCalcTemplate');
+    app.post('/sp/:id/template/reCalc', sessionAuth, subProjectCheck, 'templateController.reCalcTemplate');
     // 台账管理相关
     app.get('/tender/:id/ledger', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, ledgerAuditCheck, 'ledgerController.explode');
     app.post('/tender/:id/ledger/load', sessionAuth, tenderCheck, subProjectCheck, uncheckTenderCheck, 'ledgerController.loadExplodeData');

+ 140 - 6
app/service/calc_tmpl.js

@@ -10,6 +10,10 @@
  * @version
  */
 
+const math = require('mathjs');
+math.config({
+    number: 'BigNumber',
+});
 const ValidTemplateType = ['posCalc', 'cost'];
 const PosCalc = (function(){
     const EmptySpreadCache = {
@@ -30,7 +34,7 @@ const PosCalc = (function(){
     };
     const ValidColInfo = [
         { key: 'str', name: '文本', fields: ['str1', 'str2', 'str3', 'str4'], valid: ['title', 'width'], def: { title: '文字', width: 80, type: 'str'} },
-        { key: 'num', name: '数值', fields: ['num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9'], valid: ['title', 'width', 'calc_code', 'decimal', 'unit'], def: { title: '数值', width: 80, decimal: 2, type: 'num', unit: ''} },
+        { key: 'num', name: '数值', fields: ['num_a', 'num_b', 'num_c', 'num_d', 'num_e', 'num_f', 'num_g', 'num_h', 'num_i'], valid: ['title', 'width', 'calc_code', 'decimal', 'unit'], def: { title: '数值', width: 80, decimal: 2, type: 'num', unit: ''} },
         { key: 'spec', name: '规格', fields: ['spec'], valid: ['title', 'width', 'rela_col', 'spec_set'], def: { title: '规格', width: 80, rela_col: '', type: 'spec'} },
         { key: 'qty', name: '数量', fields: ['qty'], valid: ['title', 'width', 'expr', 'decimal'], def: { title: '数量', width: 80, decimal: 2, expr: '', type: 'qty' } },
     ];
@@ -120,6 +124,8 @@ module.exports = app => {
                 x.field_cache = x.field_cache ? JSON.parse(x.field_cache) : {};
                 x.decimal = x.decimal ? JSON.parse(x.decimal) : {};
                 x.multi_header = x.multi_header ? JSON.parse(x.multi_header) : undefined;
+                x.calc_expr = x.calc_expr ? JSON.parse(x.calc_expr) : {};
+                x.calc_order = x.calc_order ? x.calc_order.split(',') : [];
             });
             for (const d of datas) {
                 if (d.spec_set) {
@@ -284,10 +290,22 @@ module.exports = app => {
             }
             return result;
         }
+        async getCalcTestData_cost(colSet, count) {
+            const result = [];
+            for (let i = 0; i < count; i++) {
+                const testData = {};
+                colSet.forEach(x => {
+                    if (x.type === 'num') testData[x.field] = Math.max(Math.floor(Math.random()*10), 1);
+                    if (x.type === 'str') testData[x.field] = randomWord(true, 3, 6);
+                });
+                result.push(testData);
+            }
+            return result;
+        }
         async getCalcTestData(colSet, type, count = 1) {
             const funName = 'getCalcTestData_' + type;
             if (this[funName]) return await this[funName](colSet, count);
-            return null;
+            return [];
         }
 
         async _checkTemplateUsed_posCalc(template) {
@@ -305,12 +323,18 @@ module.exports = app => {
                 });
             }
         }
+        async _checkTemplateUsed_cost(template) {
+            const templates = template instanceof Array ? template : [template];
+            templates.forEach(x => { x.used = []; x.used_count = 0; });
+            // todo 检查使用情况
+        }
         async checkTemplateUsed(template, type) {
+            if (!template || template.length === 0) return;
+
             const funName = '_checkTemplateUsed_' + type;
             if (this[funName]) return await this[funName](template);
-            return false;
         }
-        // -----------------------------------------------------------------------
+        // ----------------------------------------------------------------------
 
         async _addTemplate(name, type) {
             if (ValidTemplateType.indexOf(type) < 0) throw '新增的模板类型非法';
@@ -342,6 +366,40 @@ module.exports = app => {
             if (template.create_user_id !== this.ctx.session.sessionUser.accountId) throw '非您创建的模板';
             return template;
         }
+        _getCalcLeaf(cur, cols, parentField) {
+            if (!cur || !cur.expr) return [];
+            const codeReg = /num_[a-z]{1}/gm;
+            const codeParam = cur.expr.match(codeReg);
+            if (!codeParam || codeParam.length === 0) return [];
+
+            const result = [...codeParam];
+            for (const op of codeParam) {
+                const relaCol = cols.find(x => { return x.field === op; });
+                if (relaCol.field === cur.field || op === parentField) {
+                    result.push(op);
+                } else {
+                    const sub = this._getCalcLeaf(relaCol, cols, cur.field);
+                    if (sub.length > 0) {
+                        result.push(...sub);
+                    } else {
+                        result.push(op);
+                    }
+                }
+            }
+            return this.ctx.helper._.uniq(result);
+        }
+        _getCalcExpr(cols) {
+            const calcOrder = [];
+            for (const c of cols) {
+                if (c.type !== 'Number') continue;
+                calcOrder.push({ field: c.field, expr: c.expr || '', decimal: c.decimal });
+            }
+            for (const co of calcOrder) {
+                co.leaf = this._getCalcLeaf(co, calcOrder);
+            }
+            calcOrder.sort((x, y) => {return x.leaf.length - y.leaf.length; });
+            return calcOrder;
+        }
         async _saveTemplate(id, data) {
             const org = await this.checkTemplateEdit(id);
             const updateData = { id };
@@ -360,8 +418,9 @@ module.exports = app => {
                 const decimal = { def: 2 };
                 spread_cache.cols.forEach(x => { if (x.decimal !== null && x.decimal !== undefined) decimal[x.field] = x.decimal; });
                 updateData.decimal = JSON.stringify(decimal);
-                const qtyCol = spread_cache.cols.find(x => { return x.field === 'qty'; });
-                updateData.calc_expr = qtyCol ? qtyCol.expr : '';
+                const calc_expr = this._getCalcExpr(spread_cache.cols);
+                updateData.calc_expr = JSON.stringify(calc_expr);
+                updateData.calc_order = calc_expr.map(x => { return x.field; }).join(',');
                 const specCol = data.col_set.find(x => { return x.field === 'spec' });
                 if (specCol) {
                     updateData.spec_set = specCol.spec_set;
@@ -386,6 +445,81 @@ module.exports = app => {
             if (data.update) result.update = await this._saveTemplate(data.update.id, data.update);
             return result;
         }
+        async reCalcTemplate(id, force) {
+            const data = await this.checkTemplateEdit(id);
+            const updateData = { id };
+            if (!force) {
+                await this.checkTemplateUsed(data);
+                if (data.used.length > 0) throw '模板已使用,不可修改配置!';
+            }
+            await this.analysisTemplate(data);
+
+            updateData.col_set = JSON.stringify(data.col_set);
+            updateData.multi_header = JSON.stringify(data.multi_header);
+            const spread_cache = this.calcSpreadCache(data.type, data.col_set, data.multi_header);
+            updateData.spread_cache = JSON.stringify(spread_cache);
+            const field_cache = {};
+            data.col_set.forEach(x => { field_cache[x.field] = x.title; });
+            updateData.field_cache = JSON.stringify(field_cache);
+            const decimal = { def: 2 };
+            spread_cache.cols.forEach(x => { if (x.decimal !== null && x.decimal !== undefined) decimal[x.field] = x.decimal; });
+            updateData.decimal = JSON.stringify(decimal);
+            const calc_expr = this._getCalcExpr(spread_cache.cols);
+            updateData.calc_expr = JSON.stringify(calc_expr);
+            updateData.calc_order = calc_expr.map(x => { return x.field; }).join(',');
+            const specCol = data.col_set.find(x => { return x.field === 'spec' });
+            if (specCol) {
+                updateData.spec_set = specCol.spec_set;
+                updateData.spec_rela = data.col_set.find(x => { return x.calc_code === specCol.rela_col; }).field;
+            } else {
+                updateData.spec_set = 0;
+                updateData.spec_rela = '';
+            }
+            await this.db.update(this.tableName, updateData);
+        }
+
+        _calcExpr(formula) {
+            const percentReg = /((\d+)|((\d+)(\.\d+)))%/g;
+            const percent = formula.match(percentReg);
+            if (percent) {
+                for (const p of percent) {
+                    const v = math.eval(p.replace(new RegExp('%', 'gm'), '/100'));
+                    formula = formula.replace(p, v);
+                }
+            }
+            try {
+                // 使用mathjs计算 math.eval('17259401.95*0.9') = 15533461.754999999,正确应为 15533461.755
+                // const value = math.eval(formula);
+                // 使用逆波兰法四则运算,可防止出现误差,但是只支持四则运算,不支持科学运算
+                // const value = this.ctx.helper.calcExprStrRpn(formula);
+                // 使用mathjs的大数运算,可支持所有
+                const value = parseFloat(math.eval(formula));
+                return Number.isFinite(value) ? value : 0;
+            } catch(err) {
+                return 0;
+            }
+        }
+        calcByTemplate(data, updateData, orgData, calcExpr, updateExprInfo) {
+            const codeReg = /num_[a-z]{1}/gm;
+            for (const ce of calcExpr) {
+                if (ce.expr) {
+                    let calcExpr = ce.expr;
+                    const codeParam = calcExpr.match(codeReg);
+                    for (const cp of codeParam) {
+                        calcExpr = calcExpr.replace(new RegExp(cp, 'gm'), data[cp] || orgData[cp] || 0);
+                    }
+                    if (updateExprInfo && updateExprInfo[ce.field]) updateExprInfo[ce.field] = calcExpr;
+                    try {
+                        data[ce.field] = this.ctx.helper.round(this._calcExpr(calcExpr.replace(new RegExp('%', 'gm'), '/100')), ce.decimal);
+                    } catch(err) {
+                        data[ce.field] = 0;
+                    }
+                } else {
+                    if (updateData[ce.field] === undefined) continue;
+                    data[ce.field] = this.ctx.helper.round(updateData[ce.field], ce.decimal || 2);
+                }
+            }
+        }
     }
 
     return CalcTmpl;

+ 2 - 14
app/service/pos_calc_detail.js

@@ -8,12 +8,8 @@
  * @version
  */
 const strField = ['str1', 'str2', 'str3', 'str4'];
-const numField = ['num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9'];
+const numField = ['num_a', 'num_b', 'num_c', 'num_d', 'num_e', 'num_f', 'num_g', 'num_h', 'num_i'];
 const specialField = ['spec', 'qty', 'expr'];
-const math = require('mathjs');
-math.config({
-    number: 'BigNumber',
-});
 
 module.exports = app => {
 
@@ -74,15 +70,7 @@ module.exports = app => {
                 const sv = template.specValue.find(x => { return x.spec === data.spec; });
                 data[template.spec_rela] = sv ? sv.value : 0;
             }
-            data.expr = template.calc_expr;
-            for (const nf of numField) {
-                if (updateData[nf] !== undefined && nf !== template.spec_rela) {
-                    data[nf] = this.ctx.helper.round(updateData[nf] || 0, this.getDecimal(template.decimal, nf));
-                    calc = true;
-                }
-                data.expr = data.expr.replace(new RegExp(nf, 'gm'), updateData[nf] || orgData[nf] || 0);
-            }
-            data.qty = this.ctx.helper.round(this._calcExpr(data.expr), this.getDecimal(template.decimal, 'qty'));
+            this.ctx.service.calcTmpl.calcByTemplate(data, updateData, orgData, template.calc_expr, { qty: 'expr' });
             return calc;
         }
         // 依赖前端计算

+ 2 - 0
config/web.js

@@ -2475,6 +2475,7 @@ const JsFiles = {
                 mergeFiles: [
                     '/public/js/zh_calc.js',
                     '/public/js/spreadjs_rela/spreadjs_zh.js',
+                    '/public/js/shares/ct_preview.js',
                     '/public/js/pos_calc_tmpl.js',
                 ],
                 mergeFile: 'pos_calc_tmpl',
@@ -2488,6 +2489,7 @@ const JsFiles = {
                 mergeFiles: [
                     '/public/js/zh_calc.js',
                     '/public/js/spreadjs_rela/spreadjs_zh.js',
+                    '/public/js/shares/ct_preview.js',
                     '/public/js/cost_tmpl.js',
                 ],
                 mergeFile: 'cost_tmpl',

+ 9 - 9
sql/update.sql

@@ -284,15 +284,15 @@ CREATE TABLE `zh_pos_calc_detail`  (
   `str3` varchar(255) NOT NULL DEFAULT '' COMMENT '文本3',
   `str4` varchar(255) NOT NULL DEFAULT '' COMMENT '文本4',
   `spec` varchar(50) NOT NULL DEFAULT '' COMMENT '规格',
-  `num1` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值1',
-  `num2` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值2',
-  `num3` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值3',
-  `num4` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值4',
-  `num5` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值5',
-  `num6` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值6',
-  `num7` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值7',
-  `num8` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值8',
-  `num9` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值9',
+  `num_a` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值a',
+  `num_b` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值b',
+  `num_c` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值c',
+  `num_d` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值d',
+  `num_e` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值e',
+  `num_f` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值f',
+  `num_g` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值g',
+  `num_h` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值h',
+  `num_i` decimal(24, 8) NOT NULL DEFAULT 0 COMMENT '数值i',
   PRIMARY KEY (`id`)
 );