Browse Source

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

qinlaiqiao 5 years ago
parent
commit
249d3768f2
63 changed files with 2057 additions and 154 deletions
  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. 3 1
      report/package.json
  23. 2 1
      report/src/core/helper/jpc_helper_area.ts
  24. 1 0
      report/src/core/helper/jpc_helper_common.ts
  25. 1 1
      report/src/core/helper/jpc_helper_field.ts
  26. 1 1
      report/src/core/jpc_cross_tab.ts
  27. 1 1
      report/src/core/jpc_ex.ts
  28. 3 2
      report/src/core/jpc_flow_tab.ts
  29. 1 1
      report/src/core/jpc_rte.ts
  30. 1 0
      report/src/index.ts
  31. 18 23
      report/src/interface/basic.ts
  32. 1 1
      report/src/interface/enum.ts
  33. 6 5
      report/src/interface/projectConstsEnum.ts
  34. 2 0
      report/src/pdfUnit/index.ts
  35. 26 0
      report/src/pdfUnit/rpt_font_util.ts
  36. 492 0
      report/src/pdfUnit/rpt_pdf_util.ts
  37. 1 1
      tree/package.json
  38. 6 0
      tree/src/nodeCtx.ts
  39. 29 8
      types/src/interface/base.ts
  40. 2 13
      types/src/interface/bill.ts
  41. 2 2
      types/src/interface/configMaterial.ts
  42. 7 1
      types/src/interface/error.ts
  43. 35 4
      types/src/interface/glj.ts
  44. 29 18
      types/src/interface/ration.ts
  45. 30 0
      types/src/interface/report.ts
  46. 5 0
      util/README.md
  47. 2 2
      util/package.json
  48. 0 3
      util/src/index.ts
  49. 1 0
      wise-cost-util/.eslintignore
  50. 41 0
      wise-cost-util/.eslintrc.js
  51. 22 0
      wise-cost-util/.gitignore
  52. 6 0
      wise-cost-util/.huskyrc.js
  53. 21 0
      wise-cost-util/README.md
  54. 29 0
      wise-cost-util/commitlint.config.js
  55. 9 0
      wise-cost-util/lint-staged.config.js
  56. 54 0
      wise-cost-util/package.json
  57. 7 0
      wise-cost-util/prettier.config.js
  58. 28 0
      wise-cost-util/rollup.config.js
  59. 0 0
      wise-cost-util/src/bill.ts
  60. 0 0
      wise-cost-util/src/glj.ts
  61. 3 0
      wise-cost-util/src/index.ts
  62. 1 1
      util/src/rationAss.ts
  63. 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"
+  ]
+}

File diff suppressed because it is too large
+ 717 - 59
report/package-lock.json


+ 3 - 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",
@@ -43,6 +43,8 @@
     "typescript": "^4.0.5"
   },
   "dependencies": {
+    "fs": "0.0.1-security",
+    "pdfkit": "^0.12.1",
     "stream": "0.0.2",
     "uuid": "^8.3.0"
   }

+ 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) {

+ 1 - 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';
 

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

@@ -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)) {

+ 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[];

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

@@ -16,7 +16,7 @@ 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 {

+ 3 - 2
report/src/core/jpc_flow_tab.ts

@@ -37,6 +37,7 @@ import {
     INode,
 
 } from '../interface/basic'
+import { IControlProps, IPositionProps } from '../index';
 
 class JpcFlowTabClass {
     isEx: boolean;
@@ -1439,7 +1440,7 @@ function _addPageValue(ValuedIdxLst: number[][][], sortedSequence: number[], grp
 }
 
 function push_cell(pageCellObj: IPageCellObj, cell: INode, cellIdx: number) {
-    let key = cell.area.Left + '_' + cell.area.Right;
+    let key = cell.area.Left; + '_' + cell.area.Right;
     if (!pageCellObj[key]) {
         pageCellObj[key] = [];
     }
@@ -1497,7 +1498,7 @@ function combineAutoHeightCells(prepareObj: IPageAreaObj | {}, page: number, con
             let sameColCells = (prepareObj as IPageAreaObj).pageCellObj[mergeKey]; //左右位置相同的Cell先放在一起,统一处理
             if (sameColCells.length > 1) {
                 //强转格式,此处是强制把本来是字符串的control属性转化为对象,by lish
-                let firstMergeCell: ICell = { ...sameColCells[0].cell, control: {} as IControlSubCollection };
+                let firstMergeCell = { ...sameColCells[0].cell, control: {} as IControlSubCollection }  as ICell;
                 firstMergeCell.style = firstMergeCell.style.slice(0, firstMergeCell.style.indexOf("_AutoHeightMerge")); //首先还原original style
                 //生成原始对象,并且把对象中的control属性转化为对象
                 let orgCtrl = setupControl(firstMergeCell, controls);

+ 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';

+ 18 - 23
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 {
@@ -154,7 +154,15 @@ 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;
@@ -173,21 +181,8 @@ 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;
 }
 
 interface ISimpleJSONPage {
@@ -391,7 +386,7 @@ export interface IOrgBandDetail {
     band_s?:IOrgBandDetail[]
 }
 
-export interface IBandDetail {
+export interface IBandDetail{
     Alignment: number;
     Bottom: number;
     CalculationType: number;
@@ -603,10 +598,10 @@ export interface IRstPage {
 }
 
 export interface IMergeBand {
-    Bottom: number;
-    Left: number;
-    Right: number;
-    Top: number;
+    Bottom:number;
+    Left:number;
+    Right:number;
+    Top:number;
     style?: any;
 }
 //丢失的interface

+ 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 {}

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

@@ -0,0 +1,492 @@
+
+// const pdf = require('pdfkit');
+// const fs = require('fs');
+// import jpcCmnHelper from '../core/helper/jpc_helper_common';
+// const PDF_SCALE = 0.75;
+
+// const DPI = jpcCmnHelper.getScreenDPI()[0] * PDF_SCALE;
+
+// import JV from '../core/jpc_value_define';
+// import { IMergeBand, IPositionProps, IPreviewPage } from '../index';
+// import {  ICell, IControlCollection, IControlSubCollection, IFontCollection, IFontSubCollection, IStyleCollection, IStyles } from '../interface/basic';
+
+// import {getActualFont} from './rpt_font_util';
+
+
+
+// const getNewName=()=>{
+//   return (new Date()).getTime();
+// }
+// // 目前不支持下划线
+
+// export const exportPdfFile=(pageData:IPreviewPage, paperSize:string, fName:string, callback:any) =>{
+//   const offsetX = 10;
+//   const offsetY = 10;
+//   const doc = new pdf({ autoFirstPage: false });
+//   const newName = getNewName();
+//   const stream = doc.pipe(fs.createWriteStream(`${__dirname.slice(0, __dirname.length - 21)}/tmp/${newName}.pdf`));
+//   const pageObj = pageData;
+//   // doc.rect(5,5,1190,890).lineWidth(1).strokeColor('black').stroke();//边框
+//   const paperSizeIdx = JV.PAGES_SIZE_STR.indexOf(paperSize);
+//   const size = JV.PAGES_SIZE[paperSizeIdx];
+
+//   const newPageMergeBand = {...pageObj.MergeBand};
+//   const privateDrawLine=(cell:any, doc:any, style:any, styleBorderDest:string, startP:[string,string], destP:[string,string], mergedBand:any, styles:any, isNeedMergeBand:boolean)=> {
+//     // doc.beginPath();
+//     let destStyle = style;
+//     if (mergedBand) {
+//       if (
+//         isNeedMergeBand &&
+//         mergedBand[styleBorderDest] === cell.area[styleBorderDest]
+//       ) {
+//         destStyle = styles[mergedBand.style.ID];
+//       }
+//     }
+//     // doc.moveTo(cell.area.[startP[0]] + offsetX, cell.area.[startP[1]] + offsetY);
+//     doc.moveTo(
+//       (cell.area[startP[0]] + offsetX) * PDF_SCALE,
+//       (cell.area[startP[1]] + offsetY) * PDF_SCALE
+//     );
+//     if (destStyle[styleBorderDest] && parseFloat(destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]) !== 0) {
+//       doc.lineWidth(1.0 * destStyle[styleBorderDest][JV.PROP_LINE_WEIGHT]);
+//       // doc.lineTo(cell.area.[destP[0]] + offsetX, cell.area.[destP[1]] + offsetY);
+//       doc.lineTo(
+//         (cell.area[destP[0]] + offsetX) * PDF_SCALE,
+//         (cell.area[destP[1]] + offsetY) * PDF_SCALE
+//       );
+//       doc.strokeColor(destStyle[styleBorderDest][JV.PROP_COLOR]);
+//     }
+//     doc.stroke();
+//   }
+//   const privateDrawCell=(cell:ICell, fonts:IFontCollection, styles:IStyleCollection, controls:IControlCollection, mergedBand:IMergeBand)=> {
+//     doc.save();
+//     // doc.translate(0.5,0.5); //跟H5的canvas不同,不需要这样切换
+//     const style = styles[cell.style];
+//     if (style) {
+//       const isNeedMergeBand = privateChkIfInMergedBand(mergedBand, cell);
+//       privateDrawLine(
+//         cell,
+//         doc,
+//         style,
+//         'Top',
+//         ['Left', 'Top'],
+//         ['Right',  'Top'],
+//         mergedBand,
+//         styles,
+//         isNeedMergeBand
+//       );
+//       privateDrawLine(
+//         cell,
+//         doc,
+//         style,
+//         'Right',
+//         ['Right', 'Top'],
+//         ['Right', 'Bottom'],
+//         mergedBand,
+//         styles,
+//         isNeedMergeBand
+//       );
+//       privateDrawLine(
+//         cell,
+//         doc,
+//         style,
+//         'Bottom',
+//         ['Right', 'Bottom'],
+//         ['Left','Bottom'],
+//         mergedBand,
+//         styles,
+//         isNeedMergeBand
+//       );
+//       privateDrawLine(
+//         cell,
+//         doc,
+//         style,
+//         'Left',
+//         ['Left', 'Bottom'],
+//         ['Left',  'Top'],
+//         mergedBand,
+//         styles,
+//         isNeedMergeBand
+//       );
+//     }
+//     privateDrawCellText(cell, fonts, controls);
+//     doc.restore();
+//   }
+
+//   if (pageObj && pageObj.items.length > 0) {
+//     for (let i = 0; i < pageObj.items.length; i++) {
+//       if (pageData.打印页面_信息.纸张宽高[0] > pageData.打印页面_信息.纸张宽高[1]) {
+//         doc.addPage({ size: [size[1] * DPI, size[0] * DPI] });
+//       } else {
+//         doc.addPage({ size: [size[0] * DPI, size[1] * DPI] });
+//       }
+//       const page = pageObj.items[i];
+//       const fonts = pageObj.font_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(cell, fonts, styles, controls, newPageMergeBand);
+//       }
+//     }
+//   }
+//   doc.end();
+//   stream.on('finish', function () {
+//     console.log(`${newName}.pdf was written.`);
+//     callback(newName);
+//   });
+
+//   const privateChkIfInMergedBand=(mergedBand:IMergeBand, cell:ICell)=> {
+//     let rst = false;
+//     if (mergedBand && cell) {
+//       rst =
+//         mergedBand.Top <= cell.area.Top &&
+//         mergedBand.Bottom >= cell.area.Bottom &&
+//         mergedBand.Right <= cell.area.Right &&
+//         mergedBand.Left >= cell.area.Left;
+//     }
+//     return rst;
+//   }
+
+  
+
+ 
+//   const privateDrawCellText=(cell:ICell, fonts:IFontCollection, controls:IControlCollection) =>{
+//     if (cell.Value) {
+//       const values = `${cell.Value}`.split('|');
+//       // let font = fonts[cell.font];
+//       let font = null;
+//       if (typeof cell.font === 'string') {
+//         font = fonts[cell.font];
+//       } else {
+//         font = cell.font;
+//       }
+//       // let control = controls[cell.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.Name) +
+//             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 * (height / values.length) + offsetY;
+//         // area[JV.IDX_BOTTOM] = cell.area..Top + (i + 1) * (height / values.length) + offsetY;
+//         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输出空格只有一半宽度,需要额外加空格补上 -----------------------------
+//         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])}`;
+//         }
+//         // -----------------------------
+//         privateDrawText(values[i], area, font, control);
+//         spaceIdxArr = [];
+//       }
+//     }
+//   }
+//   const privateSplitString=(strVal:string, areaWidth:number, doc: { widthOfString: (arg0: string) => any; })=> {
+//     const rst = [];
+//     if (strVal) {
+//       let preSIdx = 0;
+//       let txtWidth = 0;
+//       let currentW = 0;
+//       const chnW = doc.widthOfString('一');
+//       const otherW = doc.widthOfString('_');
+//       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 privateDrawText=(val:string, area:number[], font:IFontSubCollection, control:IControlSubCollection)=> {
+//     let dftFontHeight = 12;
+//     const output: number[] = [];
+//     let fontFile = `${__dirname}/pdf_base_files/simkai.ttf`;
+//     if (font) {
+//       dftFontHeight = 1 * font.FontHeight;
+//       fontFile = `${__dirname}/pdf_base_files/${getActualFont(
+//         font.Name,
+//         font.FontBold === 'T',
+//         font.FontItalic === 'T'
+//       )}.ttf`;
+//       doc.fontSize(dftFontHeight);
+//     }
+//     doc.font(fontFile);
+//     const options = {
+//       width:0,
+//       height:0
+//     };
+//     const innerSetupControl = function (inArea:number[], inFontHeight:number, inOutput: number[]) {
+//       if (control) {
+//         privateSetupAreaH(inArea, control.Horizon, font.FontAngle, inFontHeight, inOutput, options);
+//         privateSetupAreaV(inArea, control.Vertical, font.FontAngle, inFontHeight, inOutput);
+//       } else {
+//         privateSetupAreaH(inArea, 'left', parseInt(`${font.FontAngle}`), inFontHeight, inOutput, options);
+//         privateSetupAreaV(inArea, 'bottom', parseInt(`${font.FontAngle}`), inFontHeight, inOutput);
+//       }
+//     };
+//     innerSetupControl(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 privateDrawUnderline=(underLineVal:string, underLineArea:number[])=> {
+//       // A. 暂不支持角度; B. PDF输出时,坐标没有translate
+//       const ctx = doc;
+//       // 1. 计算下划线的相关坐标
+//       let width = ctx.widthOfString(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);
+//       }
+//       // ctx.beginPath();
+//       // ctx.moveTo(startX, startY);
+//       ctx.moveTo(startX * PDF_SCALE, startY * PDF_SCALE);
+//       ctx.lineWidth(1);
+//       ctx.strokeStyle = 'BLACK';
+//       // ctx.lineTo(endX, endY);
+//       ctx.lineTo(endX * PDF_SCALE, endY * PDF_SCALE);
+//       ctx.stroke();
+//       // ctx.restore();
+//     }
+
+//     let rotateOptions;
+//     // if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(font.FontAngle) === 0) {
+//     //     privateDrawUnderline(val);
+//     // }
+//     if (parseInt(`${font.FontAngle}`) !== 0) {
+//       if (control) {
+//         rotateOptions = privateSetupAreaRotateOption(area, validAreaTxtWidth, control.Vertical, dftFontHeight, output);
+//       } else {
+//         rotateOptions = privateSetupAreaRotateOption(area, validAreaTxtWidth, 'bottom', dftFontHeight, output);
+//       }
+//       doc.rotate(font.FontAngle, rotateOptions);
+//     }
+//     if (
+//       validAreaTxtWidth >= doc.widthOfString(val) ||
+//       (control && control.Shrink !== 'T' && validTxtLines < privateSplitString(val, validAreaTxtWidth, doc).length)
+//     ) {
+//       options.width = validAreaTxtWidth * PDF_SCALE;
+//       options.height = dftFontHeight * PDF_SCALE;
+//       doc.fontSize(dftFontHeight);
+//       if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(`${font.FontAngle}`) === 0) {
+//         privateDrawUnderline(val, area);
+//       }
+//       doc.fontSize(dftFontHeight * PDF_SCALE);
+//       doc.text(val, output[0] * PDF_SCALE, output[1] * PDF_SCALE, options);
+//       doc.font(`${__dirname}/pdf_base_files/simhei_bold_italic.ttf`);
+//     } 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 = privateSplitString(val, validAreaTxtWidth, doc);
+//         if (actLines.length > lines && dftFontHeight >= 6) {
+//           dftFontHeight--;
+//           doc.fontSize(dftFontHeight);
+//           options.width = validAreaTxtWidth * PDF_SCALE;
+//           options.height = dftFontHeight * PDF_SCALE;
+//           // doc.text(val,output[0], output[1], options);
+//         } 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);
+//             innerSetupControl(newArea, dftFontHeight, output);
+//             doc.fontSize(dftFontHeight);
+//             if (font[JV.FONT_PROPS[5]] === 'T' && parseInt(`${font.FontAngle}`) === 0) {
+//               privateDrawUnderline(actLines[lIdx], newArea);
+//             }
+//             doc.fontSize(dftFontHeight * PDF_SCALE);
+//             doc.text(actLines[lIdx], output[0] * PDF_SCALE, output[1] * PDF_SCALE, options);
+//           }
+//           break;
+//         }
+//         /* /
+//                 dftFontHeight--;
+//                 doc.fontSize(dftFontHeight);
+//                 if (validAreaTxtWidth >= doc.widthOfString(val) || dftFontHeight < 6) {
+//                     options.width = validAreaTxtWidth;
+//                     options.height = dftFontHeight;
+//                     doc.text(val,output[0], output[1], options);
+//                     doc.font(__dirname + '/pdf_base_files/simhei_bold_italic.ttf');
+//                     break;
+//                 }
+//                 // */
+//       }
+//     }
+//     // doc.text(val,output[0], output[1], options);
+//     doc.font(`${__dirname}/pdf_base_files/simhei_bold_italic.ttf`);
+//     // doc.restore();
+//   }
+
+//   const privateSetupAreaH=(area: number[], type: string, fontAngle: string | number | undefined, dftFontHeight: number, outputPoint: number[], options: { width?: number; height?: number; align?: any; })=> {
+//     let lType = type;
+//     if (type !== 'left' && type !== 'right' && type !== 'center') lType = 'left';
+//     options.align = lType;
+//     outputPoint[0] = 1 * area[JV.IDX_LEFT] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_LEFT];
+//   }
+
+//   const privateSetupAreaV=(area: number[], type: string, fontAngle: string | number | undefined, dftFontHeight: number, outputPoint: number[])=> {
+//     let lType = type;
+//     if (type !== 'top' && type !== 'bottom' && type !== 'center') lType = 'top';
+//     switch (lType) {
+//       case 'top':
+//         outputPoint[1] = 1 * area[JV.IDX_TOP] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
+//         break;
+//       case 'bottom':
+//         outputPoint[1] = 1 * area[JV.IDX_BOTTOM] - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM] - dftFontHeight;
+//         break;
+//       case 'center':
+//         outputPoint[1] = 1 * area[JV.IDX_TOP] + (1 * area[JV.IDX_BOTTOM] - 1 * area[JV.IDX_TOP] - dftFontHeight) / 2;
+//         break;
+//     }
+//   }
+
+  
+
+//   const privateSetupAreaRotateOption=(area: number[], w: number, type = 'top', dftFontHeight: number, outputPoint: any[]) =>{
+//     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;
+//   }
+// }
+// export default {}

+ 1 - 1
tree/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@sc/tree",
-  "version": "1.0.14",
+  "version": "1.0.15",
   "description": "通用树",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.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)[] = [];

+ 29 - 8
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;
@@ -48,6 +49,7 @@ export enum FromType {
 }
 
 export enum RationPrefix {
+  EMT = '',
   BOR = '借',
   CPT = '补',
   REP = '换',
@@ -86,7 +88,7 @@ export enum BRType { // 1 :大项费用 2:分部 3分项 4清单;5补项   6 
   EQUIP = 51, // 设备
 }
 
-export enum supplyType {
+export enum SupplyType {
   ZXCG = 1, // 自行采购
   BFJG, // 部分甲供
   WQJG, // 完全甲供
@@ -123,7 +125,7 @@ export enum CptModelName {
   feeRateFile = 'feeRateFile',
   labourCoeFile = 'labourCoeFile',
   importLogs = 'importLogs',
-  cptRationSectionTpl = 'cptRationSectionTpl',
+  cptRationTree = 'cptRationTree',
   cptGlj = 'cptGlj',
   cptGljTree = 'cptGljTree',
   cptRationCoeList = 'cptRationCoeList',
@@ -173,17 +175,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?: T; // 和update类型对应,
   documents?: T[]; // add 类型对应,批量插入
   odocs?: any[]; // 存放撤销的原始数据?
-  result?: any; // 特殊的返回结果
+  result?: R; // 特殊的返回结果
 }
 
 export interface IColumnMeta {
@@ -218,3 +220,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[]; // 书签批注
+}

+ 2 - 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,7 +122,6 @@ export interface IBill {
   formula?: string; // 基数计算
   formulaValue?: number; // 基数计算的值
   tenderFormulaValue?: number; // 调价基数计算的值
-  bookMark?: IBookmark; // 书签批注
   isAdd?: boolean; // 是否用户新增的清单
   [key: string]: any; // 剩下的之后补充
 }

+ 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; // 供货方式
 }
 
 // 配置材料的几个属性

+ 7 - 1
types/src/interface/error.ts

@@ -99,10 +99,16 @@ export enum ErrNo {
   SINGLE_ORG_NOT_FOUND = 5028,
   GLJ_LIB_NOT_FOUND = 5029,
   CPT_GLJ_TREE_EMPTY = 5030,
-
+  CPT_GLJ_INVALID = 5031, // 无效的补充人材机(需要编码、名称、单位、类型有值)
+  CPT_GLJ_CODE_EXISTS = 5032, // 补充人材机编码已存在
+  INVALID_CPT_GLJ_LIB_ID = 5033, // 无效的补充人材机库ID
+  CPT_GLJ_LIB_ID = 5033, // 无效的补充人材机库ID
+  CPT_GLJ_NOT_EXISTS = 5034, // 补充人材机不存在
   /* 数据配置错误(大多数为后台标准、模板数据配置问题)  6001 - 6999 */
   // 补充人材机分类树模板 未配置
   CPT_GLJ_TREE_TEMPLATE_EMPTY = 6001,
   // 补充定额库章节树模板 未配置
   CPT_RATION_TREE_TEMPLATE_EMPTY = 6002,
+  // 该费用定额下,没有标准人材机库
+  STD_GLJ_LIB_EMPTY = 6003,
 }

+ 35 - 4
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 {
@@ -167,7 +167,7 @@ export interface IProjectGlj {
   code: string; // 编码
   originalCode: string; // 原始的编码
   name: string; // 名称
-  supply: supplyType; // 供货方式
+  supply: SupplyType; // 供货方式
   supplyQuantity?: number; // 甲供数量
   delivery?: string; // 交货方式
   deliveryAddress?: string; // 送达地点
@@ -211,6 +211,15 @@ export interface IProjectGljs {
 }
 
 /* 标准人材机相关 ↓ */
+// 标准人材机库
+export interface IStdGljLib {
+  dispName: string;
+  compilationId: string;
+  compilationName: string;
+  ID: number;
+  rationLibs: [{ dispName: string; ID: number }];
+}
+
 // 标准、补充人材机共用属性(原始数据)
 export interface IBaseRationGlj {
   code: string;
@@ -275,6 +284,9 @@ export interface IStdGljTree extends ITreeScm {
 /* 标准人材机相关 ↑ */
 
 /* 补充人材机相关 ↓ */
+// 补充人材机库标记
+export const cptLibKey = 'complementaryLib';
+
 // 补充人材机分类树-模板(后台设置)
 export interface IRawCptGljTreeTemplate {
   compilationId: string;
@@ -325,6 +337,25 @@ export interface ICptGlj extends IBaseRationGlj {
   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;
+}
+
 // 补充人材机
 /* 补充人材机相关 ↑ */
 
@@ -341,7 +372,7 @@ export interface ISelectGljLibItem {
 
 // 获取人材机分页数据接口选项
 export interface IGetPagingGljOptions {
-  classList?: number[]; // 需要匹配的分类
+  classList?: (number | string)[]; // 需要匹配的分类
   typeList?: GljType[]; // 需要匹配的人材机类型
   libID?: number | string; // 人材机库ID
   replaceGlj?: IBaseGlj; // 替换的人材机
@@ -354,7 +385,7 @@ export interface IGetPagingGljOptions {
 // 选择人材机接口返回数据格式
 export interface ISelectGljResult {
   libData: ISelectGljLibItem[]; // 库下拉项
-  treeData: IStdGljTree[]; // 人材机分类树
+  treeData: (IStdGljTree | ICptGljTree)[]; // 人材机分类树
   gljData: (IStdGlj | ICptGlj)[]; // 人材机数据
   total: number; // 当前数据总数量
   locatedGlj?: IStdGlj | ICptGlj; // 需要定位到的人材机

+ 29 - 18
types/src/interface/ration.ts

@@ -5,6 +5,8 @@ import {
   GljCreateType,
   CreateLocation,
   BRType,
+  IBRBase,
+  ITreeScm,
 } from './base';
 import { IBookmark } from './bill';
 import { GljType, ICptGlj, IStdGlj, MaterialType } from './glj';
@@ -258,22 +260,10 @@ 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; // 目标单价
@@ -281,8 +271,6 @@ export interface IRation {
   from?: FromType; // { type: string; default: 'std' }; // std, cpt  来自标准、补充
   isSubcontract?: boolean; // 是否分包
   installationKey?: string; // 用来记录安装增加费的关联字段
-  // 定额特有属性:
-  stdID?: string; // 来自的标准定额ID
   repositoryID?: number; // 定额库ID
   maskName?: string;
   caption?: string;
@@ -306,8 +294,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 +304,6 @@ export interface IRation {
   rationCoeList?: IRationCoe[]; // 定额调整系数
   rationTemplate?: IRationTemplate; // 定额模板
   rationInstallList?: IRationInstall[]; // 定额安装增加
-  bookmarks?: IBookmark[];
 }
 
 export interface IRations {
@@ -337,3 +322,29 @@ 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[];
+}

+ 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;
 }

+ 5 - 0
util/README.md

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

+ 2 - 2
util/package.json

@@ -1,7 +1,7 @@
 {
   "name": "@sc/util",
-  "version": "1.0.6",
-  "description": "用的工具包",
+  "version": "1.0.7",
+  "description": "用的工具包",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",
   "browser": "./dist/index.min.js",

+ 0 - 3
util/src/index.ts

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

+ 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.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/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


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


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

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

+ 1 - 1
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;

+ 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"
+  ]
+}