'use strict';

/**
 *
 *
 * @author Mai
 * @date 2019/2/27
 * @version
 */

const auditConst = require('../const/audit').stage;

module.exports = app => {
    class StageAudit extends app.BaseService {
        /**
         * 构造函数
         *
         * @param {Object} ctx - egg全局变量
         * @return {void}
         */
        constructor(ctx) {
            super(ctx);
            this.tableName = 'stage_audit';
        }

        /**
         * 获取 审核人信息
         *
         * @param {Number} stageId - 期id
         * @param {Number} auditorId - 审核人id
         * @param {Number} times - 第几次审批
         * @returns {Promise<*>}
         */
        async getAuditor(stageId, auditorId, times = 1) {
            const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                'FROM ?? AS la, ?? AS pa ' +
                'WHERE la.`sid` = ? and la.`aid` = ? and la.`times` = ?' +
                '    and la.`aid` = pa.`id`';
            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, auditorId, times];
            return await this.db.queryOne(sql, sqlParam);
        }

        /**
         * 获取 审核列表信息
         *
         * @param {Number} stageId - 期id
         * @param {Number} times - 第几次审批
         * @returns {Promise<*>}
         */
        async getAuditors(stageId, times = 1) {
            const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                'FROM ?? AS la, ?? AS pa ' +
                'WHERE la.`sid` = ? and la.`times` = ? and la.`aid` = pa.`id` order by la.`order`';
            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, times];
            return await this.db.query(sql, sqlParam);
        }

        /**
         * 获取 当前审核人
         *
         * @param {Number} stageId - 期id
         * @param {Number} times - 第几次审批
         * @returns {Promise<*>}
         */
        async getCurAuditor(stageId, times = 1) {
            const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, pa.`mobile`, pa.`telephone`, la.`times`, la.`order`, la.`status`, la.`opinion`, la.`begin_time`, la.`end_time` ' +
                'FROM ?? AS la, ?? AS pa ' +
                'WHERE la.`sid` = ? and la.`status` = ? and la.`times` = ?' +
                '    and la.`aid` = pa.`id`';
            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, auditConst.status.checking, times];
            return await this.db.queryOne(sql, sqlParam);
        }

        /**
         * 获取 最新审核顺序
         *
         * @param {Number} stageId - 期id
         * @param {Number} times - 第几次审批
         * @returns {Promise<number>}
         */
        async getNewOrder(stageId, times = 1) {
            const sql = 'SELECT Max(??) As max_order FROM ?? Where `sid` = ? and `times` = ?';
            const sqlParam = ['order', this.tableName, stageId, times];
            const result = await this.db.queryOne(sql, sqlParam);
            return result && result.max_order ? result.max_order + 1 : 1;
        }

        /**
         * 新增审核人
         *
         * @param {Number} stageId - 期id
         * @param {Number} auditorId - 审核人id
         * @param {Number} times - 第几次审批
         * @returns {Promise<number>}
         */
        async addAuditor(stageId, auditorId, times = 1) {
            const newOrder = await this.getNewOrder(stageId, times);
            const data = {
                tid: this.ctx.tender.id,
                sid: stageId,
                aid: auditorId,
                times: times,
                order: newOrder,
                status: auditConst.status.uncheck,
            };
            const result = await this.db.insert(this.tableName, data);
            return result.effectRows = 1;
        }

        /**
         * 移除审核人时，同步其后审核人order
         * @param transaction - 事务
         * @param {Number} stageId - 标段id
         * @param {Number} auditorId - 审核人id
         * @param {Number} times - 第几次审批
         * @returns {Promise<*>}
         * @private
         */
        async _syncOrderByDelete(transaction, stageId, order, times) {
            this.initSqlBuilder();
            this.sqlBuilder.setAndWhere('sid', {
                value: stageId,
                operate: '='
            });
            this.sqlBuilder.setAndWhere('order', {
                value: order,
                operate: '>=',
            });
            this.sqlBuilder.setAndWhere('times', {
                value: times,
                operate: '=',
            });
            this.sqlBuilder.setUpdateData('order', {
                value: 1,
                selfOperate: '-',
            });
            const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
            const data = await transaction.query(sql, sqlParam);

            return data;
        }

        /**
         * 移除审核人
         *
         * @param {Number} stageId - 期id
         * @param {Number} auditorId - 审核人id
         * @param {Number} times - 第几次审批
         * @returns {Promise<boolean>}
         */
        async deleteAuditor(stageId, auditorId, times = 1) {
            const transaction = await this.db.beginTransaction();
            try {
                const condition = {sid: stageId, aid: auditorId, times: times};
                const auditor = await this.getDataByCondition(condition);
                if (!auditor) {
                    throw '该审核人不存在';
                }
                await this._syncOrderByDelete(transaction, stageId, auditor.order, times);
                await transaction.delete(this.tableName, condition);
                await transaction.commit();
            } catch(err) {
                await transaction.rollback();
                throw err;
            }
            return true;
        }

        /**
         * 开始审批
         *
         * @param {Number} stageId - 期id
         * @param {Number} times - 第几次审批
         * @returns {Promise<boolean>}
         */
        async start(stageId, times = 1) {
            const audit = await this.getDataByCondition({sid: stageId, times: times, order: 1});
            if (!audit) {
                throw '请先选择审批人，再上报数据';
            }

            const transaction = await this.db.beginTransaction();
            try {
                await transaction.update(this.tableName, {id: audit.id, status: auditConst.status.checking, begin_time: new Date()});
                // 计算原报最终数据
                await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                // 复制一份下一审核人数据
                await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, 1, transaction);
                // 更新期数据
                const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
                await transaction.update(this.ctx.service.stage.tableName, {
                    id: stageId, status: auditConst.status.checking,
                    contract_tp: tpData.contract_tp,
                    qc_tp: tpData.qc_tp
                });
                // todo 更新标段tender状态 ?
                await transaction.commit();
            } catch(err) {
                await transaction.rollback();
                throw err;
            }
            return true;
        }

        async _checked(stageId, checkData, times) {
            const time = new Date();
            // 整理当前流程审核人状态更新
            const audit = await this.getDataByCondition({sid: stageId, times: times, status: auditConst.status.checking});
            if (!audit) {
                throw '审核数据错误';
            }
            const nextAudit = await this.getDataByCondition({sid: stageId, times: times, order: audit.order + 1});
            const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);

            const transaction = await this.db.beginTransaction();
            try {
                await transaction.update(this.tableName, {id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time});
                // 计算并合同支付最终数据
                await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                // 无下一审核人表示，审核结束
                if (nextAudit) {
                    // 复制一份下一审核人数据
                    await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, nextAudit.order, transaction);
                    // 流程至下一审批人
                    await transaction.update(this.tableName, {id: nextAudit.id, status: auditConst.status.checking, begin_time: time});
                    // 同步 期信息
                    await transaction.update(this.ctx.service.stage.tableName, {
                        id: stageId, status: auditConst.status.checking,
                        contract_tp: tpData.contract_tp,
                        qc_tp: tpData.qc_tp,
                    });
                } else {
                    // 本期结束
                    // 生成截止本期数据 final数据
                    await this.ctx.service.stageBillsFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
                    await this.ctx.service.stagePosFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
                    // 同步 期信息
                    await transaction.update(this.ctx.service.stage.tableName, {
                        id: stageId, status: checkData.checkType,
                        contract_tp: tpData.contract_tp,
                        qc_tp: tpData.qc_tp,
                    });
                }
                await transaction.commit();
            } catch (err) {
                await transaction.rollback();
                throw err;
            }
        }

        async _checkNo(stageId, checkData, times) {
            const time = new Date();
            // 整理当前流程审核人状态更新
            const audit = await this.getDataByCondition({sid: stageId, times: times, status: auditConst.status.checking});
            if (!audit) {
                throw '审核数据错误';
            }
            const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
            const sql = 'SELECT `tid`, `sid`, `aid`, `order` FROM ?? WHERE `sid` = ? and `times` = ? GROUP BY `aid`';
            const sqlParam = [this.tableName, stageId, times];
            const auditors = await this.db.query(sql, sqlParam);
            let order = 1;
            for (const a of auditors) {
                a.times = times + 1;
                a.order = order;
                a.status = auditConst.status.uncheck;
                order++;
            }

            const transaction = await this.db.beginTransaction();
            try {
                await transaction.update(this.tableName, {id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time});
                // 同步 期信息
                await transaction.update(this.ctx.service.stage.tableName, {
                    id: stageId, status: checkData.checkType,
                    contract_tp: tpData.contract_tp,
                    qc_tp: tpData.qc_tp,
                    times: times + 1,
                });
                // 拷贝新一次审核流程列表
                await transaction.insert(this.tableName, auditors);
                // 计算该审批人最终数据
                await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                // 复制一份最新数据给原报
                await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times + 1, 0, transaction);
                await transaction.commit();
            } catch (err) {
                await transaction.rollback();
                throw err;
            }
        }

        async _checkNoPre(stageId, checkData, times) {
            const time = new Date();
            // 整理当前流程审核人状态更新
            const audit = await this.getDataByCondition({sid: stageId, times: times, status: auditConst.status.checking});
            if (!audit || audit.order <= 1) {
                throw '审核数据错误';
            }
            const preAuditor = await this.getDataByCondition({sid: stageId, times: times, order: audit.order - 1});

            const transaction = await this.db.beginTransaction();
            try {
                await transaction.update(this.tableName, {id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time});
                // 顺移气候审核人流程顺序
                this.initSqlBuilder();
                this.sqlBuilder.setAndWhere('sid', { value: this.ctx.stage.id, operate: '=', });
                this.sqlBuilder.setAndWhere('order', { value: audit.order, operate: '>', });
                this.sqlBuilder.setUpdateData('order', { value: 2, selfOperate: '+', });
                const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
                const data = await transaction.query(sql, sqlParam);
                // 上一审批人,当前审批人 再次添加至流程
                const newAuditors = [];
                newAuditors.push({
                    tid: preAuditor.tid, sid: preAuditor.sid, aid: preAuditor.aid,
                    times: preAuditor.times, order: preAuditor.order + 2, status: auditConst.status.checking,
                    begin_time: time,
                });
                newAuditors.push({
                    tid: audit.tid, sid: audit.sid, aid: audit.aid,
                    times: audit.times, order: audit.order + 2, status: auditConst.status.uncheck
                });
                await transaction.insert(this.tableName, newAuditors);
                // 计算该审批人最终数据
                await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
                // 复制一份最新数据给下一人
                await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, audit.order + 1, transaction);
                await transaction.commit();
            } catch(err) {
                await transaction.rollback();
                throw err;
            }
        }

        /**
         * 审批
         * @param {Number} stageId - 标段id
         * @param {auditConst.status.checked|auditConst.status.checkNo} checkType - 审批结果
         * @param {Number} times - 第几次审批
         * @returns {Promise<void>}
         */
        async check(stageId, checkData, times = 1) {
            if (checkData.checkType !== auditConst.status.checked && checkData.checkType !== auditConst.status.checkNo && checkData.checkType !== auditConst.status.checkNoPre) {
                throw '提交数据错误';
            }
            // // 整理当前流程审核人状态更新
            // const audit = await this.getDataByCondition({sid: stageId, times: times, status: auditConst.status.checking});
            // if (!audit) {
            //     throw '审核数据错误';
            // }
            //const time = new Date();

            switch (checkData.checkType) {
                case auditConst.status.checked:
                    await this._checked(stageId, checkData, times);
                    break;
                case auditConst.status.checkNo:
                    await this._checkNo(stageId, checkData, times);
                    break;
                case auditConst.status.checkNoPre:
                    await this._checkNoPre(stageId, checkData, times);
                    break;
                default:
                    throw '无效审批操作';
            }

            // const transaction = await this.db.beginTransaction();
            // try {
            //     // 更新当前审核流程
            //     await transaction.update(this.tableName, {id: audit.id, status: checkData.checkType, opinion: checkData.opinion, end_time: time});
            //     if (checkData.checkType === auditConst.status.checked) { // 审批通过
            //         const nextAudit = await this.getDataByCondition({sid: stageId, times: times, order: audit.order + 1});
            //         // 无下一审核人表示，审核结束
            //         if (nextAudit) {
            //             // 计算该审批人最终数据
            //             await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
            //             // 复制一份下一审核人数据
            //             await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, nextAudit.order, transaction);
            //             // 流程至下一审批人
            //             await transaction.update(this.tableName, {id: nextAudit.id, status: auditConst.status.checking, begin_time: time});
            //             // 同步 期信息
            //             const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
            //             await transaction.update(this.ctx.service.stage.tableName, {
            //                 id: stageId, status: auditConst.status.checking,
            //                 contract_tp: tpData.contract_tp,
            //                 qc_tp: tpData.qc_tp,
            //             });
            //         } else {
            //             // 本期结束
            //             // 生成截止本期数据 final数据
            //             await this.ctx.service.stageBillsFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
            //             await this.ctx.service.stagePosFinal.generateFinalData(transaction, this.ctx.tender, this.ctx.stage);
            //             // 计算并合同支付最终数据
            //             await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
            //             // 同步 期信息
            //             const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
            //             await transaction.update(this.ctx.service.stage.tableName, {
            //                 id: stageId, status: checkData.checkType,
            //                 contract_tp: tpData.contract_tp,
            //                 qc_tp: tpData.qc_tp,
            //             });
            //         }
            //     } else if (checkData.checkType === auditConst.status.checkNo) { // 审批退回 原报, times+1
            //         // 同步 期信息
            //         const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
            //         await transaction.update(this.ctx.service.stage.tableName, {
            //             id: stageId, status: checkData.checkType,
            //             contract_tp: tpData.contract_tp,
            //             qc_tp: tpData.qc_tp,
            //             times: times + 1,
            //         });
            //         // 拷贝新一次审核流程列表
            //         // const auditors = await this.getAllDataByCondition({
            //         //     where: {sid: stageId, times: times},
            //         //     columns: ['tid', 'sid', 'aid', 'order']
            //         // });
            //         const sql = 'SELECT `tid`, `sid`, `aid`, `order` FROM ?? WHERE `sid` = ? and `times` = ? GROUP BY `aid`';
            //         const sqlParam = [this.tableName, stageId, times];
            //         const auditors = await this.db.query(sql, sqlParam);
            //         let order = 1;
            //         for (const a of auditors) {
            //             a.times = times + 1;
            //             a.order = order;
            //             a.status = auditConst.status.uncheck;
            //             order++;
            //         }
            //         await transaction.insert(this.tableName, auditors);
            //         // 计算该审批人最终数据
            //         await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
            //         // 复制一份最新数据给原报
            //         await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times + 1, 0, transaction);
            //     } else if (checkData.checkType === auditConst.status.checkNoPre) { // 审批退回 上一审批人
            //         // 同步 期信息
            //         const tpData = await this.ctx.service.stageBills.getSumTotalPrice(this.ctx.stage);
            //         await transaction.update(this.ctx.service.stage.tableName, {
            //             id: stageId, status: checkData.checkType,
            //             contract_tp: tpData.contract_tp,
            //             qc_tp: tpData.qc_tp,
            //         });
            //         // 将当前审批人 与 上一审批人再次添加至流程，顺移其后审批人流程顺序
            //         if (audit.order > 1) {
            //             // 顺移气候审核人流程顺序
            //             this.initSqlBuilder();
            //             this.sqlBuilder.setAndWhere('sid', { value: this.ctx.stage.id, operate: '=', });
            //             this.sqlBuilder.setAndWhere('order', { value: audit.order, operate: '>', });
            //             this.sqlBuilder.setUpdateData('order', { value: 2, selfOperate: '+', });
            //             const [sql, sqlParam] = this.sqlBuilder.build(this.tableName, 'update');
            //             const data = await transaction.query(sql, sqlParam);
            //
            //             // 上一审批人,当前审批人 再次添加至流程
            //             const preAuditor = await this.getDataByCondition({sid: stageId, times: times, order: audit.order - 1});
            //             const newAuditors = [];
            //             newAuditors.push({
            //                 tid: preAuditor.tid, sid: preAuditor.sid, aid: preAuditor.aid,
            //                 times: preAuditor.times, order: preAuditor.order + 2, status: auditConst.status.checking,
            //                 begin_time: time,
            //             });
            //             newAuditors.push({
            //                 tid: audit.tid, sid: audit.sid, aid: audit.aid,
            //                 times: audit.times, order: audit.order + 2, status: auditConst.status.uncheck
            //             });
            //             await transaction.insert(this.tableName, newAuditors);
            //
            //             // 计算该审批人最终数据
            //             await this.ctx.service.stagePay.calcAllStagePays(this.ctx.stage, transaction);
            //             // 复制一份最新数据给上一人
            //             await this.ctx.service.stagePay.copyAuditStagePays(this.ctx.stage, this.ctx.stage.times, audit.order + 1, transaction);
            //         } else {
            //             throw '审核数据错误';
            //         }
            //     } else {
            //         throw '无效审批操作';
            //     }
            //
            //     await transaction.commit();
            // } catch (err) {
            //     await transaction.rollback();
            //     throw err;
            // }
        }

        /**
         * 获取审核人需要审核的期列表
         *
         * @param auditorId
         * @returns {Promise<*>}
         */
        async getAuditStage(auditorId) {
            const sql = 'SELECT sa.`aid`, sa.`times`, sa.`order`, sa.`begin_time`, sa.`end_time`, sa.`tid`, sa.`sid`,' +
                        '    s.`order` As `sorder`, s.`status` As `sstatus`,' +
                        '    t.`name`, t.`project_id`, t.`type`, t.`user_id` ' +
                        '  FROM ?? AS sa, ?? AS s, ?? As t ' +
                        '  WHERE ((sa.`aid` = ? and sa.`status` = ?) OR (s.`user_id` = ? and sa.`status` = ? and s.`status` = ? and sa.`times` = (s.`times`-1)))' +
                        '    and sa.`sid` = s.`id` and sa.`tid` = t.`id`';
            const sqlParam = [this.tableName, this.ctx.service.stage.tableName, this.ctx.service.tender.tableName, auditorId, auditConst.status.checking, auditorId, auditConst.status.checkNo, auditConst.status.checkNo];
            return await this.db.query(sql, sqlParam);
        }

        /**
         * 获取 某时间后 审批进度 更新的期
         * @param {Number} pid - 查询标段
         * @param {Number} uid - 查询人
         * @param {Date} time - 查询时间
         * @returns {Promise<*>}
         */
        async getNoticeStage(pid, uid, time) {
            const sql = 'SELECT t.`name`, t.`project_id`, t.`type`, t.`user_id`, ' +
                        '    s.`order` As `s_order`, s.`status` As `s_status`, ' +
                        '    sa.`aid`, sa.`times`, sa.`order`, sa.`end_time`, sa.`tid`, sa.`sid`, sa.`status`, ' +
                        '    pa.`name` As `su_name`, pa.role As `su_role`, pa.company As `su_company`' +
                        '  FROM ?? As t' +
                        '  LEFT JOIN ?? As s On t.`id` = s.`tid`' +
                        '  LEFT JOIN ?? As sa ON s.`id` = sa.`sid`' +
                        '  LEFT JOIN ?? As pa ON sa.`aid` = pa.`id`' +
                        '  WHERE sa.`aid` <> ? and sa.`end_time` > ? and t.`project_id` = ?' +
                        '  GROUP By t.`id`' +
                        '  ORDER By sa.`end_time`';
            const sqlParam = [this.ctx.service.tender.tableName, this.ctx.service.stage.tableName, this.tableName,
                this.ctx.service.projectAccount.tableName, uid, time, pid];
            return await this.db.query(sql, sqlParam);
        }

        /**
         * 获取审核人流程列表
         *
         * @param auditorId
         * @returns {Promise<*>}
         */
        async getAuditGroupByList(stageId, times) {
            const sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`aid`, la.`order` ' +
                'FROM ?? AS la, ?? AS pa ' +
                'WHERE la.`sid` = ? and la.`times` = ? and la.`aid` = pa.`id` GROUP BY la.`aid`';
            const sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, times];
            return await this.db.query(sql, sqlParam);
            // const sql = 'SELECT `tid`, `sid`, `aid`, `order` FROM ?? WHERE `sid` = ? and `times` = ? GROUP BY `aid`';
            // const sqlParam = [this.tableName, stageId, times];
            // return await this.db.query(sql, sqlParam);
        }

        /**
         * 复制上一期的审批人列表给最新一期
         *
         * @param transaction - 新增一期的事务
         * @param {Object} preStage - 上一期
         * @param {Object} newStage - 最新一期
         * @returns {Promise<*>}
         */
        async copyPreStageAuditors(transaction, preStage, newStage) {
            const auditors = await this.getAuditGroupByList(preStage.id, preStage.times);
            const newAuditors = [];
            for (const a of auditors) {
                const na = {
                    tid: preStage.tid,
                    sid: newStage.id,
                    aid: a.aid,
                    times: newStage.times,
                    order: newAuditors.length + 1,
                    status: auditConst.status.uncheck
                };
                newAuditors.push(na);
            }
            const result = await transaction.insert(this.tableName, newAuditors);
            return result.effectRows = auditors.length;
        }

        /**
         * 移除审核人
         *
         * @param {Number} stageId - 期id
         * @param {Number} status - 期状态
         * @param {Number} status - 期次数
         * @return {Promise<boolean>}
         */
        async getAuditorByStatus(stageId, status, times = 1) {
            let auditor = null;
            let sql = '';
            let sqlParam = '';
            switch (status) {
                case auditConst.status.checking :
                case auditConst.status.checked :
                case auditConst.status.checkNoPre :
                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`aid`, la.`order` ' +
                        'FROM ?? AS la, ?? AS pa ' +
                        'WHERE la.`sid` = ? and la.`status` = ? and la.`aid` = pa.`id` order by la.`times` desc, la.`id` desc';
                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, status];
                    auditor = await this.db.queryOne(sql, sqlParam);
                    break;
                case auditConst.status.checkNo :
                    sql = 'SELECT la.`aid`, pa.`name`, pa.`company`, pa.`role`, la.`times`, la.`sid`, la.`aid`, la.`order` ' +
                        'FROM ?? AS la, ?? AS pa ' +
                        'WHERE la.`sid` = ? and la.`status` = ? and la.`times` = ? and la.`aid` = pa.`id` order by la.`times` desc, la.`id` desc';
                    sqlParam = [this.tableName, this.ctx.service.projectAccount.tableName, stageId, auditConst.status.checkNo, parseInt(times) - 1];
                    auditor = await this.db.queryOne(sql, sqlParam);
                    break;
                case auditConst.status.uncheck :
                default:break;
            }
            return auditor;
        }
    }

    return StageAudit;
};
