瀏覽代碼

质量管理

MaiXinRong 6 天之前
父節點
當前提交
68a3fd26aa

+ 40 - 45
app/controller/quality_controller.js

@@ -25,15 +25,13 @@ module.exports = app => {
 
         async tender(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
 
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.quality.tender),
                 };
-                const accountList = await ctx.service.projectAccount.getAllDataByCondition({
-                    where: { project_id: ctx.session.sessionProject.id, enable: 1 },
-                    columns: ['id', 'name', 'company', 'role', 'enable', 'is_admin', 'account_group', 'mobile'],
-                });
+
+                const accountList = await ctx.service.projectAccount.getAllSubProjectAccount(ctx.subProject);
                 renderData.accountList = accountList;
                 const unitList = await ctx.service.constructionUnit.getAllDataByCondition({ where: { pid: ctx.session.sessionProject.id } });
                 renderData.accountGroup = unitList.map(item => {
@@ -42,8 +40,8 @@ module.exports = app => {
                 });
                 renderData.accountInfo = await this.ctx.service.projectAccount.getDataById(ctx.session.sessionUser.accountId);
                 renderData.tenderList = await ctx.service.tender.getSpecList(ctx.service.tenderPermission, 'quality', ctx.session.sessionUser.is_admin ? 'all' : '');
-                renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.session.sessionProject.id);
-                // renderData.selfCategoryLevel = this.ctx.subProject.permission.self_category_level;
+                renderData.categoryData = await this.ctx.service.category.getAllCategory(this.ctx.subProject);
+                renderData.selfCategoryLevel = this.ctx.subProject.permission.self_category_level;
                 renderData.permissionConst = ctx.service.tenderPermission.partPermissionConst('quality');
                 renderData.permissionBlock = ctx.service.tenderPermission.partPermissionBlock('quality');
                 await this.layout('quality/tender.ejs', renderData, 'quality/tender_modal.ejs');
@@ -78,7 +76,7 @@ module.exports = app => {
 
         async info(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
                 const renderData = {
                     thirdParty: {
                         gxby: ctx.session.sessionProject.gxby_status,
@@ -90,13 +88,13 @@ module.exports = app => {
             } catch (err) {
                 ctx.log(err);
                 ctx.postError(err, '无法查看质量管理数据');
-                ctx.redirect('/quality');
+                ctx.redirect(`/sp/${ctx.subProject.id}/quality`);
             }
         }
 
         async flaw(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.quality.flaw),
                 };
@@ -104,13 +102,13 @@ module.exports = app => {
             } catch (err) {
                 ctx.log(err);
                 ctx.postError(err, '无法查看质量管理数据');
-                ctx.redirect('/quality');
+                ctx.redirect(`/sp/${ctx.subProject.id}/quality`);
             }
         }
 
         async lab(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.quality.lab),
                 };
@@ -118,40 +116,40 @@ module.exports = app => {
             } catch (err) {
                 ctx.log(err);
                 ctx.postError(err, '无法查看质量管理数据');
-                ctx.redirect('/quality');
+                ctx.redirect(`/sp/${ctx.subProject.id}/quality`);
             }
         }
 
         async _loadXmjData(spec) {
             const xmj = await this.ctx.service.ledger.getAllDataByCondition({
                 where: { tender_id: this.ctx.tender.id },
-                columns: ['id', 'tender_id', 'ledger_id', 'ledger_pid', 'level', 'order', 'full_path', 'is_leaf', 'code', 'name'],
+                columns: ['id', 'tender_id', 'ledger_id', 'ledger_pid', 'level', 'order', 'full_path', 'is_leaf', 'code', 'b_code', 'name'],
             });
-            const quality = spec && spec.loadStatus ? await this.ctx.service.quality.getAllDataByCondition({
-                where: { tid: this.ctx.tender.id, rela_type: 'xmj' },
-                columns: ['rela_id', 'gxby_status', 'gxby_date', 'dagl_status'],
-            }) : [];
-            this.ctx.helper.assignRelaData(xmj, [
-                { data: quality, fields: ['gxby_status', 'gxby_date', 'dagl_status'], prefix: '', relaId: 'rela_id' },
-            ]);
-            return xmj;
+            // const quality = spec && spec.loadStatus ? await this.ctx.service.quality.getAllDataByCondition({
+            //     where: { tid: this.ctx.tender.id, rela_type: 'xmj' },
+            //     columns: ['rela_id', 'gxby_status', 'gxby_date', 'dagl_status'],
+            // }) : [];
+            // this.ctx.helper.assignRelaData(xmj, [
+            //     { data: quality, fields: ['gxby_status', 'gxby_date', 'dagl_status'], prefix: '', relaId: 'rela_id' },
+            // ]);
+            return xmj; // .filter(x => { return !x.b_code; });
         }
         async _loadPosData(condition, spec) {
             const pos = await this.ctx.service.pos.getAllDataByCondition({
                 where: condition,
-                columns: ['id', 'tid', 'lid', 'tree_id', 'tree_pid', 'level', 'order', 'full_path', 'is_leaf', 'code', 'b_code', 'name'],
+                columns: ['id', 'tid', 'lid', 'name'],
             });
-            const quality = spec && spec.loadStatus ? await this.ctx.service.quality.getAllDataByCondition({
-                where: { tid: this.ctx.tender.id, rela_type: 'pos' },
-                columns: ['rela_id', 'gxby_status', 'gxby_date', 'dagl_status'],
-            }) : [];
-            this.ctx.helper.assignRelaData(pos, [
-                { data: quality, fields: ['gxby_status', 'gxby_date', 'dagl_status'], prefix: '', relaId: 'rela_id' },
-            ]);
+            // const quality = spec && spec.loadStatus ? await this.ctx.service.quality.getAllDataByCondition({
+            //     where: { tid: this.ctx.tender.id, rela_type: 'pos' },
+            //     columns: ['rela_id', 'gxby_status', 'gxby_date', 'dagl_status'],
+            // }) : [];
+            // this.ctx.helper.assignRelaData(pos, [
+            //     { data: quality, fields: ['gxby_status', 'gxby_date', 'dagl_status'], prefix: '', relaId: 'rela_id' },
+            // ]);
             return pos;
         }
-        async _loadDetailData(id) {
-            const result = await this.ctx.service.quality.getDataByCondition({ tid: this.ctx.tender.id, rela_id: id });
+        async _loadDetailData(rela_type, rela_id, rela_name) {
+            const result = await this.ctx.service.quality.getDataByCondition({ tid: this.ctx.tender.id, rela_type, rela_id, rela_name });
             if (!result) return result;
             await this.ctx.service.quality.loadQualityDetail(result);
             await this.ctx.service.quality.checkQualityStatusAndSave(result);
@@ -165,12 +163,9 @@ module.exports = app => {
                     return this._loadXmjData(data.spec);
                 case 'pos':
                     return this._loadPosData({ tid: this.ctx.tender.id }, data.spec);
-                case 'pos1':
-                    if (result.pos) return result.pos.filter(p => { return p.level === 1; });
-                    return this._loadPosData({ tid: this.ctx.tender.id, level: 1 }, data.spec);
                 case 'detail':
-                    if (!data.id) throw '缺少参数';
-                    return this._loadDetailData(data.id);
+                    if (!data.rela_id && !data.rela_type) throw '缺少参数';
+                    return this._loadDetailData(data.rela_type, data.rela_id, data.rela_name);
                 case 'quality':
                     return await this.ctx.service.quality.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
                 case 'lab':
@@ -241,7 +236,7 @@ module.exports = app => {
                         break;
                     default: throw '请求错误';
                 }
-                const quality = await this._loadDetailData(data.rela_id);
+                const quality = await this._loadDetailData(data.rela_type, data.rela_id, data.rela_name);
                 ctx.body = { err: 0, msg: '', data: quality };
             } catch (err) {
                 ctx.log(err);
@@ -280,7 +275,7 @@ module.exports = app => {
                     const filepath = `${ctx.session.sessionProject.id}/${ctx.tender.id}/quality/${blockType}/${ctx.moment().format('YYYYMMDD')}/${create_time + '_' + index + fileInfo.ext}`;
 
                     // 保存文件
-                    await ctx.app.oss.put(filepath, stream);
+                    await ctx.fujianOss.put(ctx.fujianOssPath + filepath, stream);
                     await sendToWormhole(stream);
 
                     // 插入到stage_pay对应的附件列表中
@@ -332,9 +327,9 @@ module.exports = app => {
 
         async rule(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
-                const ruleGroups = await ctx.service.qualityRule.getRuleGroups(ctx.session.sessionProject.id);
-                const tenderList = await ctx.service.tender.getAllDataByCondition({ where: { project_id: ctx.session.sessionProject.id } });
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
+                const ruleGroups = await ctx.service.qualityRule.getRuleGroups(ctx.subProject.id);
+                const tenderList = await ctx.service.tender.getAllDataByCondition({ where: { spid: ctx.subProject.id } });
                 const renderData = {
                     jsFiles: this.app.jsFiles.common.concat(this.app.jsFiles.quality.rule),
                     ruleGroups,
@@ -348,12 +343,12 @@ module.exports = app => {
             } catch (err) {
                 ctx.log(err);
                 ctx.postError(err, '无法查看质量管理数据');
-                ctx.redirect('/quality');
+                ctx.redirect(`/sp/${ctx.subProject.id}/quality`);
             }
         }
         async ruleSave(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.group && !data.rule && !data.quality) throw '参数错误';
                 if (data.group) {
@@ -382,7 +377,7 @@ module.exports = app => {
         }
         async pushStatus(ctx) {
             try {
-                if (!ctx.session.sessionProject.page_show.quality) throw '该功能已关闭';
+                if (!ctx.subProject.page_show.quality) throw '该功能已关闭';
                 const data = JSON.parse(ctx.request.body.data);
                 if (!data.push_type) throw '参数错误';
                 let count;

+ 12 - 2
app/extend/context.js

@@ -68,14 +68,24 @@ module.exports = {
         }
     },
 
-    get hisOssPath() {
-        return this.app.config.hisOssPath;
+    // 所有附件都存储于fujianOss
+    get fujianOss() {
+        return this.app.fujianOss;
+    },
+
+    get fujianOssPath() {
+        return this.app.config.fujianOssFolder;
     },
 
+    // his和stash都存储于hisOss下,路径不同
     get hisOss() {
         return this.app.hisOss;
     },
 
+    get hisOssPath() {
+        return this.app.config.hisOssPath;
+    },
+
     get stashOssPath() {
         return this.app.config.stashOssPath;
     },

+ 10 - 0
app/public/js/global.js

@@ -431,6 +431,16 @@ const postDataWithFile = function (url, formData, successCallback, errorCallBack
     });
 };
 
+const postDataWithFileAsync = function (url, formData, showWaiting = true) {
+    return new Promise(function (resolve, reject) {
+        postDataWithFile(url, formData, result => {
+            resolve(result);
+        }, err => {
+            reject(err);
+        }, showWaiting);
+    });
+};
+
 const postDataWithFileProgress = function (url, formData, successCallback, errorCallBack) {
     showUploadFileProgress();
     $.ajax({

+ 49 - 20
app/public/js/quality_info.js

@@ -19,26 +19,55 @@ $(document).ready(() => {
     SpreadJsObj.initSheet(xmjSheet, xmjSpreadSetting);
     const xmjTree = createNewPathTree('gather', { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1 });
 
-    postData('load', { filter: 'xmj;pos1', spec: { loadStatus: 1 } }, function(result) {
-        result.xmj.forEach(x => { x.rela_type = 'xmj'; });
-        xmjTree.loadDatas(result.xmj);
-        const posIndex = {};
-        for (const p of result.pos1) {
-            if (!posIndex[p.lid]) posIndex[p.lid] = [];
-            posIndex[p.lid].push(p);
-        }
-        for (const pi in posIndex) {
-            const xmj = xmjTree.nodes.find(x => { return x.id === pi; });
-            if (!xmj || (xmj.children && xmj.children.length > 0)) continue;
+    postData('load', { filter: 'xmj;pos;quality', spec: { loadStatus: 1 } }, function(result) {
+        const ledgerTree = createNewPathTree('ledger', { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1 });
+        const pos = new PosData({id: 'id', ledgerId: 'lid',});
+        ledgerTree.loadDatas(result.xmj);
+        pos.loadDatas(result.pos);
 
-            const posRange = posIndex[pi];
-            posRange.sort((a, b) => { return a.order - b.order; });
-            for (const p of posRange) {
-                if (p.b_code) continue;
-                xmjTree.addNode({ id: p.id, code: p.code, name: p.name, rela_type: 'pos' }, xmj);
+        const recursiveLoad = function (node, parent, type = 'xmj') {
+            if (type === 'xmj') {
+                const cur = !node.b_code ? xmjTree.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) {
+                    xmjTree.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);
         }
         xmjTree.sortTreeNode(false);
+
+        const qualityIndex = [];
+        for (const q of result.quality) {
+            const key = q.rela_type + ';' + q.rela_id + ';' + q.rela_name;
+            qualityIndex[key] = q;
+        }
+        for (const x of xmjTree.nodes) {
+            const qua = qualityIndex[x.rela_type + ';' + x.rela_id + ';' + x.rela_name];
+            if (qua) {
+                x.gxby_status = qua.gxby_status;
+                x.gxby_date = qua.gxby_date;
+                x.dagl_status = qua.dagl_status;
+            }
+        }
+
         SpreadJsObj.loadSheetData(xmjSheet, SpreadJsObj.DataType.Tree, xmjTree);
     });
 
@@ -52,7 +81,7 @@ $(document).ready(() => {
         }
         getFilterData() {
             if (!this.node) return null;
-            const result = { rela_type: this.node.rela_type, rela_id: this.node.id };
+            const result = { rela_type: this.node.rela_type, rela_id: this.node.rela_id, rela_name: this.node.rela_name };
             if (this.node.quality) result.quality_id = this.node.quality.id;
             return result;
         }
@@ -864,7 +893,7 @@ $(document).ready(() => {
                 $('#quality-detail').show();
             }
             if (!node.quality || force) {
-                node.quality = (await postDataAsync('load', { filter: 'detail', id: node.id })).detail;
+                node.quality = (await postDataAsync('load', { filter: 'detail', rela_type: node.rela_type, rela_id: node.rela_id, rela_name: node.rela_name, })).detail;
                 if (node.quality) {
                     node.gxby_status = node.quality.gxby_status;
                     node.gxby_date = node.quality.gxby_date;
@@ -899,10 +928,10 @@ $(document).ready(() => {
                     if (node.children && node.children.length > 0) {
                         const posterity = xmjTree.getPosterity(node);
                         for (const p of posterity) {
-                            if (!node.children || node.children.length === 0) select.push(node.id);
+                            if (!node.children || node.children.length === 0) select.push({ rela_type: node.rela_type, rela_id: node.rela_id, rela_name: node.rela_name, pid: node.pid });
                         }
                     } else {
-                        select.push(node.id);
+                        select.push({ rela_type: node.rela_type, rela_id: node.rela_id, rela_name: node.rela_name, pid: node.pid });
                     }
                     postData('push', {push_type: 'inc', select}, function(result) {
                         if (!result) {

+ 48 - 30
app/public/js/quality_rule.js

@@ -539,39 +539,57 @@ $(() => {
     let tenderId;
     const loadTenderData = function(tid) {
         tenderId = tid;
-        postData(`/quality/tender/${tid}/load`, {filter: 'xmj;pos1;quality'}, function(result) {
-            const items = getSelectGroup();
-            result.quality.forEach(q => {
-                const index = items.findIndex( i => { return i.value === q.group_id; } );
-                if (index < 0) return;
-                if (q.rela_type === 'xmj') {
-                    const x = result.xmj.find(x => { return x.id === q.rela_id; });
-                    if (x) x.group_id = q.group_id;
-                } else if (q.rela_type === 'pos') {
-                    const x = result.pos1.find(x => { return x.id === q.rela_id; });
-                    if (x) x.group_id = q.group_id;
-                }
-            });
+        postData(`/sp/${spid}/quality/tender/${tid}/load`, {filter: 'xmj;pos;quality'}, function(result) {
+            const ledgerTree = createNewPathTree('ledger', { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1 });
+            const pos = new PosData({id: 'id', ledgerId: 'lid',});
+            ledgerTree.loadDatas(result.xmj);
+            pos.loadDatas(result.pos);
 
-            xmjTree.loadDatas(result.xmj);
-            xmjTree.nodes.forEach(x => { x.rela_type = 'xmj'; });
-            const posIndex = {};
-            for (const p of result.pos1) {
-                if (!posIndex[p.lid]) posIndex[p.lid] = [];
-                posIndex[p.lid].push(p);
+            const recursiveLoad = function (node, parent, type = 'xmj') {
+                if (type === 'xmj') {
+                    const cur = !node.b_code ? xmjTree.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) {
+                        xmjTree.addNode({ id: node.id, tender_id: node.tid, rela_id: parent.id, code: '', name: node.name, rela_type: 'type', rela_name: node.name, pid: [node.id]}, parent);
+                    } else {
+                        cur.pid.push(node.id);
+                    }
+                }
+            };
+            xmjTree.clearDatas();
+            for (const node of ledgerTree.children) {
+                recursiveLoad(node);
             }
-            for (const pi in posIndex) {
-                const xmj = xmjTree.nodes.find(x => { return x.id === pi; });
-                if (!xmj || (xmj.children && xmj.children.length > 0)) continue;
+            xmjTree.sortTreeNode(false);
 
-                const posRange = posIndex[pi];
-                posRange.sort((a, b) => { return a.order - b.order; });
-                for (const p of posRange) {
-                    if (p.b_code) continue;
-                    xmjTree.addNode({ id: p.id, tender_id: p.tid, code: p.code, name: p.name, group_id: p.group_id, rela_type: 'pos' }, xmj);
+            const items = getSelectGroup();
+            const qualityIndex = [];
+            for (const q of result.quality) {
+                const key = q.rela_type + ';' + q.rela_id + ';' + q.rela_name;
+                qualityIndex[key] = q;
+            }
+            for (const x of xmjTree.nodes) {
+                const qua = qualityIndex[x.rela_type + ';' + x.rela_id + ';' + x.rela_name];
+                if (qua) {
+                    const index = items.findIndex( i => { return i.value === qua.group_id; } );
+                    if (index < 0) return;
+                    x.group_id = qua.group_id;
                 }
             }
-            xmjTree.sortTreeNode(false);
+
             SpreadJsObj.loadSheetData(xmjSheet, SpreadJsObj.DataType.Tree, xmjTree);
         });
     };
@@ -596,11 +614,11 @@ $(() => {
         if (col.field !== 'group_id') return;
 
         const node = SpreadJsObj.getSelectObject(info.sheet);
-        const updateData = { rela_type: node.rela_type, rela_id: node.id, group_id: info.editingText || '' };
+        const updateData = { rela_type: node.rela_type, rela_id: node.rela_id, rela_name: node.rela_name, group_id: info.editingText || '' };
         if (updateData.group_id === node.group_id || (!updateData.group_id && !node.group_id)) return;
 
         // 更新至服务器
-        postData(`/quality/tender/${node.tender_id}/rule/save`, { quality: updateData }, function (result) {
+        postData(`/sp/${spid}/quality/tender/${node.tender_id}/rule/save`, { quality: updateData }, function (result) {
             node.group_id = result.group_id;
             SpreadJsObj.reLoadRowData(info.sheet, info.row, 1);
         }, function() {

+ 2 - 2
app/public/js/quality_tender.js

@@ -13,7 +13,7 @@ const tenderListSpec = (function(){
             html.push(arr.indexOf(node) === arr.length - 1 ? '└' : '├');
             html.push('</span>');
             //html.push('<a href="/tender/' + node.id + '">', node[c.field], '</a>');
-            html.push(`<a href="/quality/tender/${node.id}/info" name="name" style="min-width: 200px;word-break:break-all;" id="${node.id}">${node.name}</a>`);
+            html.push(`<a href="/sp/${spid}/quality/tender/${node.id}/info" name="name" style="min-width: 200px;word-break:break-all;" id="${node.id}">${node.name}</a>`);
         }
         html.push('</td>');
 
@@ -35,7 +35,7 @@ const tenderListSpec = (function(){
     function getTenderTreeHeaderHtml() {
         const html = [];
         const left = $('#sub-menu').css('display') === 'none' ? 56 : 176;
-        html.push('<table class="table table-hover table-bordered" id="progress-table">');
+        html.push('<table class="table table-hover table-bordered">');
         html.push('<thead style="position: sticky;left:'+ left +'px;top: 0;" class="text-center">', '<tr>');
         html.push('<th style="min-width: 50%">',  '标段名称',  tenderListOrder.getOrderButton('name'), '</th>');
         html.push('<th style="width: 15%">', '创建时间',  tenderListOrder.getOrderButton('create_time'), '</th>');

+ 1 - 0
app/public/js/tender_list_base.js

@@ -363,6 +363,7 @@ $(document).ready(() => {
     bindTenderUrl();
     localHideList();
     tenderTreeShowLevel.initShowLevel();
+    console.log($("#progress-table"));
     if ($("#progress-table").length > 0) {
         $("#progress-table").colResizable({
             liveDrag: true,

+ 107 - 36
app/service/quality.js

@@ -8,6 +8,8 @@
  * @version
  */
 
+const Ledger = require('../lib/ledger');
+
 class RuleCheck {
     sortCondition(condition) {
         const fieldKey = ['gongxu_name', 'yinbi_name', 'file_count', 'file_name'];
@@ -279,7 +281,7 @@ module.exports = app => {
 
         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_id: filter.rela_id, rela_name: filter.rela_name });
+            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 '参数错误';
         }
 
@@ -421,8 +423,14 @@ module.exports = app => {
         }
 
         async pushIncStatus(select) {
-            const quality = await this.ctx.service.quality.getAllDataByCondition({ where: { tid: this.ctx.tender.id, rela_id: select, is_used: 1 } });
-            if (quality.length === 0) return 0;
+            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 => {
@@ -437,19 +445,27 @@ module.exports = app => {
                 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, 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, 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 });
                 }
             }
-            const posExtra = posQuality.length > 0 ? await this.ctx.service.posExtra.getAllDataByCondition({ where: { id: posQuality.map(x => { return x.rela_id; }) } }) : [];
+
             for (const pq of posQuality) {
-                const pe = posExtra.find(x => { return x.id === pq.rela_id; });
-                const wbs_url = `/3f/zh/info?pid=${this.ctx.session.sessionProject.id}&tid=${pq.tid}&${pq.rela_type}id=${pq.rela_id}`;
-                if (pe) {
-                    posUpdate.push({ id: pe.id, gxby_status: pq.gxby_status, gxby_date: pq.gxby_date, dagl_status: pq.dagl_status, wbs_url });
-                } else {
-                    posInsert.push({ id: pq.rela_id, gxby_status: pq.gxby_status, gxby_date: pq.gxby_date, dagl_status: pq.dagl_status, wbs_url });
+                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();
@@ -466,41 +482,96 @@ module.exports = app => {
             }
             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 xmjQuality = [], posQuality = [];
-            quality.forEach(q => {
-                if (q.rela_type === 'xmj') {
-                    xmjQuality.push(q);
-                } else {
-                    posQuality.push(q);
-                }
-            });
+            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 } });
-            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 });
-                } else {
-                    xmjInsert.push({ id: xq.rela_id, tid: this.ctx.tender.id, gxby_status: xq.gxby_status, gxby_date: xq.gxby_date, dagl_status: xq.dagl_status, wbs_url });
-                }
-            }
             const posExtra = await this.ctx.service.posExtra.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
-            for (const pq of posQuality) {
-                const pe = posExtra.find(x => { return x.id === pq.rela_id; });
-                const wbs_url = `/3f/zh/info?pid=${this.ctx.session.sessionProject.id}&tid=${pq.tid}&${pq.rela_type}id=${pq.rela_id}`;
-                if (pe) {
-                    posUpdate.push({ id: pe.id, gxby_status: pq.gxby_status, gxby_date: pq.gxby_date, dagl_status: pq.dagl_status, wbs_url });
+            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 {
-                    posInsert.push({ id: pq.rela_id, tid: this.ctx.tender.id, gxby_status: pq.gxby_status, gxby_date: pq.gxby_date, dagl_status: pq.dagl_status, wbs_url });
+                    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, 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 } });
 

+ 1 - 1
app/service/quality_file.js

@@ -28,7 +28,7 @@ module.exports = app => {
         analysisFiles(files) {
             const helper = this.ctx.helper;
             const userId = this.ctx.session.sessionUser.accountId;
-            const ossPath = this.ctx.app.config.ossUrl;
+            const ossPath = this.ctx.app.config.fujianOssPath;
             files.forEach(x => {
                 x.viewpath = helper.canPreview(x.fileext) ? ossPath + x.filepath : '';
                 x.filepath = ossPath + x.filepath;

+ 8 - 7
app/service/quality_rule.js

@@ -23,9 +23,9 @@ module.exports = app => {
             this.tableName = 'quality_rule';
         }
 
-        async getGroupList(pid) {
-            const sql = `SELECT group_id, group_name FROM ${this.tableName} WHERE pid = ? GROUP BY group_id`;
-            return await this.db.query(sql, [pid]);
+        async getGroupList(spid) {
+            const sql = `SELECT group_id, group_name FROM ${this.tableName} WHERE spid = ? GROUP BY group_id`;
+            return await this.db.query(sql, [spid]);
         }
 
         analysisiRule(data) {
@@ -47,10 +47,10 @@ module.exports = app => {
             return result;
         }
 
-        async getRuleGroups(pid) {
+        async getRuleGroups(spid) {
             const result = await this.getAllDataByCondition({
                 columns: ['id', 'group_id', 'group_name', 'name', 'condition', 'push_status', 'memo'],
-                where: { pid },
+                where: { spid },
             });
             return this.analysisRuleGroups(result);
         }
@@ -104,7 +104,7 @@ module.exports = app => {
             }
 
             const newRule = {
-                group_id: this.uuid.v4(), pid: this.ctx.session.sessionProject.id,
+                group_id: this.uuid.v4(), pid: this.ctx.session.sessionProject.id, spid: this.ctx.subProject.id,
                 user_id: this.ctx.session.sessionUser.accountId,
                 group_name: group_name || '新增规则组', name: '新增规则', condition: '[]', push_status: '[]',
             };
@@ -133,6 +133,7 @@ module.exports = app => {
                 await this.db.update(this.tableName, data);
             } else {
                 data.pid = this.ctx.session.sessionProject.id;
+                data.spid = this.ctx.subProject.id;
                 data.user_id = this.ctx.session.sessionUser.accountId;
                 data.name = data.name || '新增规则';
                 data.condition = data.condition ? JSON.stringify(data.condition) : '[]';
@@ -155,7 +156,7 @@ module.exports = app => {
             if (!group) throw '您选择的规则组不存在,请刷新页面再试';
             const insertData = rules.map(rule => {
                 return {
-                    pid: rule.pid, user_id: this.ctx.session.sessionUser.accountId,
+                    pid: rule.pid, spid: rule.spid, user_id: this.ctx.session.sessionUser.accountId,
                     group_id: group.group_id, group_name: group.group_name,
                     name: rule.name, condition: rule.condition, push_status: rule.push_status,
                 };

+ 4 - 4
app/view/quality/sub_memu_list.ejs

@@ -1,4 +1,4 @@
-<nav-menu title="返回" url="/quality" tclass="text-primary" ml="1" icon="fa-chevron-left"></nav-menu>
-<nav-menu title="工程资料" url="/quality/tender/<%= ctx.tender.id %>/info%>" ml="3" active="<%= ctx.url.indexOf('/info') %>"></nav-menu>
-<!--<nav-menu title="缺陷管理" url="/quality/tender/<%= ctx.tender.id %>/flaw%>" ml="3" active="<%= ctx.url.indexOf('/flaw') %>"></nav-menu>-->
-<!--<nav-menu title="试验报告" url="/quality/tender/<%= ctx.tender.id %>/lab%>" ml="3" active="<%= ctx.url.indexOf('/lab') %>"></nav-menu>-->
+<nav-menu title="返回" url="/sp/<%- ctx.subProject.id %>/quality/tender" tclass="text-primary" ml="1" icon="fa-chevron-left"></nav-menu>
+<nav-menu title="工程资料" url="/sp/<%- ctx.subProject.id %>/quality/tender/<%= ctx.tender.id %>/info%>" ml="3" active="<%= ctx.url.indexOf('/info') %>"></nav-menu>
+<!--<nav-menu title="缺陷管理" url="/sp/<%- ctx.subProject.id %>/quality/tender/<%= ctx.tender.id %>/flaw%>" ml="3" active="<%= ctx.url.indexOf('/flaw') %>"></nav-menu>-->
+<!--<nav-menu title="试验报告" url="/sp/<%- ctx.subProject.id %>/quality/tender/<%= ctx.tender.id %>/lab%>" ml="3" active="<%= ctx.url.indexOf('/lab') %>"></nav-menu>-->

+ 28 - 8
app/view/quality/tender.ejs

@@ -1,18 +1,18 @@
+<% include ../tender/list_sub_menu.ejs %>
 <div class="panel-content">
     <div class="panel-title fluid">
         <div class="title-main  d-flex justify-content-between">
-            <div>
-                <div class="d-inline-block mr-2">
-                    <button type="button" class="btn btn-sm btn-light dropdown-toggle text-primary" data-toggle="dropdown">展开/收起</button>
-                    <div class="dropdown-menu">
-                        <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="open">展开所有</a>
-                        <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="hide">收起所有</a>
-                    </div>
+            <% include ../tender/list_sub_mini_menu.ejs %>
+            <div class="d-inline-block mr-2">
+                <button type="button" class="btn btn-sm btn-light dropdown-toggle text-primary" data-toggle="dropdown">展开/收起</button>
+                <div class="dropdown-menu">
+                    <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="open">展开所有</a>
+                    <a class="dropdown-item tree-toggle" href="javascript:void(0);" data-item="hide">收起所有</a>
                 </div>
             </div>
             <div class="ml-auto">
                 <% if (ctx.session.sessionUser.is_admin) { %>
-                <a class="btn btn-sm btn-primary mr-2" href="/quality/rule">设置状态规则</a>
+                <a class="btn btn-sm btn-primary mr-2" href="/sp/<%- ctx.subProject.id %>/quality/rule">设置状态规则</a>
                 <% } %>
             </div>
         </div>
@@ -27,8 +27,28 @@
 <script>
     const tenders = JSON.parse(unescape('<%- escape(JSON.stringify(tenderList)) %>'));
     const category = JSON.parse(unescape('<%- escape(JSON.stringify(categoryData)) %>'));
+    const selfCategoryLevel = '<%- (selfCategoryLevel || '') %>';
     const is_admin = <%- ctx.session.sessionUser.is_admin %>;
 
     const pid = '<%- ctx.session.sessionProject.id %>';
     const uphlname = 'user_<%- ctx.session.sessionUser.accountId %>_pro_<% ctx.session.sessionProject.id %>_category_hide_list';
+
+    $.subMenu({
+        menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
+        toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
+        key: 'list.menu.1.0.0',
+        miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
+        callback: function (info) {
+            if (info.mini) {
+                $('.panel-title').addClass('fluid');
+                $('#sub-menu').removeClass('panel-sidebar');
+                $('.c-body table thead').css('left', '56px');
+            } else {
+                $('.panel-title').removeClass('fluid');
+                $('#sub-menu').addClass('panel-sidebar');
+                $('.c-body table thead').css('left', '176px');
+            }
+            autoFlashHeight();
+        }
+    });
 </script>

+ 9 - 0
app/view/tender/list_sub_menu_list.ejs

@@ -23,6 +23,15 @@
     </ul>
 </div>
 <% } %>
+<% if (ctx.subProject.page_show.quality) { %>
+<div class="nav-box">
+    <ul class="nav-list list-unstyled">
+        <li class="<% if (ctx.url === '/sp/' + ctx.subProject.id + '/quality/tender') { %>active<% } %>">
+            <a href="/sp/<%- ctx.subProject.id %>/quality/tender"><span class="ml-3">质量管理</span></a>
+        </li>
+    </ul>
+</div>
+<% } %>
 <% if (ctx.subProject.page_show.openConstruction) { %>
 <div class="nav-box">
     <ul class="nav-list list-unstyled">

+ 1 - 0
config/web.js

@@ -2147,6 +2147,7 @@ const JsFiles = {
                     '/public/js/moment/moment.min.js',
                 ],
                 mergeFiles: [
+                    '/public/js/sub_menu.js',
                     '/public/js/PinYinOrder.bundle.js',
                     '/public/js/shares/tender_list_order.js',
                     '/public/js/shares/show_level.js',

+ 502 - 0
sql/update.sql

@@ -273,6 +273,508 @@ CREATE TABLE `zh_financial_pay_stage`  (
   PRIMARY KEY (`id`)
 )  ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT = '资金支付单位期数表';
 
+
+CREATE TABLE `zh_tender_permission` (
+  `id` varchar(36) NOT NULL COMMENT 'uuid',
+  `pid` int(11) NOT NULL COMMENT '项目id(zh_project.id)',
+  `spid` varchar(36) NOT NULL COMMENT '子项目id(zh_sub_project.id)',
+  `tid` int(11) NOT NULL COMMENT '标段id(zh_tender.id)',
+  `uid` int(11) NOT NULL COMMENT '授权用户id(zh_project_account.id)',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后编辑时间',
+  `quality` varchar(255) NOT NULL DEFAULT '' COMMENT '质量管理权限(,分隔,具体见代码定义)',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `zh_quality_rule` (
+  `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `pid` int(11) NOT NULL COMMENT '项目id',
+  `spid` varchar(36) NOT NULL COMMENT '子项目id(zh_sub_project.id)',
+  `group_id` varchar(36) NOT NULL COMMENT 'uuid(分组id)',
+  `group_name` varchar(50) NOT NULL COMMENT '分组名称',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
+  `user_id` int(11) UNSIGNED NOT NULL COMMENT '创建人',
+  `name` varchar(50) NOT NULL DEFAULT '' COMMENT '规则名称',
+  `condition` text NULL COMMENT '条件',
+  `push_status` varchar(255) NOT NULL DEFAULT '' COMMENT '推送状态',
+  `memo` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `zh_quality`  (
+  `id` varchar(36) NOT NULL COMMENT 'uuid',
+  `tid` int(11) NOT NULL COMMENT '标段id(zh_tender.id)',
+  `rela_type` varchar(10) NOT NULL COMMENT '台账类型(xmj/pos)',
+  `rela_id` varchar(36) NOT NULL COMMENT '台账id(zh_ledger.id/zh_pos.id)',
+  `rela_name` varchar(36) NOT NULL COMMENT '计量单元名称(zh_pos.name)',
+  `gxby_status` tinyint(4) NOT NULL DEFAULT -1 COMMENT '工序报验状态',
+  `gxby_date` timestamp NULL COMMENT '完工日期',
+  `gxby_limit` tinyint(4) NOT NULL DEFAULT 0 COMMENT '计量是否受限',
+  `dagl_status` tinyint(4) NOT NULL DEFAULT -1 COMMENT '档案管理状态',
+  `dagl_limit` tinyint(4) NOT NULL DEFAULT 0 COMMENT '计量是否受限',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
+  `create_uid` int(11) NOT NULL COMMENT '创建人',
+  `update_uid` int(11) NOT NULL COMMENT '最后修改人',
+  `is_used` tinyint(4) NOT NULL DEFAULT 0 COMMENT '是否使用',
+  `group_id` varchar(36) NOT NULL DEFAULT '' COMMENT '规则判断组id(zh_quality_rule.group_id)',
+  `kaigong_name` varchar(50) NOT NULL DEFAULT '' COMMENT '开工-名称',
+  `kaigong_date` varchar(20) NOT NULL DEFAULT '' COMMENT '开工-计划开工日期',
+  `kaigong_uid` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '开工-创建人',
+  `kaigong_time` timestamp NULL COMMENT '开工-创建时间',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `zh_quality_file` (
+  `id` varchar(36) NOT NULL COMMENT 'uuid',
+  `tid` int(11) NOT NULL COMMENT '标段id(zh_tender.id)',
+  `quality_id` varchar(36) NOT NULL COMMENT '质量管理id(zh_quality.id)',
+  `rela_type` varchar(20) NOT NULL COMMENT '关联台账类型(xmj/pos)',
+  `rela_id` varchar(36) NOT NULL COMMENT '关联台账id(zh_ledger.id/zh_pos.id)',
+  `block_type` varchar(20) NOT NULL COMMENT '质量管理模块(kaigong/gongxu/...)',
+  `block_id` varchar(36) NOT NULL COMMENT '质量管理模块id(zh_quality_gongxu.id/zh_quality_yinbi.id/...)',
+  `user_id` int(11) UNSIGNED NOT NULL COMMENT '用户id(zh_project_account.id)',
+  `user_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '用户名(缓存)',
+  `user_company` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '公司(缓存)',
+  `user_role` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '角色(缓存)',
+  `filename` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '文件名',
+  `fileext` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '文件类型',
+  `filesize` int(11) UNSIGNED NOT NULL COMMENT '文件大小',
+  `filepath` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '文件路径(oss路径)',
+  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
+  `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '最后更新时间',
+  `is_deleted` tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否删除',
+  `spec_type` varchar(20) NOT NULL DEFAULT '' COMMENT '特殊文件类型(质检qa)',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `zh_quality_gongxu` (
+  `id` varchar(36) NOT NULL COMMENT 'uuid',
+  `tid` int(11) NOT NULL COMMENT '标段id(zh_tender.id)',
+  `quality_id` varchar(36) NOT NULL COMMENT '质量管理id(zh_quality.id)',
+  `user_id` int(11) NOT NULL COMMENT '创建人id',
+  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后修改时间',
+  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '名称',
+  PRIMARY KEY (`id`)
+);
+
+CREATE TABLE `zh_quality_yinbi`  (
+  `id` varchar(36) NOT NULL COMMENT 'uuid',
+  `tid` int(11) NOT NULL COMMENT '标段id(zh_tender.id)',
+  `quality_id` varchar(36) NOT NULL COMMENT '质量管理id(zh_quality.id)',
+  `user_id` int(11) NOT NULL COMMENT '创建人id',
+  `create_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
+  `update_time` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '最后修改时间',
+  `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
+  `gongxu_id` varchar(36) NOT NULL DEFAULT '' COMMENT '工序id(zh_quality_gongxu.id)',
+  `gcbw` varchar(1000) NOT NULL DEFAULT '' COMMENT '工程部位',
+  `content` varchar(1000) NOT NULL DEFAULT '' COMMENT '说明',
+  PRIMARY KEY (`id`)
+);
+
+ALTER TABLE `zh_ledger_extra_0`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_1`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_2`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_3`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_4`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_5`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_6`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_7`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_8`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_9`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_10`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_11`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_12`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_13`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_14`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_15`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_16`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_17`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_18`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_19`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_20`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_21`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_22`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_23`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_24`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_25`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_26`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_27`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_28`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_29`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_30`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_31`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_32`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_33`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_34`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_35`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_36`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_37`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_38`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_39`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_40`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_41`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_42`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_43`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_44`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_45`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_46`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_47`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_48`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_49`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_50`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_51`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_52`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_53`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_54`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_55`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_56`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_57`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_58`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_59`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_60`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_61`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_62`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_63`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_64`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_65`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_66`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_67`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_68`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_69`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_70`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_71`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_72`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_73`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_74`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_75`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_76`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_77`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_78`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_79`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_80`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_81`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_82`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_83`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_84`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_85`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_86`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_87`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_88`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_89`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_90`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_91`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_92`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_93`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_94`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_95`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_96`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_97`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_98`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_ledger_extra_99`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+
+ALTER TABLE `zh_pos_extra_0`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_1`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_2`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_3`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_4`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_5`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_6`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_7`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_8`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_9`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_10`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_11`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_12`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_13`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_14`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_15`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_16`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_17`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_18`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_19`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_20`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_21`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_22`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_23`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_24`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_25`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_26`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_27`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_28`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_29`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_30`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_31`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_32`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_33`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_34`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_35`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_36`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_37`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_38`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_39`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_40`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_41`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_42`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_43`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_44`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_45`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_46`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_47`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_48`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_49`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_50`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_51`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_52`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_53`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_54`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_55`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_56`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_57`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_58`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_59`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_60`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_61`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_62`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_63`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_64`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_65`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_66`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_67`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_68`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_69`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_70`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_71`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_72`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_73`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_74`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_75`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_76`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_77`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_78`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_79`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_80`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_81`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_82`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_83`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_84`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_85`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_86`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_87`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_88`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_89`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_90`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_91`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_92`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_93`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_94`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_95`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_96`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_97`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_98`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
+ALTER TABLE `zh_pos_extra_99`
+ADD COLUMN `wbs_url` varchar(255) NOT NULL DEFAULT '' COMMENT '联动计量配置' AFTER `gxby_id`;
 ------------------------------------
 -- 表数据
 ------------------------------------