소스 검색

指标模板页面修改

MaiXinRong 7 년 전
부모
커밋
379a0115aa

+ 2 - 0
app.js

@@ -9,7 +9,9 @@
  */
 
 const BaseController = require('./app/base/base_controller');
+const BaseService = require('./app/base/base_service');
 module.exports = app => {
     // app内定义基类,方便继承
     app.BaseController = BaseController;
+    app.BaseService = BaseService;
 }

+ 119 - 0
app/base/base_service.js

@@ -0,0 +1,119 @@
+'use strict';
+
+/**
+ * 业务逻辑基类
+ *
+ * @author Mai
+ * @date 2018/4/19
+ * @version
+ */
+
+const Service = require('egg').Service;
+
+class BaseService extends Service {
+    /**
+     * 构造函数
+     *
+     * @param {Object} ctx - egg全局context
+     * @return {void}
+     */
+    constructor(ctx) {
+        super(ctx);
+        this.db = this.app.mysql;
+    }
+
+    /**
+     * 设置表名
+     *
+     * @param {String} table - 表名
+     * @return {void}
+     */
+    set tableName(table) {
+        this._table = this.app.config.tablePrefix + table;
+    }
+
+    /**
+     * 获取表名
+     *
+     * @return {String} - 返回表名
+     */
+    get tableName() {
+        return this._table;
+    }
+
+    /**
+     * 根据id查找数据
+     *
+     * @param {Number} id - 数据库中的id
+     * @return {Object} - 返回单条数据
+     */
+    async getDataById(id) {
+        return await this.db.get(this.tableName, { id });
+    }
+
+    /**
+     * 根据条件查找单条数据
+     *
+     * @param {Object} condition - 筛选条件
+     * @return {Object} - 返回单条数据
+     */
+    async getDataByCondition(condition) {
+        return await this.db.get(this.tableName, condition);
+    }
+
+    /**
+     * 根据条件查找数据
+     *
+     * @param {Object} condition - 筛选条件
+     * @return {Array} - 返回数据
+     */
+    async getAllDataByCondition(condition) {
+        return await this.db.select(this.tableName, condition);
+    }
+
+    /**
+     * 根据id删除数据
+     *
+     * @param {Number} id - 数据库中的id
+     * @return {boolean} - 返回是否删除成功
+     */
+    async deleteById(id) {
+        const result = await this.db.delete(this.tableName, { id });
+        return result.affectedRows > 0;
+    }
+
+    /**
+     * 获取总数
+     *
+     * @param {Object} option - 过滤条件(参考select方法中的condition)
+     * @return {Number} - 返回查找的总数
+     */
+    async count(option = {}) {
+        const result = await this.db.count(this.tableName, option);
+        return result;
+    }
+
+    /**
+     * 获取分页数据
+     *
+     * @param {Object} condition - 搜索条件
+     * @return {Array} - 返回分页数据
+     */
+    async getList(condition) {
+        const page = this.ctx.page;
+
+        // 分页设置
+        condition.limit = condition.limit === undefined ? this.app.config.pageSize : condition.limit;
+        condition.offset = condition.offset === undefined ? this.app.config.pageSize * (page - 1) : condition.offset;
+
+        if (this.ctx.sort !== undefined && this.ctx.sort.length > 0) {
+            condition.orders = [this.ctx.sort];
+        }
+        const list = await this.db.select(this.tableName, condition);
+
+        return list;
+    }
+
+
+}
+module.exports = BaseService;

+ 6 - 1
app/controller/template_controller.js

@@ -17,7 +17,12 @@ module.exports = app => {
          * @return {void}
          */
         async index (ctx) {
-            await this.layout('template/index.ejs', {}, 'template/modal.ejs');
+            const node = await ctx.service.templateNode.getAllDataByCondition({template_id: 1});;
+            const treeNode = ctx.helper.convertData(node, true, 'node_id', 'node_pid');
+            const renderData = {
+                nodes: JSON.stringify(treeNode),
+            }
+            await this.layout('template/index.ejs', renderData, 'template/modal.ejs');
         }
     }
 

+ 86 - 0
app/extend/helper.js

@@ -0,0 +1,86 @@
+module.exports = {
+    /**
+     * 转换数据
+     *
+     * @param {Array} list - 数据库查找的数据
+     * @param {Boolean} tree - 是否展示为树形结构
+     * @param {String} id - id属性名
+     * @param {String} pid - pid属性名
+     * @return {Object} - 返回转换后的数据
+     */
+    convertData(list, tree = true, id, pid) {
+        const rootData = [];
+        const childData = {};
+        let listData = [];
+        for (const tmp of list) {
+            if (tmp[pid] === 0 || tmp[pid] === -1) {
+                rootData.push(tmp);
+                continue;
+            }
+            if (childData[tmp[pid]] === undefined) {
+                childData[tmp[pid]] = [];
+            }
+            childData[tmp[pid]].push(tmp);
+        }
+        // 递归组织数据
+        if (tree) {
+            this._recursionTreeData(rootData, childData, id);
+        } else {
+            this._recursionData(rootData, childData, listData, id);
+        }
+
+        return tree ? rootData : listData;
+    },
+
+    /**
+     * 递归组织数组结构数据
+     *
+     * @param {Array} parent - 父节点
+     * @param {Object} childData - 子元素(以pid为key的对象)
+     * @param {Array} outputData - 处理后的数据
+     * @param {String} id - id属性名
+     * @return {void}
+     */
+    _recursionData(parent, childData, outputData = [], id) {
+        for (const index in parent) {
+            // 父节点先进数组
+            outputData.push(parent[index]);
+            // 判断是否存在子项
+            if (childData[parent[index][id]] !== undefined) {
+                // 子项作为父节点递归查找子项中是否还有子项
+                const tmpParent = childData[parent[index][id]];
+                // 已用的子项删除
+                delete childData[parent[index][id]];
+                // 递归元素
+                this._recursionData(tmpParent, childData, outputData);
+            }
+        }
+    },
+
+    /**
+     * 递归组织树结构数据
+     *
+     * @param {Array} parent - 父节点
+     * @param {Object} childData - 子元素(以pid为key的对象)
+     * @param {String} id - id属性名
+     * @return {void}
+     */
+    _recursionTreeData(parent, childData = {}, id) {
+        if (Object.keys(childData).length <= 0) {
+            return;
+        }
+        for (const index in parent) {
+            // 判断是否存在子项
+            if (childData[parent[index][id]] !== undefined) {
+                // 子项作为父节点递归查找子项中是否还有子项
+                const tmpParent = childData[parent[index][id]];
+                // 已用的子项删除
+                delete childData[parent[index][id]];
+
+                this._recursionTreeData(tmpParent, childData);
+                // 递归完赋值回原数据
+                parent[index].children = tmpParent;
+            }
+        }
+    }
+}

+ 1 - 2
app/service/customer.js

@@ -8,11 +8,10 @@
  * @version
  */
 
-const Service = require('egg').Service;
 // 加密类
 const crypto = require('crypto');
 module.exports = app => {
-    class Customer extends Service {
+    class Customer extends app.BaseService {
         async validLogin (data) {
             let result = false;
 

+ 0 - 0
app/service/template_index.js


+ 28 - 0
app/service/template_node.js

@@ -0,0 +1,28 @@
+'use strict';
+
+/**
+ * 用户管理业务类
+ *
+ * @author Mai
+ * @date 2018/4/19
+ * @version
+ */
+
+module.exports = app => {
+    class TemplateNode extends app.BaseService {
+
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局context
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'template_node';
+        }
+
+    }
+
+    return TemplateNode;
+};

+ 4 - 0
app/view/layout/layout.ejs

@@ -9,10 +9,14 @@
     <link rel="stylesheet" href="public/css/bootstrap/bootstrap.min.css">
     <link rel="stylesheet" href="public/css/main.css">
     <link rel="stylesheet" href="public/css/font-awesome/font-awesome.min.css">
+    <!--zTree-->
+    <link rel="stylesheet" href="public/css/ztree/zTreeStyle.css" type="text/css">
 
     <script src="/public/js/jquery/jquery-3.2.1.min.js"></script>
     <script src="/public/js/popper/popper.min.js"></script>
     <script src="/public/js/bootstrap/bootstrap.min.js"></script>
+    <script type="text/javascript" src="/public/js/ztree/jquery.ztree.core.js"></script>
+    <script type="text/javascript" src="/public/js/ztree/jquery.ztree.excheck.js"></script>
 </head>
 
 <body>

+ 48 - 32
app/view/template/index.ejs

@@ -1,39 +1,55 @@
+<div class="panel-sidebar">
+    <div class="panel-title">
+        <div class="title-bar">
+            <h2 class="">项目节 <a href="#upload" data-toggle="modal" data-target="#upload" class="pull-right mr-3" title="导入项目节"><i class="fa fa-upload"></i></a></h2>
+
+        </div>
+    </div>
+    <div class="scrollbar-auto">
+        <div class="nav-box">
+            <ul id="treeDemo" class="ztree"></ul>
+        </div>
+    </div>
+</div>
 <div class="panel-content">
-    <div class="panel-title fluid">
-        <div class="title-main"><h2></h2></div>
+    <div class="panel-title">
+        <div class="title-main"><h2>z2-e-a 边沟</h2></div>
     </div>
     <div class="content-wrap">
-        <div class="c-header m-0">
+        <div class="c-header m-0 p-0 d-flex flex-row-reverse">
+            <a href="#" class="btn btn-sm"><i class="fa fa-plus"></i> 添加指标</a>
         </div>
         <div class="c-body">
-            <table class="table table-bordered">
-                <tr>
-                    <th>指标编号</th>
-                    <th>项目或费用名称</th>
-                    <th colspan="2">指标单位</th>
-                    <th>合价(元)</th>
-                    <th>计算规则</th>
-                    <th>设置规则</th>
-                </tr>
-                <tr>
-                    <td>z2-e</td>
-                    <td>排水工程</td>
-                    <td></td>
-                    <td>km</td>
-                    <td></td>
-                    <td>指路基公里长度</td>
-                    <td></td>
-                </tr>
-                <tr>
-                    <td>z2-e-1</td>
-                    <td>排水工程公路公里造价</td>
-                    <td>元</td>
-                    <td>公路公里</td>
-                    <td></td>
-                    <td>合价/路线总长度</td>
-                    <td>hj(合价)/lxzcd(路线总长度)<a href="#set-count" data-toggle="modal" data-target="#set-count"><i class="fa fa-cog"></i></a></td>
-                </tr>
-            </table>
+            <div class="sjs-height-1">
+                <table class="table table-bordered">
+                    <tr>
+                        <th>指标编号</th>
+                        <th>指标名称</th>
+                        <th colspan="2">指标单位</th>
+                        <th>计算规则</th>
+                        <th>设置规则</th>
+                    </tr>
+                    <tr>
+                        <td>z2-e-1</td>
+                        <td>排水工程公路公里造价</td>
+                        <td>元</td>
+                        <td>公路公里</td>
+                        <td>合价/路线总长度</td>
+                        <td>hj(合价)/lxzcd(路线总长度)<a href="#set-count" data-toggle="modal" data-target="#set-count"><i class="fa fa-cog"></i></a></td>
+                    </tr>
+                </table>
+            </div>
         </div>
     </div>
-</div>
+</div>
+<script type="text/javascript">
+    const treeSetting = {
+        view: {showIcon: false}
+    };
+    const treeNode = '<%- nodes %>';
+    const treeNodeData = treeNode !== '' ? JSON.parse(treeNode) : [];
+
+    $(document).ready(function(){
+        $.fn.zTree.init($("#treeDemo"), treeSetting, JSON.parse(treeNode));
+    });
+</script>

+ 22 - 0
app/view/template/modal.ejs

@@ -1,3 +1,4 @@
+<!-- 设置计算式 -->
 <div id="set-count" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
     <div class="modal-dialog">
         <div class="modal-content">
@@ -36,4 +37,25 @@
             </div>
         </div>
     </div>
+</div>
+<!-- 导入项目节 -->
+<div id="upload" class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
+    <div class="modal-dialog">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">导入项目节</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+            </div>
+            <div class="modal-body">
+                <div class="form-group">
+                    <label for="exampleFormControlFile1">上传项目节文件</label>
+                    <div class="form-control"><input class="form-control-file" id="exampleFormControlFile1" type="file"></div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button class="btn btn-primary">确认导入</button>
+                <button class="btn btn-secondary" data-dismiss="modal" aria-hidden="true">关闭</button>
+            </div>
+        </div>
+    </div>
 </div>

+ 2 - 0
config/config.default.js

@@ -44,6 +44,8 @@ module.exports = appInfo => {
         httpOnly: true,
         encrypt: true,
     };
+    // 表名前缀
+    config.tablePrefix = 'is_';
 
     // add your config here
     config.middleware = ['urlParse'];

+ 54 - 0
config/config.local.js

@@ -0,0 +1,54 @@
+'use strict';
+
+const path = require('path');
+module.exports = appInfo => {
+    const config = exports = {};
+
+    // use for cookie sign key, should change to your own and keep security
+    config.keys = appInfo.name + '_smartcost3850888';
+
+    // 数据库配置
+    config.mysql = {
+        client: {
+            // host
+            host: '127.0.0.1',
+            // 端口号
+            port: '3306',
+            // 用户名
+            user: 'root',
+            // 密码
+            password: 'admin',
+            // 数据库名
+            database: 'index_sys',
+        },
+        // 是否加载到 app 上,默认开启
+        app: true,
+        // 是否加载到 agent 上,默认关闭
+        agent: false,
+    };
+    // 表名前缀
+    config.tablePrefix = 'is_';
+
+    // view
+    config.view = {
+        mapping: {
+            '.ejs': 'ejs',
+        },
+        root: [
+            path.join(appInfo.baseDir, 'app/view'),
+        ].join(','),
+    };
+
+    // session
+    config.session = {
+        key: 'ZHC_SESS',
+        maxAge: 3600 * 1000,
+        httpOnly: true,
+        encrypt: true,
+    };
+
+    // add your config here
+    config.middleware = ['urlParse'];
+
+    return config;
+};

+ 54 - 0
config/config.qa.js

@@ -0,0 +1,54 @@
+'use strict';
+
+const path = require('path');
+module.exports = appInfo => {
+    const config = exports = {};
+
+    // use for cookie sign key, should change to your own and keep security
+    config.keys = appInfo.name + '_smartcost3850888';
+
+    // 数据库配置
+    config.mysql = {
+        client: {
+            // host
+            host: '192.168.1.139',
+            // 端口号
+            port: '3306',
+            // 用户名
+            user: 'root',
+            // 密码
+            password: 'root',
+            // 数据库名
+            database: 'index_sys',
+        },
+        // 是否加载到 app 上,默认开启
+        app: true,
+        // 是否加载到 agent 上,默认关闭
+        agent: false,
+    };
+    // 表名前缀
+    config.tablePrefix = 'is_';
+
+    // view
+    config.view = {
+        mapping: {
+            '.ejs': 'ejs',
+        },
+        root: [
+            path.join(appInfo.baseDir, 'app/view'),
+        ].join(','),
+    };
+
+    // session
+    config.session = {
+        key: 'ZHC_SESS',
+        maxAge: 3600 * 1000,
+        httpOnly: true,
+        encrypt: true,
+    };
+
+    // add your config here
+    config.middleware = ['urlParse'];
+
+    return config;
+};

+ 5 - 0
config/plugin.js

@@ -6,4 +6,9 @@
 exports.ejs = {
     enable: true,
     package: 'egg-view-ejs',
+};
+// mysql插件
+exports.mysql = {
+    enable: true,
+    package: 'egg-mysql',
 };

+ 4 - 1
package.json

@@ -9,7 +9,8 @@
     "egg-redis": "^2.0.0",
     "egg-scripts": "^2.5.0",
     "egg-view": "^2.1.0",
-    "egg-view-ejs": "^2.0.0"
+    "egg-view-ejs": "^2.0.0",
+    "node-xlsx": "^0.12.0"
   },
   "devDependencies": {
     "autod": "^3.0.1",
@@ -28,6 +29,8 @@
     "start": "egg-scripts start --daemon --title=egg-server-index_sys",
     "stop": "egg-scripts stop --title=egg-server-index_sys",
     "dev": "egg-bin dev",
+    "dev-qa": "set EGG_SERVER_ENV=qa && egg-bin dev",
+    "dev-local": "set EGG_SERVER_ENV=local && egg-bin dev",
     "debug": "egg-bin debug",
     "test": "npm run lint -- --fix && npm run test-local",
     "test-local": "egg-bin test",