| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 | 'use strict';/** * 质量管理 - 工程质量 * * @author Mai * @date 2024/7/22 * @version */const Ledger = require('../lib/ledger');class RuleCheck {    sortCondition(condition) {        const fieldKey = ['gongxu_name', 'yinbi_name', 'file_count', 'file_name'];        condition.forEach(c => { c.fieldKeyIndex = fieldKey.indexOf(c.fieldKey); });        condition.sort((a, b) => { return a.fieldKeyIndex - b.fieldKeyIndex; });    }    fileCountCheck(files, check) {        if (check.operateKey === '>') return files.length > parseInt(check.value);        if (check.operateKey === '=') return files.length === parseInt(check.value);    }    fileNameCheck(files, check) {        const matchName = check.multi ? check.value.split(';') : [check.value];        if (check.operateKey === '=') return files.findIndex(f => { return matchName.indexOf(f.filename) >= 0; }) >= 0;        if (check.operateKey === 'has') return files.findIndex(f => {            return matchName.findIndex(x => { return f.filename.indexOf(x) >= 0; }) >= 0;        }) >= 0;    }    getAllFiles() {        const files = [];        if (this.quality.kaigong) files.push(...this.quality.kaigong.files);        if (this.quality.gongxu) {            for (const gx of this.quality.gongxu.list) {                files.push(...gx.files);            }        }        if (this.quality.pingding) {            files.push(...this.quality.pingding.files);            this.quality.pingding.source_files.forEach(sf => {                if (sf.spec_type === 'add') files.push(sf);            });        }        if (this.quality.jiaogong) files.push(...this.quality.jiaogong.files);        // if (this.quality.yinbi) {        //     for (const yb of this.quality.yinbi.list) {        //         files.push(...yb.files);        //     }        // }        return files;    }    kaigongCheck(check) {        if (!this.quality.kaigong) return false;        switch (check.fieldKey) {            case 'file_count':                return this.fileCountCheck(this.quality.kaigong.files, check);            case 'file_name':                return this.fileNameCheck(this.quality.kaigong.files, check);            default:                return false;        }    }    GongxuNameCheck(check) {        const matchName = check.multi ? check.value.split(';') : [check.value];        if (check.operateKey === '=') {            this.matchGongxu = this.quality.gongxu.list.filter(f => { return matchName.indexOf(f.name) >= 0; });        }        if (check.operateKey === 'has') {            this.matchGongxu = this.quality.gongxu.list.filter(f => {                return matchName.findIndex(x => { return f.name.indexOf(x) >= 0; }) >= 0;            });        }        return this.matchGongxu.length > 0;    }    getGongxuFiles() {        const files = [];        const gongxuList = this.matchGongxu || this.quality.gongxu.list;        for (const gx of gongxuList) {            files.push(...gx.files);        }        return files;    }    gongxuCheck(check) {        switch (check.fieldKey) {            case 'gongxu_name':                return this.GongxuNameCheck(check);            case 'file_count':                return this.fileCountCheck(this.getGongxuFiles(), check);            case 'file_name':                return this.fileNameCheck(this.getGongxuFiles(), check);            default:                return false;        }    }    pingdingCheck(check) {        if (!this.quality.pingding) return false;        const files = [...this.quality.pingding.files, ...this.quality.pingding.source_files];        switch (check.fieldKey) {            case 'file_count':                return this.fileCountCheck(files, check);            case 'file_name':                return this.fileNameCheck(files, check);            default:                return false;        }    }    jiaogongCheck(check) {        if (!this.quality.jiaogong) return false;        switch (check.fieldKey) {            case 'file_count':                return this.fileCountCheck(this.quality.jiaogong.files, check);            case 'file_name':                return this.fileNameCheck(this.quality.jiaogong.files, check);            default:                return false;        }    }    YinbiNameCheck(check) {        const matchName = check.multi ? check.value.split(';') : [check.value];        if (check.operateKey === '=') {            this.matchYinbi = this.quality.yinbi.list.filter(f => { return matchName.indexOf(f.name) >= 0; });        }        if (check.operateKey === '>') {            this.matchYinbi = this.quality.yinbi.list.filter(f => {                return matchName.findIndex(x => { return f.name.indexOf(x) >= 0; }) >= 0;            });        }        return this.matchYinbi.length > 0;    }    getYinbiFiles() {        const files = [];        const yinbiList = this.matchYinbi || this.quality.yinbi.list;        for (const yb of yinbiList) {            files.push(...yb.files);        }        return files;    }    yinbiCheck(check) {        switch (check.fieldKey) {            case 'gongxu_name':                return this.YinbiNameCheck(check);            case 'file_count':                return this.fileCountCheck(this.getYinbiFiles(), check);            case 'file_name':                return this.fileNameCheck(this.getYinbiFiles(), check);            default:                return false;        }    }    allFilesCheck(check) {        const allFiles = this.getAllFiles();        switch (check.fieldKey) {            case 'file_count':                return this.fileCountCheck(allFiles, check);            case 'file_name':                return this.fileNameCheck(allFiles, check);            default:                return false;        }    }    conditionCheck(check) {        switch (check.blockKey) {            case 'kaigong':                return this.kaigongCheck(check);            case 'gongxu':                return this.gongxuCheck(check);            case 'pingding':                return this.pingdingCheck(check);            case 'jiaogong':                return this.jiaogongCheck(check);            case 'yinbi':                return this.yinbiCheck(check);            case 'all':                return this.allFilesCheck(check);            default:                return false;        }    }    calcQualityStatus(quality, group) {        this.quality = quality;        this.group = group;        for (const r of group.rules) {            if (r.condition.length === 0) return false;            if (r.condition.length > 1) this.sortCondition(r.condition);        }        const match = group.rules.filter(r => {            this.matchGongxu = null;            this.matchYinbi = null;            for (const check of r.condition) {                if (!this.conditionCheck(check)) {                    return false;                }            }            return true;        });        if (match.length === 0) return null;        const data = {};        for (const m of match) {            for (const s of m.push_status) {                if (!data[s.field] || s.value > data[s.field]) {                    data[s.field] = s.value;                }            }        }        return data;    }}module.exports = app => {    class Quality extends app.BaseService {        /**         * 构造函数         *         * @param {Object} ctx - egg全局变量         * @return {void}         */        constructor(ctx) {            super(ctx);            this.tableName = 'quality';            this.editableColumns = ['gxby_status', 'gxby_date', 'gxby_limit', 'dagl_status', 'dagl_limit'];            this.blockType = {                kaigong: { key: 'kaigong', name: '开工' },                gongxu: { key: 'gongxu', name: '工序' },                jiaogong: { key: 'jiaogong', name: '中间交工' },                pingding: { key: 'pingding', name: '评定' },                yinbi: { key: 'yinbi', name: '隐蔽工程' },                shiyan: { key: 'shiyan', name: '试验检测' },                waiwei: { key: 'waiwei', name: '外委检测' },                sanfang: { key: 'sanfang', name: '第三方检测' },            };        }        async saveQualityManage(tid, data) {            const quality = await this.getDataByCondition({ tid, rela_type: data.rela_type, rela_id: data.rela_id, rela_name: data.rela_name });            if (quality) {                const updateData = { id: quality.id, group_id: data.group_id, update_uid: this.ctx.session.sessionUser.accountId, };                await this.db.update(this.tableName, updateData);                updateData.rela_id = data.rela_id;                updateData.rela_name = data.rela_name;                return updateData;            } else {                const newQuality = {                    id: this.uuid.v4(), tid, rela_type: data.rela_type, rela_id: data.rela_id, rela_name: data.rela_name,                    create_uid: this.ctx.session.sessionUser.accountId, update_uid: this.ctx.session.sessionUser.accountId,                    group_id: data.group_id,                };                await this.db.insert(this.tableName, newQuality);                return newQuality;            }        }        async saveQuality(quality, filter, data, conn) {            data.update_uid = this.ctx.session.sessionUser.accountId;            data.is_used = 1;            if (quality) {                data.id = quality.id;                if (conn) {                    await conn.update(this.tableName, data);                } else {                    await this.db.update(this.tableName, data);                }                return data;            } else {                data.id = this.uuid.v4();                data.tid = this.ctx.tender.id;                data.rela_type = filter.rela_type;                data.rela_id = filter.rela_id;                data.rela_name = filter.rela_name;                data.create_uid = this.ctx.session.sessionUser.accountId;                if (conn) {                    await conn.insert(this.tableName, data);                } else {                    await this.db.insert(this.tableName, data);                }                return data;            }        }        async getQuality(filter) {            if (filter.quality_id) return await this.getDataByCondition({ id: filter.quality_id });            if (filter.rela_type && filter.rela_id) return await this.getDataByCondition({ tid: filter.tid || this.ctx.tender.id, rela_type: filter.rela_type, rela_id: filter.rela_id, rela_name: filter.rela_name });            throw '参数错误';        }        async _loadKgData(quality) {            if (!quality.kaigong_time) return;            quality.kaigong = {};            for (const p in quality) {                if (p.indexOf('kaigong_') !== 0) continue;                quality.kaigong[p] = quality[p];                delete quality[p];            }            const files = await this.ctx.service.qualityFile.getBlockFiles(quality, 'kaigong');            quality.kaigong.files = files.filter(f => { return !f.spec_type; });            quality.kaigong.qa_files = files.filter(f => { return f.spec_type === 'qa'; });            // todo 加载开工审批数据        }        async _loadGxData(quality) {            quality.gongxu = {};            // todo 加载工序审批数据            quality.gongxu.list = await this.ctx.service.qualityGongxu.getAllDataByCondition({ where: { quality_id: quality.id }, orders:[['create_time', 'asc']] });            for (const gx of quality.gongxu.list) {                gx.canEdit = gx.user_id === this.ctx.session.sessionUser.accountId;                gx.files = await this.ctx.service.qualityFile.getBlockFiles(quality, 'gongxu', gx.id);                // todo 加载工序步骤审批数据            }        }        async _loadPdData(quality) {            if (!quality.kaigong && quality.gongxu.list.length === 0) return;            quality.pingding = {};            for (const p in quality) {                if (p.indexOf('pingding_') !== 0) continue;                quality.kaigong[p] = quality[p];                delete quality[p];            }            const files = await this.ctx.service.qualityFile.getBlockFiles(quality, 'pingding');            quality.pingding.files = files.filter(f => { return !f.spec_type; });            quality.pingding.source_files = files.filter(f => { return f.spec_type === 'add'; }); // addtional            if (quality.gongxu) {                for (const gx of quality.gongxu.list) {                    const qaFiles = gx.files.filter(f => { return f.spec_type === 'qa'; });                    for (const f of qaFiles) {                        const qaF = JSON.parse(JSON.stringify(f));                        qaF.canEdit = false;                        quality.pingding.source_files.push(qaF);                    }                }            }            // todo 加载评定审批数据        }        async _loadJgData(quality) {            if (!quality.kaigong && quality.gongxu.list.length === 0) return;            quality.jiaogong = {};            for (const p in quality) {                if (p.indexOf('jiaogong_') !== 0) continue;                quality.jiaogong[p] = quality[p];                delete quality[p];            }            quality.jiaogong.files = await this.ctx.service.qualityFile.getBlockFiles(quality, 'jiaogong');        }        async _loadYbData(quality) {            quality.yinbi = {};            quality.yinbi.list = await this.ctx.service.qualityYinbi.getAllDataByCondition({ where: { quality_id: quality.id }, orders:[['create_time', 'asc']] });            for (const yb of quality.yinbi.list) {                yb.canEdit = yb.user_id === this.ctx.session.sessionUser.accountId;                const files = await this.ctx.service.qualityFile.getBlockFiles(quality, 'yinbi', yb.id);                yb.before_files = files.filter(f => { return f.spec_type === 'before'; });                yb.after_files = files.filter(f => { return f.spec_type === 'after'; });            }        }        async loadQualityDetail(quality) {            if (!quality) return;            await this._loadKgData(quality);            await this._loadGxData(quality);            await this._loadPdData(quality);            await this._loadJgData(quality);            await this._loadYbData(quality);        }        async getQualityGroup(quality) {            if (quality.group_id) return quality.group_id;            const ledger = await this.ctx.service.ledger.getDataById(quality.rela_id);            const sql = 'SELECT l.id, l.ledger_id, l.level, q.group_id ' +                `  FROM ${this.tableName} q LEFT JOIN ${this.ctx.service.ledger.tableName} l ON q.rela_id = l.id ` +                `  WHERE q.tid = ${quality.tid} and l.ledger_id in (${ledger.full_path.split('-').join(', ')}) and group_id <> ''` +                '  ORDER BY l.level DESC';            const allQuality = await this.db.query(sql);            return allQuality.length > 0 ? allQuality[0].group_id : '';        }        async checkQualityStatus(quality) {            const groupId = await this.getQualityGroup(quality);            if (!groupId) return null;            const groupRule = await this.ctx.service.qualityRule.getGroupRule(groupId);            if (!groupRule) return null;            const ruleCheck = new RuleCheck();            return ruleCheck.calcQualityStatus(quality, groupRule);        }        async checkQualityStatusAndSave(quality) {            const data = await this.checkQualityStatus(quality);            if (!data) return;            for (const field in data) {                quality[field] = data[field];            }            data.id = quality.id;            await this.db.update(this.tableName, data);        }        async kaigong(filter, name, date) {            const quality = await this.getQuality(filter);            const conn = await this.db.beginTransaction();            try {                const kaigongData = {                    kaigong_name: name || '开工工序', kaigong_date: date || this.ctx.moment().format('YYYY-MM-DD'),                    kaigong_uid: this.ctx.session.sessionUser.accountId, kaigong_time: new Date(),                };                await this.saveQuality(quality, filter, kaigongData, conn);                await conn.commit();            } catch (err) {                await conn.rollback();                throw err;            }        }        async delKaigong(filter) {            const quality = await this.getQuality(filter);            if (!quality || !quality.kaigong_uid) throw '该工程未开工';            if (quality.kaigong_uid !== this.ctx.session.sessionUser.accountId) throw '开工数据不是您新增的,无权删除';            const conn = await this.db.beginTransaction();            try {                await this.saveQuality(quality, filter, { kaigong_name: '', kaigong_date: '', kaigong_uid: 0, kaigong_time: null }, conn);                await conn.update(this.ctx.service.qualityFile.tableName, { is_deleted: 1 }, { where: { quality_id: quality.id, block_type: 'kaigong' } });                await conn.commit();            } catch (err) {                await conn.rollback();                throw err;            }        }        async pushIncStatus(select) {            const quality = [];            for (const s of select) {                const sq = await this.ctx.service.quality.getDataByCondition({ tid: this.ctx.tender.id, rela_type: s.rela_type, rela_id: s.rela_id, rela_name: s.rela_name });                if (sq && sq.is_used) {                    quality.push(sq);                    if (sq.rela_type === 'pos') sq.rela_pid = s.pid;                }            }            const xmjInsert = [], xmjUpdate = [], posInsert = [], posUpdate = [];            const xmjQuality = [], posQuality = [];            quality.forEach(q => {                if (q.rela_type === 'xmj') {                    xmjQuality.push(q);                } else {                    posQuality.push(q);                }            });            const xmjExtra = xmjQuality.length > 0 ? await this.ctx.service.ledgerExtra.getAllDataByCondition({ where: { id: xmjQuality.map(x => { return x.rela_id; }) } }) : [];            for (const xq of xmjQuality) {                const xe = xmjExtra.find(x => { return x.id === xq.rela_id; });                const wbs_url = `/3f/zh/info?pid=${this.ctx.session.sessionProject.id}&tid=${xq.tid}&${xq.rela_type}id=${xq.rela_id}`;                if (xe) {                    // xmjUpdate.push({ id: xe.id, gxby_status: xq.gxby_status, gxby_date: xq.gxby_date, dagl_status: xq.dagl_status, wbs_url });                    xmjUpdate.push({ id: xe.id, gxby_status: xq.gxby_status, dagl_status: xq.dagl_status, wbs_url });                } else {                    // xmjInsert.push({ id: xq.rela_id, gxby_status: xq.gxby_status, gxby_date: xq.gxby_date, dagl_status: xq.dagl_status, wbs_url });                    xmjInsert.push({ id: xq.rela_id, tid: this.ctx.tender.id, gxby_status: xq.gxby_status, dagl_status: xq.dagl_status, wbs_url });                }            }            for (const pq of posQuality) {                if (!pq.rela_pid || pq.rela_pid.length === 0) continue;                const posExtra = await this.ctx.service.posExtra.getAllDataByCondition({ where: { id: pq.rela_pid } });                for (const pid of pq.rela_pid) {                    const pe = posExtra.find(x => { return x.id === pid; });                    const wbs_url = `/3f/zh/info?pid=${this.ctx.session.sessionProject.id}&tid=${pq.tid}&${pq.rela_type}id=${pid}`;                    if (pe) {                        // posUpdate.push({ id: pe.id, gxby_status: pq.gxby_status, gxby_date: pq.gxby_date, dagl_status: pq.dagl_status, wbs_url });                        posUpdate.push({ id: pe.id, gxby_status: pq.gxby_status, dagl_status: pq.dagl_status, wbs_url });                    } else {                        // posInsert.push({ id: pid, gxby_status: pq.gxby_status, gxby_date: pq.gxby_date, dagl_status: pq.dagl_status, wbs_url });                        posInsert.push({ id: pid, tid: this.ctx.tender.id, gxby_status: pq.gxby_status, dagl_status: pq.dagl_status, wbs_url });                    }                }            }            const conn = await this.db.beginTransaction();            try {                if (xmjInsert.length > 0) await conn.insert(this.ctx.service.ledgerExtra.tableName, xmjInsert);                if (xmjUpdate.length > 0) await conn.updateRows(this.ctx.service.ledgerExtra.tableName, xmjUpdate);                if (posInsert.length > 0) await conn.insert(this.ctx.service.posExtra.tableName, posInsert);                if (posUpdate.length > 0) await conn.updateRows(this.ctx.service.posExtra.tableName, posUpdate);                await conn.commit();            } catch (err) {                this.ctx.log(err);                await conn.rollback();                throw '推送状态错误';            }            return xmjInsert.length + xmjUpdate.length + posInsert.length + posUpdate.length;        }        async getQualityTree(quality) {            const ledgerData = await this.ctx.service.ledger.getAllDataByCondition({ where: { tender_id: this.ctx.tender.id }});            const posData = await this.ctx.service.pos.getAllDataByCondition({ where: { tid: this.ctx.tender.id }});            const qualityTree = new Ledger.filterGatherTree(this.ctx, { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1 });            const ledgerTree = new Ledger.billsTree(this.ctx, {id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1});            const pos = new Ledger.pos({ id: 'id', ledgerId: 'lid' });            ledgerTree.loadDatas(ledgerData);            pos.loadDatas(posData);            const recursiveLoad = function (node, parent, type = 'xmj') {                if (type === 'xmj') {                    const cur = !node.b_code ? qualityTree.addNode({ id: node.id, tender_id: node.tender_id, code: node.code, name: node.name, rela_type: type, rela_id: node.id, rela_name: '', }, parent) : parent;                    if (node.children && node.children.length > 0) {                        for (const child of node.children) {                            recursiveLoad(child, cur);                        }                    } else {                        const posRange = pos.getLedgerPos(node.id) || [];                        for (const pos of posRange) {                            recursiveLoad(pos, cur, 'pos');                        }                    }                }                if (type === 'pos') {                    if (!parent) return;                    const cur = parent.children ? parent.children.find(x => { return x.name === node.name }) : null;                    if (!cur) {                        qualityTree.addNode({ id: node.id, tender_id: node.tid, rela_id: parent.id, code: '', name: node.name, rela_type: 'pos', rela_name: node.name, pid: [node.id]}, parent);                    } else {                        cur.pid.push(node.id);                    }                }            };            for (const node of ledgerTree.children) {                recursiveLoad(node);            }            qualityTree.sortTreeNode(false);            if (quality) {                const qualityIndex = [];                for (const q of quality) {                    const key = q.rela_type + ';' + q.rela_id + ';' + q.rela_name;                    qualityIndex[key] = q;                }                for (const x of qualityTree.nodes) {                    const qua = qualityIndex[x.rela_type + ';' + x.rela_id + ';' + x.rela_name];                    if (qua) x.quality = qua;                }            }            return qualityTree;        }        async pushAllStatus() {            const quality = await this.ctx.service.quality.getAllDataByCondition({ where: { tid: this.ctx.tender.id, is_used: 1 } });            if (quality.length === 0) return 0;            const qualityTree = await this.getQualityTree(quality);            const xmjInsert = [], xmjUpdate = [], posInsert = [], posUpdate = [];            const xmjExtra = await this.ctx.service.ledgerExtra.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });            const posExtra = await this.ctx.service.posExtra.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });            for (const node of qualityTree.nodes) {                if (!node.quality) continue;                if (node.rela_type === 'xmj') {                    const xe = xmjExtra.find(x => { return x.id === node.rela_id; });                    const wbs_url = `/3f/zh/info?pid=${this.ctx.session.sessionProject.id}&tid=${this.ctx.tender.id}&xmjid=${node.rela_id}`;                    if (xe) {                        // xmjUpdate.push({ id: xe.id, gxby_status: node.quality.gxby_status, gxby_date: node.quality.gxby_date, dagl_status: node.quality.dagl_status, wbs_url });                        xmjUpdate.push({ id: xe.id, gxby_status: node.quality.gxby_status, dagl_status: node.quality.dagl_status, wbs_url });                    } else {                        // xmjInsert.push({ id: node.rela_id, tid: this.ctx.tender.id, gxby_status: node.quality.gxby_status, gxby_date: node.quality.gxby_date, dagl_status: node.quality.dagl_status, wbs_url });                        xmjInsert.push({ id: node.rela_id, tid: this.ctx.tender.id, gxby_status: node.quality.gxby_status, dagl_status: node.quality.dagl_status, wbs_url });                    }                } else {                    for (const pid of node.pid) {                        const pe = posExtra.find(x => { return x.id === pid; });                        const wbs_url = `/3f/zh/info?pid=${this.ctx.session.sessionProject.id}&tid=${this.ctx.tender.id}&posid=${pid}`;                        if (pe) {                            // posUpdate.push({ id: pe.id, gxby_status: node.quality.gxby_status, gxby_date: node.quality.gxby_date, dagl_status: node.quality.dagl_status, wbs_url });                            posUpdate.push({ id: pe.id, gxby_status: node.quality.gxby_status, dagl_status: node.quality.dagl_status, wbs_url });                        } else {                            // posInsert.push({ id: pid, tid: this.ctx.tender.id, gxby_status: node.quality.gxby_status, gxby_date: node.quality.gxby_date, dagl_status: node.quality.dagl_status, wbs_url });                            posInsert.push({ id: pid, tid: this.ctx.tender.id, gxby_status: node.quality.gxby_status, dagl_status: node.quality.dagl_status, wbs_url });                        }                    }                }            }            const conn = await this.db.beginTransaction();            try {                // const defaultData = { gxby_status: -1, gxby_date: null, dagl_status: -1 };                const defaultData = { gxby_status: -1, dagl_status: -1 };                await conn.update(this.ctx.service.ledgerExtra.tableName, defaultData, { where: {tid: this.ctx.tender.id } });                await conn.update(this.ctx.service.posExtra.tableName, defaultData, { where: {tid: this.ctx.tender.id } });                if (xmjInsert.length > 0) await conn.insert(this.ctx.service.ledgerExtra.tableName, xmjInsert);                if (xmjUpdate.length > 0) await conn.updateRows(this.ctx.service.ledgerExtra.tableName, xmjUpdate);                if (posInsert.length > 0) await conn.insert(this.ctx.service.posExtra.tableName, posInsert);                if (posUpdate.length > 0) await conn.updateRows(this.ctx.service.posExtra.tableName, posUpdate);                await conn.commit();            } catch (err) {                this.ctx.log(err);                await conn.rollback();                throw '推送状态错误';            }            return xmjInsert.length + xmjUpdate.length + posInsert.length + posUpdate.length;        }    }    return Quality;};
 |