Przeglądaj źródła

Merge branch 'master' of http://192.168.1.41:3000/SmartCost/SCCommon

TonyKang 4 lat temu
rodzic
commit
8ed7283b25
75 zmienionych plików z 2817 dodań i 489 usunięć
  1. 1 1
      handsontable/handsontable.d.ts
  2. 2 1
      handsontable/package.json
  3. 43 3
      handsontable/src/plugins/copyPaste/copyPaste.js
  4. 1 0
      overwrite/.eslintignore
  5. 42 0
      overwrite/.eslintrc.js
  6. 22 0
      overwrite/.gitignore
  7. 6 0
      overwrite/.huskyrc.js
  8. 19 0
      overwrite/README.md
  9. 29 0
      overwrite/commitlint.config.js
  10. 9 0
      overwrite/lint-staged.config.js
  11. 53 0
      overwrite/package.json
  12. 6 0
      overwrite/prettier.config.js
  13. 11 0
      overwrite/rollup.config.js
  14. 13 0
      overwrite/src/base/base.ts
  15. 29 0
      overwrite/src/base/constant.ts
  16. 45 0
      overwrite/src/base/glj.ts
  17. 6 0
      overwrite/src/chongqing-2018/chongQing2018.ts
  18. 21 0
      overwrite/src/chongqing-2018/glj.ts
  19. 17 0
      overwrite/src/index.ts
  20. 18 0
      overwrite/tsconfig.json
  21. 717 59
      report/package-lock.json
  22. 1 1
      report/package.json
  23. 2 1
      report/src/core/helper/jpc_helper_area.ts
  24. 3 0
      report/src/core/helper/jpc_helper_common.ts
  25. 5 5
      report/src/core/helper/jpc_helper_common_output.ts
  26. 4 4
      report/src/core/helper/jpc_helper_field.ts
  27. 1 1
      report/src/core/jpc_cross_tab.ts
  28. 14 12
      report/src/core/jpc_ex.ts
  29. 21 17
      report/src/core/jpc_flow_tab.ts
  30. 1 1
      report/src/core/jpc_rte.ts
  31. 1 0
      report/src/index.ts
  32. 32 36
      report/src/interface/basic.ts
  33. 8 8
      report/src/interface/classType.ts
  34. 1 1
      report/src/interface/enum.ts
  35. 6 5
      report/src/interface/projectConstsEnum.ts
  36. 2 0
      report/src/pdfUnit/index.ts
  37. 26 0
      report/src/pdfUnit/rpt_font_util.ts
  38. 542 0
      report/src/pdfUnit/rpt_pdf_util.ts
  39. 2 2
      tree/package.json
  40. 6 0
      tree/src/nodeCtx.ts
  41. 57 24
      types/src/interface/base.ts
  42. 6 13
      types/src/interface/bill.ts
  43. 7 6
      types/src/interface/calculation.ts
  44. 35 15
      types/src/interface/compilation.ts
  45. 2 2
      types/src/interface/configMaterial.ts
  46. 37 7
      types/src/interface/enterprise.ts
  47. 0 63
      types/src/interface/error.ts
  48. 173 31
      types/src/interface/glj.ts
  49. 1 1
      types/src/interface/index.ts
  50. 51 0
      types/src/interface/infoPrice.ts
  51. 35 3
      types/src/interface/project.ts
  52. 167 67
      types/src/interface/ration.ts
  53. 30 0
      types/src/interface/report.ts
  54. 46 89
      types/src/interface/user.ts
  55. 5 0
      util/README.md
  56. 3 3
      util/package.json
  57. 1 2
      util/src/index.ts
  58. 53 0
      util/src/reg.ts
  59. 1 1
      util/tests/test.ts
  60. 1 0
      wise-cost-util/.eslintignore
  61. 41 0
      wise-cost-util/.eslintrc.js
  62. 22 0
      wise-cost-util/.gitignore
  63. 6 0
      wise-cost-util/.huskyrc.js
  64. 21 0
      wise-cost-util/README.md
  65. 29 0
      wise-cost-util/commitlint.config.js
  66. 9 0
      wise-cost-util/lint-staged.config.js
  67. 54 0
      wise-cost-util/package.json
  68. 7 0
      wise-cost-util/prettier.config.js
  69. 28 0
      wise-cost-util/rollup.config.js
  70. 0 0
      wise-cost-util/src/bill.ts
  71. 31 0
      wise-cost-util/src/cptLib.ts
  72. 44 0
      wise-cost-util/src/glj.ts
  73. 4 0
      wise-cost-util/src/index.ts
  74. 4 4
      util/src/rationAss.ts
  75. 18 0
      wise-cost-util/tsconfig.json

+ 1 - 1
handsontable/handsontable.d.ts

@@ -2334,7 +2334,7 @@ declare namespace Handsontable {
     time: cellTypes.Time;
 
     // 自定义添加
-    registerCellType:(name:string, type:{editor: any; renderer: Handsontable.renderers.Base})=> void
+    registerCellType:(name:string, type:{editor: any; renderer: Handsontable.renderers.Base; validator?: (value: any, callback: (valid: boolean) => void) => void;})=> void
   }
 
   interface Editors {

+ 2 - 1
handsontable/package.json

@@ -10,7 +10,7 @@
     "url": "https://github.com/handsontable/handsontable/issues"
   },
   "author": "Handsoncode <hello@handsontable.com>",
-  "version": "6.3.7",
+  "version": "6.3.8",
   "browser": "dist/handsontable.js",
   "main": "commonjs/index.js",
   "module": "es/index.js",
@@ -59,6 +59,7 @@
     "data-spreadsheet"
   ],
   "dependencies": {
+    "@sc/util": "^1.0.7",
     "moment": "2.20.1",
     "numbro": "^2.0.6",
     "pikaday": "1.5.1"

+ 43 - 3
handsontable/src/plugins/copyPaste/copyPaste.js

@@ -1,3 +1,4 @@
+import { roundForObj, isNumber } from '@sc/util';
 import BasePlugin from './../_base';
 import Hooks from './../../pluginHooks';
 import SheetClip from './../../../lib/SheetClip/SheetClip';
@@ -215,7 +216,7 @@ class CopyPaste extends BasePlugin {
       const rowSet = [];
 
       arrayEach(copyableColumns, (column) => {
-        rowSet.push(this.hot.getCopyableData(row, column));
+        rowSet.push(this.getCopyData(row, column));
       });
 
       dataSet.push(rowSet);
@@ -253,7 +254,8 @@ class CopyPaste extends BasePlugin {
       const rowSet = [];
 
       arrayEach(copyableColumns, (column) => {
-        rowSet.push(this.hot.getCopyableData(row, column));
+
+        rowSet.push(this.prepareCopyData(row, column));
       });
 
       dataSet.push(rowSet);
@@ -262,6 +264,43 @@ class CopyPaste extends BasePlugin {
     return dataSet;
   }
 
+  // 复制key - value 的dropdown 时 返回 key
+  prepareCopyData(row, column) {
+    let rawData = this.hot.getCopyableData(row, column);
+    const settings = this.hot.getSettings();
+    if (settings && settings.columns) {
+      const colMeta = settings.columns[column];
+      if (colMeta && colMeta.source && colMeta.source.length > 0) {
+        if (typeof colMeta.source[0] === 'object') {
+          colMeta.source.forEach((option) => {
+            if (option.value === rawData) rawData = option.key;
+          });
+        }
+      }
+    }
+    return rawData;
+  }
+
+  // 粘贴数据预处理
+  preparePaseData(column, value) {
+    const settings = this.hot.getSettings();
+    if (settings && settings.columns) {
+      const colMeta = settings.columns[column];
+      if (colMeta && colMeta.source && colMeta.source.length > 0) {
+        // 粘贴key - value 的dropdown 时 返回 value
+        if (typeof colMeta.source[0] === 'object') {
+          colMeta.source.forEach((option) => {
+            if (option.key === value) value = option.value;
+          });
+        }
+      } else if (isNumber(value) && ['number', 'function'].includes(typeof colMeta.decimal)) {
+        // 粘贴数值字符串时,将其转换为number并根据小数位数进行四舍五入
+        const decimalNum = typeof colMeta.decimal === 'function' ? colMeta.decimal() : colMeta.decimal;
+        value = roundForObj(value, decimalNum);
+      }
+    }
+    return value;
+  }
   /**
    * Simulates the paste action.
    *
@@ -373,7 +412,8 @@ class CopyPaste extends BasePlugin {
       const newRow = [];
 
       for (let column = startColumn, valuesColumn = 0; column <= endColumn; column += 1) {
-        newRow.push(inputArray[valuesRow][valuesColumn]);
+
+        newRow.push(this.preparePaseData(column, inputArray[valuesRow][valuesColumn]));
 
         valuesColumn = valuesColumn === newValuesMaxColumn ? 0 : valuesColumn += 1;
       }

+ 1 - 0
overwrite/.eslintignore

@@ -0,0 +1 @@
+/dist

+ 42 - 0
overwrite/.eslintrc.js

@@ -0,0 +1,42 @@
+module.exports = {
+  env: {
+    browser: true,
+    es2021: true,
+    node: true,
+  },
+  extends: ['airbnb-base', 'plugin:@typescript-eslint/recommended', 'prettier'],
+  parser: '@typescript-eslint/parser',
+  parserOptions: {
+    ecmaVersion: 12,
+    sourceType: 'module',
+  },
+  plugins: ['@typescript-eslint', 'prettier'],
+  rules: {
+    'prettier/prettier': 'error',
+    'import/extensions': [
+      'error',
+      {
+        js: 'never',
+        jsx: 'never',
+        ts: 'never',
+        tsx: 'never',
+        json: 'always',
+      },
+    ],
+    'import/no-unresolved': 'off',
+    '@typescript-eslint/no-empty-function': 'off',
+    '@typescript-eslint/no-explicit-any': 'off',
+    'class-methods-use-this': 'off',
+    'import/prefer-default-export': 'off',
+    'no-unused-expressions': [
+      'error',
+      {
+        allowShortCircuit: true,
+      },
+    ],
+    'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
+    'no-restricted-syntax': 'off',
+    'no-shadow': 'off',
+    '@typescript-eslint/no-shadow': 'error',
+  },
+};

+ 22 - 0
overwrite/.gitignore

@@ -0,0 +1,22 @@
+.DS_Store
+node_modules
+dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 6 - 0
overwrite/.huskyrc.js

@@ -0,0 +1,6 @@
+module.exports = {
+  hooks: {
+    'pre-commit': 'lint-staged',
+    'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
+  },
+};

+ 19 - 0
overwrite/README.md

@@ -0,0 +1,19 @@
+# overwrite
+
+本项目是 wise-cost 项目,费用定额相同方法不同实现逻辑的解决方案。
+
+### 安装
+
+`$ npm i -S @sc/overwrite`
+
+### 打包
+
+`$ npm run build`
+
+### 基本用法
+
+```
+const overwrite = getOverWrite('');
+```
+
+具体接口请参考声明文件。

+ 29 - 0
overwrite/commitlint.config.js

@@ -0,0 +1,29 @@
+module.exports = {
+  ignores: [commit => commit.includes('init')],
+  extends: ['@commitlint/config-conventional'],
+  rules: {
+    'body-leading-blank': [2, 'always'],
+    'footer-leading-blank': [1, 'always'],
+    'header-max-length': [2, 'always', 108],
+    'subject-empty': [2, 'never'],
+    'type-empty': [2, 'never'],
+    'type-enum': [
+      2,
+      'always',
+      [
+        'feat', // 新增功能、变更需求
+        'fix', // 修复bug
+        'perf', // 优化性能
+        'refactor', // 代码重构
+        'style', // 代码格式(不影响功能,例如空格、分号等格式修正)
+        'docs', // 文档变更
+        'test', // 测试
+        'ci', // 更改持续集成软件的配置文件和package中的scripts命令,例如scopes: Travis, Circle等
+        'chore', // 变更构建流程或辅助工具(依赖更新/脚手架配置修改/webpack、gulp、npm等)
+        'revert', // 代码回退
+        'types', // ts类型定义文件更改
+        'wip', // work in process开发中
+      ],
+    ],
+  },
+};

+ 9 - 0
overwrite/lint-staged.config.js

@@ -0,0 +1,9 @@
+module.exports = {
+  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
+  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': [
+    'prettier --write--parser json',
+  ],
+  'package.json': ['prettier --write'],
+  '*.vue': ['prettier --write'],
+  '*.md': ['prettier --write'],
+};

+ 53 - 0
overwrite/package.json

@@ -0,0 +1,53 @@
+{
+  "name": "@sc/overwrite",
+  "version": "1.0.0",
+  "description": "wise-cost项目,费用定额相同方法不同实现逻辑的解决方案",
+  "main": "./dist/index.cjs.js",
+  "module": "./dist/index.esm.js",
+  "browser": "./dist/index.min.js",
+  "types": "./dist/index.d.ts",
+  "files": [
+    "dist",
+    "README.md"
+  ],
+  "scripts": {
+    "test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha -r ts-node/register 'tests/**/*.ts'",
+    "build": "rollup -c"
+  },
+  "keywords": [],
+  "author": "smartcost",
+  "license": "ISC",
+  "devDependencies": {
+    "@commitlint/cli": "^11.0.0",
+    "@commitlint/config-conventional": "^11.0.0",
+    "@sc/types": "^1.0.28",
+    "@types/chai": "^4.2.14",
+    "@types/mocha": "^8.0.4",
+    "@types/ms": "^0.7.31",
+    "@types/uuid": "^8.3.0",
+    "@typescript-eslint/eslint-plugin": "^4.4.1",
+    "@typescript-eslint/parser": "^4.4.1",
+    "chai": "^4.2.0",
+    "cross-env": "^7.0.2",
+    "eslint": "^7.11.0",
+    "eslint-config-airbnb-base": "^14.2.0",
+    "eslint-config-prettier": "^6.12.0",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-prettier": "^3.1.4",
+    "husky": "^4.3.0",
+    "lint-staged": "^10.5.0",
+    "mocha": "^8.2.1",
+    "prettier": "^2.1.2",
+    "rollup": "^2.30.0",
+    "rollup-plugin-commonjs": "^10.1.0",
+    "rollup-plugin-node-resolve": "^5.2.0",
+    "rollup-plugin-terser": "^7.0.2",
+    "rollup-plugin-typescript2": "^0.27.3",
+    "ts-node": "^9.0.0",
+    "tslib": "^2.0.3",
+    "typescript": "^4.0.3"
+  },
+  "dependencies": {
+    "uuid": "^8.3.2"
+  }
+}

+ 6 - 0
overwrite/prettier.config.js

@@ -0,0 +1,6 @@
+module.exports = {
+  singleQuote: true, // 单引号
+  trailingComma: 'es5', // 对象末尾以逗号结束
+  arrowParens: 'avoid', // 箭头函数只有一个参数的时候,不使用()
+  endOfLine: 'auto', // CRLF,LF都可以
+};

+ 11 - 0
overwrite/rollup.config.js

@@ -0,0 +1,11 @@
+import typescript from 'rollup-plugin-typescript2'; // 一定要是typescript2,如果使用typescript,没法自动生成.d.ts文件
+import pkg from './package.json';
+
+export default [
+  {
+    input: 'src/index.ts',
+    external: ['ms'],
+    plugins: [typescript()],
+    output: [{ file: pkg.main, format: 'cjs' }],
+  },
+];

+ 13 - 0
overwrite/src/base/base.ts

@@ -0,0 +1,13 @@
+import { gljTypes } from './constant';
+import { getComponentTypes, getCustomerCoe } from './glj';
+
+export default class BaseOverwrite {
+  // 可用的人材机类型(目前只有人材机库有限制)
+  gljTypes = gljTypes;
+
+  // 根据人材机类型,获取可含有的组成物类型,空数组即为该人材机不可含有组成物
+  getComponentTypes = getComponentTypes;
+
+  // 获取自定义系数
+  getCustomerCoe = getCustomerCoe;
+}

+ 29 - 0
overwrite/src/base/constant.ts

@@ -0,0 +1,29 @@
+import { GljType } from '@sc/types';
+
+// 可用的人材机类型(目前只有人材机库有限制)
+export const gljTypes: GljType[] = [
+  GljType.LABOUR,
+  GljType.GENERAL_MATERIAL,
+  GljType.CONCRETE,
+  GljType.MORTAR,
+  GljType.MIX_RATIO,
+  GljType.COMMERCIAL_CONCRETE,
+  GljType.COMMERCIAL_MORTAR,
+  GljType.OTHER_MATERIAL,
+  GljType.GENERAL_MACHINE,
+  GljType.MACHINE_LABOUR,
+  GljType.INSTRUMENT,
+  GljType.FUEL_POWER_FEE,
+  GljType.DEPRECIATION_FEE,
+  GljType.INSPECTION_FEE,
+  GljType.MAINTENANCE,
+  GljType.DISMANTLING_FREIGHT_FEE,
+  GljType.VERIFICATION_FEE,
+  GljType.OTHER_FEE,
+  GljType.OTHER_MACHINE_USED,
+  GljType.MAIN_MATERIAL,
+  GljType.EQUIPMENT,
+  GljType.MANAGEMENT_FEE,
+  GljType.PROFIT,
+  GljType.GENERAL_RISK_FEE,
+];

+ 45 - 0
overwrite/src/base/glj.ts

@@ -0,0 +1,45 @@
+import { CoeType, GljType, IRationCoe } from '@sc/types';
+import { v1 } from 'uuid';
+
+// 根据人材机类型,获取可含有的组成物类型,空数组即为该人材机不可含有组成物
+export const getComponentTypes = (type: GljType): GljType[] => {
+  if ([GljType.CONCRETE, GljType.MORTAR, GljType.MIX_RATIO].includes(type)) {
+    return [GljType.GENERAL_MATERIAL];
+  }
+  if ([GljType.GENERAL_MACHINE, GljType.INSTRUMENT].includes(type)) {
+    return [
+      GljType.MACHINE_COMPOSITION,
+      GljType.MACHINE_LABOUR,
+      GljType.FUEL_POWER_FEE,
+      GljType.DEPRECIATION_FEE,
+      GljType.INSPECTION_FEE,
+      GljType.MAINTENANCE,
+      GljType.DISMANTLING_FREIGHT_FEE,
+      GljType.VERIFICATION_FEE,
+      GljType.OTHER_FEE,
+    ];
+  }
+  if (GljType.MAIN_MATERIAL === type) {
+    return [GljType.MAIN_MATERIAL];
+  }
+  return [];
+};
+
+// 获取自定义系数
+export const getCustomerCoe = (): IRationCoe => {
+  return {
+    ID: v1(),
+    stdID: -1,
+    name: '自定义系数',
+    content: '人工×1,材料×1,机械×1,主材×1,设备×1',
+    isAdjust: true,
+    coes: [
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.RATION },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.LABOUR },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.MATERIAL },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.MACHINE },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.MAIN },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.EQUIPMENT },
+    ],
+  };
+};

+ 6 - 0
overwrite/src/chongqing-2018/chongQing2018.ts

@@ -0,0 +1,6 @@
+import BaseOverwrite from '../base/base';
+import { getCustomerCoe } from './glj';
+
+export default class ChongQing2018 extends BaseOverwrite {
+  getCustomerCoe = getCustomerCoe;
+}

+ 21 - 0
overwrite/src/chongqing-2018/glj.ts

@@ -0,0 +1,21 @@
+import { CoeType, IRationCoe } from '@sc/types';
+import { v1 } from 'uuid';
+
+// 获取自定义系数
+export const getCustomerCoe = (): IRationCoe => {
+  return {
+    ID: v1(),
+    stdID: -1,
+    name: '自定义系数',
+    content: '人工×1,材料×1,施工机具×1,主材×1,设备×1',
+    isAdjust: true,
+    coes: [
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.RATION },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.LABOUR },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.MATERIAL },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.TOOL },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.MAIN },
+      { amount: '1', operator: '*', gljCode: '', coeType: CoeType.EQUIPMENT },
+    ],
+  };
+};

+ 17 - 0
overwrite/src/index.ts

@@ -0,0 +1,17 @@
+import BaseOverwrite from './base/base';
+import ChongQing2018 from './chongqing-2018/chongQing2018';
+
+// 费用定额ID 与 overwrite实例 映射
+const overwriteMap: Record<string, BaseOverwrite> = {
+  '5b52b027fd3bb0000b257cf8': new ChongQing2018(),
+};
+
+const baseOverwrite = new BaseOverwrite();
+
+// 根据费用定额ID,获取overwrite单例
+export function getOverwrite(compilationID?: string): BaseOverwrite {
+  return (compilationID && overwriteMap[compilationID]) || baseOverwrite;
+}
+
+export * from './base/base';
+export * from './chongqing-2018/chongQing2018';

+ 18 - 0
overwrite/tsconfig.json

@@ -0,0 +1,18 @@
+{
+  "compilerOptions": {
+    "target": "ESNext",
+    "module": "ESNext",
+    "declaration": true,
+    "outDir": "./",
+    "strict": true,
+    "esModuleInterop": true,
+    "moduleResolution": "node",
+  },
+  "include": [
+    "src/**/*.ts",
+  ],
+  "exclude": [
+    "node_modules",
+    "test"
+  ]
+}

Plik diff jest za duży
+ 717 - 59
report/package-lock.json


+ 1 - 1
report/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@sc/report",
-  "version": "3.0.1",
+  "version": "3.0.2",
   "description": "Smartcost Report Relative Module",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",

+ 2 - 1
report/src/core/helper/jpc_helper_area.ts

@@ -1,5 +1,6 @@
 'use strict';
 
+import { IPositionProps } from '../../index';
 import { IArea, IBandDetail } from '../../interface/basic';
 import JV from '../jpc_value_define';
 
@@ -10,7 +11,7 @@ const JpcAreaHelper = {
             Left: 0,
             Right: 0,
             Top: 0,
-            Bottom: 0
+            Bottom: 0,
         },
             maxMultiColumns = 3;
         if (multipleDispCol > 0 && multipleDispCol <= maxMultiColumns) {

+ 3 - 0
report/src/core/helper/jpc_helper_common.ts

@@ -1,5 +1,6 @@
 'use strict';
 
+import { IPositionProps } from '../../index';
 import { IArea, IControlCollection, IControlSubCollection, IRptTpl, IStyles } from '../../interface/basic';
 import JV from '../jpc_value_define';
 
@@ -139,7 +140,9 @@ const JpcCommonHelper = {
         if (strVal) {
             let areaWidth = area.Right - area.Left - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT] - 1;
             let txtWidth = 0, currentW = 0;
+            // 这里是一个一个字获取宽度,然后在对比区域宽度,算出最后有多少行
             for (let sIdx = 0; sIdx < strVal.length; sIdx++) {
+                //大于127为中文字
                 currentW = (strVal.charCodeAt(sIdx) > 127) ? chnW : otherW;
                 txtWidth += currentW;
                 if (txtWidth > areaWidth) {

+ 5 - 5
report/src/core/helper/jpc_helper_common_output.ts

@@ -1,6 +1,6 @@
 'use strict';
 
-import { Fields, ICell, IControlCollection, INode } from '../../interface/basic';
+import { Fields, ICell, IControlCollection } from '../../interface/basic';
 import JV from '../jpc_value_define';
 import JpcFieldHelper from './jpc_helper_field';
 const OFFSET_FLOAT = 0.0000000001;
@@ -14,7 +14,7 @@ let JpcCommonOutputHelper = {
                 control: node.control as string,
                 style: node.style,
                 Value: value
-            } as INode;
+            } as ICell;
         //2. value
         me.formatCell(node.Format, rst);
         // innerFormat(node.Format, rst);
@@ -33,12 +33,12 @@ let JpcCommonOutputHelper = {
     createCommonOutput: function (node: Fields, value: number | string | null, controls: IControlCollection | null) {
         let me = this,
             //1. font/style/control
-            rst: INode = {
+            rst: ICell = {
                 font: node.font,
                 control: node.control as string,
                 style: node.style,
                 Value: value
-            } as INode;
+            } as ICell;
         //2. value
         JpcFieldHelper.decorateValue(rst, controls);
         me.formatCell(node.Format, rst);
@@ -51,7 +51,7 @@ let JpcCommonOutputHelper = {
         }
         return rst;
     },
-    formatCell: function (formatStr: string, rstCell: INode) {
+    formatCell: function (formatStr: string, rstCell: ICell) {
         if (formatStr) {
             const rstCellFloatVal = parseFloat(rstCell.Value as string);
             if (!(isNaN(rstCellFloatVal))) {

+ 4 - 4
report/src/core/helper/jpc_helper_field.ts

@@ -2,7 +2,7 @@
 
 import JV from '../jpc_value_define';
 import strUtil from '../../public/stringUtil';
-import { Fields, ICell, IControlCollection, ICustomizeCfg, IGroupField, INode, IOrgGroupField, IRptTpl } from '../../interface/basic';
+import { Fields, IControlCollection, ICustomizeCfg, IGroupField, ICell, IOrgGroupField, IRptTpl } from '../../interface/basic';
 
 let JpcFieldHelper = {
     getValue: function (dataField: string[] | null, valueIdx: number) {
@@ -10,7 +10,7 @@ let JpcFieldHelper = {
         if (dataField && (dataField.length > valueIdx) && (valueIdx >= 0)) {
             rst = dataField[valueIdx];
         }
-        return rst;
+        return `${rst}`;
     },
     setValue: function (dataField: string[], valueIdx: number, newValue: string) {
         if (dataField && (dataField.length > valueIdx) && (valueIdx >= 0)) {
@@ -72,9 +72,9 @@ let JpcFieldHelper = {
             tab_field.Format = formatStrs.join("");
         }
     },
-    decorateValue: function (cell: INode, controls: IControlCollection | null) {
+    decorateValue: function (cell: ICell, controls: IControlCollection | null) {
         if (controls) {
-            const showZero = controls[cell.control].ShowZero;
+            const showZero = controls[cell.control as string].ShowZero;
             if (showZero && showZero === 'F') {
                 const val = parseFloat(cell.Value as string);
                 if (val === 0) {

+ 1 - 1
report/src/core/jpc_cross_tab.ts

@@ -24,7 +24,7 @@ import {
     ICrossTab,
     IGroupField
 } from '../interface/basic';
-import { IDataObjProps } from '../interface/enum'
+import { IDataObjProps, IPositionProps } from '../interface/enum'
 class JpcCrossTabClass {
     dispValueIdxLst_Row: number[][];
     dispValueIdxLst_Col: any[];

+ 14 - 12
report/src/core/jpc_ex.ts

@@ -1,6 +1,6 @@
 
 import JE from './jpc_rte'; //Important: for self-define function execution purpose
-import JV from './jpc_value_define';
+import $JV from './jpc_value_define';
 import JpcBand from './jpc_band';
 import JpcFlowTab from './jpc_flow_tab';
 import JpcBillTab from './jpc_bill_tab';
@@ -16,9 +16,9 @@ import useReportDate from '../public/ReportDate'
 
 import { IDefProperties, IFormula, IParams, ICurrent_RPT, ICurrent_DATA, ICustomizeCfg, ITargetFields, IRptTpl, IDataObj, IBands, IControlCollection, IStyles, BorderStyle, IFontSubCollection, IControlSubCollection, IPreviewPage, IRstPage, IMergeBand } from '../interface/basic'
 import { IFlowTabClass, IBillTabClass, ICostTabClass } from '../interface/classType';
-import { IControlProps, IFontProps, IPagingOption } from '../interface/enum';
+import { IControlProps, IFontProps, IPagingOption, IPositionProps } from '../interface/enum';
 import { Key } from 'readline';
-
+const JV=$JV;
 class JpcExClass {
     flowTab!: IFlowTabClass;
     flowTabEx!: IFlowTabClass;
@@ -177,7 +177,9 @@ class JpcExClass {
                 return null;
             }
             //1.
-            let rstPage: IRstPage = {};
+            let rstPage: IRstPage = {
+                cells:[]
+            };
             rstPage.page_seq = 1;
             if (me.flowTab) {
                 rstPage.cells = me.flowTab.outputAsPreviewPage(rptTpl, bands, rst.control_collection, me);
@@ -264,8 +266,8 @@ class JpcExClass {
                 mergeRst.Top = parseInt(mergedBand.Top.toFixed(0));
                 mergeRst.Bottom = parseInt(mergedBand.Bottom.toFixed(0));
             }
-            // return mergeRst;
-            return false;
+            return mergeRst;
+            // return false;
         }
         if (me.totalPages >= page) {
             rst = {};
@@ -306,10 +308,10 @@ class JpcExClass {
 
 //暂定
 const private_buildDftItems = (
-    rptTpl: any,
+    rptTpl: IRptTpl,
     dftCollection: IControlSubCollection[] | IFontSubCollection[] | null,
-    nodeName: string
-) => {
+    nodeName: string 
+) => { 
     const rst: any = {};
     if (dftCollection) {
         for (let i = 0; i < dftCollection.length; i++) {
@@ -317,9 +319,9 @@ const private_buildDftItems = (
             rst[dftCollection[i].ID] = { ...dftCollectionProps };
         }
         const propArray = (nodeName === 'control_collection') ? JV.CONTROL_PROPS : JV.FONT_PROPS;
-        if (rptTpl && rptTpl[nodeName] && rptTpl[nodeName].length) {
-            for (let i = 0; i < rptTpl[nodeName].length; i++) {
-                const rptDftItem = rptTpl[nodeName][i];
+        if (rptTpl && rptTpl[nodeName as keyof IRptTpl] && rptTpl[nodeName  as keyof IRptTpl].length) {
+            for (let i = 0; i < rptTpl[nodeName  as keyof IRptTpl].length; i++) {
+                const rptDftItem = rptTpl[nodeName  as keyof IRptTpl][i];
                 if (rst[rptDftItem.ID] === undefined) {
                     const item: any = {};
                     for (let j = 0; j < propArray.length; j++) {

+ 21 - 17
report/src/core/jpc_flow_tab.ts

@@ -34,9 +34,9 @@ import {
     IPageCellObj,
     IPageAreaObj,
     IControlSubCollection,
-    INode,
 
 } from '../interface/basic'
+import { IControlProps, IPositionProps } from '../index';
 
 class JpcFlowTabClass {
     isEx: boolean;
@@ -44,8 +44,8 @@ class JpcFlowTabClass {
     segments: number[][];
     dispValueIdxLst: number[][][];
     page_seg_map: number[][];
-    disp_fields_idx: any[];
-    disp_fields_ex_idx: any[];
+    disp_fields_idx: number[];
+    disp_fields_ex_idx: number[];
     seg_sum_fields_idx: any[];
     seg_sum_tab_fields: any[];
     page_sum_fields_idx: any[];
@@ -811,7 +811,7 @@ class JpcFlowTabClass {
         return rst;
     };
     outputContent(rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, unitFactor: number, controls: IControlCollection, multiColIdx: number, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) {
-        let me = this, rst: any[] = [], prepareObj = {};
+        let me = this, rst: any[] = [], prepareObj =<IPageAreaObj>{};
         // let FLOW_NODE_STR = me.isEx?'流水式表_拓展信息':'流水式表_信息';
         let flow_node_str = me.isEx ? rptTpl.流水式表_拓展信息 : rptTpl.流水式表_信息;
         let tab = flow_node_str.流水式表_数据;
@@ -991,6 +991,8 @@ class JpcFlowTabClass {
                 }
             }
         }
+        //合并自动换行的格子,直接把第一个格子的值一个一个递增为目标值,并且把被合并的格子的id纪录下来,准备在下面进行删除
+        //(本来是一行一个格子的,此处通过表示对值进行递增)
         let eliminateCells = combineAutoHeightCells(prepareObj, page, controls);
         for (let idIdx = eliminateCells.length - 1; idIdx >= 0; idIdx--) {
             rst.splice(eliminateCells[idIdx], 1);
@@ -1336,7 +1338,7 @@ function _addPageValue(ValuedIdxLst: number[][][], sortedSequence: number[], grp
     let private_addAutoHeightPageValue = function (vi: number) {
         let couldBreak = false, startIdx = 0;
         let ttlValAmt = 0;
-        if (segAutoHeightInfo && [segIdx].length > startRecIdx + vi) {
+        if (segAutoHeightInfo && segAutoHeightInfo[segIdx].length > startRecIdx + vi) {
             ttlValAmt = segAutoHeightInfo[segIdx][startRecIdx + vi];
         }
         if (prePageLeftAutoHeightRecAmt > 0 && vi === 0) {
@@ -1438,7 +1440,7 @@ function _addPageValue(ValuedIdxLst: number[][][], sortedSequence: number[], grp
     return nextPageAutoHeightRecAmt;
 }
 
-function push_cell(pageCellObj: IPageCellObj, cell: INode, cellIdx: number) {
+function push_cell(pageCellObj: IPageCellObj, cell: ICell, cellIdx: number) {
     let key = cell.area.Left + '_' + cell.area.Right;
     if (!pageCellObj[key]) {
         pageCellObj[key] = [];
@@ -1447,7 +1449,7 @@ function push_cell(pageCellObj: IPageCellObj, cell: INode, cellIdx: number) {
     cellArr.push({ "cellIdx": cellIdx, "cell": cell });
 }
 
-function prepareAutoHeightCells(prepareObj: IPageAreaObj | {}, cellItem: INode, cellIdx: number, cellsArr: ICell[]) {
+function prepareAutoHeightCells(prepareObj: IPageAreaObj | {}, cellItem: ICell, cellIdx: number, cellsArr: ICell[]) {
     if (prepareObj) {
         if ((prepareObj as IPageAreaObj).cellsArr === undefined) {
             (prepareObj as IPageAreaObj).cellsArr = cellsArr;
@@ -1461,7 +1463,7 @@ function setupControl(mergeCell: ICell, controls: IControlCollection) {
     let orgCtrl = null;
     if (typeof mergeCell.control === "string") {
         orgCtrl = controls[mergeCell.control];
-        mergeCell.control = {
+        mergeCell.control = <IControlSubCollection>{
             "Shrink": "T",
             "ShrinkFirst": orgCtrl.ShrinkFirst,
             "CloseOutput": orgCtrl.CloseOutput,
@@ -1470,7 +1472,7 @@ function setupControl(mergeCell: ICell, controls: IControlCollection) {
             "Vertical": orgCtrl.Vertical,
             "Wrap": (mergeCell.isAutoHeight) ? 'T' : 'F',
             "VerticalForExcel": "center"
-        } as IControlSubCollection;
+        };
     } else {
         mergeCell.control.Shrink = "T";
         mergeCell.control.Vertical = "top";
@@ -1488,22 +1490,25 @@ function setupControl(mergeCell: ICell, controls: IControlCollection) {
     return orgCtrl;
 }
 
-function combineAutoHeightCells(prepareObj: IPageAreaObj | {}, page: number, controls: IControlCollection) {
+function combineAutoHeightCells(prepareObj: IPageAreaObj , page: number, controls: IControlCollection) {
+    // 该方法主要是用来生成自动合并的格子的,本来是已经生成了一行一个格子的,但现在需要把可以自动合并的格子进行中整合,在这里进行这个动作
+    // 最后输出的是被合并的格子的index,在外面再剔除
     let rst = [];
-    if ((prepareObj as IPageAreaObj).cellsArr) {
+    if (prepareObj.cellsArr) {
         //merge cells' value and area
         //备注: 系统逻辑已经把Cell的顺序放好,无需再做排序。
-        for (let mergeKey in (prepareObj as IPageAreaObj).pageCellObj) {
-            let sameColCells = (prepareObj as IPageAreaObj).pageCellObj[mergeKey]; //左右位置相同的Cell先放在一起,统一处理
+        for (let mergeKey in prepareObj.pageCellObj) {
+            let sameColCells = prepareObj.pageCellObj[mergeKey]; //左右位置相同的Cell先放在一起,统一处理
             if (sameColCells.length > 1) {
-                //强转格式,此处是强制把本来是字符串的control属性转化为对象,by lish
-                let firstMergeCell: ICell = { ...sameColCells[0].cell, control: {} as IControlSubCollection };
+            //    这里获取第一个被合并的cell的数据
+                let firstMergeCell = sameColCells[0].cell ;
                 firstMergeCell.style = firstMergeCell.style.slice(0, firstMergeCell.style.indexOf("_AutoHeightMerge")); //首先还原original style
                 //生成原始对象,并且把对象中的control属性转化为对象
                 let orgCtrl = setupControl(firstMergeCell, controls);
                 let validValueAmt = 0, fullValidValueAmt = 0;
                 for (let i = 1; i < sameColCells.length; i++) {
                     let mergeCell = sameColCells[i].cell;
+                    //含有“_AutoHeightMerge_Top”的都是每个自动合并的cell的第一行(项)
                     if (mergeCell.style.indexOf("_AutoHeightMerge_Top") < 0) {
                         fullValidValueAmt++;
                         //merge into the firstMergeCell! position & value
@@ -1528,8 +1533,7 @@ function combineAutoHeightCells(prepareObj: IPageAreaObj | {}, page: number, con
                                 firstMergeCell.control.VerticalForExcel = 'center';
                             }
                         }
-                        //强制把已为对象的control属性还原成为字符串,by lish
-                        firstMergeCell = sameColCells[i].cell as unknown as ICell;
+                        firstMergeCell = <ICell>sameColCells[i].cell;
                         firstMergeCell.style = firstMergeCell.style.slice(0, firstMergeCell.style.indexOf("_AutoHeightMerge"));
                         orgCtrl = setupControl(firstMergeCell, controls);
                         validValueAmt = 0;

+ 1 - 1
report/src/core/jpc_rte.ts

@@ -91,7 +91,7 @@ const JE = {
             dataObj[field.DataNodeName][field.DataSeq][valIdx] = newValue;
         }
     },
-    getFieldValue: function (field: Fields, dataObj: IDataObj, valIdx: number, newVal: number) {
+    getFieldValue: function (field: Fields, dataObj: IDataObj, valIdx: number, newVal: number|string) {
         let rst = null;
         if (field.DataNodeName === "NA") {
             if (!field.data_field) {

+ 1 - 0
report/src/index.ts

@@ -4,3 +4,4 @@
 export * from './core/index';
 export * from './interface/index';
 export * from './public/index';
+// export * from './pdfUnit/rpt_pdf_util';

+ 32 - 36
report/src/interface/basic.ts

@@ -1,6 +1,6 @@
 // import { IFlowTabClass, IBillTabClass, ICostTabClass } from './classType';
 // eslint-disable-next-line camelcase
-import { IDataObjProps, IEventType } from './enum';
+import { IDataObjProps, IEventType, IPositionProps } from './enum';
 
 export interface IArea {
     Left: number;
@@ -68,7 +68,7 @@ export interface IStyles {
     ID: string;
     CfgDispName: string;
     border_style: BorderStyle[];
-    // [key: string]: any; // 剩下的之后补充
+    [key: string]: any; // 剩下的之后补充
 }
 
 export interface IDefProperties {
@@ -85,7 +85,7 @@ export interface IFontSubCollection {
     FontAngle?: string;
     FontBold?: string;
     FontColor?: string;
-    FontHeight: number;
+    FontHeight: string;
     FontItalic: string;
     FontStrikeOut?: string;
     FontUnderline: string;
@@ -124,14 +124,6 @@ export interface IPositionExtent {
     Top: IPositionExtentDetail;
 }
 
-export interface INode {
-    font: string;
-    control: string;
-    style: string;
-    Value: number | string | null;
-    area: IArea;
-    isAutoHeight: boolean;
-}
 export interface IPageAreaObj {
     cellsArr: ICell[];
     pageCellObj: IPageCellObj;
@@ -140,7 +132,7 @@ export interface IPageAreaObj {
 export interface IPageCellObj {
     [key: string]: {
         cellIdx: number;
-        cell: INode;
+        cell: ICell;
     }[];
 }
 export interface ICell {
@@ -154,12 +146,20 @@ export interface ICell {
     Prefix?: string;
     Suffix?: any;
 }
-
+export interface IStyleCollection {
+    BORDER_ALL_AROUND: IPositionExtent;
+    Default: IPositionExtent;
+    Default_None: IPositionExtent;
+    Default_Normal: IPositionExtent;
+    Label_Topline: IPositionExtent;
+    Label_Underline: IPositionExtent;
+    [key:string]:IPositionExtent;
+}
 export interface IPreviewPage {
     打印页面_信息: {
         报表名称: string;
         纸张宽高: number[];
-        页边距: [number, number];
+        页边距: IPosition;
     };
     control_collection: IControlCollection;
     font_collection: IFontCollection;
@@ -173,21 +173,9 @@ export interface IPreviewPage {
             }
         }
     ];
-    MergeBand: {
-        Bottom: number;
-        Left: number;
-        Right: number;
-        Top: number;
-        style: any;
-    };
-    style_collection: {
-        BORDER_ALL_AROUND: IPositionExtent;
-        Default: IPositionExtent;
-        Default_None: IPositionExtent;
-        Default_Normal: IPositionExtent;
-        Label_Topline: IPositionExtent;
-        Label_Underline: IPositionExtent;
-    };
+    MergeBand: IMergeBand;
+    style_collection:IStyleCollection;
+    pageBreaks?: any[];
 }
 
 interface ISimpleJSONPage {
@@ -366,7 +354,7 @@ export interface ICustomizeCfg {
     fonts: {
         CfgDispName: string;
         FontBold: string;
-        FontHeight: number;
+        FontHeight: string;
         FontItalic: string;
         FontUnderline: string;
         ID: string;
@@ -375,6 +363,7 @@ export interface ICustomizeCfg {
     isNarrow: boolean;
     margins: IPosition;
     showVerticalLine: boolean;
+    userID?:string
 }
 export interface IOrgBandDetail {
     Alignment: string;
@@ -391,7 +380,7 @@ export interface IOrgBandDetail {
     band_s?:IOrgBandDetail[]
 }
 
-export interface IBandDetail {
+export interface IBandDetail{
     Alignment: number;
     Bottom: number;
     CalculationType: number;
@@ -598,14 +587,21 @@ interface IFlowGroup {
 
 export interface IRstPage {
     page_seq?: number;
-    cells?: INode[];
+    cells: ICell[];
     page_merge_border?: IMergeBand;
 }
 
 export interface IMergeBand {
-    Bottom: number;
-    Left: number;
-    Right: number;
-    Top: number;
+    Bottom:number;
+    Left:number;
+    Right:number;
+    Top:number;
     style?: any;
 }
+//丢失的interface
+export interface IPretreatment{
+    [key: string]: any;
+}
+export interface ISubFilters{
+    [key: string]: any;
+}

+ 8 - 8
report/src/interface/classType.ts

@@ -1,4 +1,4 @@
-import { Fields, IBandDetail, IBands, ICell, IControlCollection, ICrossTab, ICurrent_DATA, ICurrent_RPT, ICustomizeCfg, IDataObj, IDefProperties, IGrpLine, IMergePos, INode, IPreviewPage, IRptTpl, ITab } from "./basic";
+import { Fields, IBandDetail, IBands, ICell, IControlCollection, ICrossTab, ICurrent_DATA, ICurrent_RPT, ICustomizeCfg, IDataObj, IDefProperties, IGrpLine, IMergePos, IPreviewPage, IRptTpl, ITab } from "./basic";
 
 export interface IFlowTabClass {
     auto_height_fields_idx: [number, Fields][];
@@ -80,11 +80,11 @@ export interface ICostTabClass {
     preSetupPages: (rptTpl: IRptTpl, defProperties: IDefProperties, option: string) => number;
     outputAsPreviewPage: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => any; //最后一个参数其实没作用,方法中定义了,但是在实际使用并没有传值
     outputPreviewContent: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxRowRec: number, maxColRec: number, unitFactor: number) => any;
-    outputPreviewRowTab: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxRowRec: number, unitFactor: number) => INode[];
-    outputPreviewColTab: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxColRec: number, unitFactor: number) => INode[];
-    outputPreviewTabExt: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxColRec: number, unitFactor: number) => INode[];
-    outputPreviewSumTabExt: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, unitFactor: number) => INode[];
-    outputPreviewTabSum: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxRowRec: number, tabNodeName: string, unitFactor: number) => INode[];
+    outputPreviewRowTab: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxRowRec: number, unitFactor: number) => ICell[];
+    outputPreviewColTab: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxColRec: number, unitFactor: number) => ICell[];
+    outputPreviewTabExt: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxColRec: number, unitFactor: number) => ICell[];
+    outputPreviewSumTabExt: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, unitFactor: number) => ICell[];
+    outputPreviewTabSum: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxRowRec: number, tabNodeName: string, unitFactor: number) => ICell[];
     private_OutputPreviewCommon: (rptTpl: IRptTpl, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg, maxRowRec: number, maxColRec: number, tab: ICrossTab, unitFactor: number) => any
     outputAsSimpleJSONPage: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => any;
     outputTabSum: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, unitFactor: number, tabNodeName: string, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => any
@@ -92,8 +92,8 @@ export interface ICostTabClass {
     outputSumTabExt: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, unitFactor: number, segIdx: number, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => any
     outputContent: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, unitFactor: number, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => any;
     outputColTab: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, unitFactor: number, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => any
-    outputRowTabCommon: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, tabStr: string, rowFieldsIdxArr: any[], unitFactor: number, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => INode[];
-    outputTabField: (band: IBandDetail, tab_field: Fields, data_field: any, valueIdx: number, serialIdx: number, rows: number, rowIdx: number, cols: number, colIdx: number, unitFactor: number, isRow: boolean, controls: IControlCollection) => INode;
+    outputRowTabCommon: (rptTpl: IRptTpl, dataObj: IDataObj, page: number, bands: IBands, tabStr: string, rowFieldsIdxArr: any[], unitFactor: number, controls: IControlCollection, $CURRENT_RPT: ICurrent_RPT, customizeCfg: ICustomizeCfg) => ICell[];
+    outputTabField: (band: IBandDetail, tab_field: Fields, data_field: any, valueIdx: number, serialIdx: number, rows: number, rowIdx: number, cols: number, colIdx: number, unitFactor: number, isRow: boolean, controls: IControlCollection) => ICell;
 
 
 }

+ 1 - 1
report/src/interface/enum.ts

@@ -48,7 +48,7 @@ export enum IFontProps {
 }
 
 export enum IPositionProps {
-   TOP,
+   Top,
    Bottom,
    Left,
    Right

+ 6 - 5
report/src/interface/projectConstsEnum.ts

@@ -26,7 +26,7 @@ let projectConst = {
 
 let projectConstList = [
     'bills',
-    'ration',
+    'rations',
     'GLJ',
     'ration_glj',
     'ration_coe',
@@ -44,10 +44,11 @@ let projectConstList = [
 ];
 
 let summaryConstList = [
-    `Construct`,
-    `ConstructDetail`,
-    `Segment`,
-    `SegmentDetail`
+    `'construct'`,
+    `'constructDetail'`,
+    `'segment'`,
+    `'segmentDetail'`,
+    `'costTreeData'`
 ];
 
 let projectFieldConstList = [

+ 2 - 0
report/src/pdfUnit/index.ts

@@ -0,0 +1,2 @@
+export * from './rpt_font_util';
+// export * from './rpt_pdf_util';

+ 26 - 0
report/src/pdfUnit/rpt_font_util.ts

@@ -0,0 +1,26 @@
+/**
+ * Created by Tony on 2018/8/2.
+ */
+
+let fontMapObj:Record<string,string> = {
+    "宋体": "Smart"
+    ,"楷体": "simkai"
+    ,"黑体": "simhei"
+};
+//下划线在option中支持
+//另注意:PDFkit设置字体的时候会检测是否同源,也就是说,如果是同一种字体转换不同的特性(如粗体、斜体),那么在设置的时候会无效
+//      比如前一种是普通的字体,后来想设置这种字体的斜体,实际上这种设置会失效
+
+
+export const getActualFont=(mapName:string, isBold:boolean, isItalic:boolean) =>{
+    let rst = ["Smart"];
+    if (fontMapObj[mapName]) rst[0] = fontMapObj[mapName];
+    if (isBold) {
+        rst.push("_bold");
+    }
+    if (isItalic) {
+        rst.push("_italic");
+    }
+    return rst.join("");
+}
+export default {}

+ 542 - 0
report/src/pdfUnit/rpt_pdf_util.ts

@@ -0,0 +1,542 @@
+// /**
+//  * Created by Tony on 2019/9/10.
+//  */
+
+// import { IArea, ICell, IControlCollection, IFontCollection, IFontSubCollection, IMergeBand, IPreviewPage, IRptTpl, IStyleCollection, IStyles } from '../interface/basic';
+// import { jsPDF as JsPDF } from 'jspdf';
+// import { Canvas } from 'canvas';
+// import JV from '../core/jpc_value_define';
+// const PDF_SCALE = 0.75;
+// // const DPI = getScreenDPI();
+
+// export default class JpcJsPDFHelper {
+//   doc: JsPDF;
+
+//   initialize(
+//     orientation: string ,
+//     unit: 'pt' | 'px' | 'in' | 'mm' | 'cm' | 'ex' | 'em' | 'pc',
+//     format: string | number[]
+//   ) {
+//     this.doc = new JsPDF(orientation, unit, format);
+//   }
+
+
+//   outputAsPdf(pageData:IPreviewPage, paperSize:string, pdfName:string) {
+//     const me = this;
+//     const offsetX = 0;
+//     const offsetY = 0;
+//     const newName = pdfName;
+//     const pageObj = pageData;
+//     const paperSizeIdx = JV.PAGES_SIZE_STR.indexOf(paperSize);
+//     const size = JV.PAGES_SIZE[paperSizeIdx];
+//     let orientation = '';
+//     if (pageData.打印页面_信息.纸张宽高[0] > pageData.打印页面_信息.纸张宽高[1]) {
+//       orientation = 'landscape';
+//     } else {
+//       orientation = 'portrait';
+//     }
+//     this.doc = me.initialize(orientation, 'pt', paperSize.toLowerCase());
+//     const {doc}=this;
+//     doc.setFont('SmartSimsun', 'normal'); // 目前只考虑宋体
+
+
+//     const privateDrawCell=(doc:JsPDF, ctx:Canvas, cell:ICell, fonts:IFontCollection, styles:IStyles, controls:IControlCollection, mergedBand:IMergeBand) =>{
+//       ctx.beginPath();
+//       const style = styles[cell.style];
+//       if (style) {
+//         const isNeedMergeBand = private_chkIfInMergedBand(mergedBand, cell);
+//         private_drawLine(
+//           cell,
+//           doc,
+//           ctx,
+//           style,
+//           'Top',
+//           ['Left', 'Top'],
+//           ['Right', 'Top'],
+//           mergedBand,
+//           styles,
+//           isNeedMergeBand
+//         );
+//         private_drawLine(
+//           cell,
+//           doc,
+//           ctx,
+//           style,
+//           'Right',
+//           ['Right', 'Top'],
+//           ['Right', 'Bottom'],
+//           mergedBand,
+//           styles,
+//           isNeedMergeBand
+//         );
+//         private_drawLine(
+//           cell,
+//           doc,
+//           ctx,
+//           style,
+//           'Bottom',
+//           ['Right', 'Bottom'],
+//           ['Left', 'Bottom'],
+//           mergedBand,
+//           styles,
+//           isNeedMergeBand
+//         );
+//         private_drawLine(
+//           cell,
+//           doc,
+//           ctx,
+//           style,
+//          'Left',
+//           ['Left', 'Bottom'],
+//           ['Left', 'Top'],
+//           mergedBand,
+//           styles,
+//           isNeedMergeBand
+//         );
+//       }
+//       private_drawCellText(doc, ctx, cell, fonts, controls);
+//       ctx.closePath();
+//     }
+    
+//     const private_chkIfInMergedBand=(mergedBand:IMergeBand, cell:ICell)=> {
+//       let rst = false;
+//       if (mergedBand && cell) {
+//         rst =
+//           mergedBand.Top <= cell.area.Top&&
+//           mergedBand.Bottom >= cell.area.Bottom &&
+//           mergedBand.Left<= cell.area.Left &&
+//           mergedBand.Right >= cell.area.Right;
+//       }
+//       return rst;
+//     }
+
+//     const private_drawLine=(
+//       cell:ICell,
+//       doc:JsPDF,
+//       ctx:Canvas,
+//       style:IStyles,
+//       styleBorderDest:'Top'|'Left'|'Right'|'Bottom',
+//       startP:['Top'|'Left'|'Right'|'Bottom','Top'|'Left'|'Right'|'Bottom'],
+//       destP:['Top'|'Left'|'Right'|'Bottom','Top'|'Left'|'Right'|'Bottom'],
+//       mergedBand:IMergeBand,
+//       styles:Record<string,IStyleCollection>,
+//       isNeedMergeBand:boolean
+//     ) =>{
+//       let destStyle = style;
+//       if (mergedBand) {
+//         if (
+//           isNeedMergeBand &&
+//           parseFloat(`${mergedBand[styleBorderDest]}`) === parseFloat(`${cell.area[styleBorderDest]}`)
+//         ) {
+//           Object.assign(destStyle, styles[mergedBand.style.ID])
+//         }
+//       }
+//       if (destStyle[styleBorderDest] && parseFloat(destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]) !== 0) {
+//         doc.setDrawColor(destStyle[styleBorderDest][JV.PROP_COLOR]);
+//         if (parseInt(destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]) === 2) {
+//           doc.setLineWidth(1 * destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]);
+//         } else {
+//           doc.setLineWidth(0.1);
+//         }
+//         doc.line(
+//           (cell.area[startP[0]] + offsetX) * PDF_SCALE,
+//           (cell.area[startP[1]] + offsetY) * PDF_SCALE,
+//           (cell.area[destP[0]] + offsetX) * PDF_SCALE,
+//           (cell.area[destP[1]] + offsetY) * PDF_SCALE
+//         );
+//       }
+//     }
+
+//     const private_drawCellText=(doc:JsPDF, ctx:Canvas, cell:ICell, fonts:IFontCollection, controls:IControlCollection)=> {
+//       if (cell.Value !== undefined && cell.Value !== null) {
+//         const values = `${cell.Value}`.split('|');
+//         // let font = fonts[cell[JV.PROP_FONT]];
+//         let font = null;
+//         if (typeof cell.font === 'string') {
+//           font = fonts[cell.font];
+//         } else {
+//           font = cell.font;
+//         }
+//         if (font[JV.FONT_PROPS[JV.FONT_PROP_IDX_BOLD]] === 'T') {
+//           doc.setFont('SmartSimsun', 'bold');
+//           // doc.setFontStyle("bold");
+//         } else {
+//           doc.setFont('SmartSimsun', 'normal');
+//         }
+//         // let control = controls[cell[JV.PROP_CONTROL]];
+//         let control = null;
+//         if (typeof cell.control === 'string') {
+//           control = controls[cell.control];
+//         } else {
+//           control = cell.control;
+//         }
+//         const height = cell.area.Bottom - cell.area.Top;
+//         const area = [
+//           cell.area.Left + offsetX,
+//           cell.area.Top + offsetY,
+//           cell.area.Right+ offsetX,
+//           cell.area.Bottom + offsetY,
+//         ];
+//         let ah = height;
+//         let restTopH = 0;
+//         let restBottomH = 0;
+//         if (control.CloseOutput === 'T') {
+//           ah =
+//             (parseFloat(`${font.FontHeight}`) +
+//               JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] +
+//               JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM]) *
+//             values.length;
+//           const restH = height - ah;
+//           if (control.Vertical === 'center') {
+//             restTopH = restH / 2;
+//             restBottomH = restH / 2;
+//           } else if (control.Vertical === 'bottom') {
+//             restBottomH = restH;
+//           } else {
+//             restTopH = restH;
+//           }
+//         }
+//         let spaceIdxArr = [];
+//         for (let i = 0; i < values.length; i++) {
+//           area[JV.IDX_TOP] = cell.area.Top + i * (ah / values.length) + offsetY + restTopH;
+//           area[JV.IDX_BOTTOM] =
+//             cell.area.Top + (i + 1) * (ah / values.length) + offsetY + restBottomH;
+//           if (values[i] === null || values[i] === undefined || values[i] === 'null') {
+//             values[i] = '';
+//           }
+//           // 因pdfkit输出空格只有浏览器的一半宽度,需要额外加空格补上,jspdf也有这个情况 -----------------------------
+//           if (typeof values[i] === 'string') {
+//             for (let j = 0; j < values[i].length; j++) {
+//               if (values[i][j] === ' ') spaceIdxArr.push(j);
+//             }
+//           }
+//           for (let j = spaceIdxArr.length - 1; j >= 0; j--) {
+//             values[i] = `${values[i].slice(0, spaceIdxArr[j])} ${values[i].slice(spaceIdxArr[j])}`;
+//           }
+//           // -----------------------------
+//           private_drawText(doc, ctx, values[i], area, font, control);
+//           spaceIdxArr = [];
+//         }
+//       }
+//     }
+
+//     const private_drawText=(doc:JsPDF, ctx:Canvas, val:string, area:number[], font:IFontSubCollection, control:IControlCollection)=> {
+//       let dftFontHeight = 12;
+//       const output:any = [];
+//       if (font) {
+//         dftFontHeight = 1 * font.FontHeight;
+//         doc.setFontSize(dftFontHeight);
+//       }
+//       // doc.font(fontFile);
+//       const options = {};
+//       const inner_setupControl =  (outVal: string, inArea: IArea, inFontHeight: number, inOutput: any[])=> {
+//         if (control) {
+//           private_setupAreaH(outVal, inArea, control.Horizon, font.FontAngle, inFontHeight, inOutput, options);
+//           private_setupAreaV(outVal, inArea, control.Vertical, font.FontAngle, inFontHeight, inOutput);
+//         } else {
+//           private_setupAreaH(outVal, inArea, 'left', parseInt(`${font.FontAngle}`), inFontHeight, inOutput, options);
+//           private_setupAreaV(outVal, inArea, 'bottom', parseInt(`${font.FontAngle}`), inFontHeight, inOutput);
+//         }
+//       };
+//       inner_setupControl(val, area, dftFontHeight, output);
+//       let validAreaTxtWidth =
+//         area[JV.IDX_RIGHT] -
+//         JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] -
+//         area[JV.IDX_LEFT] -
+//         JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT];
+//       let validTxtLines = Math.floor(
+//         (area[JV.IDX_BOTTOM] - area[JV.IDX_TOP]) /
+//           (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4)
+//       );
+//       if (parseInt(`${font.FontAngle}`) !== 0) {
+//         validAreaTxtWidth =
+//           area[JV.IDX_BOTTOM] -
+//           JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] -
+//           area[JV.IDX_TOP] -
+//           JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+//         validTxtLines = Math.floor(
+//           (area[JV.IDX_RIGHT] - area[JV.IDX_LEFT]) /
+//             (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT] + 4)
+//         );
+//       }
+
+//       const private_drawUnderline=(underLineVal, underLineArea)=> {
+//         // A. 暂不支持角度; B. PDF输出时,坐标没有translate
+//         // let ctx = doc;
+//         // 1. 计算下划线的相关坐标
+//         let width = doc.getTextWidth(underLineVal);
+//         if (width > underLineArea[JV.IDX_RIGHT] - underLineArea[JV.IDX_LEFT]) {
+//           width = underLineArea[JV.IDX_RIGHT] - underLineArea[JV.IDX_LEFT];
+//         }
+//         const height = dftFontHeight;
+//         let startX = underLineArea[JV.IDX_LEFT];
+//         let startY = underLineArea[JV.IDX_TOP];
+//         let endX = underLineArea[JV.IDX_RIGHT];
+//         let endY = underLineArea[JV.IDX_BOTTOM];
+//         // let startX = 0, startY = 0, endX = width, endY = startY;
+//         if (control.Horizon === 'left') {
+//           startX = Math.round(underLineArea[JV.IDX_LEFT] + JV.OUTPUT_OFFSET[JV.IDX_LEFT]);
+//         } else if (control.Horizon === 'right') {
+//           startX = Math.round(underLineArea[JV.IDX_RIGHT] - width - JV.OUTPUT_OFFSET[JV.IDX_RIGHT]);
+//         } else {
+//           startX = Math.round(
+//             underLineArea[JV.IDX_LEFT] + (underLineArea[JV.IDX_RIGHT] - underLineArea[JV.IDX_LEFT] - width) / 2
+//           );
+//         }
+//         endX = Math.round(startX + width);
+
+//         if (control.Vertical === 'top') {
+//           startY = Math.round(
+//             underLineArea[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM] + height
+//           );
+//         } else if (control.Vertical === 'bottom') {
+//           startY = Math.round(underLineArea[JV.IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.IDX_BOTTOM]);
+//         } else {
+//           startY =
+//             Math.round(
+//               underLineArea[JV.IDX_TOP] + (underLineArea[JV.IDX_BOTTOM] - underLineArea[JV.IDX_TOP] + height) / 2
+//             ) +
+//             JV.OUTPUT_OFFSET[JV.IDX_TOP] +
+//             JV.OUTPUT_OFFSET[JV.IDX_BOTTOM];
+//         }
+//         endY = Math.round(startY);
+//         // 2. 画线
+//         // ctx.save();
+//         if (output[1] !== Math.round(output[1])) {
+//           ctx.translate(0, 0.5);
+//         }
+
+//         doc.setDrawColor('BLACK');
+//         doc.setLineWidth(0.1);
+//         doc.line(startX * PDF_SCALE, startY * PDF_SCALE, endX * PDF_SCALE, endY * PDF_SCALE);
+//       }
+
+//       let rotateOptions;
+//       if (parseInt(font.FontAngle) !== 0) {
+//         if (control) {
+//           rotateOptions = private_setupAreaRotateOption(
+//             area,
+//             validAreaTxtWidth,
+//             control.Vertical,
+//             dftFontHeight,
+//             output
+//           );
+//         } else {
+//           rotateOptions = private_setupAreaRotateOption(area, validAreaTxtWidth, 'bottom', dftFontHeight, output);
+//         }
+//         doc.rotate(font.FontAngle, rotateOptions);
+//       }
+//       if (
+//         validAreaTxtWidth >= doc.getTextWidth(val) ||
+//         (control && control.Shrink !== 'T' && validTxtLines < private_splitString(val, validAreaTxtWidth, doc))
+//       ) {
+//         options.width = validAreaTxtWidth * PDF_SCALE;
+//         options.height = dftFontHeight * PDF_SCALE;
+//         doc.setFontSize(dftFontHeight);
+//         if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+//           private_drawUnderline(val, area);
+//         }
+//         doc.setFontSize(dftFontHeight * PDF_SCALE);
+//         doc.text(output[0] * PDF_SCALE, output[1] * PDF_SCALE, val);
+//       } else {
+//         while (true) {
+//           let lines = Math.floor(
+//             (area[JV.IDX_BOTTOM] - area[JV.IDX_TOP]) /
+//               (dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4)
+//           );
+//           lines = lines === 0 || (control.Shrink === 'T' && control.ShrinkFirst === 'T') ? 1 : lines;
+//           const actLines = private_splitString(val, validAreaTxtWidth, doc);
+//           if (actLines.length > lines && dftFontHeight >= 6) {
+//             dftFontHeight--;
+//             doc.setFontSize(dftFontHeight);
+//             options.width = validAreaTxtWidth * PDF_SCALE;
+//             options.height = dftFontHeight * PDF_SCALE;
+//           } else {
+//             const aH = dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + 4;
+//             if (
+//               aH * actLines.length < area[JV.IDX_BOTTOM] - area[JV.IDX_TOP] &&
+//               control &&
+//               control.Vertical !== 'top'
+//             ) {
+//               if (control.Vertical === 'bottom') {
+//                 area[JV.IDX_TOP] = area[JV.IDX_BOTTOM] - aH * actLines.length;
+//               } else {
+//                 area[JV.IDX_TOP] = (area[JV.IDX_TOP] + area[JV.IDX_BOTTOM]) / 2 - (aH * actLines.length) / 2;
+//                 area[JV.IDX_BOTTOM] = area[JV.IDX_TOP] + aH * actLines.length;
+//               }
+//             }
+//             const newArea = [];
+//             const baseTop = area[JV.IDX_TOP];
+//             for (let ai = 0; ai < area.length; ai++) {
+//               newArea[ai] = area[ai];
+//             }
+//             options.width = validAreaTxtWidth * PDF_SCALE;
+//             options.height = dftFontHeight * PDF_SCALE;
+//             for (let lIdx = 0; lIdx < actLines.length; lIdx++) {
+//               newArea[JV.IDX_TOP] = Math.round(aH * lIdx + baseTop);
+//               newArea[JV.IDX_BOTTOM] = Math.round(aH * (lIdx + 1) + baseTop);
+//               doc.setFontSize(dftFontHeight);
+//               inner_setupControl(actLines[lIdx], newArea, dftFontHeight, output);
+//               if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+//                 private_drawUnderline(actLines[lIdx], newArea);
+//               }
+//               doc.setFontSize(dftFontHeight * PDF_SCALE);
+//               doc.text(output[0] * PDF_SCALE, output[1] * PDF_SCALE, actLines[lIdx]);
+//             }
+//             break;
+//           }
+//         }
+//       }
+//     }
+
+//     const private_setupAreaH=(outVal, area, type, fontAngle, dftFontHeight, outputPoint, options)=> {
+//       // jspdf输出方式不同(但与H5的canvas处理方式有所不同,因为没有相关alignment属性,需要自己算,而且角度还暂时不支持)-------------------------------------------
+//       let lType = type;
+//       if (type !== 'left' && type !== 'right' && type !== 'center') lType = 'left';
+//       switch (lType) {
+//         case 'left':
+//           if (fontAngle === JV.VERTICAL_ANGLE_INT) {
+//             // outputPoint[1] = 1 * area[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT];
+//           } else if (fontAngle === JV.ANTI_VERTICAL_ANGLE_INT) {
+//             // outputPoint[1] = 1 * area[JV.IDX_BOTTOM] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT];
+//           } else {
+//             outputPoint[0] = 1 * area[JV.IDX_LEFT] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT];
+//           }
+//           // ctx.textAlign="start";
+//           break;
+//         case 'right':
+//           if (fontAngle === JV.VERTICAL_ANGLE_INT) {
+//             outputPoint[1] = 1 * area[JV.IDX_BOTTOM] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT];
+//           } else if (fontAngle === JV.ANTI_VERTICAL_ANGLE_INT) {
+//             outputPoint[1] = 1 * area[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT];
+//           } else {
+//             const width = doc.getTextWidth(outVal);
+//             outputPoint[0] = 1 * area[JV.IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_RIGHT] - width;
+//           }
+//           // ctx.textAlign="end";
+//           break;
+//         case 'center':
+//           if (fontAngle === JV.VERTICAL_ANGLE_INT || fontAngle === JV.ANTI_VERTICAL_ANGLE_INT) {
+//             outputPoint[1] = (1 * area[JV.IDX_TOP] + 1 * area[JV.IDX_BOTTOM]) / 2;
+//           } else {
+//             const width = doc.getTextWidth(outVal);
+//             outputPoint[0] = (1 * area[JV.IDX_LEFT] + 1 * area[JV.IDX_RIGHT]) / 2 - width / 2;
+//           }
+//           // ctx.textAlign="center";
+//           break;
+//       }
+//     }
+
+//     const private_setupAreaV=(outVal, area, type, fontAngle, dftFontHeight, outputPoint)=> {
+//       // jspdf输出方式不同(与H5的canvas一样处理)-------------------------------------------
+//       let lType = type;
+//       if (type !== 'top' && type !== 'bottom' && type !== 'center') lType = 'top';
+//       switch (lType) {
+//         case 'top':
+//           if (fontAngle === JV.VERTICAL_ANGLE_INT) {
+//             outputPoint[0] = 1 * area[JV.IDX_RIGHT] - dftFontHeight - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+//           } else if (fontAngle === JV.ANTI_VERTICAL_ANGLE_INT) {
+//             outputPoint[0] = 1 * area[JV.IDX_LEFT] + dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+//           } else outputPoint[1] = 1 * area[JV.IDX_TOP] + dftFontHeight + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+//           break;
+//         case 'bottom':
+//           if (fontAngle === JV.VERTICAL_ANGLE_INT) {
+//             outputPoint[0] = 1 * area[JV.IDX_LEFT] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM];
+//           } else if (fontAngle === JV.ANTI_VERTICAL_ANGLE_INT) {
+//             outputPoint[0] = 1 * area[JV.IDX_RIGHT] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM];
+//           } else {
+//             outputPoint[1] = 1 * area[JV.IDX_BOTTOM] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM];
+//             // if (fontName === "宋体") outputPoint[1] = outputPoint[1] - 1;
+//             outputPoint[1] -= 1; // 宋体需要提上一个像素点
+//           }
+//           break;
+//         case 'center':
+//           if (fontAngle === JV.VERTICAL_ANGLE_INT) {
+//             outputPoint[0] = (1 * area[JV.IDX_LEFT] + 1 * area[JV.IDX_RIGHT] - dftFontHeight) / 2;
+//           } else if (fontAngle === JV.ANTI_VERTICAL_ANGLE_INT) {
+//             outputPoint[0] = (1 * area[JV.IDX_LEFT] + 1 * area[JV.IDX_RIGHT] + dftFontHeight) / 2;
+//           } else {
+//             outputPoint[1] = (1 * area[JV.IDX_TOP] + 1 * area[JV.IDX_BOTTOM] + dftFontHeight) / 2;
+//             // if (fontName === "宋体") outputPoint[1] = outputPoint[1] - 1;
+//             outputPoint[1] -= 1; // 宋体需要提上一个像素点
+//           }
+//           break;
+//       }
+//     }
+
+//     const private_splitString=(strVal, areaWidth, doc) =>{
+//       const rst = [];
+//       if (strVal) {
+//         let preSIdx = 0;
+//         let txtWidth = 0;
+//         let currentW = 0;
+//         const chnW = doc.getTextWidth('一');
+//         const otherW = doc.getTextWidth('_');
+//         for (let sIdx = 0; sIdx < strVal.length; sIdx++) {
+//           currentW = strVal.charCodeAt(sIdx) > 127 ? chnW : otherW;
+//           txtWidth += currentW;
+//           if (txtWidth > areaWidth) {
+//             if (preSIdx < sIdx) {
+//               rst.push(strVal.substr(preSIdx, sIdx - preSIdx));
+//               preSIdx = sIdx;
+//             } else {
+//               rst.push(strVal.substr(preSIdx, 1));
+//               preSIdx = sIdx + 1;
+//             }
+//             txtWidth = currentW;
+//           }
+//           if (sIdx === strVal.length - 1) {
+//             rst.push(strVal.substr(preSIdx, strVal.length - preSIdx));
+//           }
+//         }
+//       }
+//       if (rst.length === 0) rst.push(''); // 什么都没有,也得整个空串
+//       return rst;
+//     }
+
+//     const private_setupAreaRotateOption=(area, w, type = 'top', dftFontHeight, outputPoint)=> {
+//       const x = (area[JV.IDX_RIGHT] - area[JV.IDX_LEFT]) / 2 + area[JV.IDX_LEFT];
+//       const y = (area[JV.IDX_BOTTOM] - area[JV.IDX_TOP]) / 2 + area[JV.IDX_TOP];
+//       const rotateOptions = { origin: [x, y] };
+//       const h = area[JV.IDX_RIGHT] - area[JV.IDX_LEFT];
+//       outputPoint[0] = x - w / 2 + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT];
+//       switch (type) {
+//         case 'top':
+//           outputPoint[1] = y - h / 2 + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+//           break;
+//         case 'bottom':
+//           outputPoint[1] = y + h / 2 - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] - dftFontHeight;
+//           break;
+//         case 'center':
+//           outputPoint[1] = y + dftFontHeight / 2;
+//           break;
+//       }
+//       return rotateOptions;
+//     }
+//     const newPageMergeBand = {...pageObj.MergeBand};
+//     if (pageObj && pageObj.items.length > 0) {
+//       for (let i = 0; i < pageObj.items.length; i++) {
+//         if (i > 0) {
+//           doc.addPage(paperSize.toLowerCase(), orientation);
+//         }
+//         const ctx = doc.canvas.getContext();
+//         const page = pageObj.items[i];
+//         const fonts = pageObj.control_collection;
+//         const styles = pageObj.style_collection;
+//         const controls = pageObj.control_collection;
+
+//         if (page.page_merge_border) {
+//           Object.assign(newPageMergeBand,page.page_merge_border);
+//         }
+//         for (let j = 0; j < page.cells.length; j++) {
+//           const cell = page.cells[j];
+//           privateDrawCell(doc, ctx, cell, fonts, styles, controls, newPageMergeBand);
+//         }
+//       }
+//     }
+//     doc.save(`${newName}.pdf`);
+
+//   },
+// }
+
+

+ 2 - 2
tree/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@sc/tree",
-  "version": "1.0.13",
-  "description": "a template for npm package coding",
+  "version": "1.0.15",
+  "description": "通用树",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",
   "browser": "./dist/index.min.js",

+ 6 - 0
tree/src/nodeCtx.ts

@@ -93,6 +93,12 @@ export class NodeContext<T = any> {
     return children[children.length - 1] || null;
   }
 
+  latestChildSeq(): number {
+    const latestChild = this.lastChild();
+    if (latestChild) return latestChild.seq;
+    return 0;
+  }
+
   // 获取节点后代(包含嵌套子项)
   posterity(): (TreeNode & T)[] {
     const posterity: (TreeNode & T)[] = [];

+ 57 - 24
types/src/interface/base.ts

@@ -1,10 +1,11 @@
 import { IProjectGlj } from './glj';
-import { IBill } from './bill';
+import { IBill, IBookmark } from './bill';
 import { IProject, IProjectPermission } from './project';
-import { IRation } from './ration';
+import { IGljQtyCoe, IRation } from './ration';
 import { IFeeRateFile } from './feeRate';
 import { ICalcProgramFile } from './calculation';
 import { IConfigMaterial } from './configMaterial';
+import { IQuantityDetail } from './quantityDetail';
 
 export interface IAny {
   [prop: string]: any;
@@ -42,24 +43,26 @@ export interface IResult<T = any> {
   data: T;
 }
 
-export enum fromType {
+export enum FromType {
   STD = 'std',
   CPT = 'cpt',
 }
 
-export enum prefix {
+export enum RationPrefix {
+  EMT = '',
   BOR = '借',
   CPT = '补',
+  REP = '换',
 }
 
 // 工料机生成的类型
-export enum gljCreateType {
+export enum GljCreateType {
   NORMAL = 'normal',
   ADD = 'add',
   REPLACE = 'replace',
 }
 
-export enum createLocation {
+export enum CreateLocation {
   CSXM = 1, // 模板子目分别放在措施项目下
   FBFX = 2, // 模板子目分别放在分部分项下
   HNTZM = 3, // 模板子目分别放在对应混凝土子目下
@@ -85,7 +88,7 @@ export enum BRType { // 1 :大项费用 2:分部 3分项 4清单;5补项   6 
   EQUIP = 51, // 设备
 }
 
-export enum supplyType {
+export enum SupplyType {
   ZXCG = 1, // 自行采购
   BFJG, // 部分甲供
   WQJG, // 完全甲供
@@ -115,6 +118,7 @@ export interface IBulkWrite<T extends IAny = any> {
 export enum CptModelName {
   projects = 'projects',
   bills = 'bills',
+  billCodeSeqs = 'billCodeSeqs',
   rations = 'rations',
   rationGljs = 'rationGljs',
   shareList = 'shareList',
@@ -122,14 +126,11 @@ export enum CptModelName {
   feeRateFile = 'feeRateFile',
   labourCoeFile = 'labourCoeFile',
   importLogs = 'importLogs',
-  cptRationSectionTpl = 'cptRationSectionTpl',
-  cptGljLib = 'cptGljLib',
-  cptGljSection = 'cptGljSection',
-  cptGljSectionTpl = 'cptGljSectionTpl',
-  cptRationCoeList = 'cptRationCoeList',
-  cptRationInstallation = 'cptRationInstallation',
-  cptRationInstallationSection = 'cptRationInstallationSection',
-  cptRationItems = 'cptRationItems',
+  cptGlj = 'cptGlj',
+  cptGljTree = 'cptGljTree',
+  cptRationTree = 'cptRationTree',
+  cptRation = 'cptRation',
+  cptRationCoe = 'cptRationCoe',
   cptRationChapterTrees = 'cptRationChapterTrees',
   configMaterials = 'configMaterials',
   projectGljs = 'projectGljs',
@@ -155,11 +156,24 @@ export enum ActionType {
 // 特殊的action
 export enum ActionName {
   // ration相关
-  addStdRations = 'addStdRations', // 添加标准定额
-  resetColMetas = 'resetColMetas', // 重置默认列设置
-  updateIndexKey = 'updateIndexKey', // 修改定额工料机的名称,规格,单位
-  addRationGljs = 'addRationGljs', // 添加定额工料机(多个)
-  replaceRationGlj = 'replaceRationGlj', // 替换定额工料机(单个)
+  ADD_STD_RATIONS = 'addStdRations', // 添加标准定额
+  RESET_COL_METAS = 'resetColMetas', // 重置默认列设置
+  UPDATE_INDEX_KEY = 'updateIndexKey', // 修改定额工料机的名称,规格,单位
+  ADD_RATION_GLJS = 'addRationGljs', // 添加定额工料机(多个)
+  REPLACE_RATION_GLJ = 'replaceRationGlj', // 替换定额工料机(单个)
+  APPLY_ALL_INFO_PRICE = 'applyAllInfoPrice', // 批量套用信息价
+  PASTE_BLOCK = 'pasteBlock', // 复制整块
+
+  // 清单相关
+  ADD_STD_BILLS = 'addStdBills', // 添加标准清单
+
+  // 补充人材机相关
+  CHANGE_CPT_RATION_TREE = 'changeCptRationTree', // 补充定额章节树数据变更
+  CHANGE_CPT_RATION = 'changeCptRation', // 补充定额数据变更
+  CHANGE_CPT_RATION_GLJ = 'changeCptRationGlj', // 补充定额人材机变更
+  CHANGE_CPT_RATION_COE = 'changeCptRationCoe', // 补充定额子目换算变更
+  CHANGE_CPT_COE = 'changeCptCoe', // 补充子目换算数据变更
+  ADD_RATION_COE_TO_SECTION = 'addRationCoeToSection', // 添加子目换算到本节其他定额
 }
 
 export interface IBaseFilter {
@@ -172,17 +186,17 @@ export interface IFilter {
   [key: string]: string;
 }
 // 统一subject更新提交数据入口,为撤销功能做准备
-export interface ISetData<T = any> {
+export interface ISetData<T = any, F = any, R = any> {
   projectID: string; // 考虑到可能会跨项目更新,提高一层
   module: CptModelName | SubModelName;
   action: ActionType;
   prop?: string; // 用来指表中的数组属性名,针对如configMaterial里,一个collections 里有多个数组数据的情况
   actionName?: ActionName; // 除了增删改查,还会有更复杂的操作,用这个来区分
-  filter?: any; // 查询条件
-  update?: any; // 和update类型对应,
+  filter?: F; // 查询条件
+  update?: Partial<T>; // 和update类型对应,
   documents?: T[]; // add 类型对应,批量插入
   odocs?: any[]; // 存放撤销的原始数据?
-  result?: any; // 特殊的返回结果
+  result?: R; // 特殊的返回结果
 }
 
 export interface IColumnMeta {
@@ -217,3 +231,22 @@ export interface IGetData {
   isOwner: boolean;
   projectsPermission: IProjectPermission[];
 }
+
+// 定额和清单共有的属性,造价书中很多地方需要
+export interface IBRBase {
+  ID: string;
+  parentID: string;
+  seq: number;
+  kind: BRType;
+  stdID?: string;
+  unit?: string;
+  code?: string;
+  name?: string;
+  quantity?: number;
+  quantityEXP?: string;
+  quantityDetails?: IQuantityDetail[]; // 工程量明细 -- 原先保存在另外的表中
+  fees?: any; // 费用字段
+  gljQtyCoe?: IGljQtyCoe; // 工料机消耗量调整系数字段
+  rationQtyCoe?: number; // 子目工程量调整系数
+  bookmarks?: IBookmark[]; // 书签批注
+}

+ 6 - 13
types/src/interface/bill.ts

@@ -1,4 +1,4 @@
-import { BRType, ITreeScm } from './base';
+import { BRType, IBRBase, ITreeScm } from './base';
 import { IQuantityDetail } from './quantityDetail';
 
 // 清单固定类别
@@ -111,18 +111,8 @@ export interface ISetBookmark {
   ID: string;
   content: string;
 }
-export interface IBill {
-  ID: string;
-  parentID: string;
-  seq: number;
-  kind: BRType;
-  stdID?: string;
-  unit?: string;
-  code?: string;
-  name?: string;
+export interface IBill extends IBRBase {
   flag?: FixedFlag; // 清单固定类别
-  quantity?: number;
-  quantityDetails?: IQuantityDetail[]; // 工程量明细 -- 原先保存在另外的表中
   recharge?: string; // 补注
   ruleText?: string; // 工程量计算规则
   jobContents?: IJobContent[]; // 工作内容
@@ -132,8 +122,11 @@ export interface IBill {
   formula?: string; // 基数计算
   formulaValue?: number; // 基数计算的值
   tenderFormulaValue?: number; // 调价基数计算的值
-  bookMark?: IBookmark; // 书签批注
   isAdd?: boolean; // 是否用户新增的清单
+  feeRateID?: string; // 费率ID
+  feeRate?: number; // 费率值
+  mainBills?: boolean; // 主要清单
+  lockUnitPrice?: boolean; // 锁定单价
   [key: string]: any; // 剩下的之后补充
 }
 

+ 7 - 6
types/src/interface/calculation.ts

@@ -5,17 +5,18 @@ export interface ICalcOption {
   calcEst: boolean;
 }
 
-// 调价选项
-export enum TenderOption {
-  COE_BASE = 'coeBase',
-  GLJ_BASE = 'gljBase',
-  ZM_BASE = 'zmBase',
+// 调价类型:
+export enum TenderKinds {
+  COE_CALC, // 正向调价-按系数计算
+  REVERSE_RATION, // 反向调价-调子目
+  REVERSE_GLJ, // 反向调价-调工料机
+  NULL, // 无需参数时,用作占位
 }
 
 // 调价设置
 export interface ITenderSetting {
   gljPriceTenderCoe: number; // 工料机单价调整系数
-  calcPriceOption: TenderOption; // 根据调整系数计算报价
+  tenderKind: TenderKinds;
 }
 
 export interface ICalcItem {

+ 35 - 15
types/src/interface/compilation.ts

@@ -1,4 +1,3 @@
-import { ELockInfo } from './user';
 import { TaxType, IGLJCol } from './project';
 import { IFileRef, INumFileRef } from './base';
 
@@ -7,6 +6,7 @@ export interface ICptItem {
   name: string;
   description: string;
 }
+
 export interface IProgramLib extends INumFileRef {
   displayName: string;
 }
@@ -62,28 +62,48 @@ export enum versionType {
   PRO = 'pro', // 专业版
 }
 
+export enum LockInfo {
+  DEFAULT = 0, // 默认值
+  BORROW = 1, // 借用
+  BUY = 2, // 销售
+}
+
 export interface ICompilation {
   ID: string;
   name: string;
-  creator?: string;
-  createTime?: number;
-  releaseTime?: number;
-  rationValuations?: any;
-  billValuations?: IValuation[];
-  isRelease?: boolean;
-  description?: string;
-  overWriteUrl?: string;
-  categoryID?: string;
-  example?: number[];
-  adProjects?: number[];
+  creator: string;
+  createTime: number;
+  releaseTime: number;
+  rationValuations: any;
+  billValuations: IValuation[];
+  isRelease: boolean;
+  description: string;
+  overWriteUrl: string;
+  categoryID: string;
+  example: number[];
+  adProjects: number[];
 
   // 附加
-  version?: versionType; // 版本
-  versionText?: string; // 版本对应的显示文字:免费版,学习版,专业版
-  lockInfo?: ELockInfo; //
+  version: versionType; // 版本
+  versionText: string; // 版本对应的显示文字:免费版,学习版,专业版
+  lockInfo: LockInfo; // 锁信息
 }
 
 export enum ValuationType {
   BILL = 'bill', // 清单计价
   RATION = 'ration', // 定额计价
 }
+
+// 专业版费用定额
+export interface IProCptItem {
+  // 编办 ID
+  compilationID: string;
+  // 开通时间
+  upgradeTime: number;
+  // 备注
+  remark: string;
+  // 截至时间,0 代表无限制
+  deadline: number;
+  // 锁信息
+  lock: LockInfo;
+}

+ 2 - 2
types/src/interface/configMaterial.ts

@@ -1,4 +1,4 @@
-import { supplyType } from './base';
+import { SupplyType } from './base';
 
 export interface IBaseMaterial {
   ID: string;
@@ -32,7 +32,7 @@ export interface IContractorMaterial extends IBaseMaterial {
   standardPrice?: number; // 基准单价
   FO?: number; // 基本价格指数
   FI?: number; // 现行价格指数
-  supply: supplyType; // 供货方式
+  supply: SupplyType; // 供货方式
 }
 
 // 配置材料的几个属性

+ 37 - 7
types/src/interface/enterprise.ts

@@ -1,7 +1,30 @@
+import { IProCptItem } from './compilation';
+
+export enum Relationship {
+  ADMIN = 'admin',
+  STAFF = 'staff',
+  IRRELEVANT = 'irrelevant',
+}
+
+export enum MemberRole {
+  ADMIN = 'admin',
+  STAFF = 'staff',
+}
+
+export enum MemberStatus {
+  NORMAL = 'normal',
+  DISABLED = 'disabled',
+  UNCONFIRMED = 'unconfirmed',
+}
+
 export interface IMember {
   userID: string;
+  memberName: string;
+  position: string;
+  role: MemberRole;
+  status: MemberStatus;
   cptList: string[];
-  createProject: 'yes' | 'no';
+  createProject: boolean;
   projectView: 'self' | 'all';
   editProject: 'self' | 'all';
   exportProject: 'disabled' | 'self' | 'all';
@@ -11,16 +34,23 @@ export interface IMember {
 
 export interface IEnterprise {
   ID: string;
-  cldID: string;
-  adminID: string;
   members: IMember[];
-  companyName: string;
+  activated: boolean;
+  licenceNum: number;
+  proCptList: IProCptItem[];
+  usedCptList: string[];
+  // 公司名称
+  name: string;
   logo: string;
-  companyLocation: [string, string, string];
-  companyType: string;
-  companyScale: string;
+  location: string[];
+  // 公司类型
+  type: string;
+  scale: string;
   createTime: number;
   passwordCheck: 'no' | 'weak' | 'normal' | 'strong' | 'super';
+  subdomain: string;
+  domain: string;
+  icp: string;
   ip: string;
   logoutRule: string;
 }

+ 0 - 63
types/src/interface/error.ts

@@ -1,63 +0,0 @@
-// 错误类型
-// eslint-disable-next-line import/prefer-default-export
-export enum ErrNo {
-  // 没捕获到的通用错误
-  ERROR = 1,
-
-  /* 用户相关错误(包含登录) 1001 - 1999 */
-  ONLY_MOBILE_MESSAGE = 1001,
-  MESSAGE_ERROR = 1002,
-  MESSAGE_OVERDUE = 1003,
-  IP_EMPTY = 1004,
-  MOBILE_ERROR = 1005,
-  NOT_REGISTERED = 1006,
-  SSO_CHECK_ERROR = 1007,
-  EMAIL_NOT_VERIFIED = 1008,
-  PASSWORD_ERROR = 1009,
-  SSO_ERROR = 1010,
-  SEND_MESSAGE_ERROR = 1011,
-  // 登录参数错误
-  LOGIN_PARAM_ERROR = 1012,
-  // 未登录
-  NOT_LOGIN = 1013,
-
-  /* 费用定额相关 2001 - 2999 */
-  COMPILATION_NOT_FOUND = 2001,
-  // 编办已设置
-  COMPILATION_ALREADY_SET = 2002,
-  /* 权限相关 3001 - 3999 */
-  SET_DATA_PERMISSION = 3001, // 可以再细分setData
-  /* 分享相关 4001 - 4999 */
-  ERROR_HISTORY_PARAMS = 4001,
-  /* 项目相关 5001 - 5999 */
-  PROJECT_EXISTS = 5001,
-  PROJECT_NOT_FOUND = 5002,
-  FOLD_HAS_CHILD = 5003,
-  INVALID_PROJECT_TYPE = 5004,
-  CONSTRUCTION_NOT_FOUND = 5005,
-  COLMETAS_NOT_FOUND = 5006,
-  ENGINEERING_NOT_FOUND = 5007,
-  TAX_ITEM_NOT_FOUND = 5008,
-  ORG_CONSTRUCTION_NOT_FOUND = 509,
-  ORG_SINGLE_NOT_FOUND = 5010,
-  RECOVER_PROJECT_NOT_FOUND = 5011,
-  INVALID_RECOVER_PROJECT = 5012,
-  CANT_RECOVER_TO_PROJECT = 5013,
-  PROJECT_IS_COMPLETED_DELETED = 5014,
-  PROJECT_IS_NOT_DELETED = 5015,
-  CANT_DELETE_FOLDER = 5016,
-  CALC_PROGRAM_NOT_FOUND = 5017,
-  FEE_RATE_NOT_FOUND = 5018,
-  RATION_TEMPLATE_NOT_FOUND = 5019,
-  RATION_COE_NOT_FOUND = 5020,
-  RATION_GLJ_NOT_FOUND = 5021,
-  GLJ_COMPONENT_FOUND = 5022,
-  PROJECT_EXISTS_UPDATE = 5023,
-  PROJECT_EXISTS_LEVEL = 5024,
-  PROJECT_NOT_FOUND_REMOVE = 5025,
-  PROJECT_NOT_FOUND_TREE_DATA = 5026,
-  CONSTRUCTION_ORG_NOT_FOUND = 5027,
-  SINGLE_ORG_NOT_FOUND = 5028,
-
-  GLJ_LIB_NOT_FOUND = 5029,
-}

+ 173 - 31
types/src/interface/glj.ts

@@ -3,7 +3,7 @@
  * @Author: vian
  * @Date: 2021-05-26 17:37:16
  */
-import { fromType, ITreeScm, supplyType } from './base';
+import { FromType, ITreeScm, SupplyType } from './base';
 
 // 工料机类型
 export enum GljType {
@@ -39,6 +39,30 @@ export enum GljType {
   GENERAL_RISK_FEE = 8, // 一般风险费
 }
 
+export const hasCompMaterialTypes = [
+  // 有组成物的材料类型, //混凝土、砂浆、配合比
+  GljType.CONCRETE,
+  GljType.MORTAR,
+  GljType.MIX_RATIO,
+];
+
+export const hasCompMachineTypes = [
+  // 有组成物的机械类型
+  GljType.GENERAL_MACHINE,
+  GljType.INSTRUMENT,
+];
+export const machineCompTypes = [
+  // 可以做为机械组成物的类型
+  GljType.MACHINE_COMPOSITION,
+  GljType.MACHINE_LABOUR,
+  GljType.FUEL_POWER_FEE, // 燃料动力费
+  GljType.DEPRECIATION_FEE, // 折旧费
+  GljType.INSPECTION_FEE, // 检修费
+  GljType.MAINTENANCE, // 维护费
+  GljType.DISMANTLING_FREIGHT_FEE, // 安拆费及场外运费
+  GljType.VERIFICATION_FEE, // 校验费
+  GljType.OTHER_FEE, // 其他费用
+];
 export interface IBaseGlj {
   code: string;
   name: string;
@@ -124,7 +148,7 @@ export interface IComponent {
   code: string; // 对应工料机code
   type: GljType; // 工料机类型
   model?: number; // 机型
-  from: fromType; // std, cpt  来自标准工料机库、补充工料机库
+  from: FromType; // std, cpt  来自标准工料机库、补充工料机库
 }
 
 export enum MaterialType {
@@ -145,13 +169,29 @@ export const MaterialDisplay = {
   6: '商品砂浆',
 };
 
+// 机型
+export enum GljModel {
+  EXTRA_LARGE = 1,
+  LARGE,
+  MEDIUM,
+  SMALL,
+}
+
+// 机型名称映射
+export const GljModelName = {
+  1: '特大',
+  2: '大',
+  3: '中',
+  4: '小',
+};
+
 export interface IProjectGlj {
   ID: string;
   gljID: string; // 工料机ID
   code: string; // 编码
   originalCode: string; // 原始的编码
   name: string; // 名称
-  supply: supplyType; // 供货方式
+  supply: SupplyType; // 供货方式
   supplyQuantity?: number; // 甲供数量
   delivery?: string; // 交货方式
   deliveryAddress?: string; // 送达地点
@@ -186,7 +226,7 @@ export interface IProjectGlj {
   qualityGrade?: string; // 质量等级
   brand?: string; // 品牌
   priceFrom?: string; // 价格来源
-  from: fromType; // std, cpt  来自标准工料机库、补充工料机库
+  from: FromType; // std, cpt  来自标准工料机库、补充工料机库
 }
 
 export interface IProjectGljs {
@@ -195,40 +235,49 @@ export interface IProjectGljs {
 }
 
 /* 标准人材机相关 ↓ */
+// 标准人材机库
+export interface IStdGljLib {
+  dispName: string;
+  compilationId: string;
+  compilationName: string;
+  ID: number;
+  rationLibs: [{ dispName: string; ID: number }];
+}
+
 // 标准、补充人材机共用属性(原始数据)
 export interface IBaseRationGlj {
   code: string;
   name: string;
   specs?: string;
   basePrice: number;
-  priceProperty: any; // 多单价的情况
-  gljClass: number;
-  model: number; // 机型
+  priceProperty?: any; // 多单价的情况
+  model?: number; // 机型
   shortName: string;
   unit: string;
-  adjCoe: number;
-  materialType: MaterialType; // 三材类别
-  materialCoe: number; // 三材系数
+  adjCoe?: number;
+  materialType?: MaterialType; // 三材类别
+  materialCoe?: number; // 三材系数
   // 经济指标数据
-  materialIndexType: string; // 工料指标类别
-  materialIndexUnit: string; // 工料指标单位
-  materialIndexCoe: number; // 单位转换系数
-  taxRate: string; // 税率
+  materialIndexType?: string; // 工料指标类别
+  materialIndexUnit?: string; // 工料指标单位
+  materialIndexCoe?: number; // 单位转换系数
+  taxRate?: string; // 税率
 }
 
-// 标准人材机组成物
-export interface IStdComponent {
-  ID: number;
+// 人材机组成物
+export interface ILibComponent {
+  ID: number | string; // 可为补充、标准
   consumeAmt: number;
-  consumeAmtProperty: any; // 多消耗量的情况
+  consumeAmtProperty?: any; // 多消耗量的情况
 }
 
 // 标准人材机(原始数据)
 export interface IRawStdGlj extends IBaseRationGlj {
   ID: number;
   repositoryId: number;
+  gljClass: number;
   gljType: number;
-  component: IStdComponent[];
+  component: ILibComponent[];
 }
 
 // 标准人材机
@@ -236,8 +285,9 @@ export interface IStdGlj extends IBaseRationGlj {
   ID: number;
   repositoryID: number;
   type: number;
-  components: IStdComponent[];
-  from: fromType;
+  gljClass: number;
+  components: ILibComponent[];
+  from: FromType;
 }
 
 // 标准人材机分类树(原始数据)
@@ -253,26 +303,79 @@ export interface IRawStdGljTree {
 export interface IStdGljTree extends ITreeScm {
   repositoryID: number;
   name: string;
-  from: fromType;
+  from: FromType;
 }
 /* 标准人材机相关 ↑ */
 
 /* 补充人材机相关 ↓ */
-export interface ICptComponent {
-  ID: string; // 补充的ID改成了UUID ,标准的不变,但是这里
-  consumeAmt: number;
-  consumeAmtProperty: any; // 多消耗量的情况
-  from: fromType;
+
+// 补充人材机分类树-模板(后台设置)
+export interface IRawCptGljTreeTemplate {
+  compilationId: string;
+  Name: string;
+  ID: number;
+  ParentID: number;
+  NextSiblingID: number;
+}
+
+// 补充人材机分类树
+export interface ICptGljTree extends ITreeScm {
+  name: string;
+  from: FromType;
+}
+
+// 补充人材机分类树容器
+export interface ICptGljTreeData {
+  compilationID: string;
+  ownerID: string; // 企业或用户
+  treeData: ICptGljTree[];
 }
 
+// 补充人材机组成物
+export interface ICptComponent extends ILibComponent {
+  from: FromType;
+}
+
+// 补充人材机组成物的组合数据(增加一些字段用于显示)
+export interface ICptDisplayComponent extends ICptComponent {
+  code: string;
+  name: string;
+  unit: string;
+  basePrice: number;
+}
+
+// 补充人材机
 export interface ICptGlj extends IBaseRationGlj {
   ID: string;
   ownerID: string;
   type: number;
+  gljClass: string;
   compilationID: string;
   components: ICptComponent[];
-  from: fromType;
+  displayComponents?: ICptDisplayComponent[];
+  from: FromType;
+}
+
+// 新增补充人材机接口传输的数据接口
+export interface IInsertCptGlj {
+  ID: string;
+  gljClass: string;
+  code: string;
+  name: string;
+  unit: string;
+  specs?: string;
+  type: number;
+  basePrice: number;
+  model?: number;
+}
+
+// 准备组成物返回数据接口
+export interface IPrepareComponentResult {
+  displayComponents: ICptDisplayComponent[];
+  allowComponent: boolean;
 }
+
+// 补充人材机
 /* 补充人材机相关 ↑ */
 
 /* 选择人材机相关 ↓ */
@@ -282,16 +385,22 @@ export interface ISelectGljLibItem {
   repositoryID: number | string;
   key: string; // 与gljLibID拼接的形成的唯一值
   isPrior: boolean; // 优先的
-  from: fromType;
+  from: FromType;
   located?: boolean; // 定位到的库(替换时需要)
 }
 
+export interface IAddComponentOption {
+  type: GljType;
+  gljID?: number | string;
+}
+
 // 获取人材机分页数据接口选项
 export interface IGetPagingGljOptions {
-  classList?: number[]; // 需要匹配的分类
+  classList?: (number | string)[]; // 需要匹配的分类
   typeList?: GljType[]; // 需要匹配的人材机类型
   libID?: number | string; // 人材机库ID
   replaceGlj?: IBaseGlj; // 替换的人材机
+  addComponent?: IAddComponentOption; // 添加组成物时的参数
   located?: boolean; // 是否需要定位(打开替换窗口时)
   limit?: number; // 分页数量
   gtCode?: string; // 分页排序$gt code
@@ -301,10 +410,43 @@ export interface IGetPagingGljOptions {
 // 选择人材机接口返回数据格式
 export interface ISelectGljResult {
   libData: ISelectGljLibItem[]; // 库下拉项
-  treeData: IStdGljTree[]; // 人材机分类树
+  treeData: (IStdGljTree | ICptGljTree)[]; // 人材机分类树
   gljData: (IStdGlj | ICptGlj)[]; // 人材机数据
   total: number; // 当前数据总数量
   locatedGlj?: IStdGlj | ICptGlj; // 需要定位到的人材机
 }
 
 /* 选择人材机相关 ↑ */
+
+// 补充定额库中,需要显示用的补充定额人材机
+export interface ICptDisplayRationGlj {
+  ID: string | number; // 人材机ID(标准为number,补充为string)
+  code: string;
+  name: string;
+  unit: string;
+  specs?: string;
+  basePrice: number;
+  consumeAmt: number;
+  from: FromType;
+  type: GljType;
+}
+
+// 重算补充定额价格需要的人材机类型
+export interface IGljForCalcRationPrice {
+  basePrice: number;
+  consumeAmt: number;
+  type: GljType;
+  [props: string]: any;
+}
+
+// 价格变更人材机
+export interface IPriceChangeGlj {
+  ID: string;
+  basePrice: number;
+}
+
+// 添加组成物filter类型
+export interface IAddComponentFilter {
+  projectGljID: string;
+  libGljs: (IStdGlj | ICptGlj)[];
+}

+ 1 - 1
types/src/interface/index.ts

@@ -17,5 +17,5 @@ export * from './quantityDetail';
 export * from './report';
 export * from './configMaterial';
 export * from './socket';
-export * from './error';
 export * from './enterprise';
+export * from './infoPrice';

+ 51 - 0
types/src/interface/infoPrice.ts

@@ -0,0 +1,51 @@
+export interface IArea {
+  serialNo: number;
+  ID: string;
+  compilationID: string;
+  name: string;
+}
+
+export interface IInfoLib {
+  ID: string;
+  name: string;
+  period: string; // 期数 eg: 2020年-05月
+  compilationID: string;
+  createDate: number;
+}
+
+export interface IInfoSearch {
+  areaID: string;
+  period: string;
+  keyword: string;
+  classTree: boolean;
+  classID?: string; // 所属分类
+  code?: string; // 编码
+  commonAreaID?: string; // 通用地区ID
+}
+
+export interface IAreaClass {
+  ID: string;
+  parentID: string;
+  seq: number;
+  name: string;
+  areaID: string;
+  libID: string;
+}
+
+export interface IInfoPriceItem {
+  ID: string;
+  libID: string;
+  classID: string; // 分类
+  code: string;
+  name: string;
+  specs: string;
+  unit: string;
+  taxPrice: string; // 含税价格
+  noTaxPrice: string; // 不含税价格
+  // 以下冗余数据为方便前台信息价功能处理
+  period: string; // 期数 eg: 2020-05
+  areaID: string; // 地区
+  compilationID: string; // 费用定额
+  remark: string;
+  matchString?: string; // 临时变量关键词匹配时用到
+}

+ 35 - 3
types/src/interface/project.ts

@@ -26,7 +26,7 @@ export interface IGLJCol {
 
 // 小数位数
 export interface IDecimal {
-  bills: { unitPrice: number; totalPrice: number };
+  bill: { unitPrice: number; totalPrice: number };
   ration: { quantity: number; unitPrice: number; totalPrice: number };
   glj: { quantity: number; unitPriceHasMix: number; unitPrice: number };
   feeRate: number;
@@ -170,6 +170,14 @@ export interface IAreaIncreaseSetting {
   [AreaIncreaseType.MACHINE]: number;
 }
 
+// 关于计算取费方式
+export enum BillGetFeeType {
+  RATION_CONTENT = 0,
+  RATION_PRICE_CONVERSE = 1,
+  RATION_PRICE = 2,
+  BILL_PRICE = 3,
+}
+
 // 项目属性
 export interface IProperty {
   constructionID?: string; // 建设项目ID
@@ -193,7 +201,7 @@ export interface IProperty {
   decimal?: IDecimal; // 小数位数
   billsQuantityDecimal?: IBillsQuantityDecimal[]; // 清单工程量精度
   displaySetting?: IDisplaySetting; // 呈现选项
-  billsCalcMode?: number; // 清单计费取费方式
+  billsCalcMode?: BillGetFeeType; // 清单计费取费方式
   zanguCalcMode?: number; // 暂估合价计算方式
   calcOption?: ICalcOption; // 计算选项
   tenderSetting?: ITenderSetting; // 调价设置
@@ -209,6 +217,7 @@ export interface IProperty {
   materials?: IMaterialIndex[];
   mainQuantities?: IMainQtyIndex[];
   economics?: IEconomicIndex[];
+  overHeightSpecificID?: string; // 超高子目指定清单ID
 }
 
 // 原来的列设置太复杂了,没什么必要
@@ -226,13 +235,36 @@ export enum ImportType {
   INTERFACE,
 }
 
+// 项目活动枚举
+export enum ProjectActivity {
+  // 新建
+  CREATE = 'create',
+  // 查看
+  CHECK = 'check',
+  // 编辑
+  EDIT = 'edit',
+  // 删除
+  DELETE = 'delete',
+  // 恢复
+  RECOVER = 'recover',
+}
+
+// 项目活动
+export interface IProjectActivity {
+  activity: ProjectActivity;
+  userID: string;
+}
+
 export interface IProject extends ITreeScm {
   type: ProjectType;
   compilationID: string;
-  ownerID: string;
+  ownerID: string; // 拥有者ID(个人或企业)
   ownerType: EntityType;
+  managerID: string; // 负责人ID
   creator: string;
   name: string;
+  updateDate: number; // 更新时间
+  activities: IProjectActivity[]; // 活动
   code?: string;
   createDate: number;
   property?: IProperty;

+ 167 - 67
types/src/interface/ration.ts

@@ -1,13 +1,21 @@
 /* eslint-disable camelcase */
 import {
-  prefix,
-  fromType,
-  gljCreateType,
-  createLocation,
+  RationPrefix,
+  FromType,
+  GljCreateType,
+  CreateLocation,
   BRType,
+  IBRBase,
+  ITreeScm,
 } from './base';
 import { IBookmark } from './bill';
-import { GljType, ICptGlj, IStdGlj, MaterialType } from './glj';
+import {
+  GljType,
+  ICptDisplayRationGlj,
+  ICptGlj,
+  IStdGlj,
+  MaterialType,
+} from './glj';
 import { IQuantityDetail } from './quantityDetail';
 
 // 标准定额库
@@ -46,7 +54,7 @@ export interface ICptRationChapter {
 export interface IBaseRationGljRef {
   consumeAmt: number;
   proportion?: number; // 配合比,暂时无需使用,默认0
-  type?: fromType; // 可能有数据没有
+  from?: FromType; // 可能有数据没有
 }
 
 export interface IStdRationGljRef extends IBaseRationGljRef {
@@ -54,20 +62,30 @@ export interface IStdRationGljRef extends IBaseRationGljRef {
 }
 
 export interface ICptRationGljRef extends IBaseRationGljRef {
-  gljId: string; // 原std库已经是这样,不能改成ID
+  gljId: string | number; // 原std库已经是这样,不能改成ID
 }
-export interface IStdRationAss {
-  name: string;
-  assistCode: string;
-  stdValue: string;
-  stepValue: string;
-  decimal: number;
-  carryBit: string;
-  minValue: string;
-  maxValue: string;
-  paramName: string; // 参数名称
-  param: string; // 参数
-  thirdRationCode: string; // 第三定额
+
+// 基准辅助定额
+export interface IBaseRationAss {
+  name: string; // 调整名称
+  assistCode: string; // 辅助定额号
+  stdValue: string; // 标准值
+  stepValue: string; // 步距
+  decimal: number; // 精度
+  carryBit: string; // 进位方式
+  minValue?: string; // 最小值
+  maxValue?: string; // 最大值
+  paramName?: string; // 参数名称
+  param?: string; // 参数
+  thirdRationCode?: string; // 第三定额
+}
+
+// 标准定额辅助
+export type IStdRationAss = IBaseRationAss;
+
+// 补充定额辅助
+export interface ICptRationAss extends IBaseRationAss {
+  ID: string; // 方便录入补充数据
 }
 
 export interface IStdRationInstall {
@@ -81,8 +99,15 @@ export interface IStdRationTemp {
   billsLocation: string;
 }
 
+export interface ILibRationCondition {
+  keyword: string;
+  rationRepIds: (number | string)[];
+  from: FromType;
+  lastCode?: string; // 最后一行的定额编号
+}
+
 export interface ICoeList {
-  ID: number;
+  ID: number | string;
   no: number;
 }
 
@@ -99,10 +124,9 @@ export enum CoeType {
   SELECT = '所选人材机',
 }
 
-export interface IStdCoe {
+export interface IBaseCoe {
   coeType: CoeType; // 系数类型,指作用范围:
   // 单个(如:111量0.001)、人工类、材料类、机械类、全部(如:定额×0.925)。
-  gljID?: number; // 要调整的工料机ID(当coeType=0时有效)
   operator: string; // 运算符(*、+、-、=)
   amount: string; // 调整的量
   gljCode: string;
@@ -111,12 +135,18 @@ export interface IStdCoe {
   replaceName?: string;
 }
 
+export type IStdCoe = IBaseCoe;
+
+export interface ICptCoe extends IBaseCoe {
+  ID: string;
+}
+
 export interface IBaseCoeItem {
-  ID: number;
+  ID: number | string;
   serialNo?: number; // 编号
   name: string; // 名称
   content?: string; // 说明
-  coes: IStdCoe[];
+  coes: IBaseCoe[];
 }
 
 export interface IOptionList {
@@ -124,15 +154,19 @@ export interface IOptionList {
   value: string;
 }
 export interface ICptCoeItem extends IBaseCoeItem {
-  userID: string;
+  ID: string;
+  ownerID: string;
   compilationID: string;
+  coes: ICptCoe[];
 }
 
 export interface IStdCoeItem extends IBaseCoeItem {
+  ID: number;
   libID: number; // 所属定额定ID
   original_code?: string; // 原人材机编码
   option_codes?: string; // 可选人材机编码
   option_list?: IOptionList[]; // 下拉列表选项
+  coes: IStdCoe[];
 }
 
 export interface IRationCoe {
@@ -150,38 +184,39 @@ export interface IRationCoe {
 
 export interface IBaseRation {
   code: string;
-  name: string;
-  unit: string;
+  name?: string;
+  unit?: string;
   basePrice: number;
   labourPrice: number;
   materialPrice: number;
   machinePrice: number;
-  caption: string;
-  feeType: number;
-  jobContent: string;
-  annotation: string;
-  manageFeeRate: string; // 管理费费率
-  rationCoeList: ICoeList[];
-  rationAssList: IStdRationAss[];
-  rationInstList: IStdRationInstall[];
-  rationTemplateList: IStdRationTemp[];
-  fromType?: fromType; // 单条查找结果时用到
+  caption?: string;
+  feeType?: number;
+  jobContent?: string;
+  annotation?: string;
+  manageFeeRate?: string; // 管理费费率
+  rationCoeList?: ICoeList[];
+  rationAssList?: IBaseRationAss[];
+  rationInstList?: IStdRationInstall[];
+  rationTemplateList?: IStdRationTemp[];
+  from?: FromType; // 单条查找结果时用到
 }
 export interface IStdRation extends IBaseRation {
   ID: number;
   rationRepId: number;
   sectionId: number;
   rationGljList: IStdRationGljRef[];
-
+  rationAssList?: IStdRationAss[];
   chapter?: IStdRationChapter;
 }
 
 export interface ICptRation extends IBaseRation {
-  userID: string;
+  ownerID: string;
   compilationID: string;
   ID: string;
   sectionId: string;
   rationGljList: ICptRationGljRef[];
+  rationAssList: ICptRationAss[];
   chapter?: ICptRationChapter;
 }
 
@@ -189,7 +224,7 @@ export interface ICptRation extends IBaseRation {
 export interface IRationGlj {
   ID: string;
   gljID?: string;
-  repositoryID?: number;
+  repositoryID: number | string;
   name: string;
   code: string;
   originalCode: string; // 原始的编码 不带 “-”的
@@ -203,8 +238,8 @@ export interface IRationGlj {
   customQuantity?: number;
   rationQuantity?: number;
   tenderQuantity?: number; // 调整后消耗量
-  createType: gljCreateType; // normal、add、replace  正常、添加工料机、替换工料机
-  from: fromType; // std, cpt  来自标准工料机库、补充工料机库
+  createType: GljCreateType; // normal、add、replace  正常、添加工料机、替换工料机
+  from: FromType; // std, cpt  来自标准工料机库、补充工料机库
 }
 
 export interface IGljQtyCoe {
@@ -216,7 +251,7 @@ export interface IGljQtyCoe {
 }
 
 // 实际保存到项目中的辅助定额数据
-export interface IRationAss extends IStdRationAss {
+export interface IRationAss extends IBaseRationAss {
   ID: string;
   actualValue?: number;
   isAdjust: boolean; // 是否调整
@@ -239,7 +274,7 @@ export interface ITemplateItem {
   billID?: string; // 记取位置对应的清单ID
 }
 export interface IRationTemplate {
-  createLocation: createLocation; // 提取位置
+  createLocation: CreateLocation; // 提取位置
   templateList: ITemplateItem[];
 }
 
@@ -258,32 +293,19 @@ export interface IThirdRation {
   rationGljList: IRationGlj[];
 }
 
-export interface IRation {
-  ID: string;
-  parentID: string;
-  seq: number;
-  kind: BRType;
-  code?: string;
-  name?: string;
-  unit?: string;
+export interface IRation extends IBRBase {
   type?: GljType; // 子类型:1人工、201材料、301机械、4主材、5设备
-  quantity?: number;
   contain?: number; // 含量
-  quantityEXP?: string; // 工程量表达式
   programID?: number;
-  fees?: any; // 费用字段
-  gljQtyCoe?: IGljQtyCoe; // 工料机消耗量调整系数字段
-  rationQtyCoe?: number; // 子目工程量调整系数
   tenderQuantity?: string; // 调整后工程量
   noAdjustPrice?: boolean; // { type: boolean; default: false }; // 不调价
-  targetUnitFee?: string; // 目标单价
+  targetUnitPrice?: string; // 目标单价
   targetTotalFee?: string; // 目标合价
-  from?: fromType; // { type: string; default: 'std' }; // std, cpt  来自标准、补充
+  from?: FromType; // { type: string; default: 'std' }; // std, cpt  来自标准、补充
   isSubcontract?: boolean; // 是否分包
   installationKey?: string; // 用来记录安装增加费的关联字段
-  // 定额特有属性:
-  stdID?: string; // 来自的标准定额ID
-  repositoryID?: number; // 定额库ID
+  repositoryID?: number | string; // 定额库ID
+  sectionID?: number | string; // 章节ID用来定位
   maskName?: string;
   caption?: string;
   evaluationProject?: boolean; // { type: boolean; default: false }; // 1 true 0 false 估价项目
@@ -292,7 +314,7 @@ export interface IRation {
   content?: string; // 工作内容
   annotation?: string; // 附注
   ruleText?: string; // 计算规则
-  prefix?: prefix; // { type: string; default: '' }; // 定额是补充、借用时用  补 借
+  prefix?: RationPrefix; // { type: string; default: '' }; // 定额是补充、借用时用  补 借
   referenceRationID?: string; // 如果是通过模板关联子目生成的定额,这里记录对应的主定额ID
   jobContentText?: string; // 工作内容 (选择自清单)
   manageFeeRate?: string; // 管理费率
@@ -306,8 +328,6 @@ export interface IRation {
   model?: number; // 机型
   adjCoe?: number;
   remark?: string; // 备注
-  bookmarkBackground?: string; // 书签背景色
-  bookmarkAnnotation?: string; // 批注
   overHeight?: string; // 超高降效
   referenceRationList?: any; // { type: Array; default: [] }; // 关联的定额ID列表,如超高子目关联的定额ID列表
   // 定额子项
@@ -318,7 +338,6 @@ export interface IRation {
   rationCoeList?: IRationCoe[]; // 定额调整系数
   rationTemplate?: IRationTemplate; // 定额模板
   rationInstallList?: IRationInstall[]; // 定额安装增加
-  bookmarks?: IBookmark[];
 }
 
 export interface IRations {
@@ -327,7 +346,8 @@ export interface IRations {
   rations: IRation[];
 }
 
-export interface IStdRationsAndGljs {
+export interface ILibRationsAndGljsResult {
+  total: number;
   rations: (IStdRation | ICptRation)[];
   rationGljs: (IStdGlj | ICptGlj)[];
 }
@@ -337,3 +357,83 @@ export enum RationListType {
   COE = 'rationCoeList',
   GLJ = 'rationGljList',
 }
+
+// 补充定额章节树-模板(后台设置)
+export interface ICptRationTreeTemplate {
+  compilationId: string;
+  name: string;
+  ID: number;
+  ParentID: number;
+  NextSiblingID: number;
+}
+
+// 补充定额章节树
+export interface ICptRationTree extends ITreeScm {
+  name: string;
+  // 以下预留数据,以后开放可用
+  explanation?: string; // 说明
+  ruleText?: string; // 计算规则,
+  jobContentSituation?: string; // 工作内容适用情况,ALL适用本项全部定额,PARTIAL适用本项部分定额
+  annotationSituation?: string; // 附注适用情况,ALL适用本项全部定额,PARTIAL适用本项部分定额
+}
+
+// 补充定额章节树容器
+export interface ICptRationTreeData {
+  compilationID: string;
+  ownerID: string; // 企业或用户
+  treeData: ICptRationTree[];
+}
+
+// 新增补充定额接口传输的数据接口
+export interface IInsertCptRation {
+  ID: string;
+  sectionId: string;
+  code: string;
+  name?: string;
+  unit?: string;
+  caption?: string;
+  feeType?: number;
+  labourPrice: number;
+  materialPrice: number;
+  machinePrice: number;
+  basePrice: number;
+}
+
+// 更新补充定额人材机的请求数据
+export interface IUpdateCptRationGlj {
+  ID?: string | number; // 人材机ID
+  code?: string;
+  consumeAmt?: number;
+  from?: FromType;
+}
+
+// 更新补充定额人材机的返回更新数据
+export interface IUpdateCptRationGljResult {
+  labourPrice: number;
+  materialPrice: number;
+  machinePrice: number;
+  basePrice: number;
+  rationGljList: ICptRationGljRef[];
+  displayRationGljList: ICptDisplayRationGlj[];
+}
+
+// 新增补充子目换算接口传输的数据接口
+export interface IInsertCptCoe {
+  ID: string;
+  name?: string;
+  content?: string;
+}
+
+// 新增补充定额子目换算调整数据接口
+export interface IInsertCptRationCoe {
+  serialNo: number; // 编号
+  no: number; // 排序
+}
+
+export interface ICptDisplayRationCoe {
+  ID: string;
+  serialNo: number; // 编号
+  no: number; // 排序
+  name?: string;
+  content?: string;
+}

+ 30 - 0
types/src/interface/report.ts

@@ -1,3 +1,8 @@
+
+export interface ReportFlags{
+   constructSumType?: string | null, taxType?: string | null, auditType?: string | null 
+}
+
 export interface ReportSubTree {
   nodeType: number;
   refId: number;
@@ -5,6 +10,8 @@ export interface ReportSubTree {
   ID: number;
   released: boolean;
   items: ReportSubTree[] | null;
+  flags?:ReportFlags;
+
 }
 export interface ReportTree {
   compilationId: string;
@@ -13,4 +20,27 @@ export interface ReportTree {
   isDeleted: boolean;
   name: string;
   items: ReportSubTree[] | null;
+  flags?: { constructSumType?: string | null, taxType?: string | null, auditType?: string | null };
+}
+
+
+//汇总项目信息
+export interface Summary {
+  compilationIllustration: string;
+  name: string;
+}
+// 汇总项目明细
+export interface SummaryDetail {
+  buildingArea: string;
+  charge: number;
+  engineeringCost: number;
+  estimate: number;
+  measure: number;
+  name: string;
+  other: number;
+  perCost: string;
+  rate: number;
+  safetyConstruction: number;
+  subEngineering: number;
+  tax: number;
 }

+ 46 - 89
types/src/interface/user.ts

@@ -1,16 +1,4 @@
-import { ICompilation } from './compilation';
-
-/* eslint-disable camelcase */
-export enum ELockInfo {
-  BORROW = 1, // 借用
-  BUY = 2, // 销售
-}
-
-export interface IUpgradeItemInfo {
-  compilationID: string;
-  isUpgrade: boolean;
-  lock?: ELockInfo;
-}
+import { IProCptItem } from './compilation';
 
 // 实体类型
 export enum EntityType {
@@ -26,99 +14,68 @@ export enum LoginType {
   ENTERPRISE = 'enterprise',
 }
 
+// 登录方式(使用密码还是短信进行登录,与登录类型是不同概念)
+export enum LoginMode {
+  PASSWORD = 'password',
+  SMS = 'sms',
+}
+
 export enum UserType {
   NORMAL = 'normal',
   PROFESSIONAL = 'professional',
 }
 
-export interface IContact {
-  userID: string;
+export interface IUsedCptItem {
+  // 编办 ID
+  compilationID: string;
+  // 第一次使用的时间
+  firstUseTime: number;
 }
 
-export interface IUsed {
-  compilationId: string;
+export interface IContactItem {
+  // 用户 ID
+  userID: string;
+  // 第一成为联系人的时间
+  firstContactTime: number;
 }
 
-export interface ISpecifyCptItem {
-  accountType: string;
-  enterpriseID?: string;
-  cptID: string;
+export interface IEverydayOnlineTimeItem {
+  // 日期
+  date: number;
+  // 在线时长
+  onlineTime: number;
 }
 
-// user 表原始字段
-export interface IRawUser {
-  enterpriseID?: string;
-  _id?: string;
-  qq?: string;
-  real_name?: string;
-  avatar?: string;
-  // 职位
-  position?: string;
-  company?: string;
-  province?: number;
-  company_type?: number;
-  company_scale?: number;
-  // 指定的编办
-  specifyCpt?: string;
-  latest_login?: number;
-  user_type?: string;
-  contacts?: IContact[];
-  isSmsLogin?: number;
-  isLoginValid?: number;
-  ssoId?: string;
-  email?: string;
-  mobile?: string;
-  create_time?: string;
-  isUserActive?: number;
-  upgrade_list?: IUpgradeItemInfo[];
-  used_list?: IUsed[];
-  latest_used?: string;
+export interface ISummary {
+  // 最后登录时间
+  lastLoginTime: number;
+  // 上次使用的编办
+  lastUsedCpt: string;
+  // 总共在线时长
+  totalOnlineTime: number;
+  // 今天目前的在线时长
+  todayOnlineTime: number;
+  // 每天的在线时长
+  everydayOnlineTime: IEverydayOnlineTimeItem[];
 }
 
-// 返回给前端的字段
 export interface IUser {
-  ID?: string;
-  qq?: string;
-  realName?: string;
-  avatar?: string;
-  // 职位
-  position?: string;
-  // 公司名
-  companyName?: string;
-  // 省(个人账户只需要精确到省)
-  companyLocation?: number;
-  // 公司类型
-  companyType?: number;
-  companyScale?: number;
-  // 指定的编办
-  specifyCpt?: string;
-  latestLogin?: number;
-  userType?: string;
-  contacts?: IContact[];
-  isSmsLogin?: number;
-  isLoginValid?: number;
-  ssoID?: string;
-  email?: string;
-  mobile?: string;
-  createTime?: string;
-  isUserActive?: number;
-  upgradeList?: IUpgradeItemInfo[];
-  usedList?: IUsed[];
-  latestUsed?: string;
+  ID: string;
+  ssoID: string;
+  mobile: string;
+  realName: string;
+  createTime: number;
+  proCptList: IProCptItem[];
+  usedCptList: IUsedCptItem[];
+  specifyCpt: string;
+  contacts: IContactItem[];
+  onlySMSLogin: boolean;
+  abnormalLoginAlert: boolean;
+  defaultEnterprise: string;
+  summaryInfo: ISummary;
 }
 
 // 最近联系人
 export interface IRecentUser extends IUser {
   recentDate: number;
 }
-
-export interface IBootResult {
-  compilation: ICompilation;
-  complete: boolean;
-}
-
-export interface ILoginResult {
-  userID: string;
-  userInfo: IUser;
-  cptList: ICompilation;
-}

+ 5 - 0
util/README.md

@@ -1,7 +1,12 @@
 ### 开始
+所有项目通用的工具包
 
+## math
 统一 4 舍 5 入算法,防止浮点数计算不精确问题。
 
+## reg
+常用的正则表达式
+
 ### 初始化
 
 npm install

+ 3 - 3
util/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@sc/util",
-  "version": "1.0.3",
-  "description": "用的工具包",
+  "version": "1.0.7",
+  "description": "用的工具包",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",
   "browser": "./dist/index.min.js",
@@ -22,9 +22,9 @@
     "@commitlint/config-conventional": "^11.0.0",
     "@sc/types": "^1.0.28",
     "@types/chai": "^4.2.14",
+    "@types/lodash": "^4.14.168",
     "@types/mocha": "^8.0.4",
     "@types/ms": "^0.7.31",
-    "@types/lodash": "^4.14.168",
     "@typescript-eslint/eslint-plugin": "^4.4.1",
     "@typescript-eslint/parser": "^4.4.1",
     "chai": "^4.2.0",

+ 1 - 2
util/src/index.ts

@@ -1,3 +1,2 @@
 export * from './math';
-export * from './bill';
-export * from './rationAss';
+export * from './reg';

+ 53 - 0
util/src/reg.ts

@@ -0,0 +1,53 @@
+// 效验电话
+export const phoneReg = /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/;
+
+// 效验qq
+export const qqReg = /^[1-9][0-9]{4,10}$/;
+
+// 效验微信号
+export const wechatReg = /^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$/;
+
+// 效验邮箱
+export const emailReg = /^([A-Za-z0-9_\-.])+@([A-Za-z0-9_\-.])+\.([A-Za-z]{2,4})$/;
+
+// 效验手机号码
+export const mobileReg = /^1\d{10}$/;
+
+// 短信验证码
+export const smsCodeReg = /^\d{6}$/;
+
+// 弱密码
+export const weakPasswordReg = /^\S{6,16}$/;
+
+// 效验身份证
+export const idCardReg = /^[1-9]\d{5}(18|19|([23]\d))\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
+
+// 效验url
+export const urlReg = /^((https?|ftp|file):\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
+
+// 效验Ipv4
+export const ipv4Reg = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
+
+// 效验十六进制颜色正则
+export const rgbReg = /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/;
+
+// 只能输入字母、下划线,且字母开头结尾,不能__两个下划线相连
+export const letterAndUnderlineReg = /^[A-Za-z]([A-Za-z]|_[A-Za-z])*$/;
+
+// 正整数
+export const positiveIntegerReg = /^[1-9]\d*$/;
+
+// 整数
+export const integerReg = /^-?[1-9]\d*$/;
+
+// 数字
+export const numberReg = /^(-?\d+)(\.\d*)?$/;
+
+// 中文姓名
+export const chineseNameReg = /^[\u4e00-\u9fa5]+[·-]?[\u4e00-\u9fa5]+$/;
+
+// md5
+export const md5Reg = /^[a-f\d]{32}|[A-F\d]{32}$/;
+
+// 公司名称
+export const companyNameReg = /^[\u4e00-\u9fa5()()\da-zA-Z&]{2,}$/;

+ 1 - 1
util/tests/test.ts

@@ -1,5 +1,5 @@
 import { expect } from 'chai';
-import { isNumber, roundForObj, roundToString } from '../src/index';
+import { isNumber, roundForObj, roundToString } from '../src';
 
 describe('Test', () => {
   it('test number', () => {

+ 1 - 0
wise-cost-util/.eslintignore

@@ -0,0 +1 @@
+/dist

+ 41 - 0
wise-cost-util/.eslintrc.js

@@ -0,0 +1,41 @@
+module.exports = {
+  env: {
+    browser: true,
+    es2021: true,
+    node: true,
+  },
+  extends: ['airbnb-base', 'plugin:@typescript-eslint/recommended', 'prettier'],
+  parser: '@typescript-eslint/parser',
+  parserOptions: {
+    ecmaVersion: 12,
+    sourceType: 'module',
+  },
+  plugins: ['@typescript-eslint', 'prettier'],
+  rules: {
+    'prettier/prettier': 'error',
+    'import/extensions': [
+      'error',
+      {
+        js: 'never',
+        jsx: 'never',
+        ts: 'never',
+        tsx: 'never',
+        json: 'always',
+      },
+    ],
+    'import/no-unresolved': 'off',
+    '@typescript-eslint/no-empty-function': 'off',
+    '@typescript-eslint/no-explicit-any': 'off',
+    '@typescript-eslint/explicit-module-boundary-types': 'off',
+    'no-unused-expressions': [
+      'error',
+      {
+        allowShortCircuit: true,
+      },
+    ],
+    'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
+    'no-restricted-syntax': 'off',
+    'no-shadow': 'off',
+    '@typescript-eslint/no-shadow': 'error',
+  },
+};

+ 22 - 0
wise-cost-util/.gitignore

@@ -0,0 +1,22 @@
+.DS_Store
+node_modules
+dist
+
+# local env files
+.env.local
+.env.*.local
+
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?

+ 6 - 0
wise-cost-util/.huskyrc.js

@@ -0,0 +1,6 @@
+module.exports = {
+  hooks: {
+    'pre-commit': 'lint-staged',
+    'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS',
+  },
+};

+ 21 - 0
wise-cost-util/README.md

@@ -0,0 +1,21 @@
+### 开始
+
+wise-cost项目前后端业务通用工具包
+
+### 初始化
+
+npm install
+
+### 构建
+
+npm run build
+
+### 代码风格
+
+ESLint + Airbnb config
+
+### 发布
+
+发布
+
+`npm publish`

+ 29 - 0
wise-cost-util/commitlint.config.js

@@ -0,0 +1,29 @@
+module.exports = {
+  ignores: [commit => commit.includes('init')],
+  extends: ['@commitlint/config-conventional'],
+  rules: {
+    'body-leading-blank': [2, 'always'],
+    'footer-leading-blank': [1, 'always'],
+    'header-max-length': [2, 'always', 108],
+    'subject-empty': [2, 'never'],
+    'type-empty': [2, 'never'],
+    'type-enum': [
+      2,
+      'always',
+      [
+        'feat', // 新增功能、变更需求
+        'fix', // 修复bug
+        'perf', // 优化性能
+        'refactor', // 代码重构
+        'style', // 代码格式(不影响功能,例如空格、分号等格式修正)
+        'docs', // 文档变更
+        'test', // 测试
+        'ci', // 更改持续集成软件的配置文件和package中的scripts命令,例如scopes: Travis, Circle等
+        'chore', // 变更构建流程或辅助工具(依赖更新/脚手架配置修改/webpack、gulp、npm等)
+        'revert', // 代码回退
+        'types', // ts类型定义文件更改
+        'wip', // work in process开发中
+      ],
+    ],
+  },
+};

+ 9 - 0
wise-cost-util/lint-staged.config.js

@@ -0,0 +1,9 @@
+module.exports = {
+  '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'],
+  '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': [
+    'prettier --write--parser json',
+  ],
+  'package.json': ['prettier --write'],
+  '*.vue': ['prettier --write'],
+  '*.md': ['prettier --write'],
+};

+ 54 - 0
wise-cost-util/package.json

@@ -0,0 +1,54 @@
+{
+  "name": "@sc/wise-cost-util",
+  "version": "1.0.2",
+  "description": "wise-cost项目前后端业务通用工具包",
+  "main": "./dist/index.cjs.js",
+  "module": "./dist/index.esm.js",
+  "browser": "./dist/index.min.js",
+  "types": "./dist/index.d.ts",
+  "files": [
+    "dist",
+    "README.md"
+  ],
+  "scripts": {
+    "test": "cross-env TS_NODE_COMPILER_OPTIONS={\\\"module\\\":\\\"commonjs\\\"} mocha -r ts-node/register 'tests/**/*.ts'",
+    "build": "rollup -c"
+  },
+  "keywords": [],
+  "author": "smartcost",
+  "license": "ISC",
+  "devDependencies": {
+    "@commitlint/cli": "^11.0.0",
+    "@commitlint/config-conventional": "^11.0.0",
+    "@sc/types": "^1.0.28",
+    "@types/chai": "^4.2.14",
+    "@types/lodash": "^4.14.168",
+    "@types/mocha": "^8.0.4",
+    "@types/ms": "^0.7.31",
+    "@typescript-eslint/eslint-plugin": "^4.4.1",
+    "@typescript-eslint/parser": "^4.4.1",
+    "chai": "^4.2.0",
+    "cross-env": "^7.0.2",
+    "eslint": "^7.11.0",
+    "eslint-config-airbnb-base": "^14.2.0",
+    "eslint-config-prettier": "^6.12.0",
+    "eslint-plugin-import": "^2.22.1",
+    "eslint-plugin-prettier": "^3.1.4",
+    "husky": "^4.3.0",
+    "lint-staged": "^10.5.0",
+    "mocha": "^8.2.1",
+    "prettier": "^2.1.2",
+    "rollup": "^2.30.0",
+    "rollup-plugin-commonjs": "^10.1.0",
+    "rollup-plugin-node-resolve": "^5.2.0",
+    "rollup-plugin-terser": "^7.0.2",
+    "rollup-plugin-typescript2": "^0.27.3",
+    "ts-node": "^9.0.0",
+    "tslib": "^2.0.3",
+    "typescript": "^4.0.3"
+  },
+  "dependencies": {
+    "@sc/util": "^1.0.7",
+    "lodash": "^4.17.21"
+  }
+}

+ 7 - 0
wise-cost-util/prettier.config.js

@@ -0,0 +1,7 @@
+module.exports = {
+  singleQuote: true, // 单引号
+  trailingComma: 'es5', // 对象末尾以逗号结束
+  arrowParens: 'avoid', // 箭头函数只有一个参数的时候,不使用()
+  endOfLine: 'auto', // CRLF,LF都可以
+  printWidth: 120,
+};

+ 28 - 0
wise-cost-util/rollup.config.js

@@ -0,0 +1,28 @@
+// import resolve from 'rollup-plugin-node-resolve';
+// import commonjs from 'rollup-plugin-commonjs';
+import typescript from 'rollup-plugin-typescript2'; // 一定要是typescript2,如果使用typescript,没法自动生成.d.ts文件
+// import { terser } from 'rollup-plugin-terser';
+import pkg from './package.json';
+
+export default [
+  // UMD for browser
+  /* {
+    input: 'src/index.ts',
+    output: {
+      name: 'howLongUntilLunch',
+      file: pkg.browser,
+      format: 'umd',
+    },
+    plugins: [resolve(), commonjs(), typescript(), terser()], // 浏览器使用的代码文件进行简化
+  }, */
+  // CommonJS for Node and ES module for bundlers build
+  {
+    input: 'src/index.ts',
+    external: ['ms'],
+    plugins: [typescript()],
+    output: [
+      { file: pkg.main, format: 'cjs' },
+      // { file: pkg.module, format: 'es' },
+    ],
+  },
+];

util/src/bill.ts → wise-cost-util/src/bill.ts


+ 31 - 0
wise-cost-util/src/cptLib.ts

@@ -0,0 +1,31 @@
+// 补充库标识
+export const cptLibKey = 'complementaryLib';
+
+/**
+ * 判断库ID是否是补充的库ID
+ * @param libID 库ID
+ */
+export const isCptLib = (libID: number | string): boolean => {
+  return new RegExp(cptLibKey).test(String(libID));
+};
+
+/**
+ * 获取补充人材机库ID,根据拥有者ID、费用定额ID拼接
+ * @param ownerID 拥有者ID
+ * @param compilationID 费用定额ID
+ */
+export const getCptLibID = (ownerID: string, compilationID: string): string => {
+  return `${cptLibKey}@${ownerID}@${compilationID}`;
+};
+
+/**
+ * 从补充人材机库ID中 提取 拥有者、费用定额ID
+ * @param cptLibID 补充库ID
+ */
+export const getInfoFromCptLibID = (cptLibID: number | string): { ownerID: string; compilationID: string } => {
+  const [key, ownerID, compilationID] = String(cptLibID).split('@');
+  if (!key || key !== cptLibKey || !ownerID || !compilationID) {
+    return { ownerID: '', compilationID: '' };
+  }
+  return { ownerID, compilationID };
+};

+ 44 - 0
wise-cost-util/src/glj.ts

@@ -0,0 +1,44 @@
+import { GljType, IBaseGlj, IInfoPriceItem, TaxType } from '@sc/types';
+
+export const getInfoMarketPrice = (info: IInfoPriceItem, taxType: TaxType) => {
+  // 1: 一般计税 2: 简易计税
+  const fieldArray = ['noTaxPrice']; // 一般计税 - 不含税价 || 简易计税 - 含税价
+  if (taxType === TaxType.GENERAL) {
+    fieldArray.push('taxPrice');
+  } else {
+    fieldArray.unshift('taxPrice');
+  }
+  // 一个放后面,一个放前面
+  let infoPrice = (info as any)[fieldArray[0]];
+  if (infoPrice === null || infoPrice === undefined) infoPrice = (info as any)[fieldArray[1]]; // 信息价只有一个价格(含税价/不含税价),则不分计税方式,套用仅有的价格。
+  return parseFloat(infoPrice);
+};
+
+// 返回五大项组成的索引
+export const getIndex = (obj: IBaseGlj, pops = ['code', 'name', 'specs', 'unit', 'type']): string => {
+  let index = '';
+  const arr = [];
+  for (const p of pops) {
+    const tmpK = obj[p] === undefined || obj[p] === null || obj[p] === '' ? 'null' : obj[p];
+    arr.push(tmpK);
+  }
+  index = arr.join('|-|');
+  return index;
+};
+
+// 是否是人工
+export const isLabour = (type: GljType) => {
+  return type === GljType.LABOUR;
+};
+
+// 是否是材料
+export const isMaterial = (type: GljType) => {
+  const rootType = +String(type).charAt(0);
+  return rootType === 2;
+};
+
+// 是否是机械
+export const isMachine = (type: GljType) => {
+  const rootType = +String(type).charAt(0);
+  return rootType === 3;
+};

+ 4 - 0
wise-cost-util/src/index.ts

@@ -0,0 +1,4 @@
+export * from './bill';
+export * from './rationAss';
+export * from './glj';
+export * from './cptLib';

+ 4 - 4
util/src/rationAss.ts

@@ -1,6 +1,6 @@
 import { IRationAss, IThirdRation } from '@sc/types';
 import { ceil, floor, round, sortBy } from 'lodash';
-import { roundForObj } from './math';
+import { roundForObj } from '@sc/util';
 
 export interface IAssTime {
   times: number;
@@ -30,18 +30,18 @@ export const handleMulAss = (rationAssList: IRationAss[]) => {
     // 处理多个辅助定额的情况
     if (ass.groupList && ass.groupList.length > 0) {
       const newAss = { ...ass };
-      const newList = sortBy(ass.groupList, item => parseFloat(item.param)); // 按参数排序
+      const newList = sortBy(ass.groupList, item => parseFloat(item.param || '0')); // 按参数排序
       let pre = 0;
       for (const tem of newList) {
         if (ass.actualValue) {
-          if (ass.actualValue > pre && ass.actualValue <= parseFloat(tem.param)) {
+          if (ass.actualValue > pre && ass.actualValue <= parseFloat(tem.param || '0')) {
             // 落在中间,则用组里的这条定额
             newAss.param = tem.param;
             newAss.paramName = tem.paramName;
             newAss.assistCode = tem.assistCode;
             break;
           }
-          pre = parseFloat(tem.param);
+          pre = parseFloat(tem.param || '0');
         }
       }
       assList.push(newAss);

+ 18 - 0
wise-cost-util/tsconfig.json

@@ -0,0 +1,18 @@
+{
+  "compilerOptions": {
+    "target": "ESNext",
+    "module": "ESNext",
+    "declaration": true,
+    "outDir": "./",
+    "strict": true,
+    "esModuleInterop": true,
+    "moduleResolution": "node",
+  },
+  "include": [
+    "src/**/*.ts",
+  ],
+  "exclude": [
+    "node_modules",
+    "test"
+  ]
+}