Browse Source

变更令相关部分代码

MaiXinRong 7 years ago
parent
commit
79c5c516ce

+ 30 - 4
app/const/audit.js

@@ -16,19 +16,45 @@ const status = {
 };
 
 const statusString = [];
-statusString[status.uncheck] = '上报';
+statusString[status.uncheck] = '上报';
 statusString[status.checking] = '审批中';
 statusString[status.checked] = '审批完成';
 statusString[status.checkNo] = '审批退回';
 
+const statusButton = [];
+statusButton[status.uncheck] = '上报';
+statusButton[status.checking] = '审批';
+statusButton[status.checked] = '';
+statusButton[status.checked] = '重新上报';
+
 const statusClass = [];
 statusClass[status.uncheck] = '';
 statusClass[status.checking] = 'text-warning';
 statusClass[status.checked] = 'text-success';
 statusClass[status.checkNo] = 'text-warning';
 
+const filter = {
+    status: {
+        pending: 1,
+        uncheck: 2,
+        checking: 3,
+        checked: 4,
+        checkNo: 5,
+    },
+    statusString: [],
+}
+filter.statusString[filter.status.pending] = '待处理';
+filter.statusString[filter.status.uncheck] = '待上报';
+filter.statusString[filter.status.checking] = '进行中';
+filter.statusString[filter.status.checked] = '已完成';
+filter.statusString[filter.status.checkNo] = '不通过';
+
 module.exports = {
-    status,
-    statusString,
-    statusClass,
+    flow: {
+        status,
+        statusString,
+        statusButton,
+        statusClass,
+    },
+    filter,
 };

+ 72 - 0
app/const/change.js

@@ -0,0 +1,72 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2018/8/24
+ * @version
+ */
+
+module.exports = {
+    // 变更类型
+    type: {
+        pos: {
+            value: 1, name: 'A.位置',
+        },
+        num: {
+            value: 2, name: 'B.数量',
+        },
+        structure: {
+            value: 3, name: 'C.结构',
+        },
+        add: {
+            value: 4, name: 'D.新增',
+        },
+        cancel: {
+            value: 5, name: 'E.取消',
+        },
+        correct: {
+            value: 6, name: 'F.纠错',
+        },
+    },
+    // 变更类别
+    class: {
+        A: {
+            value: 1, name: 'A类变更(设计变更)',
+        },
+        B: {
+            value: 2, name: 'B类变更(施工措施变)',
+        },
+        C: {
+            value: 3, name: 'C类变更(计划变更)',
+        },
+        D: {
+            value: 4, name: 'D类变更(条件变更)',
+        },
+        E: {
+            value: 5, name: 'E类变更(新增工程)',
+        },
+    },
+    // 变更性质
+    quality: {
+        common: {
+            value: 1, name: '一般设计变更',
+        },
+        more: {
+            value: 1, name: '较大设计变更',
+        },
+        great: {
+            value: 1, name: '重大设计变更',
+        },
+    },
+    //费用承担方
+    charge: {
+        partyA: {
+            value: 1, name: '业主',
+        },
+        partyB: {
+            value: 2, name: '承包人',
+        },
+    },
+}

+ 3 - 0
app/const/code_rule.js

@@ -10,11 +10,14 @@
 
 const ruleType = {
     measure: 1,
+    change: 2,
 };
 const ruleField = [];
 ruleField[ruleType.measure] = 'm_rule';
+ruleField[ruleType.change] = 'c_rule';
 const ruleString = [];
 ruleString[ruleType.measure] = 'measure';
+ruleString[ruleType.change] = 'change';
 
 // 中间计量编号规则
 const measure = {

+ 260 - 0
app/controller/change_controller.js

@@ -0,0 +1,260 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2018/8/14
+ * @version
+ */
+
+const moment = require('moment');
+const audit = require('../const/audit');
+const codeRuleConst = require('../const/code_rule');
+const changeConst = require('../const/change');
+
+module.exports = app => {
+    class ChangeController extends app.BaseController {
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            ctx.showProject = true;
+            ctx.showTender = true;
+            ctx.showTitle = true;
+        }
+
+        async _filterChanges(ctx, status) {
+            const tender = ctx.tenderData;
+            const tenderList = ctx.tenderList;
+
+            const changes = await ctx.service.change.checkingDatas(tender.id, ctx.session.sessionUser.accountId);
+            const filter = JSON.parse(JSON.stringify(audit.filter));
+            filter.count = [];
+            filter.count[filter.status.pending] = 4;// await ctx.service.change.pendingDatas(tender.id, ctx.session.sessionUser.accountId);
+            filter.count[filter.status.uncheck] = 4;// await ctx.service.change.checkingDatas(tender.id, ctx.session.sessionUser.accountId);
+            filter.count[filter.status.checking] = 4;// await ctx.service.change.checkedDatas(tender.id, ctx.session.sessionUser.accountId);
+            filter.count[filter.status.checked] = 4;// await ctx.service.change.pendingDatas(tender.id, ctx.session.sessionUser.accountId);
+            filter.count[filter.status.checkNo] = 4;//await ctx.service.change.pendingDatas(tender.id, ctx.session.sessionUser.accountId);
+
+            const codeRule = tender.c_rule ? JSON.parse(tender.c_rule) : [];
+            for (const rule of codeRule) {
+                switch (rule.rule_type) {
+                    case codeRuleConst.measure.ruleType.tenderName:
+                        rule.preview = tender.name;
+                        break;
+                    case codeRuleConst.measure.ruleType.inDate:
+                        rule.preview = moment().format('YYYYMM');
+                        break;
+                    case codeRuleConst.measure.ruleType.text:
+                        rule.preview = rule.text;
+                        break;
+                    case codeRuleConst.measure.ruleType.addNo:
+                        const s = '0000000000';
+                        rule.preview = s.substr(s.length - rule.format);
+                        break;
+                }
+            }
+            const renderData = {
+                moment,
+                tender,
+                tenderList,
+                changes,
+                filter,
+                status: status,
+                codeRule,
+                auditConst: audit.flow,
+                ruleType: codeRuleConst.ruleType.change,
+                ruleConst: codeRuleConst.measure,
+            };
+
+            await this.layout('change/index.ejs', renderData, 'change/modal.ejs');
+        }
+
+        /**
+         * 变更管理 页面 (Get)
+         *
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async index(ctx) {
+            try {
+                await this._filterChanges(ctx, audit.filter.status.uncheck);
+            } catch (err) {
+                console.log(err);
+                this.logger.err(err);
+                ctx.redirect('/dashboard');
+            }
+        }
+
+        /**
+         *
+         * @param ctx
+         * @returns {Promise<void>}
+         */
+        async newCode(ctx) {
+            const responseData = {
+                err: 0,
+                msg: '',
+                data: '',
+            };
+            try {
+                const tenderId = ctx.session.sessionUser.tenderId;
+                if (!tenderId) {
+                    throw '当前未打开标段';
+                }
+                const tenderData = await ctx.service.tender.getDataById(tenderId);
+                const cCodeRule = JSON.parse(tenderData.c_rule);
+
+                const code = [];
+                for (const rule of cCodeRule) {
+                    switch (rule.rule_type) {
+                        case codeRuleConst.measure.ruleType.tenderName:
+                            code.push(tenderData.name);
+                            break;
+                        case codeRuleConst.measure.ruleType.text:
+                            code.push(rule.text);
+                            break;
+                        case codeRuleConst.measure.ruleType.inDate:
+                            code.push(moment().format('YYYYMM'));
+                            break;
+                        case codeRuleConst.measure.ruleType.addNo:
+                            let s = '0000000000';
+                            const count = rule.start + await ctx.service.change.count({tid: tenderId});
+                            s = s + count;
+                            code.push(s.substr(s.length - rule.format));
+                            break;
+                    }
+                }
+                responseData.data = code.join('');
+            } catch (err) {
+                responseData.err = 1;
+                responseData.msg = err;
+            }
+
+            ctx.body = responseData;
+        }
+
+        /**
+         * 新增变更 (Post)
+         *
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async add(ctx) {
+            try {
+                const tenderId = ctx.session.sessionUser.tenderId;
+                if (!tenderId) {
+                    throw '当前未打开标段';
+                }
+                const data = JSON.parse(ctx.request.body.data);
+                if (!data.code || data.code === '' || !data.name || data.name === '') {
+                    throw '提交数据错误';
+                }
+
+                const change = await ctx.service.change.add(tenderId, ctx.session.sessionUser.accountId, data.code, data.name);
+
+                ctx.body = { err: 0, msg: '', data: change };
+            } catch (err) {
+                console.log(err);
+                ctx.body = { err: 1, msg: err.toString() };
+            }
+        }
+
+        /**
+         * 变更管理 状态筛选 页面 (Get)
+         * @param ctx
+         * @returns {Promise<void>}
+         */
+        async status(ctx) {
+            try {
+                const status = parseInt(ctx.params.status);
+                await this._filterChanges(ctx, status);
+            } catch (err) {
+                this.logger.error(err);
+                ctx.redirect('/change');
+            }
+        }
+
+        /**
+         * 变更信息 页面 (Get)
+         *
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async info(ctx) {
+            try {
+                const tender = ctx.tenderData;
+                const tenderList = ctx.tenderList;
+                const change = await ctx.service.change.getDataByCondition({cid: ctx.params.cid});
+
+                const renderData = {
+                    tender,
+                    tenderList,
+                    change,
+                    changeConst,
+                };
+                await this.layout('change/info.ejs', renderData);
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/change');
+            }
+        }
+
+        /**
+         * 变更清单 页面 (Get)
+         *
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async bills(ctx) {
+            try {
+                const tender = ctx.tenderData;
+                const tenderList = ctx.tenderList;
+                const change = await ctx.service.change.getDataByCondition({cid: ctx.params.cid});
+
+                const renderData = {
+                    tender,
+                    tenderList,
+                    change,
+                };
+                await this.layout('change/bills.ejs', renderData, 'change/bills_modal.ejs');
+
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/change');
+            }
+        }
+
+        /**
+         * 附件 页面 (Get)
+         *
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async file(ctx) {
+            try {
+                const tender = ctx.tenderData;
+                const tenderList = ctx.tenderList;
+                const change = await ctx.service.change.getDataByCondition({cid: ctx.params.cid});
+
+                const renderData = {
+                    tender,
+                    tenderList,
+                    change,
+                };
+                await this.layout('change/file.ejs', renderData, 'change/file_modal.ejs');
+
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/change');
+            }
+        }
+    }
+
+    return ChangeController;
+};

+ 1 - 1
app/controller/ledger_audit_controller.js

@@ -7,7 +7,7 @@
  * @date 2018/5/28
  * @version
  */
-const auditConst = require('../const/audit');
+const auditConst = require('../const/audit').flow;
 const spreadConst = require('../const/spread');
 
 module.exports = app => {

+ 1 - 1
app/controller/ledger_controller.js

@@ -12,7 +12,7 @@ const stdDataAddType = {
     self: 1,
     withParent: 2
 }
-const auditConst = require('../const/audit');
+const auditConst = require('../const/audit').flow;
 const spreadConst = require('../const/spread');
 
 module.exports = app => {

+ 1 - 9
app/controller/measure_audit_controller.js

@@ -8,7 +8,7 @@
  * @version
  */
 
-const auditConst = require('../const/audit');
+const auditConst = require('../const/audit').flow;
 const spreadConst = require('../const/spread');
 
 module.exports = app => {
@@ -38,14 +38,6 @@ module.exports = app => {
                 }
 
                 const works = await ctx.service.measure.joinMeasure(tenderId, ctx.session.sessionUser.accountId);
-                for (const w of works) {
-                    w.in_time_str = moment(w.in_time_str).format('YYYYMM');
-                    if (w.times > 1 && w.status === auditConst.status.checkNo) {
-                        w.curAuditor = await ctx.service.measureAudit.getAuditor(w.mid, w.user_id, w.times);
-                    } else {
-                        w.curAuditor = await ctx.service.measureAudit.getCurAuditor(w.mid, w.times);
-                    }
-                }
                 const renderData = {
                     works,
                     auditConst,

+ 32 - 15
app/controller/measure_controller.js

@@ -10,7 +10,7 @@
 
 const spreadConst = require('../const/spread');
 const codeRuleConst = require('../const/code_rule');
-const auditConst = require('../const/audit');
+const auditConst = require('../const/audit').flow;
 const moment = require('moment');
 
 module.exports = app => {
@@ -53,18 +53,11 @@ module.exports = app => {
                             break;
                     }
                 }
-                const works = await ctx.service.measure.getAllDataByCondition({
-                    where: {tender_id: tenderData.id, user_id: ctx.session.sessionUser.accountId}
+                const works = await ctx.service.measure.measureList({
+                    tender_id: tenderData.id,
+                    user_id: ctx.session.sessionUser.accountId,
+                    valid: true,
                 });
-                for (const w of works) {
-                    w.in_time_str = moment(w.in_time_str).format('YYYYMM');
-                    if (w.times > 1 && w.status === auditConst.status.checkNo) {
-                        w.curAuditor = await ctx.service.measureAudit.getAuditor(w.mid, w.user_id, w.times);
-                    } else {
-                        w.curAuditor = await ctx.service.measureAudit.getCurAuditor(w.mid, w.times);
-                    }
-                }
-
                 const renderData = {
                     tenderData,
                     tenderList,
@@ -111,7 +104,10 @@ module.exports = app => {
                 }
 
                 const mid = ctx.params.mid
-                const measure = await ctx.service.measure.getDataByCondition({mid: mid});
+                const measure = await ctx.service.measure.getDataByCondition({mid: mid, valid: true});
+                if (!measure) {
+                    throw '该数据已被删除'
+                }
                 const renderData = {
                     tenderData,
                     tenderList,
@@ -160,7 +156,7 @@ module.exports = app => {
                             break;
                         case codeRuleConst.measure.ruleType.addNo:
                             let s = '0000000000';
-                            const count = rule.start + await ctx.service.measure.count();
+                            const count = rule.start + await ctx.service.measure.count({tender_id: tenderId});
                             s = s + count;
                             code.push(s.substr(s.length - rule.format));
                             break;
@@ -197,7 +193,7 @@ module.exports = app => {
                 const data = JSON.parse(ctx.request.body.data);
                 await ctx.service.measure.add(tenderId, data.code, ctx.session.sessionUser.accountId, data.date, data.stage);
 
-                responseData.data = await ctx.service.measure.getDataByCondition({
+                responseData.data = await ctx.service.measure.measureData({
                     tender_id: tenderId, code: data.code,
                 });
             } catch (err) {
@@ -205,7 +201,28 @@ module.exports = app => {
                 responseData.err = 1;
                 responseData.msg = err.toString();
             }
+            ctx.body = responseData;
+        }
 
+        async deleteMeasure(ctx) {
+            const responseData = {
+                err: 0,
+                msg: '',
+                data: '',
+            };
+            try {
+                const tenderId = ctx.session.sessionUser.tenderId;
+                if (!tenderId) {
+                    throw '当前未打开标段';
+                }
+
+                const data = JSON.parse(ctx.request.body.data);
+                responseData.data = await ctx.service.measure.invalid(tenderId, data.code, ctx.session.sessionUser.accountId);
+            } catch (err) {
+                console.log(err);
+                responseData.err = 1;
+                responseData.msg = err.toString();
+            }
             ctx.body = responseData;
         }
 

+ 68 - 28
app/controller/stage_controller.js

@@ -8,6 +8,8 @@
  * @version
  */
 
+const moment = require('moment');
+
 module.exports = app => {
     class StageController extends app.BaseController {
         /**
@@ -24,44 +26,82 @@ module.exports = app => {
         }
 
         /**
-         * 期计量页面
-         *
-         @param {Object} ctx - egg全局变量
+         * 期计量页面 (Get)
+         * @param {Object} ctx - egg全局变量
          * @returns {Promise<void>}
          */
         async index(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;
+            try {
+                const tender = ctx.tenderData;
+                const tenderList = ctx.tenderList;
 
-                ctx.redirect('/stage');
-            } else {
-                let tenderId = ctx.session.sessionUser.tenderId;
-                const tenderList = await ctx.service.tender.getList();
-                for (const tender of tenderList) {
-                    tender.url = ctx.menuList.stage.url + '?tenderId=' + tender.id;
-                }
+                const stages = await ctx.service.stage.getAllDataByCondition({
+                    where: {tender_id: tender.id},
+                    order: ['order'],
+                });
+                const renderData = {
+                    moment,
+                    tender,
+                    tenderList,
+                    stages,
+                };
 
+                await this.layout('stage/index.ejs', renderData, 'stage/modal.ejs');
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/dashboard');
+            }
+        }
+
+        /**
+         * 新增期 (Post)
+         *
+         * @param {Object} ctx - egg全局变量
+         * @returns {Promise<void>}
+         */
+        async add(ctx) {
+            try {
+                const tenderId = ctx.session.sessionUser.tenderId;
                 if (!tenderId) {
-                    // 根据标段列表获取默认tenderId
-                    if (tenderList && tenderList.length > 0) {
-                        tenderId = tenderList[0].id;
-                        ctx.session.sessionUser.tenderId = tenderId;
-                        ctx.session.sessionUser.tenderName = tenderList[0].name;
-                    } else {
-                        throw '项目无标段数据';
-                    }
+                    throw '当前未打开标段';
                 }
-                const tender = await ctx.service.tender.getDataById(tenderId);
 
-                const renderData = {
-                    tender,
-                    tenderList
+                const stages = await ctx.service.stage.getAllDataByCondition({
+                    where: {tender_id: tender.id},
+                    order: ['order'],
+                });
+                const order = stages.length + 1;
+                const newStage = {
+                    sid: this.uuid.v4(),
+                    tender_id: tenderId,
+                    order: order,
+                    name: ctx.body.stageName,
+                    in_time: new Date(),
+                    s_time: ctx.body.stageTime,
+                    times: 1,
+                    status: auditConst.status.uncheck,
                 };
+                const result = await ctx.service.stage.insert(newStage);
+                if (result.affected === 1) {
+                    ctx.redirect('/stage/' + newStage.sid);
+                }
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/stage');
+            }
+        }
 
-                await this.layout('stage/index.ejs', renderData, 'stage/modal.ejs');
+        async stage(ctx) {
+            try {
+                const tenderId = ctx.session.sessionUser.tenderId;
+                if (!tenderId) {
+                    throw '当前未打开标段'
+                }
+                const tenderData = await ctx.service.tender.getDataById(tenderId);
+
+            } catch (err) {
+                console.log(err);
+                ctx.redirect('/stage');
             }
         }
     }

+ 1 - 0
app/controller/tender_controller.js

@@ -181,6 +181,7 @@ module.exports = app => {
                     throw '更新规则失败';
                 }
             } catch (err) {
+                console.log(err);
                 responseData.err = 1;
                 responseData.msg = err.toString();
             }

+ 173 - 0
app/public/js/change.js

@@ -0,0 +1,173 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2018/8/21
+ * @version
+ */
+// 向后端请求中间计量号
+function getNewCode() {
+    postData('/change/newCode', null, function (code) {
+        if (code !== '') {
+            $('#bj-code').val(code);
+        }
+    });
+}
+
+class codeRuleSet {
+    constructor (obj) {
+        this.body = obj;
+        // 切换规则组件类型
+        $('select', obj).change(function () {
+            const codeType = this.selectedIndex;
+            if (codeType === ruleConst.ruleType.addNo) {
+                $('#format', obj).show();
+                $('#text', obj).show();
+                $('#text>label', obj).text('起始编号');
+                $('#text>input', obj).val('001');
+                const s = '0000000000' + 1;
+                $('#text>input', obj).val(s.substr(s.length - $('#format>input', obj).val()));
+            } else if (codeType === ruleConst.ruleType.text) {
+                $('#format', obj).hide();
+                $('#text', obj).show();
+                $('#text>label', obj).text('文本');
+                $('#text>input', obj).val('').attr('placeholder', '请在这里输入需要的文本');
+            } else {
+                $('#format', obj).hide();
+                $('#text', obj).hide();
+            }
+        });
+        // 修改编号位数
+        $('#format>input', obj).change(function () {
+            const s = '0000000000' + parseInt($('#text>input', obj).val());
+            $('#text>input', obj).val(s.substr(s.length - $(this).val()));
+        });
+        // 新增规则组件
+        $('#addRule', obj).click(function () {
+            const codeType = $('select', obj)[0].selectedIndex;
+            const rule = {rule_type: codeType}, html = [];
+            let preview;
+            switch (codeType) {
+                case ruleConst.ruleType.tenderName: {
+                    preview = $('#tenderName').text();
+                    break;
+                }
+                case ruleConst.ruleType.text: {
+                    rule.text =  $('#text>input', obj).val();
+                    preview = rule.text;
+                    break;
+                }
+                case ruleConst.ruleType.inDate: {
+                    preview = moment().format('YYYYMM');
+                    break;
+                }
+                case ruleConst.ruleType.addNo: {
+                    rule.format = parseInt($('#format>input', obj).val());
+                    rule.start = parseInt($('#text>input', obj).val());
+                    const s = '0000000000';
+                    preview = s.substr(s.length - rule.format);
+                    break;
+                }
+            }
+            // 更新规则
+            codeRule.push(rule);
+            // 更新规则显示
+            html.push('<span class="badge badge-light" title="' + ruleConst.ruleString[codeType] + '" rule="' + JSON.stringify(rule) + '">');
+            html.push('<span>' + preview + '</span>');
+            html.push('<a href="javascript: void(0);" class="text-danger" title="移除"><i class="fa fa-remove"></i></a>');
+            html.push('</span>');
+            const part = $('#ruleParts', obj).append(html.join(''));
+            // 更新规则预览
+            $('#preview', obj).text($('#preview', obj).text() + preview);
+
+            $('a', part).bind('click', function () {
+                const index = $('a', obj).index(this);
+                codeRule.splice(index, 1);
+                $(this).parent().remove();
+                const rules = $('span>span', obj), ruleText = [];
+                for (const r of rules) {
+                    ruleText.push(r.innerText);
+                }
+                $('#preview', obj).text(ruleText.join(''));
+            });
+        });
+        // 删除规则组件
+        $('a', $('#ruleParts', obj)).bind('click', function () {
+            const index = $('a', obj).index(this);
+            codeRule.splice(index, 1);
+            $(this).parent().remove();
+            const rules = $('span>span', obj), ruleText = [];
+            for (const r of rules) {
+                console.log(r.innerText + ':1');
+                ruleText.push(r.innerText);
+            }
+            $('#preview', obj).text('当前规则:' + ruleText.join(''));
+        });
+    }
+}
+
+$(document).ready(() => {
+    // 首次进入设置
+    if (!codeRule || codeRule.length === 0) {
+        codeRule = [];
+        const firstSet = new codeRuleSet($('div.modal-body', '#first'));
+        // 确认规则上传服务器
+        $('#setRule', '#first').bind('click', function () {
+            const data = {
+                rule: ruleType,
+                data: JSON.stringify(codeRule),
+            };
+            postData('/tender/rule', data, function () {
+                $('#first').modal('hide');
+                $('#add-bj').modal('show');
+            });
+        });
+
+        $('#first').modal('show');
+    } else if ($('#changList').children.length === 0) {
+        $('#add-bj').modal('show');
+    }
+    // 设置
+    const ruleSet = new codeRuleSet($('div.modal-body', '#setting'));
+    $('#setRule', '#setting').bind('click', function () {
+        const data = {
+            rule: ruleType,
+            data: JSON.stringify(codeRule),
+        };
+        postData('/tender/rule', data, function () {
+            $('#setting').modal('hide');
+        });
+    })
+    // 新增变更令 modal显示
+    $('#add-bj').on('show.bs.modal', function() {
+        getNewCode();
+        if ($('#changeList').children.length === 0) {
+            $('#addCancel').hide();
+        } else {
+            $('#addCancel').show();
+        }
+        $('#bj-code').removeClass('is-invalid');
+    });
+    // 获取最新可用变更令号
+    $('#autoCode').click(getNewCode);
+    // 新增变更令 确认
+    $('#addOk').click(function () {
+        const data = {
+            code: $('#bj-code').val(),
+            name: $('#bj-name').val(),
+        };
+        if (data.code || data.code !== '' || data.name || data.name !== '') {
+            postData('/change/add', data, function (rst) {
+                $('#bj-code').removeClass('is-invalid');
+                $('#mj-add').modal('hide');
+                window.location.href = '/change/' + rst.cid + '/info';
+            }, function () {
+                $('#mj-code').addClass('is-invalid');
+                $('#mj-Hint').show();
+            });
+        }
+    });
+
+});

+ 42 - 2
app/public/js/measure_wlist.js

@@ -25,8 +25,8 @@ function getMeasureWorkHtml (data) {
     html.push('<td>' + moment(data.in_time).format('YYYYMM') + '</td>');
     html.push('<td></td>');
     html.push('<td>未上报</td>');
-    html.push('<td></td>');
-    html.push('<td><a href="#edit" data-toggle="modal" data-target="#edit" class="btn btn-outline-primary btn-sm">编辑</a></td>')
+    html.push('<td>', data.user.role + '-' + data.user.name, '</td>');
+    html.push('<td><a href="javascript: void(0);" data-toggle="modal" class="btn btn-outline-primary btn-sm" name="edit">编辑</a></td>')
     html.push('</tr>');
     return html.join('');
 }
@@ -178,4 +178,44 @@ $(document).ready(() => {
     const obj = $('#rule');
     console.log(obj);
     const ruleSet = new codeRuleSet(obj);
+
+    // 编辑
+    $('a[name=edit]').bind('click', function () {
+        const tr = $(this).parent().parent();
+        const mid = tr.attr('mid');
+        const code = tr.attr('code');
+        // 调整删除页面
+        $('#delOk').attr('mid', mid);
+        $('#code', $('#del')).text(code);
+        // 调整编辑页面
+        const edit = $('#edit');
+        edit.attr('mid', mid);
+        $('#codeEdit').val(code);
+        $('[data-target=#del]').text('删除 ' + code);
+        edit.modal('show');
+    });
+    // 编辑 确定
+    $('#editOk').click(function () {
+        const data = {
+            mid: $('#edit').attr('mid'),
+            code: $('#codeEdit').val()
+        }
+        postData('/measure/modify', data, function (m) {
+            const tr = $('tr[mid= ' + m.mid + ']');
+            const tds = tr.children();
+            tds[0].text(m.code);
+            tds[2].text(moment(m.in_time).format('YYYYMM'));
+        });
+    });
+    // 删除 确定
+    $('#delOk').click(function () {
+        const data = {
+            mid: $(this).attr('mid'),
+        }
+        postData('/measure/delete', data, function (result) {
+            if (result) {
+                $('tr[mid= ' + data.mid + ']').remove();
+            }
+        })
+    })
 });

+ 13 - 1
app/router.js

@@ -81,6 +81,7 @@ module.exports = app => {
     app.get('/measure/work/:mid', sessionAuth, tenderSelect, 'measureController.work');
     app.post('/measure/newCode', sessionAuth, 'measureController.newCode');
     app.post('/measure/add', sessionAuth, 'measureController.addMeasure');
+    app.post('/measure/delete', sessionAuth, 'measureController.deleteMeasure');
     app.post('/measure/search', sessionAuth, 'measureController.search');
     app.post('/measure/pos', sessionAuth, 'measureController.pos');
     app.post('/measure/bills', sessionAuth, 'measureController.bills');
@@ -96,7 +97,18 @@ module.exports = app => {
     app.post('/measure/audit/check', sessionAuth, 'measureAuditController.check');
 
     // 期计量管理相关
-    app.get('/stage', sessionAuth, 'stageController.index');
+    app.get('/stage', sessionAuth, tenderSelect, 'stageController.index');
+    app.post('/stage/add', sessionAuth, 'stageController.add');
+    app.get('/stage/:sid', sessionAuth, 'stageController.stage');
+
+    // 变更管理
+    app.get('/change', sessionAuth, tenderSelect, 'changeController.index');
+    app.get('/change/status/:status', sessionAuth, tenderSelect, 'changeController.status');
+    app.post('/change/newCode', sessionAuth, 'changeController.newCode');
+    app.post('/change/add', sessionAuth, 'changeController.add');
+    app.get('/change/:cid/info', sessionAuth, tenderSelect, 'changeController.info');
+    app.get('/change/:cid/bills', sessionAuth, tenderSelect, 'changeController.bills');
+    app.get('/change/:cid/file', sessionAuth, tenderSelect, 'changeController.file');
 
     //标准库相关
     app.post('/std/bills/get-data', sessionAuth, 'stdBillsController.getData');

+ 97 - 0
app/service/change.js

@@ -0,0 +1,97 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2018/8/14
+ * @version
+ */
+
+const audit = require('../const/audit');
+
+module.exports = app => {
+    class Change extends app.BaseService {
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'change';
+        }
+
+        async add(tenderId, userId, code, name) {
+            const count = await this.count({tid: tenderId, code: code});
+            if (count > 0) {
+                throw '变更令号重复';
+            }
+
+            const change = {
+                cid: this.uuid.v4(),
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.uncheck,
+                times: 1,
+                valid: true,
+                in_time: new Date(),
+                code: code,
+                name: name,
+            };
+            await this.db.insert(this.tableName, change);
+            return change;
+        }
+
+        async pendingDatas(tenderId, userId) {
+            return await this.getAllDataByCondition({
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.checking,
+            });
+        }
+
+        async uncheckDatas(tenderId, userId) {
+            return await this.getAllDataByCondition({
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.uncheck,
+            });
+        }
+
+        async checkingDatas(tenderId, userId) {
+            return await this.getAllDataByCondition({
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.checking,
+            });
+        }
+
+        async checkedDatas(tenderId, userId) {
+            return await this.getAllDataByCondition({
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.checked,
+            });
+        }
+
+        async checkNoDatas(tenderId, userId) {
+            return await this.getAllDataByCondition({
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.checkNo,
+            });
+        }
+
+        async checkNoCount(tenderId, userId) {
+            return await this.count({
+                tid: tenderId,
+                uid: userId,
+                status: audit.flow.status.checkNo,
+            });
+        }
+    }
+
+    return Change;
+};

+ 1 - 1
app/service/ledger_audit.js

@@ -8,7 +8,7 @@
  * @version
  */
 
-const auditConst = require('../const/audit');
+const auditConst = require('../const/audit').flow;
 
 module.exports = app => {
     class LedgerAudit extends app.BaseService {

+ 45 - 3
app/service/measure.js

@@ -8,6 +8,9 @@
  * @version
  */
 
+const auditConst = require('../const/audit').flow;
+const moment = require('moment');
+
 module.exports = app => {
 
     class Measure extends app.BaseService {
@@ -40,7 +43,9 @@ module.exports = app => {
                     mid: this.uuid.v4(),
                     code: code,
                     in_time: new Date(),
-                    userId: userId,
+                    user_id: userId,
+                    status: auditConst.status.uncheck,
+                    valid: true,
                 };
                 const result = await this.ctx.service.measure.db.insert(this.tableName, newData);
                 if (result.affectedRow === 0) {
@@ -49,14 +54,51 @@ module.exports = app => {
             } else {
                 throw '您输入的编号已存在';
             }
+        }
 
+        async invalid(mid, userId) {
+            const measure = this.getDataByCondition({mid: mid});
+            if (measure.user_id === userId) {
+                const result = await this.update({valid: false}, {mid: mid});
+                return result.affectedRow === 0;
+            } else {
+                throw '数据错误';
+            }
+        }
+
+        async _getAssistData(m) {
+            m.in_time_str = moment(m.in_time_str).format('YYYYMM');
+            if (m.times > 1 && m.status === auditConst.status.checkNo) {
+                m.curAuditor = await this.ctx.service.measureAudit.getAuditor(m.mid, m.user_id, m.times);
+            } else {
+                m.curAuditor = await this.ctx.service.measureAudit.getCurAuditor(m.mid, m.times);
+            }
+            m.user = await this.ctx.service.projectAccount.getAccountInfoById(m.user_id);
         }
 
         async joinMeasure(tenderId, audit_id) {
             const sql = 'SELECT M.* FROM ?? As M, ?? As MA ' +
-                ' WHERE M.`tender_id` = ? and MA.`audit_id` = ? and M.times = MA.times and MA.`order` > 0';
+                ' WHERE M.`tender_id` = ? and MA.`audit_id` = ? and M.times = MA.times and MA.`order` > 0 and M.valid = true';
             const sqlParam = [this.tableName, this.ctx.service.measureAudit.tableName, tenderId, audit_id];
-            return await this.db.query(sql, sqlParam);
+            const measures = await this.db.query(sql, sqlParam);
+            for (const m of measures) {
+                await this._getAssistData(m);
+            }
+            return measures;
+        }
+
+        async measureList(condition) {
+            const measures = await this.getAllDataByCondition({where: condition});
+            for (const m of measures) {
+                await this._getAssistData(m);
+            }
+            return measures;
+        }
+
+        async measureData (condition) {
+            const measure = await this.getDataByCondition(condition);
+            await this._getAssistData(measure);
+            return measure;
         }
     }
 

+ 1 - 1
app/service/measure_audit.js

@@ -8,7 +8,7 @@
  * @version
  */
 
-const auditConst = require('../const/audit');
+const auditConst = require('../const/audit').flow;
 
 module.exports = app => {
     class MeasureAudit extends app.BaseService {

+ 14 - 1
app/service/project_account.js

@@ -257,6 +257,20 @@ module.exports = app => {
             return info;
         }
 
+        async getAccountInfoById(id) {
+            this.initSqlBuilder();
+            this.sqlBuilder.columns = ['id', 'name', 'company', 'role'];
+            this.sqlBuilder.setAndWhere('id', {
+                operate: '=',
+                value: id,
+            });
+
+            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'select');
+            const info = await this.db.queryOne(sql, sqlParam);
+
+            return info;
+        }
+
         /**
          * 修改用户数据
          *
@@ -369,7 +383,6 @@ module.exports = app => {
 
             return this.save(updateData, accountId);
         }
-
     }
 
     return ProjectAccount;

+ 26 - 0
app/service/stage.js

@@ -0,0 +1,26 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date 2018/8/13
+ * @version
+ */
+
+module.exports = app => {
+    class Stage extends app.BaseService {
+        /**
+         * 构造函数
+         *
+         * @param {Object} ctx - egg全局变量
+         * @return {void}
+         */
+        constructor(ctx) {
+            super(ctx);
+            this.tableName = 'stage';
+        }
+    }
+
+    return Stage;
+};

File diff suppressed because it is too large
+ 40 - 0
app/view/change/bills.ejs


+ 210 - 0
app/view/change/bills_modal.ejs

@@ -0,0 +1,210 @@
+<!--添加清单-->
+<div class="modal fade " tabindex="-1" role="dialog" aria-hidden="true" id="addlist">
+    <div class="modal-dialog modal-lg">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="mySmallModalLabel">从清单中选择</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div style="height:400px;overflow-y:auto">
+                    <table class="table table-striped table-bordered table-condensed">
+                        <thead><tr><th>序号</th><th>清单编号</th><th>名称</th><th>单位</th><th>单价</th><th>选择</th></tr></thead>
+                        <tbody>
+                        <tr>
+                            <td>1</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr class="table-success">
+                            <td>2</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox" checked></td>
+                        </tr>
+                        <tr class="table-success">
+                            <td>3</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox" checked></td>
+                        </tr>
+                        <tr>
+                            <td>4</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>5</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>6</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>7</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>8</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>9</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>10</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr><tr>
+                            <td>11</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>12</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>13</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>14</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>15</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>16</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>17</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>18</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>19</td>
+                            <td>202-1-1</td>
+                            <td>清理现场</td>
+                            <td>m2</td>
+                            <td>3.88</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        <tr>
+                            <td>20</td>
+                            <td>204-1</td>
+                            <td>干处挖土方</td>
+                            <td>m3</td>
+                            <td>435</td>
+                            <td><input type="checkbox"></td>
+                        </tr>
+                        </tbody>
+                    </table>
+                </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>
+<!--提交审批-->
+<div class="modal fade" id="sub-ap" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="myModalLabel">提交审批</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <h5>还没添加任何变更清单,无法提交。</h5>
+                <h5>还没设置审批流程,无法提交。</h5>
+                <h5>确认提交审批?</h5>
+            </div>
+            <div class="modal-footer">
+                <!--无法提交-->
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">好的</button>
+                <!--确认提交-->
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-primary" data-dismiss="modal">确认提交</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 33 - 0
app/view/change/file.ejs

@@ -0,0 +1,33 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="d-inline-block">
+                    <ul class="nav nav-pills m-0">
+                        <li class="nav-item"><a class="nav-link active" href="/change/<%- change.cid %>/info">变更信息</a></li>
+                        <li class="nav-item"><a class="nav-link" href="/change/<%- change.cid %>/bills">变更清单</a></li>
+                        <li class="nav-item"><a class="nav-link" href="/change/<%- change.cid %>/file">附件</a></li>
+                    </ul>
+                </div>
+            </div>
+            <div>
+                <a href="#sub-ap" data-toggle="modal" data-target="#sub-ap" class="btn btn-sm btn-primary pull-right">上报审批</a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <legend>附件&nbsp;&nbsp;<a href="#addfujian" class="btn btn-outline-primary btn-sm pull-right" data-toggle="modal"><span class="glyphicon glyphicon-open"></span> 上传附件</a></legend>
+            <table class="table table-bordered">
+                <thead>
+                <tr><th width="50">序号</th><th>名称</th><th width="90">大小</th><th width="100">上传时间</th><th width="100">操作</th></tr>
+                </thead>
+                <tbody>
+                <tr><td>1</td><td><a href="">合同段工程变更现场办公会议纪要的通知.rar</a></td><td>682.64 KB</td><td>2017-01-01 13:22</td><td><a href="#" class="btn btn-light btn-sm" title="删除附件"><span class="fa fa-trash text-danger"></span></a></td></tr>
+                <tr><td>2</td><td><a href="">管理处关于发送LZTJ-1合同段YT-24号设计更改的通知.rar</a></td><td>1.52 MB</td><td>2017-01-01 14:22</td><td><a href="#" class="btn btn-light btn-sm" title="删除附件"><span class="fa fa-trash text-danger"></span></a></td></tr>
+                <tr><td>3</td><td><a href="">原设计施工图.pdf</a></td><td>396.73 KB</td><td>2017-01-01 12:22</td><td></td></tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>

+ 46 - 0
app/view/change/file_modal.ejs

@@ -0,0 +1,46 @@
+<!--添加附件-->
+<div class="modal fade" id="addfujian">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="myModalLabel">上传附件</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <p>上传文件大小最大:10MB</p>
+                <p><a href="" class="btn btn-primary">选择文件</a></p>
+            </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>
+<!--提交审批-->
+<div class="modal fade" id="sub-ap" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title" id="myModalLabel">提交审批</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <h5>还没添加任何变更清单,无法提交。</h5>
+                <h5>还没设置审批流程,无法提交。</h5>
+                <h5>确认提交审批?</h5>
+            </div>
+            <div class="modal-footer">
+                <!--无法提交-->
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">好的</button>
+                <!--确认提交-->
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <button type="button" class="btn btn-primary" data-dismiss="modal">确认提交</button>
+            </div>
+        </div>
+    </div>
+</div>

+ 99 - 0
app/view/change/index.ejs

@@ -0,0 +1,99 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="d-inline-block">
+                    <ul class="nav nav-pills m-0">
+                        <% for (const fs in filter.status) { %>
+                        <% const f = filter.status[fs]; %>
+                        <li class="nav-item">
+                            <a class="nav-link <% if (f === status) { %>active<% } %>" href="/change/status/<%- f %>">
+                                <%- filter.statusString[f] %>
+                                <span class="badge badge-secondary"><%- filter.count[f] %></span>
+                            </a>
+                        </li>
+                        <% } %>
+                    </ul>
+                </div>
+            </div>
+            <div>
+                <a href="#add-bj" data-toggle="modal" data-target="#add-bj" class="btn btn-sm btn-primary pull-right">新建变更令</a>
+                <a href="#setting" data-toggle="modal" data-target="#setting" class="btn btn-sm btn-outline-primary pull-right"><i class="fa fa-cog"></i></a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <% if (status === filter.status.pending || status === filter.status.uncheck) { %>
+            <table class="table">
+                <thead>
+                <tr><th width="10%">标段</th><th width="20%">变更令号</th><th width="30%">工程名称</th><th width="10%">变更类别</th><th width="10%">变更金额</th><th width="10%">操作</th></tr>
+                </thead>
+                <tbody id="changeList">
+                <% for (const c of changes) { %>
+                <tr>
+                    <td><%- ctx.session.sessionUser.tenderName %></td>
+                    <td><a href="/change/<%- c.cid %>/info"><%- c.code %></a></td>
+                    <td><%- c.name %></td>
+                    <td><%- c.class %></td>
+                    <td><%- c.total_price %></td>
+                    <td>
+                        <a href="/change/<%- c.cid %>/info" class="btn <% if (c.status === auditConst.status.checking) { %>btn-warning<% } %> btn-sm">
+                            <%- auditConst.statusButton[c.status] %>
+                        </a>
+                    </td>
+                </tr>
+                <% } %>
+                </tbody>
+            </table>
+            <% } else if (status === filter.status.checking) { %>
+            <!--进行中-->
+            <table class="table">
+                <thead>
+                <tr><th width="10%">标段</th><th width="20%">变更令号</th><th width="30%">工程名称</th><th width="10%">变更类别</th><th width="10%">变更金额</th><th width="10%">审批流程</th></tr>
+                </thead>
+                <tbody>
+                <tr><td>LZTJ-1</td><td><a href="biangeng-list-detail.html">LZTJ-1标项目部发变更(2015)001号 (点我)</a></td><td>收费站出口右侧加宽段及K0+532基底换填</td><td>A类变更(设计变更)</td><td>101112.23</td><td>陈特 <span class="colOrange">审批中</span></td></tr>
+                <tr><td>LZTJ-1</td><td><a href="">LZTJ-1标项目部发变更(2015)002号</a></td><td>路基基底换填</td><td>A类变更(设计变更)</td><td>191991.32</td><td>陈特 <span class="colOrange">审批中</span></td></tr>
+                <tr><td>LZTJ-1</td><td><a href="">LZTJ-1标项目部发变更(2015)004号</a></td><td>土方运距</td><td>B类变更(施工措施变)</td><td>432664.96</td><td>陈特 <span class="colOrange">审批中</span></td></tr>
+                <tr><td>LZTJ-1</td><td><a href="">LZTJ-1标项目部发变更(2015)005号</a></td><td>K0+440通道台背回填</td><td>C类变更(计划变更)</td><td>136515.46</td><td>陈特 <span class="colOrange">审批中</span></td></tr>
+                </tbody>
+            </table>
+            <% } else if (status === filter.status.checked || status === filter.status.checkNo) { %>
+            <!--已完成-->
+            <table class="table">
+                <thead>
+                <tr><th width="10%">标段</th><th width="20%">变更令号</th><th width="30%">工程名称</th><th width="10%">变更类别</th><th width="10%">变更金额</th></tr>
+                </thead>
+                <tbody>
+                <tr><td>LZTJ-1</td><td><a href="biangeng-list-detail.html">LZTJ-1标项目部发变更(2015)001号 (点我)</a></td><td>收费站出口右侧加宽段及K0+532基底换填</td><td>A类变更(设计变更)</td><td>101112.23</td></tr>
+                <tr><td>LZTJ-1</td><td><a href="">LZTJ-1标项目部发变更(2015)002号</a></td><td>路基基底换填</td><td>A类变更(设计变更)</td><td>191991.32</td></tr>
+                <tr><td>LZTJ-1</td><td><a href="">LZTJ-1标项目部发变更(2015)004号</a></td><td>土方运距</td><td>B类变更(施工措施变)</td><td>432664.96</td></tr>
+                <tr><td>LZTJ-1</td><td><a href="">LZTJ-1标项目部发变更(2015)005号</a></td><td>K0+440通道台背回填</td><td>C类变更(计划变更)</td><td>136515.46</td></tr>
+                </tbody>
+            </table>
+            <% } %>
+            <!--翻页-->
+            <nav aria-label="Page navigation">
+                <ul class="pagination">
+                    <li>
+                        <a href="#" aria-label="Previous">
+                            <span aria-hidden="true">«</span>
+                        </a>
+                    </li>
+                    <li><a href="#">1</a></li>
+                    <li><a href="#">2</a></li>
+                    <li><a href="#">3</a></li>
+                    <li><a href="#">4</a></li>
+                    <li><a href="#">5</a></li>
+                    <li>
+                        <a href="#" aria-label="Next">
+                            <span aria-hidden="true">»</span>
+                        </a>
+                    </li>
+                </ul>
+            </nav>
+        </div>
+    </div>
+</div>
+<script src="/public/js/change.js"></script>

+ 131 - 0
app/view/change/info.ejs

@@ -0,0 +1,131 @@
+<div class="panel-content">
+    <div class="panel-title fluid">
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="d-inline-block">
+                    <ul class="nav nav-pills m-0">
+                        <li class="nav-item"><a class="nav-link active" href="/change/<%- change.cid %>/info">变更信息</a></li>
+                        <li class="nav-item"><a class="nav-link" href="/change/<%- change.cid %>/bills">变更清单</a></li>
+                        <li class="nav-item"><a class="nav-link" href="/change/<%- change.cid %>/file">附件</a></li>
+                    </ul>
+                </div>
+            </div>
+            <div>
+                <a href="#sub-ap" data-toggle="modal" data-target="#sub-ap" class="btn btn-sm btn-primary pull-right">上报审批</a>
+                <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-secondary btn-sm pull-right">审批中</a>
+                <a href="#sp-list" data-toggle="modal" data-target="#sp-list" class="btn btn-outline-warning btn-sm pull-right text-muted">审批退回</a>
+
+                <!--审批-->
+                <a href="#sp-done" data-toggle="modal" data-target="#sp-done" class="btn btn-success btn-sm pull-right">审批通过</a>
+                <a href="#sp-back" data-toggle="modal" data-target="#sp-back" class="btn btn-warning btn-sm pull-right">审批退回</a>
+                <a href="#" class="btn btn-outline-danger btn-sm pull-right text-truncate" style="max-width: 100px;" title="删除 LZTJ-1标项目部发变更(2015)001号">删除 <%- change.code %></a>
+            </div>
+        </div>
+    </div>
+    <div class="content-wrap">
+        <div class="c-body">
+            <!--变更信息-->
+            <legend>变更信息</legend>
+            <div class="row">
+                <div class="col-md-4">
+                    <form>
+                        <div class="form-group">
+                            <label><b class="text-danger">*&nbsp;</b>申请编号</label>
+                            <a href="#" class="pull-right" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="自动编号"><i class="fa fa-repeat"></i></a>
+                            <input class="form-control" value="<%- change.code %>" type="text">
+                        </div>
+                        <div class="form-group">
+                            <label><b class="text-danger">*&nbsp;</b>工程名称</label>
+                            <input class="form-control" value="<%- change.name %>" type="text">
+                        </div>
+                        <div class="form-group">
+                            <label>桩号</label>
+                            <input class="form-control" value="<%- change.peg %>" type="text">
+                        </div>
+                        <div class="form-group">
+                            <label>原设计图名称</label>
+                            <input class="form-control" placeholder="" type="text" value="<%- change.org_name %>">
+                        </div>
+                        <div class="form-group">
+                            <label>原图号</label>
+                            <input class="form-control" placeholder="" type="text" value="<%- change.org_code %>">
+                        </div>
+                        <div class="form-group">
+                            <label>变更设计图名称</label>
+                            <input class="form-control" placeholder="" type="text" value="<%- change.new_name %>">
+                        </div>
+                        <div class="form-group">
+                            <label>变更图号</label>
+                            <input class="form-control" placeholder="" type="text" value="<%- change.new_code %>">
+                        </div>
+                    </form>
+                </div>
+                <div class="col-md-4" style="z-index:999">
+                    <form>
+                        <div class="form-group">
+                            <label><b class="text-danger">*&nbsp;</b>工程变更理由及内容</label>
+                            <textarea class="form-control" rows="6"><%- change.content %></textarea>
+                        </div>
+                        <div class="form-group">
+                            <label>工程变更合同依据</label>
+                            <textarea class="form-control" rows="6"><%- change.basis %></textarea>
+                        </div>
+                        <div class="form-group">
+                            <label>备注</label>
+                            <textarea class="form-control" rows="3"><%- change.memo %></textarea>
+                        </div>
+                    </form>
+                </div>
+                <div class="col-md-4">
+                    <form>
+                        <div class="form-group">
+                            <label>变更类型</label>
+                            <div class="checkbox">
+                                <% for (const t in changeConst.type) { %>
+                                <% const cType = changeConst.type[t] %>
+                                <label class="checkbox-inline">
+                                    <input value="<%- cType.value %>" type="checkbox"><%- cType.name %>
+                                </label>
+                                <% } %>
+                            </div>
+                        </div>
+                        <div class="form-group">
+                            <label>变更类别 </label>
+                            <select class="form-control">
+                                <% for (const c in changeConst.class) { %>
+                                <% const cClass = changeConst.class[c] %>
+                                <option value="<%- cClass.value %>"><%- cClass.name %></option>
+                                <% } %>
+                            </select>
+                        </div>
+                        <div class="form-group">
+                            <label>变更性质 </label>
+                            <select class="form-control">
+                                <% for (const q in changeConst.quality) { %>
+                                <% const cQuality = changeConst.quality[q] %>
+                                <option value="<%- cQuality.value %>"><%- cQuality.name %></option>
+                                <% } %>
+                            </select>
+                        </div>
+                        <div class="form-group">
+                            <label>变更提出单位</label>
+                            <a href="#editcompany" style="float:right;" class="" data-toggle="modal">编辑</a>
+                            <select class="form-control"><option>AA公司</option><option>BB公司</option></select>
+                        </div>
+                        <div class="form-group">
+                            <label>费用承担方</label>
+                            <div class="radio">
+                                <% for (const c in changeConst.charge) { %>
+                                <% const cCharge = changeConst.charge[c] %>
+                                <label class="radio-inline">
+                                    <input value="<%- cCharge.value %>" type="radio"> <%- cCharge.name %>
+                                </label>
+                                <% } %>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

+ 161 - 0
app/view/change/modal.ejs

@@ -0,0 +1,161 @@
+<!--首次使用-->
+<div class="modal" id="first">
+    <div class="modal-dialog" role="document" >
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">设置变更令号规则</h5>
+            </div>
+            <div class="modal-body">
+                <h5 >
+                    当前规则:
+                    <span id="preview">
+                        <% if (codeRule && codeRule instanceof Array) { %>
+                        <% const preview = []; %>
+                        <% for (const rule of codeRule) { %>
+                        <% preview.push(rule.preview); %>
+                        <% } %>
+                        <%- preview.join(''); %>
+                        <% } %>
+                    </span>
+                </h5>
+                <h5 id="ruleParts">
+                    <% if (codeRule && codeRule instanceof Array) { %>
+                    <% for (const rule of codeRule) { %>
+                    <span class="badge badge-light" title="<%- ruleConst.ruleString[rule.rule_type]%>">
+                            <span>
+                                <%- rule.preview %>
+                            </span>
+                            <a href="javascript: void(0);" class="text-danger" title="移除"><i class="fa fa-remove"></i></a>
+                        </span>
+                    <% } %>
+                    <% } %>
+                </h5>
+                <h5>添加新规则组件</h5>
+                <div class="form-group">
+                    <select class="form-control">
+                        <option disabled selected>请选择组件</option>
+                        <% for (const index in ruleConst.ruleString) { %>
+                        <option value="<%- index %>"><%- ruleConst.ruleString[index] %></option>
+                        <% } %>
+                    </select>
+                </div>
+                <div class="form-group" id="format" style="display: none">
+                    <label>自动编号位数</label>
+                    <input min="3" class="form-control" step="1" max="6" value="3" type="number">
+                </div>
+                <div class="form-group" id="text" style="display: none">
+                    <label>起始编号</label>
+                    <input class="form-control" value="001" type="text">
+                </div>
+                <button class="btn btn-primary" id="addRule">添加组件</button>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+                <button class="btn btn-primary" id="setRule">确定</button>
+            </div>
+        </div>
+    </div>
+</div>
+<!--弹出添加变更令-->
+<div class="modal fade" id="add-bj" 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>
+                    <div class="input-group">
+                        <input type="text" class="form-control is-invalid" placeholder="请输入变更令号" value="WJQR1-201711" id="bj-code">
+                        <div class="input-group-append">
+                            <button class="btn btn-outline-secondary" type="button" title="自动编号" id="autoCode"><i class="fa fa-repeat"></i></button>
+                        </div>
+                        <div class="invalid-feedback" style="display: none" id="bjHint">您输入的编号已存在</div>
+                    </div>
+                </div>
+                <div class="form-group">
+                    <label>工程名称<b class="text-danger">*</b></label>
+                    <input class="form-control" value="" type="text" id="bj-name">
+                </div>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-secondary" data-dismiss="modal" id="addCancel">关闭</button>
+                <a href="javascript: void(0)" class="btn btn-primary" id="addOk">确认添加</a>
+            </div>
+        </div>
+    </div>
+</div>
+<!--设置-->
+<div class="modal fade" id="setting" 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">
+                <ul class="nav nav-tabs mb-3" role="tablist">
+                    <li class="nav-item">
+                        <a class="nav-link active" data-toggle="tab" href="#bianhao" role="tab" aria-controls="home" aria-selected="true">编号规则</a>
+                    </li>
+                </ul>
+                <div class="tab-content">
+                    <div class="tab-pane active" id="bianhao">
+                        <h5>
+                            当前规则:
+                            <span id="preview">
+                                <% if (codeRule && codeRule instanceof Array) { %>
+                                    <% const preview = []; %>
+                                    <% for (const rule of codeRule) { %>
+                                        <% preview.push(rule.preview); %>
+                                    <% } %>
+                                    <%- preview.join(''); %>
+                                <% } %>
+                            </span>
+                        </h5>
+                        <h5 id="ruleParts">
+                            <% if (codeRule && codeRule instanceof Array) { %>
+                                <% for (const rule of codeRule) { %>
+                                <span class="badge badge-light" title="<%- ruleConst.ruleString[rule.rule_type]%>">
+                                    <span>
+                                        <%- rule.preview %>
+                                    </span>
+                                    <a href="javascript: void(0);" class="text-danger" title="移除"><i class="fa fa-remove"></i></a>
+                                </span>
+                                <% } %>
+                            <% } %>
+                        </h5>
+                        <h5>添加新规则组件</h5>
+                        <div class="form-group">
+                            <select class="form-control">
+                                <option disabled selected>请选择组件</option>
+                                <% for (const index in ruleConst.ruleString) { %>
+                                <option value="<%- index %>"><%- ruleConst.ruleString[index] %></option>
+                                <% } %>
+                            </select>
+                        </div>
+                        <div class="form-group" id="format" style="display: none">
+                            <label>自动编号位数</label>
+                            <input min="3" class="form-control" step="1" max="6" value="3" type="number">
+                        </div>
+                        <div class="form-group" id="text" style="display: none">
+                            <label>起始编号</label>
+                            <input class="form-control" value="001" type="text">
+                        </div>
+                        <button class="btn btn-primary" id="addRule">添加组件</button>
+                    </div>
+                </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="setRule">确定添加</button>
+            </div>
+        </div>
+    </div>
+</div>
+<script>
+    const ruleType = <%- ruleType %>;
+    const ruleConst = JSON.parse('<%- JSON.stringify(ruleConst) %>');
+    let codeRule = JSON.parse('<%- JSON.stringify(codeRule) %>');
+</script>
+<script src="/public/js/moment/moment.min.js"></script>

+ 6 - 4
app/view/measure/wlist.ejs

@@ -82,7 +82,7 @@
                     </thead>
                     <tbody id="wlist">
                     <% for (const w of works) { %>
-                    <tr>
+                    <tr mid="<%- w.mid %>" code="<%- w.code %>">
                         <td><a href="/measure/work/<%- w.mid %>"><%- w.code %></a></td>
                         <td class="text-right"><%- (w.deal_sum + w.qc_sum).toFixed(2) %></td>
                         <td><%- w.in_time_str %></td>
@@ -97,11 +97,13 @@
                         <td>
                             <% if (w.curAuditor) { %>
                             <%- w.curAuditor.role %>-<%- w.curAuditor.name %>
+                            <% } else { %>
+                            <%- w.user.role %>-<%- w.user.name %>
                             <% } %>
                         </td>
                         <td>
-                            <% if (w.status === auditConst.status.uncheck) { %>\
-                            <a href="#edit" data-toggle="modal" data-target="#edit" class="btn btn-outline-primary btn-sm">编辑</a>
+                            <% if (w.status === auditConst.status.uncheck) { %>
+                            <a href="javascript: void(0);" data-toggle="modal" class="btn btn-outline-primary btn-sm" name="edit">编辑</a>
                             <% } %>
                         </td>
                     </tr>
@@ -113,7 +115,7 @@
     </div>
 </div>
 <script>
-    const userId = <%- ctx.session.sessionUser.accountId%>;
+    const userId = <%- ctx.session.sessionUser.accountId %>;
     const auditConst = JSON.parse('<%- JSON.stringify(auditConst) %>');
 </script>
 <script src="/public/js/measure_wlist.js"></script>

+ 5 - 5
app/view/measure/wlist_modal.ejs

@@ -136,7 +136,7 @@
                 <div class="form-group">
                     <label>中间计量编号<b class="text-danger">*</b></label>
                     <div class="input-group">
-                        <input type="text" class="form-control" placeholder="请输入中间计量编号" value="WJQR1-201711">
+                        <input id="codeEdit" type="text" class="form-control" placeholder="请输入中间计量编号" value="WJQR1-201711">
                         <div class="input-group-append">
                             <button class="btn btn-outline-secondary" type="button" title="自动编号"><i class="fa fa-repeat"></i></button>
                         </div>
@@ -148,10 +148,10 @@
                 </div>
             </div>
             <div class="modal-footer d-flex justify-content-between">
-                <a href="#del" data-toggle="modal" data-target="#del" class="btn btn-outline-danger btn-sm pull-right">删除 WJQR1-201710</a>
+                <a href="javascript: void(0)" data-toggle="modal" data-target="#del" class="btn btn-outline-danger btn-sm pull-right">删除 WJQR1-201710</a>
                 <div>
                     <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" id="editOk">确定</button>
                 </div>
             </div>
         </div>
@@ -220,11 +220,11 @@
     <div class="modal-dialog" role="document">
         <div class="modal-content">
             <div class="modal-body">
-                <h5>确认删除 WJQR1-201710 ?</h5>
+                <h5>确认删除 <span id="code">WJQR1-201710</span> ?</h5>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
-                <button type="button" class="btn btn-danger" >确认删除</button>
+                <button type="button" class="btn btn-danger" id="delOk">确认删除</button>
             </div>
         </div>
     </div>

+ 12 - 40
app/view/stage/index.ejs

@@ -27,46 +27,18 @@
                 </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>
+                    <% for (const s of stages) { %>
+                    <tr>
+                        <td><a href="/stage/<%- s.order %>">第 <%- s.order %> 期</a></td>
+                        <td class="text-center"><%- moment(s.s_time).format('YYYYMM') %></td>
+                        <td class="text-right"></td>
+                        <td class="text-right"></td>
+                        <td class="text-right"></td>
+                        <td class="text-right"></td>
+                        <td class="text-right"></td>
+                        <td class="text-centre"><%- auditConst.statusString[s.status] %></td>
+                    </tr>
+                    <% } %>
                 </tbody>
             </table>
         </div>

+ 6 - 2
app/view/stage/modal.ejs

@@ -8,11 +8,11 @@
             <div class="modal-body">
                 <div class="form-group">
                     <label>期</label>
-                    <input class="form-control" value="第 4 期" type="text">
+                    <input class="form-control" value="第 <%- stages.length + 1 %> 期" type="text" name="stageName">
                 </div>
                 <div class="form-group">
                     <label>计量月份</label>
-                    <input class="form-control" type="month">
+                    <input class="form-control" type="month" name="stageTime">
                 </div>
             </div>
             <div class="modal-footer">
@@ -22,3 +22,7 @@
         </div>
     </div>
 </div>
+<script src="/public/js/moment/moment.min.js"></script>
+<script>
+    $('input[type=month]').val(moment().format('YYYY-MM'));
+</script>

+ 16 - 16
config/menu.js

@@ -62,22 +62,22 @@ const menu = {
             },
         },
     },
-    measure: {
-        name: '中间计量',
-        icon: 'fa-calendar-check-o',
-        display: true,
-        url: '',
-        children: {
-            middle: {
-                name: '计量编制',
-                url: '/measure/wlist',
-            },
-            list: {
-                name: '计量审批',
-                url: '/measure/alist',
-            }
-        },
-    },
+    // measure: {
+    //     name: '中间计量',
+    //     icon: 'fa-calendar-check-o',
+    //     display: true,
+    //     url: '',
+    //     children: {
+    //         middle: {
+    //             name: '计量编制',
+    //             url: '/measure/wlist',
+    //         },
+    //         list: {
+    //             name: '计量审批',
+    //             url: '/measure/alist',
+    //         }
+    //     },
+    // },
     stage: {
         name: '期计量',
         icon: 'fa-calendar-check-o',