Browse Source

标段管理和期计量更新

laiguoran 7 years ago
parent
commit
6a3fa2b18f

+ 6 - 3
app/base/base_controller.js

@@ -25,8 +25,8 @@ class BaseController extends Controller {
         this.jsValidator = this.app.jsValidator;
         // 当前菜单
         ctx.menu = menuList[ctx.controllerName] === undefined ? {} : menuList[ctx.controllerName];
-        ctx.title = '';
-        if (ctx.menu.children !== undefined) {
+        ctx.title = ctx.menu === {} ? '' : ctx.menu.name;
+        if (ctx.menu !== {} && ctx.menu.children !== null) {
             for (const index in ctx.menu.children) {
                 if (index === ctx.actionName) {
                     ctx.title = ctx.menu.children[index].name;
@@ -60,7 +60,10 @@ class BaseController extends Controller {
             message: JSON.stringify(message),
             dropDownMenu: data.dropDownMenu === undefined ? [] : data.dropDownMenu,
             breadCrumb: data.breadCrumb === undefined ? '' : data.breadCrumb,
-            tenderList: data.tenderList === undefined ? [] : data.tenderList
+            tenderList: data.tenderList === undefined ? [] : data.tenderList,
+            tenderInfo: data.tenderInfo === undefined ? [] : data.tenderInfo,
+            tenderType: data.tenderType === undefined ? '' : data.tenderType,
+            tenderConst: data.tenderConst === undefined ? [] : data.tenderConst,
         };
         await this.ctx.render('layout/layout.ejs', renderData);
     }

+ 4 - 0
app/const/tender.js

@@ -19,10 +19,14 @@ statusString[status.APPROVAL] = '审批中';
 // 标段类型
 const type = {
     TJ: 1,
+    XX: 2,
+    YY: 3
 };
 
 const typeString = [];
 typeString[type.TJ] = '土建标';
+typeString[type.XX] = 'XX标';
+typeString[type.YY] = 'YY标';
 
 module.exports = {
     status,

+ 32 - 1
app/controller/measure_controller.js

@@ -22,7 +22,7 @@ module.exports = app => {
             super(ctx);
             ctx.showProject = true;
             ctx.showTender = true;
-            ctx.showTitle = false;
+            ctx.showTitle = true;
         }
 
         /**
@@ -36,6 +36,37 @@ module.exports = app => {
             await this.layout('measure/middle.ejs', renderData);
         }
 
+        /**
+         * 期计量页面
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async stage(ctx) {
+            if (ctx.request.query.tenderId) {
+                const tenderId = parseInt(ctx.request.query.tenderId);
+                const tender = await ctx.service.tender.getDataById(tenderId);
+                ctx.session.sessionUser.tenderId = tender.id;
+                ctx.session.sessionUser.tenderName = tender.name;
+
+                ctx.redirect('/measure/stage');
+            } else {
+                let tenderId = ctx.session.sessionUser.tenderId;
+                const tenderInfo = await ctx.service.tender.getDataById(tenderId);
+                const tenderList = await ctx.service.tender.getList();
+                for (const tender of tenderList) {
+                    tender.url = ctx.menuList.measure.children.stage.url + '?tenderId=' + tender.id;
+                }
+                const renderData = {
+                    tenderInfo,
+                    tenderList
+                };
+
+                await this.layout('measure/stage.ejs', renderData);
+            }
+
+        }
+
     }
 
     return MeasureController;

+ 86 - 1
app/controller/tender_controller.js

@@ -36,12 +36,15 @@ module.exports = app => {
             const rule = ctx.service.tender.rule('add');
             const jsValidator = await this.jsValidator.convert(rule).build();
 
+            let tenderType = ctx.query.type;
+
             // 根据项目id获取标段数据
-            const tenderList = await ctx.service.tender.getList();
+            const tenderList = await ctx.service.tender.getList(tenderType);
             const renderData = {
                 tenderList,
                 tenderConst,
                 jsValidator,
+                tenderType
             };
             await this.layout('tender/index.ejs', renderData);
         }
@@ -68,6 +71,88 @@ module.exports = app => {
 
             ctx.redirect(ctx.request.headers.referer);
         }
+
+        /**
+         * 切换标段 --》 暂时废弃,不存在此功能
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async switchTender(ctx) {
+            let tenderId = ctx.params.tenderId;
+            tenderId = parseInt(tenderId);
+            try{
+                if(isNaN(tenderId) || tenderId <= 0) {
+                    throw '参数错误';
+                }
+                const result = await ctx.service.tender.switchTender(tenderId);
+                if (!result) {
+                    throw '切换标段失败!';
+                }
+            } catch (error) {
+                this.setMessage(error.toString(), this.messageType.ERROR);
+            }
+            ctx.redirect(ctx.request.headers.referer);
+        }
+
+        /**
+         * 保存标段操作
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        async save(ctx) {
+            let id = ctx.request.body.tenderId;
+            id = parseInt(id);
+
+            try {
+                if (isNaN(id) || id < 0) {
+                    throw '参数错误';
+                }
+                // 获取数据规则
+                const rule = ctx.service.tender.rule('save');
+                ctx.validate(rule);
+
+                const result = await ctx.service.tender.save(ctx.request.body, id);
+
+                if (!result) {
+                    throw '保存标段数据失败';
+                }
+
+                this.setMessage('保存标段数据成功', this.messageType.SUCCESS);
+            } catch (error) {
+                this.setMessage(error.toString(), this.messageType.ERROR);
+            }
+            ctx.redirect(ctx.request.headers.referer);
+        }
+
+        /**
+         * 删除标段
+         *
+         * @param {Object} ctx -egg全局变量
+         * @return {void}
+         */
+        async delete(ctx) {
+            let id = ctx.request.body.tenderId;
+            id = parseInt(id);
+
+            try {
+                if (isNaN(id) || id <= 0) {
+                    throw '参数错误';
+                }
+                const result = ctx.service.tender.deleteTenderById(id);
+
+                if (!result) {
+                    throw '删除标段失败';
+                }
+
+                this.setMessage('删除标段成功', this.messageType.SUCCESS);
+            } catch (error) {
+                this.setMessage(error.toString(), this.messageType.ERROR);
+            }
+
+            ctx.redirect(ctx.request.headers.referer);
+        }
     }
 
     return TenderController;

+ 19 - 1
app/public/js/tender.js

@@ -126,4 +126,22 @@ option = {
 
 // 为echarts对象加载数据
 myChart.setOption(option);
-//3 标段计量分布//
+//3 标段计量分布//
+
+$(document).ready(function() {
+    //标段类型选择
+    $('#tender_type_select').change(function () {
+        const type = $(this).val() != 0 ? '/?type='+$(this).val() : '';
+        window.location.href = '/tender' + type;
+    });
+    //编辑标段 选择
+    $('.save-btn').on('click',function () {
+        $('#saveid').val($(this).attr('tender-id'));
+        $('#savename').val($(this).attr('tender-name'));
+        $('#savetype').val($(this).attr('tender-type'));
+    });
+    //删除标段 选择
+    $('.del-btn').on('click',function () {
+        $('#delid').val($(this).attr('tender-id'));
+    });
+});

+ 4 - 0
app/router.js

@@ -52,9 +52,13 @@ module.exports = app => {
     // 标段管理相关
     app.get('/tender', sessionAuth, 'tenderController.index');
     app.post('/tender/add', sessionAuth, datetimeFill, 'tenderController.add');
+    app.get('/tender/switch/:tenderId', sessionAuth, 'tenderController.switchTender');
+    app.post('/tender/save', sessionAuth, datetimeFill, 'tenderController.save');
+    app.post('/tender/delete', sessionAuth, datetimeFill, 'tenderController.delete');
 
     // 计量管理相关
     app.get('/measure/middle', sessionAuth, 'measureController.middle');
+    app.get('/measure/stage', sessionAuth, 'measureController.stage');
 
     //标准库相关
     app.post('/std/bills/get-data', sessionAuth, 'stdBillsController.getData');

+ 112 - 33
app/service/tender.js

@@ -22,6 +22,22 @@ module.exports = app => {
         constructor(ctx) {
             super(ctx);
             this.tableName = 'tender';
+
+            // 状态相关
+            this.status = {
+                TRY: 1,
+                NORMAL: 2,
+                DISABLE: 3,
+            };
+            this.displayStatus = [];
+            this.displayStatus[this.status.TRY] = '试用';
+            this.displayStatus[this.status.NORMAL] = '正常';
+            this.displayStatus[this.status.DISABLE] = '禁用';
+
+            this.statusClass = [];
+            this.statusClass[this.status.TRY] = 'warning';
+            this.statusClass[this.status.NORMAL] = 'success';
+            this.statusClass[this.status.DISABLE] = 'danger';
         }
 
         /**
@@ -39,6 +55,11 @@ module.exports = app => {
                         type: { type: 'string', required: true, min: 1 },
                     };
                     break;
+                case 'save':
+                    rule = {
+                        name: { type: 'string', required: true, min: 2 },
+                        type: { type: 'string', required: true, min: 1 },
+                    };
                 default:
                     break;
             }
@@ -49,9 +70,10 @@ module.exports = app => {
         /**
          * 获取标段列表
          *
+         * @param {Object} type - 标段类型
          * @return {Array} - 返回标段数据
          */
-        async getList() {
+        async getList(type = 0) {
             // 获取当前项目信息
             const sessionProject = this.ctx.session.sessionProject;
             this.initSqlBuilder();
@@ -59,6 +81,12 @@ module.exports = app => {
                 value: sessionProject.id,
                 operate: '=',
             });
+            if(type !== 0) {
+                this.sqlBuilder.setAndWhere('type', {
+                    value: type,
+                    operate: '=',
+                });
+            }
             this.sqlBuilder.limit = 10;
             this.sqlBuilder.columns = ['id', 'name', 'status', 'type'];
             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName);
@@ -73,46 +101,97 @@ module.exports = app => {
          * @return {Boolean} - 返回新增结果
          */
         async add(postData) {
-            let result = false;
-            this.transaction = await this.db.beginTransaction();
-            try {
-                // 获取当前用户信息
-                const sessionUser = this.ctx.session.sessionUser;
-                // 获取当前项目信息
-                const sessionProject = this.ctx.session.sessionProject;
-
-                const insertData = {
-                    name: postData.name,
-                    status: tenderConst.status.APPROVAL,
-                    project_id: sessionProject.id,
-                    user_id: sessionUser.accountId,
-                    create_time: postData.create_time,
-                    type: postData.type,
-                };
-                const operate = await this.transaction.insert(this.tableName, insertData);
+            // 获取当前用户信息
+            const sessionUser = this.ctx.session.sessionUser;
+            // 获取当前项目信息
+            const sessionProject = this.ctx.session.sessionProject;
+            const insertData = {
+                name: postData.name,
+                status: tenderConst.status.APPROVAL,
+                project_id: sessionProject.id,
+                user_id: sessionUser.accountId,
+                create_time: postData.create_time,
+                type: postData.type,
+            };
+            const operate = await this.db.insert(this.tableName, insertData);
+            return operate.insertId > 0;
+        }
 
-                result = operate.insertId > 0;
-                if (!result) {
-                    throw '新增标段数据失败';
-                }
+        /**
+         * 保存标段
+         *
+         * @param {Object} postData - 表单post过来的数据
+         * @param {Number} id - 用于判断修改还是新增的id
+         * @return {Boolean} - 返回执行结果
+         */
+        async save(postData,id = 0) {
+            id = parseInt(id);
 
-                // 获取标段项目节点模板
-                const tenderNodeTemplateData = await this.ctx.service.tenderNodeTemplate.getData();
-                // 复制模板数据到标段数据表
-                result = await this.ctx.service.ledger.innerAdd(tenderNodeTemplateData, operate.insertId, this.transaction);
+            const rowData = {
+                id: id,
+                name: postData.name,
+                type: postData.type,
+            };
+            const result = await this.db.update(this.tableName, rowData);
+            return result.affectedRows > 0;
+        }
 
-                if (!result) {
-                    throw '新增标段项目节点失败';
+        /**
+         * 假删除
+         *
+         * @param {Number} id - 删除的id
+         * @return {Boolean} - 删除结果
+         */
+        async deleteTenderById(id) {
+
+            const updateData = {
+                status: this.status.DISABLE,
+                id,
+            };
+
+            const result = this.db.update(this.tableName, updateData);
+
+            return result.affectedRows > 0;
+        }
+
+        /**
+         * 切换标段
+         *
+         * @param {Number} tenderId - 标段id
+         * @return {Boolean} - 返回切换结果
+         */
+        async switchTender(tenderId) {
+            // 获取该用户拥有的项目数据
+            const sessionUser = this.ctx.session.sessionUser;
+            const tenderInfo = await this.ctx.service.projectAccount.getProjectInfoByAccount(sessionUser.account);
+
+            let result = false;
+            // 判断切换的标段是否属于对应用户
+            if (tenderInfo.length < 0) {
+                return result;
+            }
+
+            let targetTender = {};
+            for (const tmp of tenderInfo) {
+                if (tmp.id === tenderId) {
+                    result = true;
+                    targetTender = tmp;
                 }
-                this.transaction.commit();
-            } catch (error) {
-                result = false;
-                this.transaction.rollback();
             }
+
+            // 成功后更改session
+            if (result) {
+                this.ctx.session.sessionTender = {
+                    id: targetTender.id,
+                    name: targetTender.name,
+                    userAccount: targetTender.user_account,
+                };
+            }
+
             return result;
         }
 
     }
 
     return Tender;
-};
+};

+ 106 - 23
app/view/layout/modal.ejs

@@ -1,3 +1,45 @@
+<!--弹出编辑权限-->
+<div class="modal fade" id="permission-form" 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>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary" id="modify-permission">提交修改</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+<!--弹出新建台帐变更-->
+<div class="modal fade" id="add-bg" 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">
+                    <label>变更编号<b class="text-danger">*</b></label>
+                    <input class="form-control"  value="0006" type="text" readonly>
+                </div>
+                <div class="form-group">
+                    <label>变更名称<b class="text-danger">*</b></label>
+                    <input class="form-control"  placeholder="输入标段名称" type="text">
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                <button type="button" class="btn btn-primary">确定新建</button>
+            </div>
+        </div>
+    </div>
+</div>
+<% if(ctx.controllerName == 'tender' && ctx.actionName == '')  { %>
 <!--弹出添加标段-->
 <div class="modal fade" id="add-bd" data-backdrop="static">
     <div class="modal-dialog" role="document">
@@ -14,9 +56,9 @@
                     <div class="form-group">
                         <label>标段类型</label>
                         <select class="form-control" name="type">
-                            <option value="1">土建标</option>
-                            <option value="2">XX标</option>
-                            <option value="3">YY标</option>
+                            <% for(const index in tenderConst.typeString) { %>
+                            <option value="<%= index %>"<% if(tenderType == index) { %> selected<% } %>><%= tenderConst.typeString[index] %></option>
+                            <% } %>
                         </select>
                     </div>
                 </div>
@@ -30,44 +72,85 @@
     </div>
 </div>
 
-<!--弹出编辑权限-->
-<div class="modal fade" id="permission-form" data-backdrop="static">
+<!--弹出编辑标段-->
+<div class="modal fade" id="save-bd" 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">
+        <form method="post" action="/tender/save">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">编辑标段</h5>
+                </div>
+                <div class="modal-body">
+                    <div class="form-group">
+                        <label>标段名称<b class="text-danger">*</b></label>
+                        <input class="form-control" value="" id="savename" name="name" placeholder="输入标段名称" type="text">
+                    </div>
+                    <div class="form-group">
+                        <label>标段类型</label>
+                        <select class="form-control" name="type" id="savetype">
+                            <% for(const index in tenderConst.typeString) { %>
+                            <option value="<%= index %>"<% if(tenderType == index) { %> selected<% } %>><%= tenderConst.typeString[index] %></option>
+                            <% } %>
+                        </select>
+                    </div>
+                </div>
+                <div class="modal-footer">
+                    <input type="hidden" name="_csrf" value="<%= ctx.csrf %>"/>
+                    <input type="hidden" name="tenderId" value="" id="saveid">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <button type="submit" class="btn btn-primary">确定修改</button>
+                </div>
             </div>
-            <div class="modal-footer">
-                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-primary" id="modify-permission">提交修改</button>
+        </form>
+    </div>
+</div>
+
+<!--删除标段-->
+<div class="modal fade" id="del-bd" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <form method="post" action="/tender/delete">
+            <div class="modal-content">
+                <div class="modal-header">
+                    <h5 class="modal-title">确认删除标段</h5>
+                </div>
+                <div class="modal-body">
+                    <h5>删除后,数据无法恢复,请谨慎操作。</h5>
+                </div>
+                <div class="modal-footer">
+                    <input type="hidden" name="_csrf" value="<%= ctx.csrf %>"/>
+                    <input type="hidden" name="tenderId" value="" id="delid">
+                    <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+                    <button type="submit" class="btn btn-danger">确定删除</button>
+                </div>
             </div>
-        </div>
+        </form>
     </div>
 </div>
+<% } %>
 
-<!--弹出新建台帐变更-->
-<div class="modal fade" id="add-bg" data-backdrop="static">
+<% if(ctx.controllerName == 'measure' && ctx.actionName == 'stage')  { %>
+<!--弹出添加标段-->
+<div class="modal fade" id="add-qi" data-backdrop="static">
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-header">
-                <h5 class="modal-title">新建变更</h5>
+                <h5 class="modal-title">添加新一期</h5>
             </div>
             <div class="modal-body">
                 <div class="form-group">
-                    <label>变更编号<b class="text-danger">*</b></label>
-                    <input class="form-control"  value="0006" type="text" readonly>
+                    <label></label>
+                    <input class="form-control" value="第 4 期" type="text">
                 </div>
                 <div class="form-group">
-                    <label>变更名称<b class="text-danger">*</b></label>
-                    <input class="form-control"  placeholder="输入标段名称" type="text">
+                    <label>计量月份</label>
+                    <input class="form-control" type="month">
                 </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-primary">确定新建</button>
+                <button type="button" class="btn btn-primary">确定添加</button>
             </div>
         </div>
     </div>
-</div>
+</div>
+<% } %>

+ 164 - 0
app/view/measure/stage.ejs

@@ -0,0 +1,164 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main  d-flex justify-content-between">
+            <div>
+            </div>
+            <div>
+                <a href="#add-qi" data-toggle="modal" data-target="#add-qi" class="btn btn-primary btn-sm pull-right">添加期</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <!--期汇总图表-->
+            <div id="chartContainer4" style="height: 300px; width: 100%;" class="mb-4">
+            </div>
+            <table class="table table-bordered">
+                <thead>
+                <tr>
+                    <th>期数</th>
+                    <th class="text-center">计量月份</th>
+                    <th class="text-center">本期合同计量</th>
+                    <th class="text-center">本期数量变更计量</th>
+                    <th class="text-center">截止上期累计完成</th>
+                    <th class="text-center">本期完成计量</th>
+                    <th class="text-center">累计完成计量</th>
+                    <th class="text-center">状态</th>
+                </tr>
+                </thead>
+                <tbody>
+                <tr>
+                    <td><a href="jiliang-qi-detail.html">第 4 期</a></td>
+                    <td class="text-center">201710</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-cenetr">待上报</td>
+                </tr>
+                <tr>
+                    <td><a href="jiliang-qi-detail.html">第 3 期</a></td>
+                    <td class="text-center">201710</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-cenetr"><a href="" class="btn btn-primary btn-sm">审批</a></td>
+                </tr>
+                <tr>
+                    <td><a href="jiliang-qi-detail.html">第 2 期</a></td>
+                    <td class="text-center">201710</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-cenetr text-warning">审批中</td>
+                </tr>
+                <tr>
+                    <td><a href="jiliang-qi-detail.html">第 1 期</a></td>
+                    <td class="text-center">201710</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-right">34234234.00</td>
+                    <td class="text-cenetr text-success">审批完成</td>
+                </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+<script src=/public/js/echarts/echarts.min.js></script>
+<script type="text/javascript">
+    //4 标段期数计量进度//
+    var myChart = echarts.init(document.getElementById('chartContainer4'));
+    var option = {
+        color: ['#e9af68','#57b7b6','#e4575a','#959eac','#6699FF',
+            '#d38b70','#8fb7cf','#cd5c5c','#ffa500','#40e0d0',
+            '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
+            '#5c616b','#ff6666','#3cb371','#b8860b','#30e0e0'],
+        tooltip : {
+            trigger: 'axis'
+        },
+        calculable : true,
+        legend: {
+            data:['本期合同计量','本期数量变更计量','截至上期累计完成','本期完成计量','完成度']
+        },
+        dataZoom: [
+            {show: true,start: 0, end: 100}
+        ],
+        xAxis : [
+            {
+                type : 'category',
+                splitLine : {show : true},
+                data : ['第一期','第二期','第三期','第四期','第五期','第六期','第七期']
+            }
+        ],
+        yAxis : [
+            {
+                type : 'value',
+                name : '金额',
+                position:'left',
+                axisLabel : {
+                    formatter: '{value} 元'
+                },
+                splitArea : {show : true}
+            },
+            {
+                type : 'value',
+                name:'完成度',
+                axisLabel : {
+                    formatter: '{value} %'
+                },
+                position: 'right',
+                splitArea : {show : true}
+            }
+        ],
+        series : [
+            {
+                name:'本期合同计量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '合同',
+                data:[320, 332, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'本期数量变更计量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '合同',
+                data:[320, -20, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'截至上期累计完成',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '完成',
+                data:[120, 132, 101, 134, 90, 230, 210]
+            },
+            {
+                name:'本期完成计量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '完成',
+                data:[220, 182, 191, 234, 290, 330, 310]
+            },
+            {
+                name:'完成度',
+                type:'line',
+                tooltip : {trigger: 'axis',formatter: "{b}占总标段<br/>{a}:{c} %"},
+                yAxisIndex: 1,
+                data:[10, 15, 20, 13, 11, 9, 5]
+            },
+        ]
+    };
+
+    // 为echarts对象加载数据
+    myChart.setOption(option);
+    //4 标段期数计量进度//
+
+</script>

+ 2 - 2
app/view/project/info.ejs

@@ -26,9 +26,9 @@
                                     <h6 class="card-subtitle mb-2 text-muted"><%= officeList[salesmanData.office] !== undefined ? officeList[salesmanData.office] : '' %></h6>
                                 </div>
                                 <ul class="list-group list-group-flush">
-                                    <li class="list-group-item" data-toggle="tooltip" data-placement="bottom" title="腾讯QQ"><i class="fa fa-qq"></i> 914630468</li>
+                                    <li class="list-group-item" data-toggle="tooltip" data-placement="bottom" title="腾讯QQ"><i class="fa fa-qq"></i> <%= salesmanData.qq %></li>
                                     <li class="list-group-item" data-toggle="tooltip" data-placement="bottom" title="手机号码"><i class="fa fa-tablet"></i> <%= salesmanData.telephone %></li>
-                                    <li class="list-group-item" data-toggle="tooltip" data-placement="bottom" title="固定电话"><i class="fa fa-phone"></i> 0756-3850891</li>
+                                    <li class="list-group-item" data-toggle="tooltip" data-placement="bottom" title="固定电话"><i class="fa fa-phone"></i> <%= salesmanData.fixedphone %></li>
                                 </ul>
                             </div>
                         </div>

+ 268 - 0
app/view/tender/detail.ejs

@@ -0,0 +1,268 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main  d-flex justify-content-between">
+            <div>
+                <div class="btn-group">
+                    <a href="/tender">返回 </a>
+                </div>
+            </div>
+            <div>
+                <a href="#add-bd" data-toggle="modal" data-target="#save-bd" class="btn btn-outline-primary btn-sm">编辑</a> <a href="#del-bd" data-toggle="modal" data-target="#del-bd" class="btn btn-outline-danger btn-sm">删除</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <table class="table table-bordered table-sm">
+                <thead><th width="300">名称</th><th width="120">标段类型</th><th width="120">审批状态</th><th width="120">创建时间</th><th>计量进度</th></thead>
+                <tr><td><%= tenderInfo.name %></td>
+                    <td><%= tenderConst.typeString[tenderInfo.type] %></td>
+                    <td><%= tenderConst.statusString[tenderInfo.status] %></td>
+                    <td><%= tenderInfo.create_time > 0 ? moment(tenderInfo.create_time * 1000).format('YYYY-MM-DD') : '-' %></td>
+                    <td>
+                        <div class="progress">
+                            <div class="progress-bar bg-success" style="width: 45%;" data-placement="bottom" data-toggle="tooltip" data-original-title="截止本期累计完成:¥731,121,121.00">45%</div>
+                            <div class="progress-bar bg-info" style="width:25%;" data-placement="bottom" data-toggle="tooltip" data-original-title="本期完成:¥31,121,121.00">25%</div>
+                            <div class="progress-bar bg-gray" style="width:30%;" data-placement="bottom" data-toggle="tooltip" data-original-title="未完成:¥71,121,121.00">30%</div>
+                        </div>
+                    </td>
+                </tr>
+            </table>
+            <table class="table table-bordered table-sm">
+                <thead>
+                <th width="120">计量期数</th>
+                <th>0号台帐合同</th>
+                <th>本期完成</th>
+                <th>截止本期合同</th>
+                <th>截止本期变更</th>
+                <th>截止本期完成</th>
+                <th>截止上期完成</th>
+                <th>本期应付</th>
+                </thead>
+                <tr>
+                    <td>15 <a href="jiliang-qi.html" target="_balnk"><i class="fa fa-ellipsis-h"></i></a></td>
+                    <td>0</td>
+                    <td>0</td>
+                    <td>0</td>
+                    <td>0</td>
+                    <td>0</td>
+                    <td>0</td>
+                    <td>0</td>
+                </tr>
+            </table>
+            <!--图表1-->
+            <div id="chartContainer1" style="height: 400px; width: 100%;" class="mt-5">
+            </div>
+            <!--图表3-->
+            <div id="chartContainer3" style="height: 400px; width: 100%;" class="mt-5">
+            </div>
+            <!--图表2-->
+            <div id="chartContainer2" style="height: 600px; width: 100%;">
+            </div>
+        </div>
+    </div>
+</div>
+<script src=/public/js/echarts/echarts.min.js></script>
+<script type="text/javascript">
+    //1 标段期数计量进度//
+    var myChart = echarts.init(document.getElementById('chartContainer1'));
+    var option = {
+        color: ['#e9af68','#57b7b6','#e4575a','#959eac','#6699FF',
+            '#d38b70','#8fb7cf','#cd5c5c','#ffa500','#40e0d0',
+            '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
+            '#5c616b','#ff6666','#3cb371','#b8860b','#30e0e0'],                  title : {
+            text: '期进度',
+            x:'left'
+        },
+        tooltip : {
+            trigger: 'axis'
+        },
+        calculable : true,
+        legend: {
+            data:['本期合同计量','本期数量变更计量','截至上期累计完成','本期完成计量','完成度']
+        },
+        dataZoom : {
+            show : true,
+            start :0,
+            end : 100
+        },
+        xAxis : [
+            {
+                type : 'category',
+                splitLine : {show :true},
+                data : ['第一期','第二期','第三期','第四期','第五期','第六期','第七期']
+            }
+        ],
+        yAxis : [
+            {
+                type : 'value',
+                position: 'left',
+                splitArea : {show : true}
+            },
+            {
+                type : 'value',
+                name:'完成度',
+                axisLabel : {
+                    formatter: '{value} %'
+                },
+                position: 'right',
+                splitLine : {show :false},
+                splitArea : {show : false}
+            }
+        ],
+        series : [
+            {
+                name:'本期合同计量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '合同',
+                data:[320, 332, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'本期数量变更计量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '合同',
+                data:[320, -20, 301, 334, 390, 330, 320]
+            },
+            {
+                name:'截至上期累计完成',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '完成',
+                data:[120, 132, 101, 134, 90, 230, 210]
+            },
+            {
+                name:'本期完成计量',
+                type:'bar',
+                tooltip : {trigger: 'item',formatter: "{b}  <br/>{a}:{c}元"},
+                stack: '完成',
+                data:[220, 182, 191, 234, 290, 330, 310]
+            },
+            {
+                name:'完成度',
+                type:'line',
+                tooltip : {trigger: 'axis',formatter: "{b}占总标段<br/>{a}:{c} %"},
+                yAxisIndex: 1,
+                data:[10, 15, 20, 13, 11, 9, 5]
+            },
+        ]
+    };
+
+    // 为echarts对象加载数据
+    myChart.setOption(option);
+    //1 标段期数计量进度//
+    //2 期数组成//
+    var myChart = echarts.init(document.getElementById('chartContainer2'));
+    var option = {
+        color: ['#e9af68','#57b7b6','#e4575a','#959eac','#6699FF',
+            '#d38b70','#8fb7cf','#cd5c5c','#ffa500','#40e0d0',
+            '#1e90ff','#ff6347','#7b68ee','#00fa9a','#ffd700',
+            '#5c616b','#ff6666','#3cb371','#b8860b','#30e0e0'],
+        title : {
+            text: '期完成占比',
+            x:'left'
+        },
+
+        tooltip : {
+            trigger: 'item',
+            formatter: "{a} <br/>{b}:{c} 元<br>占标段:{d} %"
+        },
+        calculable : true,
+        series : [
+            {
+                name:'标段计量分布',
+                type:'pie',
+                radius : '80%',
+                center: ['50%','50%'],
+                data:[
+                    {value:7814964.00, name:'第一期'},
+                    {value:6043186.10, name:'第二期'},
+                    {value:6917475.00, name:'第三期'},
+                    {value:7634982.00, name:'第四期'},
+                    {value:7634982.00, name:'第五期'},
+                    {value:7634982.00, name:'第六期'},
+                    {value:7634982.00, name:'第七期'}
+                ]
+            }
+        ]
+    };
+    // 为echarts对象加载数据
+    myChart.setOption(option);
+    //2 期数组成//
+    //3 标段计量分布//
+    var myChart = echarts.init(document.getElementById('chartContainer3'));
+    var option = {
+        color:['#ff6666','#3cb371'],
+        title : {
+            text: '期月进度'
+        },
+        tooltip : {
+            trigger: 'axis',
+            formatter: "{b} <br/>{a}:{c} %<br/>{a1}:{c1} %"
+        },
+        legend: {
+            data:['累计完成','本月完成']
+        },
+        dataZoom : {
+            show : true,
+            start :50,
+            end : 100
+        },
+        xAxis : [
+            {
+                type : 'category',
+                boundaryGap : true,
+                data : [
+                    '2017-01','2017-02','2017-03','2017-04','2017-05','2017-06','2017-07','2017-08','2017-09'
+                ]
+            }
+        ],
+        yAxis : [
+            {
+                type : 'value',
+                axisLabel : {
+                    formatter: '{value} %'
+                },
+                splitArea : {show : true}
+            }
+        ],
+        series : [
+            {
+                name:'累计完成',
+                type:'line',
+                itemStyle: {
+                    normal: {
+                        lineStyle: {
+                            shadowColor : 'rgba(0,0,0,0.4)',
+                            shadowBlur: 5,
+                            shadowOffsetX: 3,
+                            shadowOffsetY: 3
+                        }
+                    }
+                },
+                data:[10, 10, 30, 40, 50, 60, 80, 85, 100]
+            },
+            {
+                name:'本月完成',
+                type:'line',
+                itemStyle: {
+                    normal: {
+                        lineStyle: {
+                            shadowColor : 'rgba(0,0,0,0.4)',
+                            shadowBlur: 5,
+                            shadowOffsetX: 3,
+                            shadowOffsetY: 3
+                        }
+                    }
+                },
+                data:[10, 0, 20, 10, 10, 10, 10, 5, 15]
+            }
+        ]
+    };
+
+
+    // 为echarts对象加载数据
+    myChart.setOption(option);
+    //3 标段计量分布//
+</script>

+ 49 - 19
app/view/tender/index.ejs

@@ -2,6 +2,14 @@
     <div class="panel-title fluid">
         <div class="title-main  d-flex justify-content-between">
             <div>
+                <div class="btn-group mr-2">
+                    <select class="form-control form-control-sm m-0" id="tender_type_select">
+                        <option value="0">标段类型筛选</option>
+                        <% for(const index in tenderConst.typeString) { %>
+                        <option value="<%= index %>"<% if(tenderType == index) { %> selected<% } %>><%= tenderConst.typeString[index] %></option>
+                        <% } %>
+                    </select>
+                </div>
                 <div class="btn-group">
                     <div class="form-check-inline">
                         <label class="form-check-label">
@@ -11,12 +19,12 @@
                     </div>
                 </div>
                 <div class="btn-group">
-                    <select class="form-control form-control-sm m-0">
-                        <option>标段类型筛选</option>
-                        <% for(const index in tenderConst.typeString) { %>
-                        <option value="<%= index %>"><%= tenderConst.typeString[index] %></option>
-                        <% } %>
-                    </select>
+                    <div class="form-check-inline">
+                        <label class="form-check-label">
+                            <input class="form-check-input" type="checkbox">
+                            管理标段
+                        </label>
+                    </div>
                 </div>
             </div>
             <div>
@@ -26,6 +34,17 @@
     </div>
     <div class="content-wrap">
         <div class="c-body">
+            <!--图表-->
+            <div class="row mb-5">
+                <div class="col-4">
+                    <!--图表1-->
+                    <div id="chartContainer1" style="width:100%;height:300px"></div>
+                </div>
+                <div class="col-8">
+                    <!--图表2-->
+                    <div id="chartContainer2" style="width:100%;height:300px"></div>
+                </div>
+            </div>
             <!--默认-->
             <table class="table table-bordered table-sm">
                 <thead>
@@ -44,7 +63,7 @@
                 <% if(tenderList.length > 0) { %>
                 <% tenderList.forEach(function(tender) { %>
                 <tr>
-                    <td><a href="biaoduan-detail.html"><%= tender.name %></a></td>
+                    <td><a href="/measure/stage/?tenderId=<%= tender.id %>"><%= tender.name %></a></td>
                     <td><%= tenderConst.typeString[tender.type] %></td>
                     <td>15</td>
                     <td><%= tenderConst.statusString[tender.status] %></td>
@@ -71,7 +90,7 @@
                 <% if(tenderList.length > 0) { %>
                 <% tenderList.forEach(function(tender) { %>
                 <tr>
-                    <td><a href="biaoduan-detail.html"><%= tender.name %></a></td>
+                    <td><a href="/measure/stage/?tenderId=<%= tender.id %>"><%= tender.name %></a></td>
                     <td><%= tenderConst.typeString[tender.type] %></td>
                     <td>15</td>
                     <td>¥5,000,000.00</td>
@@ -92,17 +111,28 @@
                 <% }) %>
                 <% } %>
             </table>
-            <!--按标段类型筛选后,增加显示图表-->
-            <div class="row mt-5">
-                <div class="col-4">
-                    <!--图表1-->
-                    <div id="chartContainer1" style="width:100%;height:400px"></div>
-                </div>
-                <div class="col-8">
-                    <!--图表2-->
-                    <div id="chartContainer2" style="width:100%;height:400px"></div>
-                </div>
-            </div>
+            <!--管理标段-->
+            <table class="table table-bordered table-sm">
+                <thead>
+                <th>名称</th>
+                <th width="120">标段类型</th>
+                <th width="120">完成期数</th>
+                <th>操作</th>
+                </thead>
+                <% if(tenderList.length > 0) { %>
+                <% tenderList.forEach(function(tender) { %>
+                <tr>
+                    <td><a href="/measure/stage/?tenderId=<%= tender.id %>"><%= tender.name %></a></td>
+                    <td><%= tenderConst.typeString[tender.type] %></td>
+                    <td>共15期</td>
+                    <td>
+                        <a tender-id="<%= tender.id %>" tender-name="<%= tender.name %>" tender-type="<%= tender.type %>" href="#save-bd" data-toggle="modal" data-target="#save-bd" class="save-btn btn btn-outline-primary btn-sm">编辑</a>
+                        <a tender-id="<%= tender.id %>" href="#del-bd" data-toggle="modal" data-target="#del-bd" class="del-btn btn btn-outline-danger btn-sm">删除</a>
+                    </td>
+                </tr>
+                <% }) %>
+                <% } %>
+            </table>
         </div>
     </div>
 </div>

+ 4 - 0
config/menu.js

@@ -72,6 +72,10 @@ const menu = {
                 name: '中间计量',
                 url: '/measure/middle',
             },
+            list: {
+                name: '计量审批',
+                url: '/measure/list',
+            },
             stage: {
                 name: '期计量',
                 url: '/measure/stage',

+ 32 - 0
test/app/service/tender.test.js

@@ -0,0 +1,32 @@
+/**
+ * 项目数据模型单元测试
+ *
+ * @author CaiAoLin
+ * @date 2017/11/17
+ * @version
+ */
+
+'use strict';
+
+const { app, assert } = require('egg-mock/bootstrap');
+const tenderConst = require('../../../app/const/tender');
+describe('test/app/service/tender.test.js', () => {
+
+    it('test getinfo', function* () {
+        const ctx = app.mockContext();
+        const tenderInfo = yield ctx.service.tender.getDataById(14);
+        assert(tenderInfo.id === 14);
+        // assert(tenderInfo.name === '测试标段5');
+    });
+
+    it('save test',function* () {
+        const ctx = app.mockContext();
+        const renderbody = {
+            name : '测试标段5',
+            type : 1
+        };
+        const result = yield ctx.service.tender.save(renderbody,14);
+        assert(result);
+    })
+
+});