Browse Source

匹配总表

vian 1 year ago
parent
commit
a0674b51bf

+ 1 - 1
modules/all_models/std_price_info_summary.js

@@ -5,7 +5,7 @@ const collectionName = 'std_price_info_summary';
 
 
 const modelSchema = {
 const modelSchema = {
   ID: { type: String, required: true },
   ID: { type: String, required: true },
-  masterSubCode: String, // 主从对应码
+  code: String, // 主从对应码
   classCode: String, // 别名编码
   classCode: String, // 别名编码
   expString: String, // 计算式,
   expString: String, // 计算式,
   name: String, // 材料名称
   name: String, // 材料名称

+ 12 - 0
modules/price_info_lib/controllers/index.js

@@ -262,6 +262,18 @@ class PriceInfoController extends BaseController {
         }
         }
     }
     }
 
 
+    // 匹配总表
+    async matchSummary(req, res) {
+        try {
+            const { compilationID, libID } = JSON.parse(req.body.data);
+            await facade.matchSummary(compilationID, libID);
+            res.json({ error: 0, message: 'matchSummary success' });
+        } catch (err) {
+            console.log(err);
+            res.json({ error: 1, message: err.toString() });
+        }
+    }
+
     async exportPriceData(request, response) {
     async exportPriceData(request, response) {
         const libID = request.query.libID;
         const libID = request.query.libID;
         try {
         try {

+ 62 - 2
modules/price_info_lib/facade/index.js

@@ -11,7 +11,7 @@ const priceInfoAreaModel = mongoose.model('std_price_info_areas');
 const compilationModel = mongoose.model('compilation');
 const compilationModel = mongoose.model('compilation');
 const importLogsModel = mongoose.model('import_logs');
 const importLogsModel = mongoose.model('import_logs');
 const priceInfoIndexModel = mongoose.model('std_price_info_index');
 const priceInfoIndexModel = mongoose.model('std_price_info_index');
-
+const priceInfoSummaryModel = mongoose.model('std_price_info_summary');
 
 
 
 
 async function getLibs(query) {
 async function getLibs(query) {
@@ -634,6 +634,65 @@ async function exportExcelData(libID, areaName) {
     return excelData;
     return excelData;
 }
 }
 
 
+const getMatchSummaryKey = (item) => {
+    const props = ['name', 'specs', 'unit'];
+    return props.map(prop => {
+        const subKey = item[prop] ? item[prop].trim() : '';
+        return subKey;
+    }).join('@');
+
+}
+
+const getSummaryMap = (items) => {
+    const map = {};
+    items.forEach(item => {
+        const key = getMatchSummaryKey(item);
+        map[key] = item;
+    });
+    return map;
+}
+
+// 匹配总表
+// 按规则匹配信息价的编码、别名编码、计算式(只匹配珠海建筑,要单独标记珠海地区);
+// 匹配规则:名称+规格型号+单位,与总表一致则自动填入编码、别名编码、计算式(珠海建筑);
+const matchSummary = async (compilationID, libID) => {
+    const updateBulks = [];
+    const areas = await priceInfoAreaModel.find({ compilationID }, '-_id ID name').lean();
+    const areaNameMap = {};
+    areas.forEach(area => {
+        areaNameMap[area.ID] = area.name;
+    });
+    const priceItems = await priceInfoItemModel.find({ libID }, '-_id ID compilationID name specs unit areaID period').lean();
+    const summaryItems = await priceInfoSummaryModel.find({}, '-_id ID name specs unit code classCode expString').lean();
+    const summaryMap = getSummaryMap(summaryItems);
+    priceItems.forEach(priceItem => {
+        const key = getMatchSummaryKey(priceItem);
+        const matched = summaryMap[key];
+        if (matched) {
+            const updateObj = {
+                code: matched.code,
+                classCode: matched.classCode,
+            }
+            console.log(matched);
+            console.log(updateObj);
+            const areaName = areaNameMap[priceItem.areaID];
+            if (/珠海/.test(areaName)) {
+                updateObj.expString = matched.expString;
+            }
+            updateBulks.push({
+                updateOne: {
+                    filter: { ID: priceItem.ID, compilationID: priceItem.compilationID, areaID: priceItem.areaID, period: priceItem.period },
+                    update: updateObj
+                }
+            })
+        }
+    });
+    if (updateBulks.length) {
+        console.log(`updateBulks.length`, updateBulks.length);
+        await priceInfoItemModel.bulkWrite(updateBulks);
+    }
+}
+
 module.exports = {
 module.exports = {
     getLibs,
     getLibs,
     createLib,
     createLib,
@@ -652,5 +711,6 @@ module.exports = {
     getPriceData,
     getPriceData,
     editPriceData,
     editPriceData,
     editClassData,
     editClassData,
-    exportExcelData
+    exportExcelData,
+    matchSummary,
 }
 }

+ 1 - 0
modules/price_info_lib/routes/index.js

@@ -25,6 +25,7 @@ module.exports = function (app) {
     router.post("/getPriceData", priceInfoController.auth, priceInfoController.init, priceInfoController.getPriceData);
     router.post("/getPriceData", priceInfoController.auth, priceInfoController.init, priceInfoController.getPriceData);
     router.post("/editPriceData", priceInfoController.auth, priceInfoController.init, priceInfoController.editPriceData);
     router.post("/editPriceData", priceInfoController.auth, priceInfoController.init, priceInfoController.editPriceData);
     router.post("/editClassData", priceInfoController.auth, priceInfoController.init, priceInfoController.editClassData);
     router.post("/editClassData", priceInfoController.auth, priceInfoController.init, priceInfoController.editClassData);
+    router.post("/matchSummary", priceInfoController.auth, priceInfoController.init, priceInfoController.matchSummary);
 
 
     router.get("/export", priceInfoController.auth, priceInfoController.init, priceInfoController.exportPriceData);
     router.get("/export", priceInfoController.auth, priceInfoController.init, priceInfoController.exportPriceData);
 
 

+ 4 - 7
modules/price_info_summary/facade/index.js

@@ -1,9 +1,6 @@
 const mongoose = require('mongoose');
 const mongoose = require('mongoose');
-const uuidV1 = require('uuid/v1');
-const _ = require('lodash');
-const scMathUtil = require('../../../public/scMathUtil').getUtil();
 
 
-const infoPriceSummaryModel = mongoose.model('std_price_info_summary');
+const priceInfoSummaryModel = mongoose.model('std_price_info_summary');
 
 
 // 获取分页数据
 // 获取分页数据
 const getPagingData = async (page, pageSize, searchStr) => {
 const getPagingData = async (page, pageSize, searchStr) => {
@@ -14,8 +11,8 @@ const getPagingData = async (page, pageSize, searchStr) => {
             $or: [{ classCode: searchStr }, { name: { $regex: nameReg } }]
             $or: [{ classCode: searchStr }, { name: { $regex: nameReg } }]
         }
         }
     }
     }
-    const totalCount = await infoPriceSummaryModel.count(query);
-    const items = await infoPriceSummaryModel.find(query).lean().sort({ classCode: 1 }).skip(page * pageSize).limit(pageSize);
+    const totalCount = await priceInfoSummaryModel.count(query);
+    const items = await priceInfoSummaryModel.find(query).lean().sort({ classCode: 1 }).skip(page * pageSize).limit(pageSize);
     return { items, totalCount };
     return { items, totalCount };
 }
 }
 
 
@@ -51,7 +48,7 @@ async function editSummaryData(postData) {
         }
         }
     });
     });
     if (bulks.length) {
     if (bulks.length) {
-        await infoPriceSummaryModel.bulkWrite(bulks);
+        await priceInfoSummaryModel.bulkWrite(bulks);
     }
     }
 }
 }
 
 

+ 16 - 0
web/maintain/price_info_lib/js/priceClass.js

@@ -103,6 +103,7 @@ const CLASS_BOOK = (() => {
   const $downMove = $('#tree-down-move');
   const $downMove = $('#tree-down-move');
   const $upMove = $('#tree-up-move');
   const $upMove = $('#tree-up-move');
   const $calcPriceIndex = $('#calc-price-index');
   const $calcPriceIndex = $('#calc-price-index');
+  const $matchSummary = $('#match-summary');
 
 
   // 插入
   // 插入
   let canInsert = true;
   let canInsert = true;
@@ -445,6 +446,21 @@ const CLASS_BOOK = (() => {
 
 
   }, DEBOUNCE_TIME, { leading: true }));
   }, DEBOUNCE_TIME, { leading: true }));
 
 
+  // 匹配总表
+  $matchSummary.click(_.debounce(async () => {
+    $.bootstrapLoading.progressStart('匹配总表', true);
+    $("#progress_modal_body").text('正在匹配总表,请稍后...');
+    try {
+      await ajaxPost('/priceInfo/matchSummary', { libID, compilationID }, 1000 * 60 * 10);
+      $.bootstrapLoading.progressEnd();
+      window.location.reload()
+    } catch (error) {
+      alert(error)
+      console.log(error);
+      $.bootstrapLoading.progressEnd();
+    }
+  }, DEBOUNCE_TIME, { leading: true }))
+
 
 
   return {
   return {
     initData,
     initData,

+ 3 - 1
web/maintain/price_info_lib/js/priceItem.js

@@ -33,7 +33,7 @@ const PRICE_BOOK = (() => {
     }
     }
     $.bootstrapLoading.start();
     $.bootstrapLoading.start();
     try {
     try {
-      cache = await ajaxPost('/priceInfo/getPriceData', { classIDList }, TIME_OUT);
+      cache = await ajaxPost('/priceInfo/getPriceData', { classIDList }, 1000 * 60 * 10);
       cache = _.sortBy(cache, 'classCode');
       cache = _.sortBy(cache, 'classCode');
       showData(sheet, cache, setting.header, 5);
       showData(sheet, cache, setting.header, 5);
       const row = sheet.getActiveRowIndex();
       const row = sheet.getActiveRowIndex();
@@ -81,6 +81,7 @@ const PRICE_BOOK = (() => {
 
 
   // 编辑处理
   // 编辑处理
   async function handleEdit(changedCells) {
   async function handleEdit(changedCells) {
+    $.bootstrapLoading.start();
     const postData = []; // 请求用
     const postData = []; // 请求用
     // 更新缓存用
     // 更新缓存用
     const updateData = [];
     const updateData = [];
@@ -135,6 +136,7 @@ const PRICE_BOOK = (() => {
       // 恢复各单元格数据
       // 恢复各单元格数据
       showData(sheet, cache, setting.header, 5);
       showData(sheet, cache, setting.header, 5);
     }
     }
+    $.bootstrapLoading.end();
   }
   }
   sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) {
   sheet.bind(GC.Spread.Sheets.Events.ValueChanged, function (e, info) {
     const changedCells = [{ row: info.row }];
     const changedCells = [{ row: info.row }];

+ 3 - 3
web/maintain/price_info_summary/js/summarySheet.js

@@ -84,13 +84,13 @@ const UpdateType = {
   CREATE: 'create',
   CREATE: 'create',
 };
 };
 
 
-const TIME_OUT = 10000;
+const TIME_OUT = 20000;
 
 
 const SUMMARY_BOOK = (() => {
 const SUMMARY_BOOK = (() => {
   const locked = lockUtil.getLocked();
   const locked = lockUtil.getLocked();
   const setting = {
   const setting = {
     header: [
     header: [
-      { headerName: '主从对应码', headerWidth: 200, dataCode: 'masterSubCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
+      { headerName: '主从对应码', headerWidth: 200, dataCode: 'code', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
       { headerName: '别名编码', headerWidth: 100, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
       { headerName: '别名编码', headerWidth: 100, dataCode: 'classCode', dataType: 'String', hAlign: 'left', vAlign: 'center', formatter: "@" },
       { headerName: '计算式', headerWidth: 100, dataCode: 'expString', dataType: 'String', hAlign: 'left', vAlign: 'center' },
       { headerName: '计算式', headerWidth: 100, dataCode: 'expString', dataType: 'String', hAlign: 'left', vAlign: 'center' },
       { headerName: '材料名称', headerWidth: 350, dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' },
       { headerName: '材料名称', headerWidth: 350, dataCode: 'name', dataType: 'String', hAlign: 'left', vAlign: 'center' },
@@ -201,7 +201,7 @@ const SUMMARY_BOOK = (() => {
         }
         }
       });
       });
       if (postData.length) {
       if (postData.length) {
-        await ajaxPost('/priceInfoSummary/editSummaryData', { postData }, TIME_OUT);
+        await ajaxPost('/priceInfoSummary/editSummaryData', { postData }, 1000 * 60 * 2);
         // 更新缓存,先更新然后删除,最后再新增,防止先新增后缓存数据的下标与更新、删除数据的下标对应不上
         // 更新缓存,先更新然后删除,最后再新增,防止先新增后缓存数据的下标与更新、删除数据的下标对应不上
         updateData.forEach(item => {
         updateData.forEach(item => {
           Object.assign(cache[item.row], item.data);
           Object.assign(cache[item.row], item.data);