فهرست منبع

Merge branch 'dev' of http://192.168.1.41:3000/maixinrong/Calculation into dev

TonyKang 4 سال پیش
والد
کامیت
ee17627deb
100فایلهای تغییر یافته به همراه111929 افزوده شده و 201 حذف شده
  1. 1 1
      app/base/base_bills_service.js
  2. 1 1
      app/controller/advance_controller.js
  3. 9 1
      app/controller/ledger_controller.js
  4. 37 13
      app/controller/report_archive_controller.js
  5. 7 107
      app/controller/report_controller.js
  6. 8 1
      app/controller/revise_controller.js
  7. 67 1
      app/controller/setting_controller.js
  8. 8 4
      app/controller/stage_controller.js
  9. 21 12
      app/extend/helper.js
  10. 177 0
      app/lib/ledger.js
  11. 33 25
      app/lib/rptCustomData.js
  12. 22 0
      app/lib/s2b.js
  13. 5 8
      app/lib/stage_im.js
  14. 6 7
      app/public/js/advance_audit.js
  15. 12 12
      app/public/js/change.js
  16. 1 1
      app/public/js/change_information_set.js
  17. 141 5
      app/public/js/ledger_check.js
  18. 1 1
      app/public/js/se_jgcl.js
  19. 6 0
      app/public/js/shares/cs_tools.js
  20. 13 1
      app/public/js/stage.js
  21. 237 0
      app/public/netcasign/example/appPackage.js
  22. 1 0
      app/public/netcasign/js/base64.min.js
  23. 615 0
      app/public/netcasign/js/debugger.js
  24. 506 0
      app/public/netcasign/js/json2.js
  25. 11012 0
      app/public/netcasign/js/netca-jquery-client.js
  26. 191 0
      app/public/netcasign/js/netcaseal.js
  27. 2048 0
      app/public/netcasign/js/netcasealpdf.js
  28. 2185 0
      app/public/netcasign/js/netcawebsocket.js
  29. 23599 0
      app/public/netcasign/js/pdf.js
  30. 1 0
      app/public/netcasign/js/pdf.js.map
  31. 55370 0
      app/public/netcasign/js/pdf.worker.js
  32. 1 0
      app/public/netcasign/js/pdf.worker.js.map
  33. 15580 0
      app/public/netcasign/js/viewer.js
  34. 1 0
      app/public/netcasign/js/viewer.js.map
  35. BIN
      app/public/netcasign/ui/cmaps/78-EUC-H.bcmap
  36. BIN
      app/public/netcasign/ui/cmaps/78-EUC-V.bcmap
  37. BIN
      app/public/netcasign/ui/cmaps/78-H.bcmap
  38. BIN
      app/public/netcasign/ui/cmaps/78-RKSJ-H.bcmap
  39. BIN
      app/public/netcasign/ui/cmaps/78-RKSJ-V.bcmap
  40. BIN
      app/public/netcasign/ui/cmaps/78-V.bcmap
  41. BIN
      app/public/netcasign/ui/cmaps/78ms-RKSJ-H.bcmap
  42. BIN
      app/public/netcasign/ui/cmaps/78ms-RKSJ-V.bcmap
  43. BIN
      app/public/netcasign/ui/cmaps/83pv-RKSJ-H.bcmap
  44. BIN
      app/public/netcasign/ui/cmaps/90ms-RKSJ-H.bcmap
  45. BIN
      app/public/netcasign/ui/cmaps/90ms-RKSJ-V.bcmap
  46. BIN
      app/public/netcasign/ui/cmaps/90msp-RKSJ-H.bcmap
  47. BIN
      app/public/netcasign/ui/cmaps/90msp-RKSJ-V.bcmap
  48. BIN
      app/public/netcasign/ui/cmaps/90pv-RKSJ-H.bcmap
  49. BIN
      app/public/netcasign/ui/cmaps/90pv-RKSJ-V.bcmap
  50. BIN
      app/public/netcasign/ui/cmaps/Add-H.bcmap
  51. BIN
      app/public/netcasign/ui/cmaps/Add-RKSJ-H.bcmap
  52. BIN
      app/public/netcasign/ui/cmaps/Add-RKSJ-V.bcmap
  53. BIN
      app/public/netcasign/ui/cmaps/Add-V.bcmap
  54. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-0.bcmap
  55. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-1.bcmap
  56. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-2.bcmap
  57. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-3.bcmap
  58. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-4.bcmap
  59. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-5.bcmap
  60. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-6.bcmap
  61. BIN
      app/public/netcasign/ui/cmaps/Adobe-CNS1-UCS2.bcmap
  62. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-0.bcmap
  63. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-1.bcmap
  64. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-2.bcmap
  65. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-3.bcmap
  66. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-4.bcmap
  67. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-5.bcmap
  68. BIN
      app/public/netcasign/ui/cmaps/Adobe-GB1-UCS2.bcmap
  69. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-0.bcmap
  70. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-1.bcmap
  71. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-2.bcmap
  72. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-3.bcmap
  73. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-4.bcmap
  74. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-5.bcmap
  75. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-6.bcmap
  76. BIN
      app/public/netcasign/ui/cmaps/Adobe-Japan1-UCS2.bcmap
  77. BIN
      app/public/netcasign/ui/cmaps/Adobe-Korea1-0.bcmap
  78. BIN
      app/public/netcasign/ui/cmaps/Adobe-Korea1-1.bcmap
  79. BIN
      app/public/netcasign/ui/cmaps/Adobe-Korea1-2.bcmap
  80. BIN
      app/public/netcasign/ui/cmaps/Adobe-Korea1-UCS2.bcmap
  81. BIN
      app/public/netcasign/ui/cmaps/B5-H.bcmap
  82. BIN
      app/public/netcasign/ui/cmaps/B5-V.bcmap
  83. BIN
      app/public/netcasign/ui/cmaps/B5pc-H.bcmap
  84. BIN
      app/public/netcasign/ui/cmaps/B5pc-V.bcmap
  85. BIN
      app/public/netcasign/ui/cmaps/CNS-EUC-H.bcmap
  86. BIN
      app/public/netcasign/ui/cmaps/CNS-EUC-V.bcmap
  87. BIN
      app/public/netcasign/ui/cmaps/CNS1-H.bcmap
  88. BIN
      app/public/netcasign/ui/cmaps/CNS1-V.bcmap
  89. BIN
      app/public/netcasign/ui/cmaps/CNS2-H.bcmap
  90. 3 0
      app/public/netcasign/ui/cmaps/CNS2-V.bcmap
  91. BIN
      app/public/netcasign/ui/cmaps/ETHK-B5-H.bcmap
  92. BIN
      app/public/netcasign/ui/cmaps/ETHK-B5-V.bcmap
  93. BIN
      app/public/netcasign/ui/cmaps/ETen-B5-H.bcmap
  94. BIN
      app/public/netcasign/ui/cmaps/ETen-B5-V.bcmap
  95. 3 0
      app/public/netcasign/ui/cmaps/ETenms-B5-H.bcmap
  96. BIN
      app/public/netcasign/ui/cmaps/ETenms-B5-V.bcmap
  97. BIN
      app/public/netcasign/ui/cmaps/EUC-H.bcmap
  98. BIN
      app/public/netcasign/ui/cmaps/EUC-V.bcmap
  99. BIN
      app/public/netcasign/ui/cmaps/Ext-H.bcmap
  100. 0 0
      app/public/netcasign/ui/cmaps/Ext-RKSJ-H.bcmap

+ 1 - 1
app/base/base_bills_service.js

@@ -14,7 +14,7 @@ const rootId = -1;
 const calcFields = ['unit_price', 'sgfh_qty', 'sgfh_tp', 'sjcl_qty', 'sjcl_tp', 'qtcl_qty', 'qtcl_tp', 'deal_qty', 'deal_tp', 'dgn_qty1', 'dgn_qty2'];
 const readOnlyFields = ['id', 'tender_id', 'ledger_id', 'ledger_pid', 'order', 'level', 'full_path', 'is_leaf'];
 const upFields = ['unit_price'];
-const qtyFields = ['sgfh_qty', 'sjcl_qty', 'qtcl_qty', 'quantity', 'deal_qty', 'dgn_qty1', 'dgn_qty2'];
+const qtyFields = ['sgfh_qty', 'sjcl_qty', 'qtcl_qty', 'quantity', 'deal_qty'];
 const tpFields = ['sgfh_tp', 'sjcl_tp', 'qtcl_tp', 'total_price', 'deal_tp'];
 const measureType = require('../const/tender').measureType;
 const billsUtils = require('../lib/bills_utils');

+ 1 - 1
app/controller/advance_controller.js

@@ -152,7 +152,7 @@ module.exports = app => {
                 // 获取上一期预付款记录
                 const prevAdvance = await ctx.service.advance.getPreviousRecord(ctx.tender.id, ctx.advance.type);
                 // 最大支付比例
-                const max_pr = ctx.helper.mul(ctx.helper.div(ctx.helper.sub(advancePayTotal, (prevAdvance && prevAdvance.prev_total_amount || 2)), advancePayTotal, 10), 100);
+                const max_pr = ctx.helper.mul(ctx.helper.div(ctx.helper.sub(advancePayTotal, (prevAdvance && prevAdvance.prev_total_amount || 0)), advancePayTotal, 10), 100);
 
                 const isLimitMax = ctx.helper.round(max_pr, 2) === ctx.advance.pay_ratio;
                 // 特殊处理金额的显示(formatMoney)

+ 9 - 1
app/controller/ledger_controller.js

@@ -357,6 +357,7 @@ module.exports = app => {
                         responseData.data = await this._base(ctx, data.postType, data.postData);
                         break;
                     case 'update':
+                        ctx.helper.checkDgnQtyPrecision(data.postData);
                         responseData.data = await ctx.service.ledger.updateCalc(ctx.tender.id, data.postData);
                         break;
                     case 'paste-block':
@@ -469,6 +470,13 @@ module.exports = app => {
                 const ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
                 const posData = this.ctx.tender.data.measure_type === measureType.tz.value
                     ? await ctx.service.pos.getPosData({ tid: ctx.tender.id }) : [];
+
+                const checkDataModel = require('../lib/ledger').checkData;
+                const checkData = new checkDataModel(ctx);
+                checkData.loadData(ledgerData, posData);
+                const sameCodeError = checkData.checkSameCode();
+                const siblingError = checkData.checkSibling();
+
                 const qtyData = ctx.helper.checkBillsWithPos(ledgerData, posData,
                     ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
                 qtyData.error.forEach(x => { x.errorType = 'qty'; });
@@ -478,7 +486,7 @@ module.exports = app => {
                 ], this.ctx.tender.info.decimal);
                 tpData.error.forEach(x => { x.errorType = 'tp'; });
                 ctx.body = { err: 0, msg: '', data: {
-                    error: [...qtyData.error, ...tpData.error],
+                    error: [...qtyData.error, ...tpData.error, ...sameCodeError, ...siblingError],
                     source: {
                         bills: [...qtyData.source.bills, ...tpData.source.bills],
                         pos: [...qtyData.source.pos, ...tpData.source.pos],

+ 37 - 13
app/controller/report_archive_controller.js

@@ -100,7 +100,17 @@ module.exports = app => {
                 const newName = uuidV1();
                 const fileName = newName + '.PDF';
                 // console.log('adding fileName: ' + fileName);
-                await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', 'public/archive', fileName));
+                // await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', 'public/archive', fileName));
+                const oss_result = await ctx.oss.put('archive/' + fileName, stream);
+                if (!(oss_result && oss_result.url && oss_result.res.status === 200)) {
+                    throw '上传文件失败';
+                }
+                // const url = await ctx.oss.delete('archive/52d3e7f0-c7fb-11eb-b8c2-51b890b95d23.PDF');
+                // console.log(url);
+                // const flag = true;
+                // if (flag) {
+                //     throw 'ok';
+                // }
                 const updateDate = new Date();
                 const montStr = (updateDate.getMonth() + 1) < 10 ? ('0' + (updateDate.getMonth() + 1)) : ((updateDate.getMonth() + 1));
                 const dateStr = (updateDate.getDate()) < 10 ? ('0' + (updateDate.getDate())) : ((updateDate.getDate()));
@@ -120,6 +130,8 @@ module.exports = app => {
                                         rmIdx = idx;
                                     }
                                 }
+                                // 同时删除oss文件
+                                await ctx.oss.delete('archive/' + item.items[rmIdx].uuid + '.PDF');
                                 item.items.splice(rmIdx, 1);
                             }
                             const newItem = { uuid: newName, updateDate_time: dtStr };
@@ -157,7 +169,12 @@ module.exports = app => {
                 const orgName = ctx.params.orgName;
                 const fileName = orgName + '.PDF';
                 console.log('updating fileName: ' + fileName);
-                await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', 'public/archive', fileName));
+                // await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', 'public/archive', fileName));
+                const oss_result = await ctx.oss.put('archive/' + fileName, stream);
+                if (!(oss_result && oss_result.url && oss_result.res.status === 200)) {
+                    throw '上传文件失败';
+                }
+
                 const updateDate = new Date();
                 const montStr = (updateDate.getMonth() + 1) < 10 ? ('0' + (updateDate.getMonth() + 1)) : ((updateDate.getMonth() + 1));
                 const dateStr = (updateDate.getDate()) < 10 ? ('0' + (updateDate.getDate())) : ((updateDate.getDate()));
@@ -207,17 +224,21 @@ module.exports = app => {
                 console.log('removing fileName: ' + fileName);
                 const fullName = path.join(this.app.baseDir, 'app', 'public/archive', fileName);
                 // await ctx.helper.saveStreamFile(stream, path.join(this.app.baseDir, 'app', 'public/archive', fileName));
-                fs.stat(fullName, function(err, data) {
-                    if (err) {
-                        console.log(err);
-                    } else {
-                        fs.unlink(fullName, function(err) {
-                            if (err) {
-                                console.log(err);
-                            }
-                        });
-                    }
-                });
+                // fs.stat(fullName, function(err, data) {
+                //     if (err) {
+                //         console.log(err);
+                //     } else {
+                //         fs.unlink(fullName, function(err) {
+                //             if (err) {
+                //                 console.log(err);
+                //             }
+                //         });
+                //     }
+                // });
+                const oss_result = await ctx.oss.delete('archive/' + fileName);
+                if (!(oss_result && oss_result.res.status === 204)) {
+                    throw '删除归档文件失败';
+                }
                 const orgArchiveList = await ctx.service.rptArchive.getPrjStgArchive(prjId, stgId);
                 if (orgArchiveList.length > 0) {
                     const contentArr = JSON.parse(orgArchiveList[0].content);
@@ -269,6 +290,9 @@ module.exports = app => {
             }
         }
 
+        async pdfShow(ctx) {
+            await ctx.render('report/archive_pdf.ejs');
+        }
     }
     return ReportArchiveController;
 };

+ 7 - 107
app/controller/report_controller.js

@@ -20,7 +20,12 @@ const RPT_DEF_PROPERTIES = require('../const/report_defined_properties');
 const reportConst = require('../const/report');
 // const stringUtil = require('../public/js/string_util_light');
 const scheduleJob = require('node-schedule');
-const needCustomTables = ['mem_gather_stage_bills', 'mem_gather_deal_bills', 'mem_gather_stage_pay', 'mem_gather_tender_info', 'mem_stage_sum_bills', 'mem_stage_sum_pay'];
+const needCustomTables = [
+    'mem_custom_select',
+    'mem_gather_stage_bills', 'mem_gather_deal_bills', 'mem_gather_stage_pay', 'mem_gather_tender_info',
+    'mem_stage_sum_bills', 'mem_stage_sum_pay',
+    'mem_jh_gather_im_change', 'mem_jh_im_change',
+];
 
 module.exports = app => {
     class ReportController extends app.BaseController {
@@ -730,116 +735,11 @@ async function checkStg(ctx, params) {
         }
     }
 }
-/*
-async function getReportData(ctx, params, filters, memFieldKeys) {
-    const rst = {};
-    const runnableRst = [];
-    const runnableKey = []; // 这个配合runnableRst用,未来考虑并行查询优化
-    // console.log('params');
-    // console.log(params);
-    // console.log('memFieldKeys');
-    // console.log(memFieldKeys);
-    for (const filter of filters) {
-        if (runnableKey.indexOf(filter) < 0) {
-            switch (filter) {
-                case 'project' :
-                    runnableRst.push(ctx.service.project.getProjectById(params.project_id));
-                    runnableKey.push('project');
-                    break;
-                case 'tender_info' :
-                    runnableRst.push(ctx.service.tenderInfo.getTenderInfo(params.tender_id));
-                    runnableKey.push('tender_info');
-                    break;
-                case 'ledger' :
-                    runnableRst.push(ctx.service.ledger.getData(params.tender_id, 0));
-                    runnableKey.push('ledger');
-                    break;
-                case 'deal_bills' :
-                    // console.log('has push deal_bills! ' + params.tender_id);
-                    runnableRst.push(ctx.service.dealBills.getDataByTenderId(params.tender_id));
-                    runnableKey.push('deal_bills');
-                    break;
-                case 'stage_bills':
-                    runnableRst.push(ctx.service.stageBills.getLastestStageData(params.tender_id, params.stage_id));
-                    runnableKey.push('stage_bills');
-                    break;
-                case 'stage_bills_final':
-                    await checkStg(ctx, params);
-                    // const stage = ctx.stage;
-                    // runnableRst.push(ctx.service.stageBillsFinal.getFinalDataEx(params.tender_id, params.stage_order));
-                    runnableRst.push(ctx.service.stageBillsFinal.getFinalDataEx(params.tender_id, ctx.stage.order));
-                    runnableKey.push('stage_bills_final');
-                    break;
-                case 'stage':
-                    runnableRst.push(ctx.service.stage.getStageById(params.stage_id));
-                    runnableKey.push('stage');
-                    break;
-                case 'stage_pay':
-                    await checkStg(ctx, params);
-                    // const stage2 = ctx.stage;
-                    // runnableRst.push(ctx.service.stagePay.getAuditorStageData(params.stage_id, params.stage_times, params.stage_order));
-                    runnableRst.push(ctx.service.stagePay.getAuditorStageData(params.stage_id, ctx.stage.times, ctx.stage.order));
-                    runnableKey.push('stage_pay');
-                    break;
-                case 'mem_stage_im_zl':
-                    // memFieldKeys[filter]
-                    runnableRst.push(ctx.service.reportMemory.getStageImZlData(params.tender_id, params.stage_id, memFieldKeys[filter]));
-                    runnableKey.push(filter);
-                    break;
-                case 'mem_month_progress':
-                    runnableRst.push(ctx.service.reportMemory.getMonthProgress(params.tender_id, memFieldKeys[filter]));
-                    runnableKey.push(filter);
-                    break;
-                case 'mem_stage_bills':
-                    runnableRst.push(ctx.service.reportMemory.getStageBillsData(params.tender_id, params.stage_id, memFieldKeys[filter]));
-                    runnableKey.push(filter);
-                    break;
-                case 'mem_stage_pos':
-                    runnableRst.push(ctx.service.reportMemory.getStagePosData(params.tender_id, params.stage_id, memFieldKeys[filter]));
-                    runnableKey.push(filter);
-                    break;
-                case 'mem_stage_bills_compare':
-                    runnableRst.push(ctx.service.reportMemory.getStagePosData(params.tender_id, params.stage_id, memFieldKeys[filter]));
-                    runnableKey.push(filter);
-                    break;
-                case 'change':
-                    runnableRst.push(ctx.service.change.getListByStatus(params.tender_id, 3)); // 获取所有审核通过的变更主信息
-                    runnableKey.push('change');
-                    break;
-                case 'change_audit_list':
-                    runnableRst.push(ctx.service.changeAuditList.getChangeAuditBills(params.tender_id)); // 获取所有审核通过的变更清单
-                    runnableKey.push('change_audit_list');
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-    const queryRst = await Promise.all(runnableRst);
-    for (let idx = 0; idx < runnableKey.length; idx++) {
-        rst[runnableKey[idx]] = queryRst[idx];
-    }
-    for (const filter of filters) {
-        switch (filter) {
-            case 'mem_stage_im_tz':
-                rst[filter] = await ctx.service.reportMemory.getStageImTzData(params.tender_id, params.stage_id, memFieldKeys[filter]);
-                break;
-            case 'mem_stage_im_tz_bills':
-                rst[filter] = await ctx.service.reportMemory.getStageImTzBillsData(params.tender_id, params.stage_id, memFieldKeys[filter]);
-                break;
-            default:
-                break;
-        }
-    }
-    return rst;
-}
-*/
 
 async function getAllPagesCommon(ctx, rptTpl, params, option, outputType, baseDir, customSelect) {
     const rptDataUtil = new rptDataExtractor();
     rptDataUtil.initialize(rptTpl);
     const filter = rptDataUtil.getDataRequestFilter();
-    // console.log(filter.tables);
     const rawDataObj = await ctx.service.report.getReportData(params, filter.tables, filter.memFieldKeys,
         rptTpl[JV.NODE_CUSTOM_DEFINE], customSelect);
     // console.log(rawDataObj);
@@ -956,7 +856,7 @@ async function getMultiRptsCommon(ctx, params, outputType, baseDir) {
                 curRawDataObj[table] = ctx.helper.clone(rawDataObj[table]);
             }
             // 如果是用户交互类型的表,则应该单独获取数据
-            if (params.customSelect && params.customSelect[tplIdx]) {
+            if ((params.customSelect && params.customSelect[tplIdx]) || rptTpl[JV.NODE_CUSTOM_DEFINE][JV.NODE_CUS_OPTION]) {
                 const cfTables = [],
                     cmFieldKeys = [];
                 const curFilter = rptDataUtil.getDataRequestFilter();

+ 8 - 1
app/controller/revise_controller.js

@@ -459,6 +459,12 @@ module.exports = app => {
                 const reviseBills = await ctx.service.reviseBills.getData(ctx.tender.id);
                 const revisePos = await ctx.service.revisePos.getData(ctx.tender.id);
 
+                const checkDataModel = require('../lib/ledger').checkData;
+                const checkData = new checkDataModel(ctx);
+                checkData.loadData(reviseBills, revisePos);
+                const sameCodeError = checkData.checkSameCode();
+                const siblingError = checkData.checkSibling();
+
                 const qtyData = ctx.helper.checkBillsWithPos(reviseBills, revisePos,
                     ['sgfh_qty', 'qtcl_qty', 'sjcl_qty', 'quantity']);
                 qtyData.error.forEach(x => { x.errorType = 'qty'; });
@@ -468,7 +474,7 @@ module.exports = app => {
                 ], this.ctx.tender.info.decimal);
                 tpData.error.forEach(x => { x.errorType = 'tp'; });
                 ctx.body = { err: 0, msg: '', data: {
-                        error: [...qtyData.error, ...tpData.error],
+                        error: [...qtyData.error, ...tpData.error, ...sameCodeError, ...siblingError],
                         source: {
                             bills: [...qtyData.source.bills, ...tpData.source.bills],
                             pos: [...qtyData.source.pos, ...tpData.source.pos],
@@ -701,6 +707,7 @@ module.exports = app => {
                         responseData.data = await this._billsBase(revise, data.postType, data.postData);
                         break;
                     case 'update':
+                        ctx.helper.checkDgnQtyPrecision(data.postData);
                         responseData.data = await this.ctx.service.reviseBills.updateCalc(revise.tid, data.postData);
                         break;
                     case 'batch-insert':

+ 67 - 1
app/controller/setting_controller.js

@@ -1,4 +1,4 @@
-'use strict';
+ 'use strict';
 
 /**
  *
@@ -15,6 +15,8 @@ const accountGroup = require('../const/account_group').group;
 const permission = require('../const/account_permission').permission;
 const projectLog = require('../const/project_log');
 const imType = require('../const/tender').imType;
+const S2b = require('../lib/s2b');
+const measureType = require('../const/tender').measureType;
 
 module.exports = app => {
 
@@ -31,6 +33,14 @@ module.exports = app => {
             ctx.subMenu = settingMenu;
         }
 
+        async _checkMenu(pid) {
+            const s2bData = new S2b(this.ctx);
+            const s2bProj = await s2bData.getS2bProj(pid);
+            // this.ctx.subMenu.s2b.display = !!s2bProj && (!!s2bProj.gxby || !!s2bProj.dagl);
+            this.ctx.subMenu.s2b.display = false;
+            return s2bProj;
+        }
+
         /**
          * 项目信息页面(Get)
          *
@@ -41,6 +51,7 @@ module.exports = app => {
             try {
                 // 获取项目数据
                 const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
                 const projectData = await ctx.service.project.getDataById(projectId);
                 if (projectData === null) {
                     throw '没有对应的项目数据';
@@ -85,6 +96,7 @@ module.exports = app => {
             try {
                 // 获取项目数据
                 const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
                 const projectData = await ctx.service.project.getDataById(projectId);
                 if (projectData === null) {
                     throw '没有对应的项目数据';
@@ -410,6 +422,7 @@ module.exports = app => {
             try {
                 // 获取项目数据
                 const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
                 const projectData = await ctx.service.project.getDataById(projectId);
                 if (projectData === null) {
                     throw '没有对应的项目数据';
@@ -626,6 +639,7 @@ module.exports = app => {
             try {
                 // 获取项目数据
                 const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
                 const projectData = await ctx.service.project.getDataById(projectId);
                 if (!projectData) {
                     throw '没有对应的项目数据';
@@ -666,6 +680,7 @@ module.exports = app => {
             try {
                 // 获取项目数据
                 const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
                 const projectData = await ctx.service.project.getDataById(projectId);
                 if (projectData === null) {
                     throw '没有对应的项目数据';
@@ -692,6 +707,7 @@ module.exports = app => {
         async fun(ctx) {
             try {
                 const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
                 const projectData = await ctx.service.project.getDataById(projectId);
                 const funRela = await ctx.service.project.getFunRela(projectId);
                 if (projectData === null) {
@@ -741,6 +757,56 @@ module.exports = app => {
                 this.ajaxErrorBody(error, '保存数据失败');
             }
         }
+
+        async s2b (ctx) {
+            try {
+                const projectId = ctx.session.sessionProject.id;
+                await this._checkMenu(projectId);
+                const projectData = await ctx.service.project.getDataById(projectId);
+                if (projectData === null) throw '没有对应的项目数据';
+                if (ctx.session.sessionUser.is_admin === 0) throw '没有访问权限';
+
+                const tenders = await ctx.service.tender.getAllDataByCondition({ where: { project_id: projectId } });
+                for (const t of tenders) {
+                    t.measure_type_str = t.measure_type === measureType.tz.value ? measureType.tz.title : measureType.gcl.title;
+                    const stages = await ctx.service.stage.getAllDataByCondition({ where: { tid: t.id } });
+                    t.stage_count_str = `第${stages.count || 0}期`;
+                    const user = await ctx.service.projectAccount.getAccountInfoById(t.user_id);
+                    t.user_str = user.name + '-' + user.company;
+                    t.show_time = stages.length > 0 ? stages[stages.length - 1].cache_time_r || stages[stages.length - 1].in_time : t.create_time;
+                }
+                await this.layout('setting/s2b.ejs', {
+                    projectData,
+                    tenders,
+                })
+            } catch (error) {
+                ctx.helper.log(error);
+                ctx.redirect('/dashboard');
+            }
+        }
+
+        async s2bUpdate(ctx) {
+            try {
+                const projectId = ctx.session.sessionProject.id;
+                const projectData = await ctx.service.project.getDataById(projectId);
+                if (projectData === null) throw '没有对应的项目数据';
+                if (ctx.session.sessionUser.is_admin === 0) throw '没有访问权限';
+
+                const data = JSON.parse(ctx.request.body.data);
+                if (!data.tid) throw '提交数据错误';
+
+                const updateData = {};
+                if (data.gxby_limit !== undefined) updateData.s2b_gxby_limit = data.gxby_limit;
+                if (data.gxby_check !== undefined) updateData.s2b_gxby_check = data.gxby_check;
+                if (data.dagl_limit !== undefined) updateData.s2b_dagl_limit = data.dagl_limit;
+                if (data.dagl_check !== undefined) updateData.s2b_dagl_check = data.dagl_check;
+                await ctx.service.tender.saveApiRela(data.tid, updateData);
+                ctx.body = { err: 0, msg: '', data: null };
+            } catch (error) {
+                ctx.helper.log(error);
+                ctx.ajaxError(error, '保存数据错误');
+            }
+        }
     }
 
     return SettingController;

+ 8 - 4
app/controller/stage_controller.js

@@ -363,6 +363,10 @@ module.exports = app => {
                 const ledgerData = await this._getStageLedgerData(ctx);
                 const posData = await this._getStagePosData(ctx);
 
+                const checkDataModel = require('../lib/ledger').checkData;
+                const checkData = new checkDataModel(ctx);
+                checkData.loadData(ledgerData, posData);
+                const check3fResult = checkData.check3fLimit(ctx.tender.data);
                 const [qtyData, overData] = ctx.helper.checkBillsWithPos2(ledgerData, posData,
                     ['contract_qty', 'qc_qty'], projRela.banOver, this.ctx.tender.data.measure_type === measureType.tz.value);
                 qtyData.error.forEach(x => { x.errorType = 'qty'; });
@@ -372,10 +376,10 @@ module.exports = app => {
                 ], this.ctx.tender.info.decimal);
                 tpData.error.forEach(x => { x.errorType = 'tp'; });
                 ctx.body = { err: 0, msg: '', data: {
-                    error: [...qtyData.error, ...tpData.error, ...overData.error],
+                    error: [...qtyData.error, ...tpData.error, ...overData.error, ...check3fResult.error],
                     source: {
-                        bills: [...qtyData.source.bills, ...tpData.source.bills, ...overData.source.bills],
-                        pos: [...qtyData.source.pos, ...tpData.source.pos, ...overData.source.pos],
+                        bills: ctx.helper._.uniqBy([...qtyData.source.bills, ...tpData.source.bills, ...overData.source.bills, ...check3fResult.source.bills], 'id'),
+                        pos: ctx.helper._.uniqBy([...qtyData.source.pos, ...tpData.source.pos, ...overData.source.pos, ...check3fResult.source.pos], 'id'),
                     },
                 } };
             } catch (err) {
@@ -452,6 +456,7 @@ module.exports = app => {
                         responseData.data.bills = await ctx.service.ledger.getDataByIds(this.ctx.helper._.map(updateDatas, 'id'));
                     }
                     if (data.bills.dgn) {
+                        ctx.helper.checkDgnQtyPrecision(data.bills.dgn);
                         responseData.data.dgn = await ctx.service.stageBillsDgn.saveDgnData(data.bills.dgn);
                     }
                     if (data.bills.stage) {
@@ -1432,7 +1437,6 @@ module.exports = app => {
                     }
                 } catch (err) {
                     this.log(err);
-                    console.log(err);
                     this.setMessage(err.toString(), this.messageType.ERROR);
                 }
             }

+ 21 - 12
app/extend/helper.js

@@ -635,6 +635,14 @@ module.exports = {
         }
     },
 
+    checkDgnQtyPrecision(data, precision = 3) {
+        const datas = data instanceof Array ? data : [data];
+        for (const d of datas) {
+            for (const prop in d) {
+                if (prop.indexOf('dgn_qty') >= 0) d[prop] = this.round(d[prop], precision);
+            }
+        }
+    },
     /**
      * 过滤无效数据
      *
@@ -1125,17 +1133,18 @@ module.exports = {
     },
 
     /**
-     * 短链接生成
+     * 短链接生成(暂停生成)
      * @param url
      * @return {*}
      */
     async urlToShort(url) {
-        const apiUrl = 'http://scn.ink/api/shorturl';
-        const data = {
-            url: encodeURI(url),
-        };
-        const result = await this.sendRequest(apiUrl, data, 'get');
-        return result && result.code === 200 && result.url ? result.url : url;
+        // const apiUrl = 'http://scn.ink/api/shorturl';
+        // const data = {
+        //     url: encodeURI(url),
+        // };
+        // const result = await this.sendRequest(apiUrl, data, 'get');
+        // return result && result.code === 200 && result.url ? result.url : url;
+        return url;
     },
 
     /**
@@ -1364,10 +1373,10 @@ module.exports = {
         return counts(array, val);
     },
 
-    filterTimesOrderData(data, keyFields, times, order) {
+    filterTimesOrderData(data, keyFields, timesField, orderField, times, order) {
         const dataIndex = {};
         for (const d of data) {
-            if (d.times > times || (d.times = times || d.order > order)) continue;
+            if (d[timesField] > times || (d[timesField] = times && d[orderField] > order)) continue;
             let key = 'd';
             for (const kf of keyFields) {
                 key = key + '.' + (d[kf] || '');
@@ -1375,7 +1384,7 @@ module.exports = {
 
             const di = dataIndex[key];
             if (di) {
-                if ((di.times * timesLen + di.order) < (d.times * timesLen + d.order)) dataIndex[key] = d;
+                if ((di[timesField] * timesLen + di[orderField]) < (d[timesField] * timesLen + d[orderField])) dataIndex[key] = d;
             } else {
                 dataIndex[key] = d;
             }
@@ -1387,7 +1396,7 @@ module.exports = {
         return result;
     },
 
-    filterLastestData(data, keyFields) {
+    filterLastestData(data, keyFields, timesField = 'times', orderField = 'order') {
         const dataIndex = {};
         for (const d of data) {
             let key = 'd';
@@ -1397,7 +1406,7 @@ module.exports = {
 
             const di = dataIndex[key];
             if (di) {
-                if ((di.times * timesLen + di.order) < (d.times * timesLen + d.order)) dataIndex[key] = d;
+                if ((di[timesField] * timesLen + di[orderField]) < (d[timesField] * timesLen + d[orderField])) dataIndex[key] = d;
             } else {
                 dataIndex[key] = d;
             }

+ 177 - 0
app/lib/ledger.js

@@ -572,10 +572,187 @@ class pos {
     }
 }
 
+class checkData {
+    constructor(ctx) {
+        this.ctx = ctx;
+        this.checkBills = new billsTree(ctx, { id: 'ledger_id', pid: 'ledger_pid', order: 'order', level: 'level', rootId: -1 });
+        this.checkPos = new pos({ id: 'id', ledgerId: 'lid' });
+    }
+
+    _check3f(data, limit, ratio) {
+        if (limit === 0) {
+            if (data.contract_tp || data.pre_contract_tp) return 1; // 违规
+        }
+        if (limit === 1) {
+            if (ratio === 0) {
+                if (!data.contract_tp && !data.pre_contract_tp) return 2; // 漏计
+            } else {
+                const tp = this.ctx.helper.mul(data.total_price, ratio, this.ctx.tender.info.decimal.tp);
+                const checkTp = this.ctx.helper.add(data.contract_tp, data.pre_contract_tp);
+                if (tp > checkTp) return 1; // 违规
+                if (tp < checkTp) return 2; // 漏计
+            }
+        }
+        return 0; // 合法
+    }
+    _check3fQty(data, limit, ratio, unit) {
+        if (limit === 0) {
+            if (data.contract_qty || data.qc_qty || data.pre_contract_qty || data.pre_qc_qty) return 1; // 违规
+        }
+        if (limit === 1) {
+            if (ratio === 0) {
+                if (!data.contract_qty && !data.qc_qty && !data.pre_contract_qty && !data.pre_qc_qty) return 2; // 漏计
+            } else {
+                const precision = this.ctx.helper.findPrecision(this.ctx.tender.info.precision, unit);
+                const checkQty = this.ctx.helper.mul(data.quantity, ratio, precision.value);
+                const qty = this.ctx.helper.add(data.contract_qty, data.pre_contract_qty);
+                if (qty > checkQty) return 1; // 违规
+                if (qty < checkQty) return 2; // 漏计
+            }
+        }
+        return 0; // 合法
+    }
+
+    _checkLeafBills3fLimit(checkType, bills, result, checkInfo) {
+        const over = [], lost = [];
+        const posRange = this.checkPos.getLedgerPos(bills.id);
+        if (posRange && posRange.length > 0) {
+            for (const p of posRange) {
+                const posCheckInfo = this.ctx.helper._.assign({}, checkInfo);
+                for (const ct of checkType) {
+                    if (p[ct + '_limit'] >= 0) {
+                        posCheckInfo[ct + '_limit'] = p[ct + '_limit'];
+                        posCheckInfo[ct + '_ratio'] = p[ct + '_ratio'];
+                    }
+                }
+                for (const ct of checkType) {
+                    const checkResult = this._check3fQty(p, posCheckInfo[ct + '_limit'], posCheckInfo[ct + '_ratio'], bills.unit);
+                    if (checkResult === 1) {
+                        if (over.indexOf(ct) === -1) over.push(ct);
+                    }
+                    if (checkResult === 2) {
+                        if (lost.indexOf(ct) === -1) lost.push(ct);
+                    }
+                }
+            }
+        } else {
+            for (const ct of checkType) {
+                const checkResult = bills.is_tp
+                    ? this._check3f(bills, checkInfo[ct + '_limit'], checkInfo[ct + '_ratio'])
+                    : this._check3fQty(bills, checkInfo[ct + '_limit'], checkInfo[ct + '_ratio'], bills.unit);
+                if (checkResult === 1) {
+                    if (over.indexOf(ct) === -1) over.push(ct);
+                }
+                if (checkResult === 2) {
+                    if (lost.indexOf(ct) === -1) lost.push(ct);
+                }
+            }
+        }
+        if (over.length + lost.length > 0) {
+            for (const o of over) {
+                result.error.push({
+                    ledger_id: bills.ledger_id,
+                    b_code: bills.b_code,
+                    name: bills.name,
+                    errorType: 's2b_over_' + o,
+                });
+            }
+            for (const l of lost) {
+                result.error.push({
+                    ledger_id: bills.ledger_id,
+                    b_code: bills.b_code,
+                    name: bills.name,
+                    errorType: 's2b_lost_' + l,
+                });
+            }
+            result.source.bills.push(bills);
+            if (posRange && posRange.length > 0) result.source.pos.push(...posRange);
+        }
+    }
+    _recursiveCheckBills3fLimit(checkType, bills, result, parentCheckInfo) {
+        const checkInfo = this.ctx.helper._.assign({}, parentCheckInfo);
+        for (const ct of checkType) {
+            if (bills[ct + '_limit'] >= 0) {
+                checkInfo[ct + '_limit'] = bills[ct + '_limit'];
+                checkInfo[ct + '_ratio'] = bills[ct + '_ratio'];
+            }
+        }
+        if (bills.children && bills.children.length > 0) {
+            for (const c of bills.children) {
+                this._recursiveCheckBills3fLimit(checkType, c, result, checkInfo);
+            }
+        } else {
+            this._checkLeafBills3fLimit(checkType, bills, result, checkInfo);
+        }
+    }
+
+    loadData(bills, pos) {
+        this.checkBills.loadDatas(bills);
+        this.checkPos.loadDatas(pos);
+    }
+
+    checkSibling() {
+        const error = [];
+        for (const node of this.checkBills.nodes) {
+            if (!node.children || node.children.length === 0) continue;
+            let hasXmj, hasGcl;
+            for (const child of node.children) {
+                if (child.b_code) hasXmj = true;
+                if (!child.b_code) hasGcl = true;
+            }
+            if (hasXmj && hasGcl) error.push({
+                ledger_id: node.ledger_id,
+                b_code: node.b_code,
+                name: node.name,
+                errorType: 'sibling',
+            });
+        }
+        return error;
+    }
+
+    checkSameCode() {
+        const error = [];
+        let xmj = this.checkBills.nodes.filter(x => { return /^((GD*)|G)?[0-9]+/.test(x.code); });
+        let check = null;
+        while (xmj.length > 0) {
+            [check, xmj] = this.ctx.helper._.partition(xmj, x => { return x.code === xmj[0].code; });
+            if (check.length > 1) {
+                for (const c of check) {
+                    error.push({
+                        ledger_id: c.ledger_id,
+                        b_code: c.b_code,
+                        name: c.name,
+                        errorType: 'same_code',
+                    })
+                }
+            }
+        }
+        return error;
+    }
+
+    check3fLimit(tender) {
+        const result = {
+            error: [],
+            source: {bills: [], pos: []},
+        };
+
+        const check = [];
+        if (tender.s2b_gxby_limit) check.push('gxby');
+        if (tender.s2b_dagl_limit) check.push('dagl');
+        if (check.length === 0) return result;
+
+        for (const b of this.checkBills.children) {
+            this._recursiveCheckBills3fLimit(check, b, result, {});
+        }
+        return result;
+    }
+}
+
 module.exports = {
     billsTree,
     pos,
     filterTree,
     filterGatherTree,
     gatherTree,
+    checkData,
 };

+ 33 - 25
app/lib/rptCustomData.js

@@ -121,7 +121,7 @@ class jhHelper {
         }
     }
 
-    _loadMergeResult(bills, prefixes) {
+    _loadMergeResult(bills, prefixes, decimal) {
         const rst = {
             id: bills.id,
             tid: bills.tender_id,
@@ -135,22 +135,22 @@ class jhHelper {
                 let gather = false;
                 if (p.pre_cd && p.pre_cd.length > 0) gather = true;
                 for (const prefix of prefixes) {
-                    if (p[prefix + '_cd'] && p[prefix + '_cd'].length > 0) gather = true;
+                    if (p[prefix + 'cd'] && p[prefix + 'cd'].length > 0) gather = true;
                 }
                 if (gather) {
                     rst.qc_qty = this.ctx.helper.add(rst.qc_qty, p.qc_qty);
-                    rst.qc_tp = this.ctx.helper.add(rst.qc_qty, p.qc_tp);
                     rst.pre_qc_qty = this.ctx.helper.add(rst.pre_qc_qty, p.pre_qc_qty);
-                    rst.pre_qc_tp = this.ctx.helper.add(rst.pre_qc_tp, p.pre_qc_tp);
                     rst.end_qc_qty = this.ctx.helper.add(rst.end_qc_qty, p.end_qc_qty);
-                    rst.end_qc_tp = this.ctx.helper.add(rst.end_qc_tp, p.end_qc_tp);
                     for (const prefix of prefixes) {
                         rst[prefix + 'qc_qty'] = this.ctx.helper.add(rst[prefix + 'qc_qty'], p[prefix + 'qc_qty']);
                     }
                 }
             }
+            rst.qc_tp = this.ctx.helper.mul(rst.unit_price, rst.qc_qty, decimal.tp);
+            rst.pre_qc_tp = this.ctx.helper.mul(rst.unit_price, rst.pre_qc_qty, decimal.tp);
+            rst.end_qc_tp = this.ctx.helper.add(rst.pre_qc_tp, rst.qc_tp);
             for (const prefix of prefixes) {
-                rst[prefix + 'qc_tp'] = this.ctx.helper.mul(rst.unit_price, rst[prefix + 'qc_qty'], 2);
+                rst[prefix + 'qc_tp'] = this.ctx.helper.mul(rst.unit_price, rst[prefix + 'qc_qty'], decimal.tp);
             }
         } else {
             rst.qc_qty = bills.qc_qty;
@@ -167,13 +167,13 @@ class jhHelper {
         this.result.push(rst);
     }
 
-    _loadResult(bills, prefixes) {
+    _loadResult(bills, prefixes, decimal) {
         if (bills.pos) {
             for (const p of bills.pos) {
                 let load = false;
                 if (p.pre_cd && p.pre_cd.length > 0) load = true;
                 for (const prefix of prefixes) {
-                    if (p[prefix + '_cd'] && p[prefix + '_cd'].length > 0) load = true;
+                    if (p[prefix + 'cd'] && p[prefix + 'cd'].length > 0) load = true;
                 }
                 if (!load) continue;
 
@@ -184,14 +184,14 @@ class jhHelper {
                     unit_price: bills.unit_price, 
                 };
                 rst.qc_qty = p.qc_qty;
-                rst.qc_tp = p.qc_tp;
+                rst.qc_tp = this.ctx.helper.mul(bills.unit_price, p.qc_qty, decimal.tp);
                 rst.pre_qc_qty = p.pre_qc_qty;
-                rst.pre_qc_tp = p.pre_qc_tp;
+                rst.pre_qc_tp = this.ctx.helper.mul(bills.unit_price, p.pre_qc_qty, decimal.tp);
                 rst.end_qc_qty = p.end_qc_qty;
-                rst.end_qc_tp = p.end_qc_tp;
+                rst.end_qc_tp = this.ctx.helper.add(rst.qc_tp, p.pre_qc_tp);
                 for (const prefix of prefixes) {
                     rst[prefix + 'qc_qty'] = p[prefix + 'qc_qty'];
-                    rst[prefix + 'qc_tp'] = p[prefix + 'qc_tp'];
+                    rst[prefix + 'qc_tp'] = this.ctx.helper.mul(bills.unit_price, p[prefix + 'qc_qty'], decimal.tp);
                 }
                 this.result.push(rst);
             }
@@ -216,7 +216,7 @@ class jhHelper {
         }
     }
 
-    _generateResult(billsData, gsDefine) {
+    _generateResult(billsData, gsDefine, decimal) {
         for (const bills of billsData) {
             let load = false;
             if (bills.pre_cd && bills.pre_cd.length > 0) load = true;
@@ -224,7 +224,7 @@ class jhHelper {
                 if (bills['r' + dc + '_cd'] && bills['r' + dc + '_cd'].length > 0) load = true;
             }
             if (!load) continue;
-            gsDefine.merge ? this._loadMergeResult(bills, this.prefixes) : this._loadResult(bills, this.prefixes);
+            gsDefine.merge ? this._loadMergeResult(bills, this.prefixes, decimal) : this._loadResult(bills, this.prefixes, decimal);
         }
     }
 
@@ -241,8 +241,8 @@ class jhHelper {
         ];
         for (const dc of gsDefine.defaultCompare) {
             const auditor = auditors[dc];
-            const auditorStage = await this.ctx.service.stagePos.getAuditorStageData2(tender.id, stage.id, auditor.times, auditor.order);
-            loadData.push({ data: auditorStage, fields: ['qc_qty', 'qc_tp'], prefix: `r${dc}_`, relaId: 'pid' });
+            const auditorStage = await this.ctx.service.stageBills.getAuditorStageData(tender.id, stage.id, auditor.times, auditor.order);
+            loadData.push({ data: auditorStage, fields: ['qc_qty', 'qc_tp'], prefix: `r${dc}_`, relaId: 'lid' });
         }
         helper.assignRelaData(billsData, loadData);
         // 计算截止本期
@@ -279,7 +279,13 @@ class jhHelper {
         const helper = this.ctx.helper;
 
         await this.ctx.service.stage.doCheckStage(stage);
+
         const auditors = this.getLastestAuditors(stage.auditors);
+        const user = await this.ctx.service.projectAccount.getDataById(stage.user_id);
+        auditors.unshift({
+            aid: user.id, name: user.name, company: user.company, role: user.role,
+            times: stage.curTimes, order: 0
+        });
         const billsData = await this._loadStageBillsData(tender, stage, gsDefine, auditors);
         const posData = await this._loadStagePosData(tender, stage, gsDefine, auditors);
         // 创建索引
@@ -287,24 +293,20 @@ class jhHelper {
         for (const b of billsData) {
             billsIndex[b.id] = b;
             b.pos = posData.filter(x => { return x.lid === b.id; });
-            b.pos.forEach(x => {
-                x.qc_tp = helper.mul(b.unit_price, x.qc_qty, 2);
-                x.pre_qc_tp = helper.mul(b.unit_price, x.pre_qc_qty, 2);
-                x.end_qc_tp = helper.add(x.qc_tp, x.pre_qc_tp);
-            })
         }
 
         // 查询比较人数据
         this.prefixes = [];
         const stageChangeDetail = await this.getCurChangeDetailData(tender.id, stage.id);
+        this.ctx.helper.saveBufferFile(JSON.stringify(stageChangeDetail, '', '\t'), this.ctx.app.baseDir + '/temp.json');
         for (const dc of gsDefine.defaultCompare) {
-            const scd = helper.filterTimesOrderData(stageChangeDetail, ['lid', 'pid', 'cid', 'cbid'], auditors[dc].times, auditors[dc].order);
+            const scd = helper.filterTimesOrderData(stageChangeDetail, ['lid', 'pid', 'cid', 'cbid'], 'stimes', 'sorder', auditors[dc].times, auditors[dc].order);
             this._loadChangeDetail(billsIndex, scd, gsDefine, `r${dc}_`);
             this.prefixes.push(`r${dc}_`);
         }
         const finalChangeData = await this.getPreChangeDetailData(tender.id, stage.order);
         this._loadChangeDetail(billsIndex, finalChangeData, gsDefine, 'pre_');
-        this._generateResult(billsData, gsDefine);
+        this._generateResult(billsData, gsDefine, tender.info.decimal);
     }
 
     async _gatherMonthData(tender, month, defaultCompare) {
@@ -367,11 +369,17 @@ class jhHelper {
         return this.result;
     }
 
-    async convert(tid, sid, memFieldKeys, setting) {
+    async convert(tid, sid, memFieldKeys, option) {
+        if (!option) return [];
+        const setting = JSON.parse(option);
         if (!setting || !setting.defaultCompare) return [];
         const tender = await this.ctx.service.tender.getCheckTender(tid);
         const stage = await this.ctx.service.stage.getDataById(sid);
-        await this._gatherStageData(tender, stage, { defaultCompare: setting.defaultCompare });
+        await this._gatherStageData(tender, stage, setting);
+        const helper = this.ctx.helper;
+        // 排序
+        this.result.sort((x, y) => { return helper.compareCode(x.b_code, y.b_code); });
+        return this.result;
     }
 }
 

+ 22 - 0
app/lib/s2b.js

@@ -0,0 +1,22 @@
+'use strict';
+
+/**
+ *
+ *
+ * @author Mai
+ * @date
+ * @version
+ */
+
+class S2b {
+    constructor(ctx) {
+        this.ctx = ctx;
+        this.db = ctx.app.mysql;
+    }
+
+    getS2bProj(pid) {
+        return this.db.get('zh_s2b_proj', { pid });
+    }
+};
+
+module.exports = S2b;

+ 5 - 8
app/lib/stage_im.js

@@ -308,7 +308,6 @@ class StageIm {
         }
     }
 
-
     _checkCustomDetail(im) {
         const self = this;
         const cd = this._.find(this.details, function(d) {
@@ -320,11 +319,14 @@ class StageIm {
                 (!im.pid || im.pid === d.pid) &&
                 (!im.pos_name || im.pos_name === d.pos_name);
         });
+        if (im.code === '101-1-b') console.log(im, cd);
         if (cd) {
             im.custom_define = cd.custom_define ? cd.custom_define.split(',') : this.imFields;
             this._.assignInWith(im, cd, function(oV, sV, key) {
-                return im.custom_define.indexOf(key) > -1 && sV !== undefined && sV !== null ? sV : oV;
+                if (key === 'calc_memo') console.log(im.code, sV);
+                return im.custom_define.indexOf(key) > -1 ? sV : oV;
             });
+            if (im.code === '101-1-b') console.log(im.calc_memo);
         }
     }
 
@@ -534,7 +536,6 @@ class StageIm {
             im.bw = this._getZlNormalBw(node, peg);
             im.xm = node.name;
         }
-        this._checkCustomDetail(im);
         im.check = this.ctx.stage.im_gather && node.check;
         this._generateTzGclBillsData(node, im);
         this.ImData.push(im);
@@ -633,7 +634,6 @@ class StageIm {
             changes: [], gclBills: [],
             dwgc: this._getDwgc(peg, node), fbgc: this._getFbgc(peg, node), fxgc: this._getFxgc(peg, node),
         };
-        this._checkCustomDetail(im);
         return im;
     }
     _getBwBillsPosIm(imArr, node, peg, index, bw, posName) {
@@ -651,7 +651,6 @@ class StageIm {
                 changes: [], gclBills: [],
             };
             imArr.push(im);
-            this._checkCustomDetail(im);
         }
         return im;
     }
@@ -828,7 +827,6 @@ class StageIm {
                     im.drawing_code = this._getDrawingCode(p);
                 }
                 nodeImData.push(im);
-                this._checkCustomDetail(im);
                 this.ImData.push(im);
             }
             // if (!this.ctx.stage.im_gather || !node.check) {
@@ -904,7 +902,6 @@ class StageIm {
                     im.end_contract_tp = this.ctx.helper.mul(im.end_contract_jl, im.unit_price, tp_decimal);
                     im.end_qc_tp = this.ctx.helper.mul(im.end_qc_jl, im.unit_price, tp_decimal);
                     im.calc_memo = '本期计量:' + (this.ctx.helper.checkZero(im.jl) ? 0 : im.jl) + ' ' + im.unit;
-                    this._checkCustomDetail(im);
                     this.ImData.push(im);
                     if (pp.qc_qty && pp.qc_qty !== 0) {
                         for (const c of this.changes) {
@@ -937,7 +934,6 @@ class StageIm {
                     lIndex: this.billsTree.getNodeSerialNo(node),
                 };
                 im.calc_memo = '本期计量:' + (this.ctx.helper.checkZero(im.jl) ? 0 : im.jl) + ' ' + im.unit;
-                this._checkCustomDetail(im);
                 this.ImData.push(im);
                 if (p.qc_qty && p.qc_qty !== 0) {
                     for (const c of this.changes) {
@@ -1005,6 +1001,7 @@ class StageIm {
             }
 
             this._getCalcMemo(im);
+            this._checkCustomDetail(im);
             delete im.leafXmjs;
             delete im.gclBills;
 

+ 6 - 7
app/public/js/advance_audit.js

@@ -218,9 +218,7 @@ $(document).ready(function () {
         const type = parseInt($(this).data('type'))
         let pay_ratio = null
         let cur_amount = null
-
         let isLimitMax = false  // 用来判断是否达到最大
-
         if (val < min) {
             // 限制最小值为min
             $(this).val(min)
@@ -236,32 +234,33 @@ $(document).ready(function () {
             if (val >= re_amount) {
                 // 限制不能超过最大值
                 val = re_amount
-                debugger
                 isLimitMax = true
             }
+            
             $(this).val(isLimitMax ? val : fixedToSub(val, decimal)) // 重新赋值限制只有两位小数
             const pay_a_input = $(`.pay-input[data-type=${reverse(type)}]`)
-            pay_ratio = parseFloat(ZhCalc.mul(ZhCalc.div(val, advancePayTotal), 100).toFixed(2))
+            pay_ratio = ZhCalc.mul(ZhCalc.div(val, advancePayTotal), 100).toFixed(2)
             cur_amount = isLimitMax ? re_amount : ZhCalc.round(val, decimal)
             pay_a_input.val(pay_ratio)
-            const total = parseFloat(ZhCalc.add(cur_amount, p_amount)).toString().split('.')[1]
+            const total = ZhCalc.add(cur_amount, p_amount).toString().split('.')[1] || ''
             // 截止本期金额文案更新
             $('#p_total2').text(formatMoney(ZhCalc.add(cur_amount, p_amount), ',', isLimitMax ? total.length : 2) + '元')
         } else {
-            // 支付比例转化
 
+            // 支付比例转化
             val = fixedToSub(val)
             if (val.toFixed(2) === max.toFixed(2)) {
               // 比例达到最大,特殊处理金额的显示小数点
                 val = fixedToSub(max, 2);
                 isLimitMax = true
             }
+
             $(this).val(val) // 重新赋值限制只有两位小数
             const cur_m_input = $(`.pay-input[data-type=${reverse(type)}]`)
             cur_amount = isLimitMax ? re_amount : ZhCalc.round(ZhCalc.mul(advancePayTotal, ZhCalc.div(val, 100), 10), decimal)
             pay_ratio = val
             cur_m_input.val(cur_amount)
-            const total = parseFloat(ZhCalc.add(cur_amount, p_amount)).toString().split('.')[1]
+            const total = ZhCalc.add(cur_amount, p_amount).toString().split('.')[1] || ''
             // 截止本期金额文案更新
             $('#p_total2').text(formatMoney(ZhCalc.add(cur_amount, p_amount), ',', isLimitMax ? total.length : 2) + '元')
         }

+ 12 - 12
app/public/js/change.js

@@ -307,28 +307,28 @@ $(document).ready(() => {
     } else {
         $('#bpaixu').text('排序:变更令号');
     }
-    let sortSetting = getLocalCache('change-'+ $('#tenderId').val() +'-list-sort');
-    if (sortSetting && parseInt(sortSetting) === 1) {
-        $('#bpaixu').click();
-    }
-    $('#sort-dropdown').on('shown.bs.dropdown', function () {
-        setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 1);
-    });
-    $('#sort-dropdown').on('hidden.bs.dropdown', function () {
-        setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 0);
-    });
+    // let sortSetting = getLocalCache('change-'+ $('#tenderId').val() +'-list-sort');
+    // if (sortSetting && parseInt(sortSetting) === 1) {
+    //     $('#bpaixu').click();
+    // }
+    // $('#sort-dropdown').on('shown.bs.dropdown', function () {
+    //     setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 1);
+    // });
+    // $('#sort-dropdown').on('hidden.bs.dropdown', function () {
+    //     setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 0);
+    // });
 
     $('#sort-radio input[name="paizhi"]').click(function () {
         const orderStr = $(this).val() + '|' + $('#order-radio input[name="paixu"]:checked').val();
         setLocalCache('change-'+ $('#tenderId').val() +'-list-order', orderStr);
-        setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 1);
+        // setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 1);
         const link = window.location.origin + window.location.pathname + '?sort='+ $(this).val() + '&order=' + $('#order-radio input[name="paixu"]:checked').val();
         window.location.href = link;
     });
     $('#order-radio input[name="paixu"]').click(function () {
         const orderStr = $('#sort-radio input[name="paizhi"]:checked').val() + '|' + $(this).val();
         setLocalCache('change-'+ $('#tenderId').val() +'-list-order', orderStr);
-        setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 1);
+        // setLocalCache('change-'+ $('#tenderId').val() +'-list-sort', 1);
         const link = window.location.origin + window.location.pathname + '?sort='+ $('#sort-radio input[name="paizhi"]:checked').val() + '&order=' + $(this).val();
         window.location.href = link;
     })

+ 1 - 1
app/public/js/change_information_set.js

@@ -272,7 +272,7 @@ $(document).ready(() => {
                     // 判断是否大于等于限制值,否则无法更改
                     const usedInfo = _.find(changeUsedData, { id: select.id });
                     if (usedInfo && validText < usedInfo.used_qty) {
-                        toastr.error('已调用清单更数值必须大于等于已调用值');
+                        toastr.error('清单更数值必须大于等于已调用值');
                         SpreadJsObj.reLoadRowData(info.sheet, info.row);
                         return;
                     }

+ 141 - 5
app/public/js/ledger_check.js

@@ -17,6 +17,14 @@ const ledgerCheckType = {
     tp: {value: 5, text: '清单金额≠数量×单价', fun: 'checkTp', },
     over: {value: 6, text: '超计', fun: 'checkOver', },
     same_code: {value: 7, text: '重复项目节', fun: 'checkSameCode', },
+    limit3f: {
+        fun: 'check3fLimit', items: [
+            { value: 8, text: '违规计量(工序报验)', key: 'gxbyOver', type: 'gxby', },
+            { value: 9, text: '遗漏计量(工序报验)', key: 'gxbyLost', type: 'gxby', },
+            { value: 10, text: '违规计量(档案管理)', key: 'daglOver', type: 'dagl', },
+            { value: 11, text: '遗漏计量(档案管理)', key: 'daglLost', type: 'dagl', },
+        ]
+    },
 };
 const ledgerCheckUtil = {
     checkSibling: function (ledgerTree, ledgerPos, decimal, option) {
@@ -118,7 +126,120 @@ const ledgerCheckUtil = {
             }
         }
         return error;
-    }
+    },
+    check3fLimit: function (ledgerTree, ledgerPos, decimal, option) {
+        const error = {};
+        for (const i of ledgerCheckType.limit3f.items) {
+            error[i.key] = [];
+        }
+        if (option.checkType.length === 0) return error;
+
+        const findPrecision = function (list, unit) {
+            if (unit) {
+                for (const p in list) {
+                    if (list[p].unit && list[p].unit === unit) {
+                        return list[p];
+                    }
+                }
+            }
+            return list.other;
+        };
+        const check3f = function (data, limit, ratio) {
+            if (limit === 0) {
+                if (data.contract_tp || data.pre_contract_tp) return 1; // 违规
+            }
+            if (limit === 1) {
+                if (ratio === 0) {
+                    if (!data.contract_tp && !data.pre_contract_tp) return 2; // 漏计
+                } else {
+                    const tp = ZhCalc.mul(data.total_price, ratio, this.ctx.tender.info.decimal.tp);
+                    const checkTp = ZhCalc.add(data.contract_tp, data.pre_contract_tp);
+                    if (tp > checkTp) return 1; // 违规
+                    if (tp < checkTp) return 2; // 漏计
+                }
+            }
+            return 0; // 合法
+        };
+        const check3fQty = function (data, limit, ratio, unit) {
+            if (limit === 0) {
+                if (data.contract_qty || data.qc_qty || data.pre_contract_qty || data.pre_qc_qty) return 1; // 违规
+            }
+            if (limit === 1) {
+                if (ratio <= 0) {
+                    if (!data.contract_qty && !data.qc_qty && !data.pre_contract_qty && !data.pre_qc_qty) return 2; // 漏计
+                } else {
+                    const precision = findPrecision(tenderInfo.precision, unit);
+                    const checkQty = ZhCalc.mul(data.quantity, ratio, precision.value);
+                    const qty = ZhCalc.add(data.contract_qty, data.pre_contract_qty);
+                    if (qty > checkQty) return 1; // 违规
+                    if (qty < checkQty) return 2; // 漏计
+                }
+            }
+            return 0; // 合法
+        };
+        const checkLeafBills3fLimit = function(bills, checkInfo) {
+            const over = [], lost = [];
+            const posRange = ledgerPos.getLedgerPos(bills.id);
+            if (posRange && posRange.length > 0) {
+                for (const p of posRange) {
+                    const posCheckInfo = _.assign({}, checkInfo);
+                    for (const ct of option.checkType) {
+                        if (p[ct + '_limit'] >= 0) {
+                            posCheckInfo[ct + '_limit'] = p[ct + '_limit'];
+                            posCheckInfo[ct + '_ratio'] = p[ct + '_ratio'];
+                        }
+                    }
+                    for (const ct of option.checkType) {
+                        const checkResult = check3fQty(p, posCheckInfo[ct + '_limit'], posCheckInfo[ct + '_ratio'], bills.unit);
+                        if (checkResult === 1) {
+                            if (over.indexOf(ct) === -1) over.push(ct);
+                        }
+                        if (checkResult === 2) {
+                            if (lost.indexOf(ct) === -1) lost.push(ct);
+                        }
+                    }
+                }
+            } else {
+                for (const ct of option.checkType) {
+                    const checkResult = bills.is_tp
+                        ? check3f(bills, checkInfo[ct + '_limit'], checkInfo[ct + '_ratio'])
+                        : check3fQty(bills, checkInfo[ct + '_limit'], checkInfo[ct + '_ratio'], bills.unit);
+                    if (checkResult === 1) {
+                        if (over.indexOf(ct) === -1) over.push(ct);
+                    }
+                    if (checkResult === 2) {
+                        if (lost.indexOf(ct) === -1) lost.push(ct);
+                    }
+                }
+            }
+
+            if (over.indexOf('gxby') >= 0) error.gxbyOver.push(bills);
+            if (over.indexOf('dagl') >= 0) error.daglOver.push(bills);
+            if (lost.indexOf('gxby') >= 0) error.gxbyLost.push(bills);
+            if (lost.indexOf('dagl') >= 0) error.daglLost.push(bills);
+        };
+        const recursiveCheckBills3fLimit = function (bills, parentCheckInfo) {
+            const checkInfo = _.assign({}, parentCheckInfo);
+            for (const ct of option.checkType) {
+                if (bills[ct + '_limit'] >= 0) {
+                    checkInfo[ct + '_limit'] = bills[ct + '_limit'];
+                    checkInfo[ct + '_ratio'] = bills[ct + '_ratio'];
+                }
+            }
+            if (bills.children && bills.children.length > 0) {
+                for (const c of bills.children) {
+                    recursiveCheckBills3fLimit(c, checkInfo);
+                }
+            } else {
+                checkLeafBills3fLimit(bills, checkInfo);
+            }
+        };
+
+        for (const b of ledgerTree.children) {
+            recursiveCheckBills3fLimit(b, {});
+        }
+        return error;
+    },
 };
 
 const ledgerCheck2 = function (setting) {
@@ -145,9 +266,18 @@ const ledgerCheck2 = function (setting) {
     for (const prop in ledgerCheckType) {
         if (!checkOption[prop] || !checkOption[prop].enable) continue;
 
-        const errors = ledgerCheckUtil[ledgerCheckType[prop].fun](ledger, ledgerPos, decimal, checkOption[prop]) || [];
-        assignWarningData(errors, ledgerCheckType[prop].value, checkData.warning_data);
-        progressData.push({key: prop, caption: ledgerCheckType[prop].text, error: errors.length});
+        if (ledgerCheckType[prop].items) {
+            const errors = ledgerCheckUtil[ledgerCheckType[prop].fun](ledger, ledgerPos, decimal, checkOption[prop]) || {};
+            for (const i of ledgerCheckType[prop].items) {
+                if (checkOption[prop].checkType.indexOf(i.type) < 0) continue;
+                assignWarningData(errors[i.key], i.value, checkData.warning_data);
+                progressData.push({key: prop + i.key, caption: i.text, error: errors[i.key].length});
+            }
+        } else {
+            const errors = ledgerCheckUtil[ledgerCheckType[prop].fun](ledger, ledgerPos, decimal, checkOption[prop]) || [];
+            assignWarningData(errors, ledgerCheckType[prop].value, checkData.warning_data);
+            progressData.push({key: prop, caption: ledgerCheckType[prop].text, error: errors.length});
+        }
     }
     setting.checkList.clearCheckData();
     if (checkData.warning_data.length > 0) {
@@ -161,7 +291,13 @@ const getCheckType = function (option) {
     const result = {};
     for (const o in option) {
         if (option[o].enable) {
-            result[o] = ledgerCheckType[o];
+            if (ledgerCheckType[o].items) {
+                for (const i of ledgerCheckType[o].items) {
+                    result[o + i.key] = i;
+                }
+            } else {
+                result[o] = ledgerCheckType[o];
+            }
         }
     }
     return result;

+ 1 - 1
app/public/js/se_jgcl.js

@@ -296,7 +296,7 @@ $(document).ready(() => {
                     case 'name':
                     case 'unit':
                     case 'unit_price':
-                        info.cancel = readOnly || node.pre_used;
+                        info.cancel = readOnly;
                         break;
                 }
             },

+ 6 - 0
app/public/js/shares/cs_tools.js

@@ -76,6 +76,12 @@ const showSelectTab = function(select, spread, afterShow) {
                                 case 'qty': return '数量';
                                 case 'tp': return '金额';
                                 case 'over': return '超计';
+                                case 'sibling': return '项目节清单同层';
+                                case 'same_code': return '重复项目节编号';
+                                case 's2b_over_gxby': return '违规计量(工序报验)';
+                                case 's2b_over_dagl': return '违规计量(档案管理)';
+                                case 's2b_lost_gxby': return '遗漏计量(工序报验)';
+                                case 's2b_lost_dagl': return '遗漏计量(档案管理)';
                                 default: return '';
                             }
                         }

+ 13 - 1
app/public/js/stage.js

@@ -240,8 +240,13 @@ $(document).ready(() => {
         },
         over: {
             enable: 1, isTz: checkTzMeasureType(),
+        },
+        limit3f: {
+            enable: 1, checkType: [],
         }
     };
+    if (tender.s2b_gxby_check) checkOption.limit3f.checkType.push('gxby');
+    if (tender.s2b_dagl_check) checkOption.limit3f.checkType.push('dagl');
     // 界面布局
     autoFlashHeight();
     // 初始化 台账树结构 数据结构
@@ -339,7 +344,7 @@ $(document).ready(() => {
                 html.push('<td>', moment(p.confirm_time).format('YYYY-MM-DD HH:mm') + ' ' + (coopwd ? `<a name="ledger-unconfirm" href="javascript: void(0);" lid="${p.ledger_id}">重新审批</a>` : ''), '</td>');
             } else if (!p.check && p.confirm) {
                 html.push('<td>', moment(p.confirm_time).format('YYYY-MM-DD HH:mm'), '</td>');
-            } else if (p.check && !p.confirm) {
+            } else if (p.check && !p.confirm && coopwd) {
                 html.push('<td>', `<a name="ledger-confirm" href="javascript: void(0);" lid="${p.ledger_id}" class="btn btn-sm btn-success">确认</a>`, '</td>');
             } else {
                 html.push('<td>', '</td>');
@@ -628,6 +633,12 @@ $(document).ready(() => {
     // 初始化 台账 spread
     const slSpread = SpreadJsObj.createNewSpread($('#stage-ledger')[0]);
     customizeStageTreeSetting(ledgerSpreadSetting, customColDisplay());
+    ledgerSpreadSetting.cols.push(
+        {title: '工序限制', colSpan: '1', rowSpan: '2', field: 'gxby_limit', hAlign: 0, width: 80, readOnly: true},
+    );
+    posSpreadSetting.cols.push(
+        {title: '工序限制', colSpan: '1', rowSpan: '2', field: 'gxby_limit', hAlign: 0, width: 80, readOnly: true},
+    );
     // 数量变更列,添加按钮
     const qcCol = _.find(ledgerSpreadSetting.cols, {field: 'qc_qty'});
     qcCol.readOnly = true;
@@ -1914,6 +1925,7 @@ $(document).ready(() => {
         },
         selectionChanged: function (e, info) {
             stagePosSpreadObj.loadExprToInput(info.sheet);
+            console.log(SpreadJsObj.getSelectObject(info.sheet));
         },
         addPegs: function (pegs) {
             if (!pegs || pegs.length <= 0) return;

+ 237 - 0
app/public/netcasign/example/appPackage.js

@@ -0,0 +1,237 @@
+// 下载文件
+function dataURLtoBlob(dataurl) {
+    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
+    while (n--) {
+        u8arr[n] = bstr.charCodeAt(n);
+    }
+    return new Blob([u8arr], { type: mime });
+}
+
+function downloadFile(blob, url, name){
+
+    if (window.navigator.msSaveBlob) {
+        try {
+            window.navigator.msSaveBlob(blob, name)
+        } catch (e) {
+            console.log(e);
+        }
+    } else {
+        // 谷歌浏览器 创建a标签 添加download属性下载
+        var a = document.createElement("a");
+        a.setAttribute("href",url);
+        a.setAttribute("download",name);
+        a.setAttribute("target","_blank");
+        var clickEvent = document.createEvent("MouseEvents"); //创建
+        clickEvent.initEvent("click", true, true);//初始化
+        a.dispatchEvent(clickEvent);//触发
+    }
+
+}
+
+function downloadFileByBase64(base64,name){
+    var myBlob = dataURLtoBlob(base64);
+    var myUrl = URL.createObjectURL(myBlob);
+    downloadFile(myBlob, myUrl,name)
+}
+
+function downloadNewFile(){
+    var base64 = NetcaPDFSeal.getSignPDFBytes();
+    var file = 'data:application/pdf;base64,' + base64;
+    var name = new Date();
+    name = name.getTime();
+    downloadFileByBase64(file, name+'.pdf');
+
+}
+
+
+
+
+// 演示功能
+function demonstrationFn(){
+
+    var obj = {
+
+        'netcasave':false,
+        'netcaFirstSeparator':false,
+        'netcaSecondSeparator':false,
+        'netcaThirdSeparaor':false,
+        'netcaSetting':false,
+        'netcaAbout':false
+    };
+    checkObjHasOwnProperty(obj);
+    hideExtraCheckboxesIE(obj);
+    removeExtraCheckboxes();
+    hideExtraCheckboxes();
+
+}
+
+
+/**检查obj是否有指定属性存在*/
+function checkObjHasOwnProperty(obj){
+    if(!obj.hasOwnProperty('openFile')){
+        obj.openFile = true
+    }
+    if(!obj.hasOwnProperty('netcasave')){
+        obj.netcasave = true
+    }
+    if(!obj.hasOwnProperty('viewFind')){
+        obj.viewFind = true
+    }
+    if(!obj.hasOwnProperty('zoomOut')){
+        obj.zoomOut = true
+    }
+    if(!obj.hasOwnProperty('zoomIn')){
+        obj.zoomIn = true
+    }
+    if(!obj.hasOwnProperty('scaleSelectContainer')){
+        obj.scaleSelectContainer = true
+    }
+    if(!obj.hasOwnProperty('netcaFirstSeparator')){
+        obj.netcaFirstSeparator = true
+    }
+    if(!obj.hasOwnProperty('previous')){
+        obj.previous = true
+    }
+    if(!obj.hasOwnProperty('next')){
+        obj.next = true
+    }
+    if(!obj.hasOwnProperty('netcaSecondSeparator')){
+        obj.netcaSecondSeparator = true
+    }
+    if(!obj.hasOwnProperty('verify')){
+        obj.verify = true
+    }
+    if(!obj.hasOwnProperty('netcasign')){
+        obj.netcasign = true
+    }
+    if(!obj.hasOwnProperty('netcaThirdSeparaor')){
+        obj.netcaThirdSeparaor = true
+    }
+    if(!obj.hasOwnProperty('netcaSetting')){
+        obj.netcaSetting = true
+    }
+    if(!obj.hasOwnProperty('netcaAbout')){
+        obj.netcaAbout = true
+    }
+    if(!obj.hasOwnProperty('netcastaff')){
+        obj.netcastaff = true
+    }
+    if(!obj.hasOwnProperty('netcaorganization')){
+        obj.netcaorganization = true
+    }
+    if(!obj.hasOwnProperty('netcalegalperson')){
+        obj.netcalegalperson = true
+    }
+    if(!obj.hasOwnProperty('print')){
+        obj.print = true
+    }
+    if(!obj.hasOwnProperty('closeFile')){
+        obj.closeFile = true
+    }
+}
+/**
+ * 非IE浏览器下,移除多余的checkbox
+ * */
+function removeExtraCheckboxes(){
+    var arr = [2,7,11,14,15,16];
+    if(!NetcaPDFSeal._isIE()){
+        for(var i=0;i<arr.length;i++){
+            (function(i){
+                $('input[name="checkbox'+arr[i]+'"]').parent().remove()
+            })(i);
+        }
+    }
+}
+/**
+ * 根据toolbarButton的true/false,隐藏多余的checkbox
+ * */
+function hideExtraCheckboxes(){
+    var arr1 = [4,5,6,8,9,10,12,13,20,21,22,23,24,28];
+    for(var j=0;j<arr1.length;j++){
+        (function(j){
+            if($('.netca_btn'+arr1[j]+'').css('display') === 'none'){
+                $('input[name="checkbox'+arr1[j]+'"]').parent().remove()
+            }
+        })(j);
+    }
+}
+/** IE 隐藏多余的checkbox
+ * */
+function hideExtraCheckboxesIE(obj) {
+    for (var k in obj) {
+        if(k === 'print' && obj[k] === false){
+            $('#checkbox20').parent().remove();
+        }
+        if(k === 'zoomOut' &&  obj[k] === false){
+            $('#checkbox4').parent().remove();
+        }
+        if(k === 'zoomIn' &&  obj[k] === false){
+            $('#checkbox5').parent().remove();
+        }
+        if(k === 'scaleSelectContainer' && obj[k] === false){
+            $('#checkbox6').parent().remove();
+        }
+        if(k === 'previous' && obj[k] === false){
+            $('#checkbox8').parent().remove();
+        }
+        if(k === 'next' && obj[k] === false){
+            $('#checkbox9').parent().remove();
+        }
+        if(k === 'netcapage' && obj[k] === false){
+            $('#checkbox10').parent().remove();
+        }
+        if(k === 'openFile' && obj[k] === false){
+            $('#checkbox1').parent().remove();
+        }
+        if(k === 'netcasave' && obj[k] === false){
+            $('#checkbox2').parent().remove();
+        }
+        if(k === 'viewFind' && obj[k] === false){
+            $('#checkbox3').parent().remove();
+        }
+        if(k === 'netcaFirstSeparator' && obj[k] === false){
+            $('#checkbox7').parent().remove();
+        }
+        if(k === 'netcaSecondSeparator' && obj[k] === false){
+            $('#checkbox11').parent().remove();
+        }
+        if(k === 'netcaThirdSeparaor' && obj[k] === false){
+            $('#checkbox14').parent().remove();
+        }
+        if(k === 'verfity' && obj[k] === false){
+            $('#checkbox13').parent().remove();
+        }
+        if(k === 'netcaSetting' && obj[k] === false){
+            $('#checkbox15').parent().remove();
+        }
+        if(k === 'netcaAbout' && obj[k] === false){
+            $('#checkbox16').parent().remove();
+        }
+        if(k === 'netcasign' && obj[k] === false){
+            $('#checkbox21').parent().remove();
+        }
+        if(k === 'netcastaff' && obj[k] === false){
+            $('#checkbox22').parent().remove();
+        }
+        if(k === 'netcaorganization' && obj[k] === false){
+            $('#checkbox23').parent().remove();
+        }
+        if(k === 'netcalegalperson' && obj[k] === false){
+            $('#checkbox24').parent().remove();
+        }
+        if(k === 'closeFile' && obj[k] === false){
+            $('#checkbox28').parent().remove();
+        }
+    }
+}
+
+function getSignCallBack(res){
+    console.log("签名信息", JSON.parse(res))
+}
+function getVerifyCallBack(res){
+    console.log("验证信息", JSON.parse(res))
+}
+// NetcaPDFSeal.setSignCallbackEvent(getSignCallBack);
+// NetcaPDFSeal.setVerifyCallbackEvent(getVerifyCallBack);
+

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
app/public/netcasign/js/base64.min.js


+ 615 - 0
app/public/netcasign/js/debugger.js

@@ -0,0 +1,615 @@
+/* Copyright 2012 Mozilla Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* eslint-disable no-var */
+
+'use strict';
+
+var FontInspector = (function FontInspectorClosure() {
+  var fonts, createObjectURL;
+  var active = false;
+  var fontAttribute = 'data-font-name';
+  function removeSelection() {
+    let divs = document.querySelectorAll(`span[${fontAttribute}]`);
+    for (let div of divs) {
+      div.className = '';
+    }
+  }
+  function resetSelection() {
+    let divs = document.querySelectorAll(`span[${fontAttribute}]`);
+    for (let div of divs) {
+      div.className = 'debuggerHideText';
+    }
+  }
+  function selectFont(fontName, show) {
+    let divs = document.querySelectorAll(`span[${fontAttribute}=${fontName}]`);
+    for (let div of divs) {
+      div.className = show ? 'debuggerShowText' : 'debuggerHideText';
+    }
+  }
+  function textLayerClick(e) {
+    if (!e.target.dataset.fontName ||
+        e.target.tagName.toUpperCase() !== 'SPAN') {
+      return;
+    }
+    var fontName = e.target.dataset.fontName;
+    var selects = document.getElementsByTagName('input');
+    for (var i = 0; i < selects.length; ++i) {
+      var select = selects[i];
+      if (select.dataset.fontName !== fontName) {
+        continue;
+      }
+      select.checked = !select.checked;
+      selectFont(fontName, select.checked);
+      select.scrollIntoView();
+    }
+  }
+  return {
+    // Properties/functions needed by PDFBug.
+    id: 'FontInspector',
+    name: 'Font Inspector',
+    panel: null,
+    manager: null,
+    init: function init(pdfjsLib) {
+      var panel = this.panel;
+      panel.setAttribute('style', 'padding: 5px;');
+      var tmp = document.createElement('button');
+      tmp.addEventListener('click', resetSelection);
+      tmp.textContent = 'Refresh';
+      panel.appendChild(tmp);
+
+      fonts = document.createElement('div');
+      panel.appendChild(fonts);
+
+      createObjectURL = pdfjsLib.createObjectURL;
+    },
+    cleanup: function cleanup() {
+      fonts.textContent = '';
+    },
+    enabled: false,
+    get active() {
+      return active;
+    },
+    set active(value) {
+      active = value;
+      if (active) {
+        document.body.addEventListener('click', textLayerClick, true);
+        resetSelection();
+      } else {
+        document.body.removeEventListener('click', textLayerClick, true);
+        removeSelection();
+      }
+    },
+    // FontInspector specific functions.
+    fontAdded: function fontAdded(fontObj, url) {
+      function properties(obj, list) {
+        var moreInfo = document.createElement('table');
+        for (var i = 0; i < list.length; i++) {
+          var tr = document.createElement('tr');
+          var td1 = document.createElement('td');
+          td1.textContent = list[i];
+          tr.appendChild(td1);
+          var td2 = document.createElement('td');
+          td2.textContent = obj[list[i]].toString();
+          tr.appendChild(td2);
+          moreInfo.appendChild(tr);
+        }
+        return moreInfo;
+      }
+      var moreInfo = properties(fontObj, ['name', 'type']);
+      var fontName = fontObj.loadedName;
+      var font = document.createElement('div');
+      var name = document.createElement('span');
+      name.textContent = fontName;
+      var download = document.createElement('a');
+      if (url) {
+        url = /url\(['"]?([^\)"']+)/.exec(url);
+        download.href = url[1];
+      } else if (fontObj.data) {
+        download.href = createObjectURL(fontObj.data, fontObj.mimeType);
+      }
+      download.textContent = 'Download';
+      var logIt = document.createElement('a');
+      logIt.href = '';
+      logIt.textContent = 'Log';
+      logIt.addEventListener('click', function(event) {
+        event.preventDefault();
+        console.log(fontObj);
+      });
+      var select = document.createElement('input');
+      select.setAttribute('type', 'checkbox');
+      select.dataset.fontName = fontName;
+      select.addEventListener('click', (function(select, fontName) {
+        return (function() {
+           selectFont(fontName, select.checked);
+        });
+      })(select, fontName));
+      font.appendChild(select);
+      font.appendChild(name);
+      font.appendChild(document.createTextNode(' '));
+      font.appendChild(download);
+      font.appendChild(document.createTextNode(' '));
+      font.appendChild(logIt);
+      font.appendChild(moreInfo);
+      fonts.appendChild(font);
+      // Somewhat of a hack, should probably add a hook for when the text layer
+      // is done rendering.
+      setTimeout(() => {
+        if (this.active) {
+          resetSelection();
+        }
+      }, 2000);
+    },
+  };
+})();
+
+var opMap;
+
+// Manages all the page steppers.
+var StepperManager = (function StepperManagerClosure() {
+  var steppers = [];
+  var stepperDiv = null;
+  var stepperControls = null;
+  var stepperChooser = null;
+  var breakPoints = Object.create(null);
+  return {
+    // Properties/functions needed by PDFBug.
+    id: 'Stepper',
+    name: 'Stepper',
+    panel: null,
+    manager: null,
+    init: function init(pdfjsLib) {
+      var self = this;
+      this.panel.setAttribute('style', 'padding: 5px;');
+      stepperControls = document.createElement('div');
+      stepperChooser = document.createElement('select');
+      stepperChooser.addEventListener('change', function(event) {
+        self.selectStepper(this.value);
+      });
+      stepperControls.appendChild(stepperChooser);
+      stepperDiv = document.createElement('div');
+      this.panel.appendChild(stepperControls);
+      this.panel.appendChild(stepperDiv);
+      if (sessionStorage.getItem('pdfjsBreakPoints')) {
+        breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints'));
+      }
+
+      opMap = Object.create(null);
+      for (var key in pdfjsLib.OPS) {
+        opMap[pdfjsLib.OPS[key]] = key;
+      }
+    },
+    cleanup: function cleanup() {
+      stepperChooser.textContent = '';
+      stepperDiv.textContent = '';
+      steppers = [];
+    },
+    enabled: false,
+    active: false,
+    // Stepper specific functions.
+    create: function create(pageIndex) {
+      var debug = document.createElement('div');
+      debug.id = 'stepper' + pageIndex;
+      debug.setAttribute('hidden', true);
+      debug.className = 'stepper';
+      stepperDiv.appendChild(debug);
+      var b = document.createElement('option');
+      b.textContent = 'Page ' + (pageIndex + 1);
+      b.value = pageIndex;
+      stepperChooser.appendChild(b);
+      var initBreakPoints = breakPoints[pageIndex] || [];
+      var stepper = new Stepper(debug, pageIndex, initBreakPoints);
+      steppers.push(stepper);
+      if (steppers.length === 1) {
+        this.selectStepper(pageIndex, false);
+      }
+      return stepper;
+    },
+    selectStepper: function selectStepper(pageIndex, selectPanel) {
+      var i;
+      pageIndex = pageIndex | 0;
+      if (selectPanel) {
+        this.manager.selectPanel(this);
+      }
+      for (i = 0; i < steppers.length; ++i) {
+        var stepper = steppers[i];
+        if (stepper.pageIndex === pageIndex) {
+          stepper.panel.removeAttribute('hidden');
+        } else {
+          stepper.panel.setAttribute('hidden', true);
+        }
+      }
+      var options = stepperChooser.options;
+      for (i = 0; i < options.length; ++i) {
+        var option = options[i];
+        option.selected = (option.value | 0) === pageIndex;
+      }
+    },
+    saveBreakPoints: function saveBreakPoints(pageIndex, bps) {
+      breakPoints[pageIndex] = bps;
+      sessionStorage.setItem('pdfjsBreakPoints', JSON.stringify(breakPoints));
+    },
+  };
+})();
+
+// The stepper for each page's IRQueue.
+var Stepper = (function StepperClosure() {
+  // Shorter way to create element and optionally set textContent.
+  function c(tag, textContent) {
+    var d = document.createElement(tag);
+    if (textContent) {
+      d.textContent = textContent;
+    }
+    return d;
+  }
+
+  function simplifyArgs(args) {
+    if (typeof args === 'string') {
+      var MAX_STRING_LENGTH = 75;
+      return args.length <= MAX_STRING_LENGTH ? args :
+        args.substring(0, MAX_STRING_LENGTH) + '...';
+    }
+    if (typeof args !== 'object' || args === null) {
+      return args;
+    }
+    if ('length' in args) { // array
+      var simpleArgs = [], i, ii;
+      var MAX_ITEMS = 10;
+      for (i = 0, ii = Math.min(MAX_ITEMS, args.length); i < ii; i++) {
+        simpleArgs.push(simplifyArgs(args[i]));
+      }
+      if (i < args.length) {
+        simpleArgs.push('...');
+      }
+      return simpleArgs;
+    }
+    var simpleObj = {};
+    for (var key in args) {
+      simpleObj[key] = simplifyArgs(args[key]);
+    }
+    return simpleObj;
+  }
+
+  function Stepper(panel, pageIndex, initialBreakPoints) {
+    this.panel = panel;
+    this.breakPoint = 0;
+    this.nextBreakPoint = null;
+    this.pageIndex = pageIndex;
+    this.breakPoints = initialBreakPoints;
+    this.currentIdx = -1;
+    this.operatorListIdx = 0;
+  }
+  Stepper.prototype = {
+    init: function init(operatorList) {
+      var panel = this.panel;
+      var content = c('div', 'c=continue, s=step');
+      var table = c('table');
+      content.appendChild(table);
+      table.cellSpacing = 0;
+      var headerRow = c('tr');
+      table.appendChild(headerRow);
+      headerRow.appendChild(c('th', 'Break'));
+      headerRow.appendChild(c('th', 'Idx'));
+      headerRow.appendChild(c('th', 'fn'));
+      headerRow.appendChild(c('th', 'args'));
+      panel.appendChild(content);
+      this.table = table;
+      this.updateOperatorList(operatorList);
+    },
+    updateOperatorList: function updateOperatorList(operatorList) {
+      var self = this;
+
+      function cboxOnClick() {
+        var x = +this.dataset.idx;
+        if (this.checked) {
+          self.breakPoints.push(x);
+        } else {
+          self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
+        }
+        StepperManager.saveBreakPoints(self.pageIndex, self.breakPoints);
+      }
+
+      var MAX_OPERATORS_COUNT = 15000;
+      if (this.operatorListIdx > MAX_OPERATORS_COUNT) {
+        return;
+      }
+
+      var chunk = document.createDocumentFragment();
+      var operatorsToDisplay = Math.min(MAX_OPERATORS_COUNT,
+                                        operatorList.fnArray.length);
+      for (var i = this.operatorListIdx; i < operatorsToDisplay; i++) {
+        var line = c('tr');
+        line.className = 'line';
+        line.dataset.idx = i;
+        chunk.appendChild(line);
+        var checked = this.breakPoints.includes(i);
+        var args = operatorList.argsArray[i] || [];
+
+        var breakCell = c('td');
+        var cbox = c('input');
+        cbox.type = 'checkbox';
+        cbox.className = 'points';
+        cbox.checked = checked;
+        cbox.dataset.idx = i;
+        cbox.onclick = cboxOnClick;
+
+        breakCell.appendChild(cbox);
+        line.appendChild(breakCell);
+        line.appendChild(c('td', i.toString()));
+        var fn = opMap[operatorList.fnArray[i]];
+        var decArgs = args;
+        if (fn === 'showText') {
+          var glyphs = args[0];
+          var newArgs = [];
+          var str = [];
+          for (var j = 0; j < glyphs.length; j++) {
+            var glyph = glyphs[j];
+            if (typeof glyph === 'object' && glyph !== null) {
+              str.push(glyph.fontChar);
+            } else {
+              if (str.length > 0) {
+                newArgs.push(str.join(''));
+                str = [];
+              }
+              newArgs.push(glyph); // null or number
+            }
+          }
+          if (str.length > 0) {
+            newArgs.push(str.join(''));
+          }
+          decArgs = [newArgs];
+        }
+        line.appendChild(c('td', fn));
+        line.appendChild(c('td', JSON.stringify(simplifyArgs(decArgs))));
+      }
+      if (operatorsToDisplay < operatorList.fnArray.length) {
+        line = c('tr');
+        var lastCell = c('td', '...');
+        lastCell.colspan = 4;
+        chunk.appendChild(lastCell);
+      }
+      this.operatorListIdx = operatorList.fnArray.length;
+      this.table.appendChild(chunk);
+    },
+    getNextBreakPoint: function getNextBreakPoint() {
+      this.breakPoints.sort(function(a, b) {
+        return a - b;
+      });
+      for (var i = 0; i < this.breakPoints.length; i++) {
+        if (this.breakPoints[i] > this.currentIdx) {
+          return this.breakPoints[i];
+        }
+      }
+      return null;
+    },
+    breakIt: function breakIt(idx, callback) {
+      StepperManager.selectStepper(this.pageIndex, true);
+      var self = this;
+      var dom = document;
+      self.currentIdx = idx;
+      var listener = function(e) {
+        switch (e.keyCode) {
+          case 83: // step
+            dom.removeEventListener('keydown', listener);
+            self.nextBreakPoint = self.currentIdx + 1;
+            self.goTo(-1);
+            callback();
+            break;
+          case 67: // continue
+            dom.removeEventListener('keydown', listener);
+            var breakPoint = self.getNextBreakPoint();
+            self.nextBreakPoint = breakPoint;
+            self.goTo(-1);
+            callback();
+            break;
+        }
+      };
+      dom.addEventListener('keydown', listener);
+      self.goTo(idx);
+    },
+    goTo: function goTo(idx) {
+      var allRows = this.panel.getElementsByClassName('line');
+      for (var x = 0, xx = allRows.length; x < xx; ++x) {
+        var row = allRows[x];
+        if ((row.dataset.idx | 0) === idx) {
+          row.style.backgroundColor = 'rgb(251,250,207)';
+          row.scrollIntoView();
+        } else {
+          row.style.backgroundColor = null;
+        }
+      }
+    },
+  };
+  return Stepper;
+})();
+
+var Stats = (function Stats() {
+  var stats = [];
+  function clear(node) {
+    while (node.hasChildNodes()) {
+      node.removeChild(node.lastChild);
+    }
+  }
+  function getStatIndex(pageNumber) {
+    for (var i = 0, ii = stats.length; i < ii; ++i) {
+      if (stats[i].pageNumber === pageNumber) {
+        return i;
+      }
+    }
+    return false;
+  }
+  return {
+    // Properties/functions needed by PDFBug.
+    id: 'Stats',
+    name: 'Stats',
+    panel: null,
+    manager: null,
+    init(pdfjsLib) {
+      this.panel.setAttribute('style', 'padding: 5px;');
+    },
+    enabled: false,
+    active: false,
+    // Stats specific functions.
+    add(pageNumber, stat) {
+      if (!stat) {
+        return;
+      }
+      var statsIndex = getStatIndex(pageNumber);
+      if (statsIndex !== false) {
+        var b = stats[statsIndex];
+        this.panel.removeChild(b.div);
+        stats.splice(statsIndex, 1);
+      }
+      var wrapper = document.createElement('div');
+      wrapper.className = 'stats';
+      var title = document.createElement('div');
+      title.className = 'title';
+      title.textContent = 'Page: ' + pageNumber;
+      var statsDiv = document.createElement('div');
+      statsDiv.textContent = stat.toString();
+      wrapper.appendChild(title);
+      wrapper.appendChild(statsDiv);
+      stats.push({ pageNumber, div: wrapper, });
+      stats.sort(function(a, b) {
+        return a.pageNumber - b.pageNumber;
+      });
+      clear(this.panel);
+      for (var i = 0, ii = stats.length; i < ii; ++i) {
+        this.panel.appendChild(stats[i].div);
+      }
+    },
+    cleanup() {
+      stats = [];
+      clear(this.panel);
+    },
+  };
+})();
+
+// Manages all the debugging tools.
+window.PDFBug = (function PDFBugClosure() {
+  var panelWidth = 300;
+  var buttons = [];
+  var activePanel = null;
+
+  return {
+    tools: [
+      FontInspector,
+      StepperManager,
+      Stats
+    ],
+    enable(ids) {
+      var all = false, tools = this.tools;
+      if (ids.length === 1 && ids[0] === 'all') {
+        all = true;
+      }
+      for (var i = 0; i < tools.length; ++i) {
+        var tool = tools[i];
+        if (all || ids.includes(tool.id)) {
+          tool.enabled = true;
+        }
+      }
+      if (!all) {
+        // Sort the tools by the order they are enabled.
+        tools.sort(function(a, b) {
+          var indexA = ids.indexOf(a.id);
+          indexA = indexA < 0 ? tools.length : indexA;
+          var indexB = ids.indexOf(b.id);
+          indexB = indexB < 0 ? tools.length : indexB;
+          return indexA - indexB;
+        });
+      }
+    },
+    init(pdfjsLib, container) {
+      /*
+       * Basic Layout:
+       * PDFBug
+       *  Controls
+       *  Panels
+       *    Panel
+       *    Panel
+       *    ...
+       */
+      var ui = document.createElement('div');
+      ui.id = 'PDFBug';
+
+      var controls = document.createElement('div');
+      controls.setAttribute('class', 'controls');
+      ui.appendChild(controls);
+
+      var panels = document.createElement('div');
+      panels.setAttribute('class', 'panels');
+      ui.appendChild(panels);
+
+      container.appendChild(ui);
+      container.style.right = panelWidth + 'px';
+
+      // Initialize all the debugging tools.
+      var tools = this.tools;
+      var self = this;
+      for (var i = 0; i < tools.length; ++i) {
+        var tool = tools[i];
+        var panel = document.createElement('div');
+        var panelButton = document.createElement('button');
+        panelButton.textContent = tool.name;
+        panelButton.addEventListener('click', (function(selected) {
+          return function(event) {
+            event.preventDefault();
+            self.selectPanel(selected);
+          };
+        })(i));
+        controls.appendChild(panelButton);
+        panels.appendChild(panel);
+        tool.panel = panel;
+        tool.manager = this;
+        if (tool.enabled) {
+          tool.init(pdfjsLib);
+        } else {
+          panel.textContent = tool.name + ' is disabled. To enable add ' +
+                              ' "' + tool.id + '" to the pdfBug parameter ' +
+                              'and refresh (separate multiple by commas).';
+        }
+        buttons.push(panelButton);
+      }
+      this.selectPanel(0);
+    },
+    cleanup() {
+      for (var i = 0, ii = this.tools.length; i < ii; i++) {
+        if (this.tools[i].enabled) {
+          this.tools[i].cleanup();
+        }
+      }
+    },
+    selectPanel(index) {
+      if (typeof index !== 'number') {
+        index = this.tools.indexOf(index);
+      }
+      if (index === activePanel) {
+        return;
+      }
+      activePanel = index;
+      var tools = this.tools;
+      for (var j = 0; j < tools.length; ++j) {
+        if (j === index) {
+          buttons[j].setAttribute('class', 'active');
+          tools[j].active = true;
+          tools[j].panel.removeAttribute('hidden');
+        } else {
+          buttons[j].setAttribute('class', '');
+          tools[j].active = false;
+          tools[j].panel.setAttribute('hidden', 'true');
+        }
+      }
+    },
+  };
+})();

+ 506 - 0
app/public/netcasign/js/json2.js

@@ -0,0 +1,506 @@
+//  json2.js
+//  2016-10-28
+//  Public Domain.
+//  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+//  See http://www.JSON.org/js.html
+//  This code should be minified before deployment.
+//  See http://javascript.crockford.com/jsmin.html
+
+//  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+//  NOT CONTROL.
+
+//  This file creates a global JSON object containing two methods: stringify
+//  and parse. This file provides the ES5 JSON capability to ES3 systems.
+//  If a project might run on IE8 or earlier, then this file should be included.
+//  This file does nothing on ES5 systems.
+
+//      JSON.stringify(value, replacer, space)
+//          value       any JavaScript value, usually an object or array.
+//          replacer    an optional parameter that determines how object
+//                      values are stringified for objects. It can be a
+//                      function or an array of strings.
+//          space       an optional parameter that specifies the indentation
+//                      of nested structures. If it is omitted, the text will
+//                      be packed without extra whitespace. If it is a number,
+//                      it will specify the number of spaces to indent at each
+//                      level. If it is a string (such as "\t" or "&nbsp;"),
+//                      it contains the characters used to indent at each level.
+//          This method produces a JSON text from a JavaScript value.
+//          When an object value is found, if the object contains a toJSON
+//          method, its toJSON method will be called and the result will be
+//          stringified. A toJSON method does not serialize: it returns the
+//          value represented by the name/value pair that should be serialized,
+//          or undefined if nothing should be serialized. The toJSON method
+//          will be passed the key associated with the value, and this will be
+//          bound to the value.
+
+//          For example, this would serialize Dates as ISO strings.
+
+//              Date.prototype.toJSON = function (key) {
+//                  function f(n) {
+//                      // Format integers to have at least two digits.
+//                      return (n < 10)
+//                          ? "0" + n
+//                          : n;
+//                  }
+//                  return this.getUTCFullYear()   + "-" +
+//                       f(this.getUTCMonth() + 1) + "-" +
+//                       f(this.getUTCDate())      + "T" +
+//                       f(this.getUTCHours())     + ":" +
+//                       f(this.getUTCMinutes())   + ":" +
+//                       f(this.getUTCSeconds())   + "Z";
+//              };
+
+//          You can provide an optional replacer method. It will be passed the
+//          key and value of each member, with this bound to the containing
+//          object. The value that is returned from your method will be
+//          serialized. If your method returns undefined, then the member will
+//          be excluded from the serialization.
+
+//          If the replacer parameter is an array of strings, then it will be
+//          used to select the members to be serialized. It filters the results
+//          such that only members with keys listed in the replacer array are
+//          stringified.
+
+//          Values that do not have JSON representations, such as undefined or
+//          functions, will not be serialized. Such values in objects will be
+//          dropped; in arrays they will be replaced with null. You can use
+//          a replacer function to replace those with JSON values.
+
+//          JSON.stringify(undefined) returns undefined.
+
+//          The optional space parameter produces a stringification of the
+//          value that is filled with line breaks and indentation to make it
+//          easier to read.
+
+//          If the space parameter is a non-empty string, then that string will
+//          be used for indentation. If the space parameter is a number, then
+//          the indentation will be that many spaces.
+
+//          Example:
+
+//          text = JSON.stringify(["e", {pluribus: "unum"}]);
+//          // text is '["e",{"pluribus":"unum"}]'
+
+//          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
+//          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+//          text = JSON.stringify([new Date()], function (key, value) {
+//              return this[key] instanceof Date
+//                  ? "Date(" + this[key] + ")"
+//                  : value;
+//          });
+//          // text is '["Date(---current time---)"]'
+
+//      JSON.parse(text, reviver)
+//          This method parses a JSON text to produce an object or array.
+//          It can throw a SyntaxError exception.
+
+//          The optional reviver parameter is a function that can filter and
+//          transform the results. It receives each of the keys and values,
+//          and its return value is used instead of the original value.
+//          If it returns what it received, then the structure is not modified.
+//          If it returns undefined then the member is deleted.
+
+//          Example:
+
+//          // Parse the text. Values that look like ISO date strings will
+//          // be converted to Date objects.
+
+//          myData = JSON.parse(text, function (key, value) {
+//              var a;
+//              if (typeof value === "string") {
+//                  a =
+//   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+//                  if (a) {
+//                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+//                          +a[5], +a[6]));
+//                  }
+//              }
+//              return value;
+//          });
+
+//          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+//              var d;
+//              if (typeof value === "string" &&
+//                      value.slice(0, 5) === "Date(" &&
+//                      value.slice(-1) === ")") {
+//                  d = new Date(value.slice(5, -1));
+//                  if (d) {
+//                      return d;
+//                  }
+//              }
+//              return value;
+//          });
+
+//  This is a reference implementation. You are free to copy, modify, or
+//  redistribute.
+
+/*jslint
+    eval, for, this
+*/
+
+/*property
+    JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+    lastIndex, length, parse, prototype, push, replace, slice, stringify,
+    test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (typeof JSON !== "object") {
+    JSON = {};
+}
+
+(function () {
+    "use strict";
+
+    var rx_one = /^[\],:{}\s]*$/;
+    var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
+    var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
+    var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
+    var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+    var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
+
+    function f(n) {
+        // Format integers to have at least two digits.
+        return n < 10
+            ? "0" + n
+            : n;
+    }
+
+    function this_value() {
+        return this.valueOf();
+    }
+
+    if (typeof Date.prototype.toJSON !== "function") {
+
+        Date.prototype.toJSON = function () {
+
+            return isFinite(this.valueOf())
+                ? this.getUTCFullYear() + "-" +
+                        f(this.getUTCMonth() + 1) + "-" +
+                        f(this.getUTCDate()) + "T" +
+                        f(this.getUTCHours()) + ":" +
+                        f(this.getUTCMinutes()) + ":" +
+                        f(this.getUTCSeconds()) + "Z"
+                : null;
+        };
+
+        Boolean.prototype.toJSON = this_value;
+        Number.prototype.toJSON = this_value;
+        String.prototype.toJSON = this_value;
+    }
+
+    var gap;
+    var indent;
+    var meta;
+    var rep;
+
+
+    function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+        rx_escapable.lastIndex = 0;
+        return rx_escapable.test(string)
+            ? "\"" + string.replace(rx_escapable, function (a) {
+                var c = meta[a];
+                return typeof c === "string"
+                    ? c
+                    : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
+            }) + "\""
+            : "\"" + string + "\"";
+    }
+
+
+    function str(key, holder) {
+
+// Produce a string from holder[key].
+
+        var i;          // The loop counter.
+        var k;          // The member key.
+        var v;          // The member value.
+        var length;
+        var mind = gap;
+        var partial;
+        var value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+        if (value && typeof value === "object" &&
+                typeof value.toJSON === "function") {
+            value = value.toJSON(key);
+        }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+        if (typeof rep === "function") {
+            value = rep.call(holder, key, value);
+        }
+
+// What happens next depends on the value's type.
+
+        switch (typeof value) {
+        case "string":
+            return quote(value);
+
+        case "number":
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+            return isFinite(value)
+                ? String(value)
+                : "null";
+
+        case "boolean":
+        case "null":
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce "null". The case is included here in
+// the remote chance that this gets fixed someday.
+
+            return String(value);
+
+// If the type is "object", we might be dealing with an object or an array or
+// null.
+
+        case "object":
+
+// Due to a specification blunder in ECMAScript, typeof null is "object",
+// so watch out for that case.
+
+            if (!value) {
+                return "null";
+            }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+            gap += indent;
+            partial = [];
+
+// Is the value an array?
+
+            if (Object.prototype.toString.apply(value) === "[object Array]") {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+                length = value.length;
+                for (i = 0; i < length; i += 1) {
+                    partial[i] = str(i, value) || "null";
+                }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+                v = partial.length === 0
+                    ? "[]"
+                    : gap
+                        ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
+                        : "[" + partial.join(",") + "]";
+                gap = mind;
+                return v;
+            }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+            if (rep && typeof rep === "object") {
+                length = rep.length;
+                for (i = 0; i < length; i += 1) {
+                    if (typeof rep[i] === "string") {
+                        k = rep[i];
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (
+                                gap
+                                    ? ": "
+                                    : ":"
+                            ) + v);
+                        }
+                    }
+                }
+            } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+                for (k in value) {
+                    if (Object.prototype.hasOwnProperty.call(value, k)) {
+                        v = str(k, value);
+                        if (v) {
+                            partial.push(quote(k) + (
+                                gap
+                                    ? ": "
+                                    : ":"
+                            ) + v);
+                        }
+                    }
+                }
+            }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+            v = partial.length === 0
+                ? "{}"
+                : gap
+                    ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
+                    : "{" + partial.join(",") + "}";
+            gap = mind;
+            return v;
+        }
+    }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+    if (typeof JSON.stringify !== "function") {
+        meta = {    // table of character substitutions
+            "\b": "\\b",
+            "\t": "\\t",
+            "\n": "\\n",
+            "\f": "\\f",
+            "\r": "\\r",
+            "\"": "\\\"",
+            "\\": "\\\\"
+        };
+        JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+            var i;
+            gap = "";
+            indent = "";
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+            if (typeof space === "number") {
+                for (i = 0; i < space; i += 1) {
+                    indent += " ";
+                }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+            } else if (typeof space === "string") {
+                indent = space;
+            }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+            rep = replacer;
+            if (replacer && typeof replacer !== "function" &&
+                    (typeof replacer !== "object" ||
+                    typeof replacer.length !== "number")) {
+                throw new Error("JSON.stringify");
+            }
+
+// Make a fake root object containing our value under the key of "".
+// Return the result of stringifying the value.
+
+            return str("", {"": value});
+        };
+    }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+    if (typeof JSON.parse !== "function") {
+        JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+            var j;
+
+            function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+                var k;
+                var v;
+                var value = holder[key];
+                if (value && typeof value === "object") {
+                    for (k in value) {
+                        if (Object.prototype.hasOwnProperty.call(value, k)) {
+                            v = walk(value, k);
+                            if (v !== undefined) {
+                                value[k] = v;
+                            } else {
+                                delete value[k];
+                            }
+                        }
+                    }
+                }
+                return reviver.call(holder, key, value);
+            }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+            text = String(text);
+            rx_dangerous.lastIndex = 0;
+            if (rx_dangerous.test(text)) {
+                text = text.replace(rx_dangerous, function (a) {
+                    return "\\u" +
+                            ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
+                });
+            }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with "()" and "new"
+// because they can cause invocation, and "=" because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
+// replace all simple value tokens with "]" characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or "]" or
+// "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
+
+            if (
+                rx_one.test(
+                    text
+                        .replace(rx_two, "@")
+                        .replace(rx_three, "]")
+                        .replace(rx_four, "")
+                )
+            ) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The "{" operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+                j = eval("(" + text + ")");
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+                return (typeof reviver === "function")
+                    ? walk({"": j}, "")
+                    : j;
+            }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+            throw new SyntaxError("JSON.parse");
+        };
+    }
+}());

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 11012 - 0
app/public/netcasign/js/netca-jquery-client.js


+ 191 - 0
app/public/netcasign/js/netcaseal.js

@@ -0,0 +1,191 @@
+
+/* 
+    Netca电子签章模块(V1.3.0)
+    版本 V1.0.0
+        提供基础的电子签章接口    
+
+    版本 V1.2.0  2019-10-07
+        提供关键字的印章接口
+
+    版本 V1.3.0  2020-03-03
+        提供获取签名域信息接口
+*/
+
+NetcaPKI.getSealClientVersion = function (params) {
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "GetSealClientVersion";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.getNetcaSealImage=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["function"] ="GetNetcaSealImage";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.GetNetcaSealImage=function(params){
+    return NetcaPKI.getNetcaSealImage(params);
+}
+
+NetcaPKI.SignatureCreatorPdfSignSealFieldOrPosition = function(params)
+{
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "SignatureCreatorSignSeal";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.signatureCreatorSignSeal = function(params)
+{
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "SignatureCreatorSignSeal";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.SignatureCreatorPdfSignSealFieldOrPositionEx = function(params)
+{
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "SignatureCreatorSignSealEx";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.signatureCreatorSignSealEx = function(params)
+{
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "SignatureCreatorSignSealEx";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.SignatureCreatorSignSealEx = function(params)
+{
+    return NetcaPKI.signatureCreatorSignSealEx(params)
+}
+
+NetcaPKI.signatureVerifierVerifyPDF = function (params) {
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "SignatureVerifierVerifyPDF";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.signatureVerifierUndoPDF = function (params) {
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] = "SignatureVerifierUndoPDF";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.Custom_PdfSignAndUpload=function(params){
+	var requestQueryParams = {};
+    requestQueryParams["function"] ="Custom_PdfSignAndUploadByBytes";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.custom_PdfSignAndUploadByBytes=function(params){
+	var requestQueryParams = {};
+    requestQueryParams["function"] ="Custom_PdfSignAndUploadByBytes";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.Custom_PdfSignAndUploadByURL=function(params){
+	var requestQueryParams = {};
+    requestQueryParams["function"] ="Custom_PdfSignAndUploadByURL";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.getSignatureFieldInfo=function(params){
+	var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="GetSignatureFieldInfo";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+NetcaPKI.SelectSealSigntureInfoWithDispaly=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="SelectSealSigntureInfoWithDispaly";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+NetcaPKI.getSealConfigInfo=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="GetSealConfigInfo";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+NetcaPKI.printPDF=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="PrintPDF";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+NetcaPKI.signatureCreatorBatchSeal=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="SignatureCreatorBatchSeal";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+NetcaPKI.signatureCreatorAcrossPageSeal=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="SignatureCreatorAcrossPageSeal";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+NetcaPKI.getPdfPageInfo=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="GetPdfPageInfo";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.createStream=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="CreateStream";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.writeStream=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="WriteStream";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.destoryStream=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="DestoryStream";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}
+
+NetcaPKI.readStream=function(params){
+    var requestQueryParams = {};
+    requestQueryParams["appName"] = "SignatureCreator";
+    requestQueryParams["function"] ="ReadStream";
+    requestQueryParams["param"] = params;
+    return NetcaPKI.SendNetcaCryptoJsonRpcMessage(requestQueryParams);
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2048 - 0
app/public/netcasign/js/netcasealpdf.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 2185 - 0
app/public/netcasign/js/netcawebsocket.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 23599 - 0
app/public/netcasign/js/pdf.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
app/public/netcasign/js/pdf.js.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 55370 - 0
app/public/netcasign/js/pdf.worker.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
app/public/netcasign/js/pdf.worker.js.map


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 15580 - 0
app/public/netcasign/js/viewer.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
app/public/netcasign/js/viewer.js.map


BIN
app/public/netcasign/ui/cmaps/78-EUC-H.bcmap


BIN
app/public/netcasign/ui/cmaps/78-EUC-V.bcmap


BIN
app/public/netcasign/ui/cmaps/78-H.bcmap


BIN
app/public/netcasign/ui/cmaps/78-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/78-RKSJ-V.bcmap


BIN
app/public/netcasign/ui/cmaps/78-V.bcmap


BIN
app/public/netcasign/ui/cmaps/78ms-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/78ms-RKSJ-V.bcmap


BIN
app/public/netcasign/ui/cmaps/83pv-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/90ms-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/90ms-RKSJ-V.bcmap


BIN
app/public/netcasign/ui/cmaps/90msp-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/90msp-RKSJ-V.bcmap


BIN
app/public/netcasign/ui/cmaps/90pv-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/90pv-RKSJ-V.bcmap


BIN
app/public/netcasign/ui/cmaps/Add-H.bcmap


BIN
app/public/netcasign/ui/cmaps/Add-RKSJ-H.bcmap


BIN
app/public/netcasign/ui/cmaps/Add-RKSJ-V.bcmap


BIN
app/public/netcasign/ui/cmaps/Add-V.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-0.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-1.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-3.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-4.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-5.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-6.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-CNS1-UCS2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-0.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-1.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-3.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-4.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-5.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-GB1-UCS2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-0.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-1.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-3.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-4.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-5.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-6.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Japan1-UCS2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Korea1-0.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Korea1-1.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Korea1-2.bcmap


BIN
app/public/netcasign/ui/cmaps/Adobe-Korea1-UCS2.bcmap


BIN
app/public/netcasign/ui/cmaps/B5-H.bcmap


BIN
app/public/netcasign/ui/cmaps/B5-V.bcmap


BIN
app/public/netcasign/ui/cmaps/B5pc-H.bcmap


BIN
app/public/netcasign/ui/cmaps/B5pc-V.bcmap


BIN
app/public/netcasign/ui/cmaps/CNS-EUC-H.bcmap


BIN
app/public/netcasign/ui/cmaps/CNS-EUC-V.bcmap


BIN
app/public/netcasign/ui/cmaps/CNS1-H.bcmap


BIN
app/public/netcasign/ui/cmaps/CNS1-V.bcmap


BIN
app/public/netcasign/ui/cmaps/CNS2-H.bcmap


+ 3 - 0
app/public/netcasign/ui/cmaps/CNS2-V.bcmap

@@ -0,0 +1,3 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSEáCNS2-H

BIN
app/public/netcasign/ui/cmaps/ETHK-B5-H.bcmap


BIN
app/public/netcasign/ui/cmaps/ETHK-B5-V.bcmap


BIN
app/public/netcasign/ui/cmaps/ETen-B5-H.bcmap


BIN
app/public/netcasign/ui/cmaps/ETen-B5-V.bcmap


+ 3 - 0
app/public/netcasign/ui/cmaps/ETenms-B5-H.bcmap

@@ -0,0 +1,3 @@
+àRCopyright 1990-2009 Adobe Systems Incorporated.
+All rights reserved.
+See ./LICENSEá	ETen-B5-H` ^

BIN
app/public/netcasign/ui/cmaps/ETenms-B5-V.bcmap


BIN
app/public/netcasign/ui/cmaps/EUC-H.bcmap


BIN
app/public/netcasign/ui/cmaps/EUC-V.bcmap


BIN
app/public/netcasign/ui/cmaps/Ext-H.bcmap


+ 0 - 0
app/public/netcasign/ui/cmaps/Ext-RKSJ-H.bcmap


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است