Browse Source

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

LuoHaoxuan 3 years ago
parent
commit
ea039c52ec

+ 16 - 0
handsontable/handsontable.d.ts

@@ -317,6 +317,12 @@ declare namespace Handsontable {
       saveValue(val?: any, ctrlDown?: boolean): void;
       saveValue(val?: any, ctrlDown?: boolean): void;
 
 
       setValue(newValue?: any): void;
       setValue(newValue?: any): void;
+
+      lock(): void;
+
+      unlock(): void;
+
+      getLockState(): boolean;
     }
     }
 
 
     class Checkbox extends Base {
     class Checkbox extends Base {
@@ -774,6 +780,16 @@ declare namespace Handsontable {
       extendEvent(context: object, event: Event): any;
       extendEvent(context: object, event: Event): any;
     }
     }
 
 
+    interface EditorManagerInstance {
+      lockEditor(): void;
+      unlockEditor(): void;
+      getLockState(): boolean;
+    }
+
+    interface EditorManager {
+      getInstance(hotInstance: _Handsontable.Core, hotSettings?: Handsontable.DefaultSettings, selection?: any, datamap?: any): EditorManagerInstance
+    }
+
     interface GhostTable {
     interface GhostTable {
       columns: number[];
       columns: number[];
       container: HTMLElement | null;
       container: HTMLElement | null;

+ 1 - 1
handsontable/package.json

@@ -10,7 +10,7 @@
     "url": "https://github.com/handsontable/handsontable/issues"
     "url": "https://github.com/handsontable/handsontable/issues"
   },
   },
   "author": "Handsoncode <hello@handsontable.com>",
   "author": "Handsoncode <hello@handsontable.com>",
-  "version": "6.3.15",
+  "version": "6.3.16",
   "browser": "dist/handsontable.js",
   "browser": "dist/handsontable.js",
   "main": "commonjs/index.js",
   "main": "commonjs/index.js",
   "module": "es/index.js",
   "module": "es/index.js",

+ 5 - 1
handsontable/src/editorManager.js

@@ -280,7 +280,7 @@ function EditorManager(instance, priv, selection) {
   };
   };
 
 
   /**
   /**
-  * Unlock the editor from being prepared and closed. This method restores the original behavior of
+  * Unlock the editor from being prepare  d and closed. This method restores the original behavior of
   * the editors where for every new selection its instances are closed.
   * the editors where for every new selection its instances are closed.
   *
   *
   * @function unlockEditor
   * @function unlockEditor
@@ -290,6 +290,10 @@ function EditorManager(instance, priv, selection) {
     lock = false;
     lock = false;
   };
   };
 
 
+  this.getLockState = function() {
+    return lock;
+  };
+
   /**
   /**
    * Destroy current editor, if exists.
    * Destroy current editor, if exists.
    *
    *

+ 19 - 0
handsontable/src/editors/_baseEditor.js

@@ -1,5 +1,6 @@
 import { CellCoords } from './../3rdparty/walkontable/src';
 import { CellCoords } from './../3rdparty/walkontable/src';
 import { stringify } from './../helpers/mixed';
 import { stringify } from './../helpers/mixed';
+import EditorManager from './../editorManager';
 
 
 export const EditorState = {
 export const EditorState = {
   VIRGIN: 'STATE_VIRGIN', // before editing
   VIRGIN: 'STATE_VIRGIN', // before editing
@@ -266,4 +267,22 @@ BaseEditor.prototype.checkEditorSection = function() {
   return section;
   return section;
 };
 };
 
 
+// 锁定editor,锁定后,点击事件不会关闭editor
+BaseEditor.prototype.lock = function() {
+  const editorManagerInstance = EditorManager.getInstance(this.instance);
+  editorManagerInstance.lockEditor();
+};
+
+// 解锁editor
+BaseEditor.prototype.unlock = function() {
+  const editorManagerInstance = EditorManager.getInstance(this.instance);
+  editorManagerInstance.unlockEditor();
+};
+
+// 获取editor是否锁定
+BaseEditor.prototype.getLockState = function() {
+  const editorManagerInstance = EditorManager.getInstance(this.instance);
+  return editorManagerInstance.getLockState();
+};
+
 export default BaseEditor;
 export default BaseEditor;

+ 2 - 0
handsontable/src/index.js

@@ -12,6 +12,7 @@ import { getRegisteredCellTypeNames, getCellType, registerCellType } from './cel
 import Core from './core';
 import Core from './core';
 import jQueryWrapper from './helpers/wrappers/jquery';
 import jQueryWrapper from './helpers/wrappers/jquery';
 import EventManager, { getListenersCounter } from './eventManager';
 import EventManager, { getListenersCounter } from './eventManager';
+import EditorManager from './editorManager';
 import Hooks from './pluginHooks';
 import Hooks from './pluginHooks';
 import GhostTable from './utils/ghostTable';
 import GhostTable from './utils/ghostTable';
 import * as arrayHelpers from './helpers/array';
 import * as arrayHelpers from './helpers/array';
@@ -49,6 +50,7 @@ jQueryWrapper(Handsontable);
 Handsontable.Core = Core;
 Handsontable.Core = Core;
 Handsontable.DefaultSettings = DefaultSettings;
 Handsontable.DefaultSettings = DefaultSettings;
 Handsontable.EventManager = EventManager;
 Handsontable.EventManager = EventManager;
+Handsontable.EditorManager = EditorManager;
 Handsontable._getListenersCounter = getListenersCounter; // For MemoryLeak tests
 Handsontable._getListenersCounter = getListenersCounter; // For MemoryLeak tests
 
 
 Handsontable.buildDate = process.env.HOT_BUILD_DATE;
 Handsontable.buildDate = process.env.HOT_BUILD_DATE;

+ 2 - 1
report/src/interface/basic.ts

@@ -640,7 +640,8 @@ export interface RptTreeNode {
         auditType?: string | null;
         auditType?: string | null;
         rptTplType?:string | null;
         rptTplType?:string | null;
     };
     };
-    UID?:number
+    UID?:number;
+    refId?:string;
   }
   }
 //   方案列表
 //   方案列表
 export interface IRptSchemeList{
 export interface IRptSchemeList{

+ 1 - 1
tree/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@sc/tree",
   "name": "@sc/tree",
-  "version": "1.0.18",
+  "version": "1.0.20",
   "description": "通用树",
   "description": "通用树",
   "main": "./dist/index.cjs.js",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",
   "module": "./dist/index.esm.js",

+ 14 - 0
tree/src/tree.ts

@@ -659,4 +659,18 @@ export class Tree<T extends TreeRaw = TreeRaw> {
     Object.keys(this.IDMap).forEach(key => delete this.IDMap[key]);
     Object.keys(this.IDMap).forEach(key => delete this.IDMap[key]);
     Object.keys(this.ctxMap).forEach(key => delete this.ctxMap[key]);
     Object.keys(this.ctxMap).forEach(key => delete this.ctxMap[key]);
   }
   }
+
+  // 检测树结构
+  check(): TreeNode<T>[] {
+    const errNodes: TreeNode<T>[] = [];
+    errNodes.push(...this.checkParent());
+    return errNodes;
+  }
+
+  // 检查找不到父项的(parentID对应的节点不存在),返回有问题的节点
+  private checkParent(): TreeNode<T>[] {
+    return this.rawData.filter(
+      node => node.parentID !== this.rootID && !this.IDMap[node.parentID]
+    );
+  }
 }
 }

+ 22 - 6
types/src/interface/base.ts

@@ -278,14 +278,15 @@ export interface IGetData {
   approval?: IProjectApproval;
   approval?: IProjectApproval;
 }
 }
 
 
+export interface IFee {
+  tenderTotalFee: number;
+  tenderUnitPrice: number;
+  totalFee: number;
+  unitPrice: number;
+}
 // 费用字段
 // 费用字段
 export interface IFees {
 export interface IFees {
-  [key: string]: {
-    tenderTotalFee: number;
-    tenderUnitPrice: number;
-    totalFee: number;
-    unitPrice: number;
-  };
+  [key: string]: IFee;
 }
 }
 
 
 // 定额和清单共有的属性,造价书中很多地方需要
 // 定额和清单共有的属性,造价书中很多地方需要
@@ -317,3 +318,18 @@ export interface IBRBase {
 }
 }
 
 
 export const SeparateString = '|----|';
 export const SeparateString = '|----|';
+
+// 检查subjec tree返回类型
+export enum CheckSubjectTreeType {
+  // 项目被删除
+  PROJECT_DELETED = 1,
+  // 项目被取消分享
+  PROJECT_CANCEL_SHARED,
+  // 权限限制(未知情况)
+  PERMISSION_LIMITED,
+}
+
+// 检查subjec tree返回结果
+export interface ICheckSubjectTreeRst {
+  checkType: CheckSubjectTreeType;
+}

+ 29 - 11
types/src/interface/bill.ts

@@ -1,6 +1,7 @@
+import { IComponent } from './glj';
 import { FileType } from './project';
 import { FileType } from './project';
 import { IElfItem } from './billGuide';
 import { IElfItem } from './billGuide';
-import { IBRBase, INumFileRef, ITreeScm } from './base';
+import { BRType, IBRBase, IFees, INumFileRef, ITreeScm } from './base';
 import { ICalcItem } from './calculation';
 import { ICalcItem } from './calculation';
 
 
 // 清单固定类别
 // 清单固定类别
@@ -107,6 +108,9 @@ export interface IBookmark {
   creatorID: string;
   creatorID: string;
   createTime: number;
   createTime: number;
   telNo: string;
   telNo: string;
+  kind: BRType;
+  institution?: string;
+  procunit?: string;
 }
 }
 // 修改书签
 // 修改书签
 export interface ISetBookmark {
 export interface ISetBookmark {
@@ -120,6 +124,17 @@ export interface IPriceScope {
   maxUnitPrice: number;
   maxUnitPrice: number;
 }
 }
 
 
+export interface ICheckOptions {
+  fileType: string;
+  year: string;
+  projLocation: string;
+  projectType: string;
+  engineerType: string;
+  classCode?: string;
+  indexType?: string;
+  unit?: string;
+}
+
 export interface IBill extends IBRBase {
 export interface IBill extends IBRBase {
   flag?: FixedFlag; // 清单固定类别
   flag?: FixedFlag; // 清单固定类别
   recharge?: string; // 补注
   recharge?: string; // 补注
@@ -150,6 +165,7 @@ export interface IBill extends IBRBase {
   groupCode?: string; // 类别组,当机器检测结果不正确时,纠正措施
   groupCode?: string; // 类别组,当机器检测结果不正确时,纠正措施
   checkRationResult?: string; // 机器检测结果(必套、选套、错套定额相关)
   checkRationResult?: string; // 机器检测结果(必套、选套、错套定额相关)
   checked?: boolean; // 是否已经进行清单检测过的清单,为true表式已经检测过了(用来计算通过率)
   checked?: boolean; // 是否已经进行清单检测过的清单,为true表式已经检测过了(用来计算通过率)
+  checkOptions?: ICheckOptions; // 清单检测时保存的筛选条件
   setParentQuantity?: boolean; // 是否打勾了填父量
   setParentQuantity?: boolean; // 是否打勾了填父量
   [key: string]: any; // 剩下的之后补充
   [key: string]: any; // 剩下的之后补充
 }
 }
@@ -242,6 +258,11 @@ export interface IBillClass {
   errorRationIDs: number[]; // 错套定额ID
   errorRationIDs: number[]; // 错套定额ID
 }
 }
 
 
+export interface IIndexComponent extends IComponent {
+  marketPrice: string;
+  basePrice: string;
+}
+
 export interface IBillIndexGlj {
 export interface IBillIndexGlj {
   code: string;
   code: string;
   name: string;
   name: string;
@@ -251,6 +272,7 @@ export interface IBillIndexGlj {
   marketPrice: string;
   marketPrice: string;
   basePrice: string;
   basePrice: string;
   rationQuantity: string;
   rationQuantity: string;
+  components?: IIndexComponent[];
 }
 }
 
 
 export interface IBillIndexRation {
 export interface IBillIndexRation {
@@ -263,7 +285,9 @@ export interface IBillIndexRation {
   quantity: string;
   quantity: string;
   unitPrice: string;
   unitPrice: string;
   rationGljList: IBillIndexGlj[];
   rationGljList: IBillIndexGlj[];
-  dynamicIndex?: Record<string, string>; // 动态指标,年-月为key 综合指标的映射
+  dynamicIndex?: Record<string, IFees>; // 动态指标,年-月为key 综合指标的映射
+  fees?: IFees; // 费用字段
+  calcItems?: ICalcItem[];
 }
 }
 
 
 export interface IFBIndex {
 export interface IFBIndex {
@@ -286,15 +310,17 @@ export interface IFBIndex {
   month?: string; // 信息价月
   month?: string; // 信息价月
   fileType?: FileType; // 文件类型
   fileType?: FileType; // 文件类型
   indexTypes?: string[]; // 项目分类或者说功能分类--
   indexTypes?: string[]; // 项目分类或者说功能分类--
-  dynamicIndex?: Record<string, string>; // 动态指标,年-月为key 综合指标的映射
+  dynamicIndex?: Record<string, IFees>; // 动态指标,年-月为key 综合指标的映射
   minUnitPrice?: string;
   minUnitPrice?: string;
   maxUnitPrice?: string;
   maxUnitPrice?: string;
+  fees?: IFees; // 费用字段
 }
 }
 export interface IBillIndex extends IFBIndex {
 export interface IBillIndex extends IFBIndex {
   classCode: string; // 类别别名
   classCode: string; // 类别别名
   groupCode?: string;
   groupCode?: string;
   itemCharacter: string;
   itemCharacter: string;
   rations?: IBillIndexRation[];
   rations?: IBillIndexRation[];
+  dynamicGljMap?: Record<string, Record<string, string>>; // 动态工料机价格指标,年-月为key 工料机工五大项为子key  value为市场价
 }
 }
 
 
 export enum LibType {
 export enum LibType {
@@ -304,11 +330,3 @@ export enum LibType {
 export interface IBillOption extends INumFileRef {
 export interface IBillOption extends INumFileRef {
   libType?: LibType;
   libType?: LibType;
 }
 }
-
-export interface IBillCheckOptions {
-  fileType: FileType[];
-  year: string;
-  projLocation: string;
-  projectType: string;
-  engineerType: string;
-}

+ 11 - 1
types/src/interface/compilation.ts

@@ -142,9 +142,17 @@ export interface IMonomerTemplateData {
   items: ISubMonomerTemplate[];
   items: ISubMonomerTemplate[];
 }
 }
 
 
+export interface IConstructionTemplate {
+  dispName: string;
+  key: string;
+}
 export interface IMonomerTemplate {
 export interface IMonomerTemplate {
   compilationID: string;
   compilationID: string;
-  data: IMonomerTemplateData[];
+  data: any; // 兼容还没改结构之前的版本,写法,上线后修改回来 -- 不然部署报错
+  /*  data: {
+    constructionTemplate: IConstructionTemplate[];
+    monomerTemplate: IMonomerTemplateData[];
+  }; */
 }
 }
 
 
 export interface ICompilation {
 export interface ICompilation {
@@ -168,7 +176,9 @@ export interface ICompilation {
   versionText: string; // 版本对应的显示文字:免费版,学习版,专业版
   versionText: string; // 版本对应的显示文字:免费版,学习版,专业版
   lockInfo: LockInfo; // 锁信息
   lockInfo: LockInfo; // 锁信息
   monomerTemplate: IMonomerTemplateData[];
   monomerTemplate: IMonomerTemplateData[];
+  constructionTemplate: IConstructionTemplate[];
   structuralSegment: IStructuralSegmentData[];
   structuralSegment: IStructuralSegmentData[];
+  edition: string; // 版本号(用于项目信息、项目特征等项目信息的升级)
 }
 }
 
 
 export enum ValuationType {
 export enum ValuationType {

+ 2 - 0
types/src/interface/editLog.ts

@@ -17,6 +17,8 @@ export interface ILogDetail<T = any> {
   oldValue?: string; // 旧值
   oldValue?: string; // 旧值
   field?: string; // 修改的field
   field?: string; // 修改的field
   processID?: string; // 流程ID
   processID?: string; // 流程ID
+  institution?: string; // 单位名称
+  procunit?: string; // 流程环节
 }
 }
 
 
 export interface IEditLog {
 export interface IEditLog {

+ 7 - 0
types/src/interface/glj.ts

@@ -375,6 +375,8 @@ export interface ICptGlj extends IBaseRationGlj {
   creatorName?: string; // 创建者姓名
   creatorName?: string; // 创建者姓名
   createTime?: number; // 创建时间
   createTime?: number; // 创建时间
   displayLibName?: string; // 工料机所在库在前端UI上的显示,如:[企业库]。
   displayLibName?: string; // 工料机所在库在前端UI上的显示,如:[企业库]。
+  alias?: string; // 别名(名称 规格)
+  period?: string; // 期数
 }
 }
 
 
 // 新增补充人材机接口传输的数据接口
 // 新增补充人材机接口传输的数据接口
@@ -508,3 +510,8 @@ export interface ICptGljLib {
   isEnterpriseInternal: boolean;
   isEnterpriseInternal: boolean;
   createDate: number;
   createDate: number;
 }
 }
+
+// 以工料机五大项为key,映射表
+export interface IGljKeyMap {
+  [key: string]: IBaseGlj;
+}

+ 6 - 0
types/src/interface/process.ts

@@ -232,3 +232,9 @@ export interface ITodo {
 export interface IApprovalTodo extends ITodo {
 export interface IApprovalTodo extends ITodo {
   data: IApprovalTodoData;
   data: IApprovalTodoData;
 }
 }
+
+export enum ChangeRecord{
+  CURRENT = 'current', // 当前清单
+  ALLBILLS = 'all-bills', // 全部清单
+  ALLGLJS = 'all-gljs', // 全部材价
+}

+ 19 - 5
types/src/interface/project.ts

@@ -1,11 +1,10 @@
-import { EntityType } from './user';
+import { EntityType } from './user';
 import { ValuationType } from './compilation';
 import { ValuationType } from './compilation';
 import { IIncreaseSetting } from './increaseFee';
 import { IIncreaseSetting } from './increaseFee';
 import { ITreeScm, DeleteEnum, INumFileRef, IColumnMeta } from './base';
 import { ITreeScm, DeleteEnum, INumFileRef, IColumnMeta } from './base';
 import { ICalcOption, ITenderSetting, IDistributeSetting } from './calculation';
 import { ICalcOption, ITenderSetting, IDistributeSetting } from './calculation';
-import { ISharePermission } from './share';
 import { IOverHeight, IOverHeightSetting } from './overHeight';
 import { IOverHeight, IOverHeightSetting } from './overHeight';
-import { IProcessAccount } from './process';
+import { ICheckOptions, IPriceScope } from './bill';
 
 
 // 项目类型
 // 项目类型
 export enum ProjectType {
 export enum ProjectType {
@@ -85,9 +84,12 @@ export enum FileType {
   CONTROL = 3, // 控制价
   CONTROL = 3, // 控制价
 
 
   // 预算类型  --- end
   // 预算类型  --- end
+
   ESTIMATE = 5, // 概算
   ESTIMATE = 5, // 概算
 
 
   SETTLEMENT = 10, // 结算
   SETTLEMENT = 10, // 结算
+
+  GUSUAN = 15, // 估算
 }
 }
 
 
 // 结算流程类型
 // 结算流程类型
@@ -104,6 +106,7 @@ export enum FileTypeName {
   INVITATION = '预算',
   INVITATION = '预算',
   ESTIMATE = '概算',
   ESTIMATE = '概算',
   SETTLEMENT = '结算',
   SETTLEMENT = '结算',
+  GUSUAN = '估算',
 }
 }
 
 
 export const FileTypeMap = {
 export const FileTypeMap = {
@@ -247,6 +250,9 @@ export interface IProperty {
   saveLog?: boolean; // 记录项目编辑log
   saveLog?: boolean; // 记录项目编辑log
   indexType?: string; // 指标项目分类用于指标入库
   indexType?: string; // 指标项目分类用于指标入库
   normLib?: string;
   normLib?: string;
+  saveToIndex?: boolean; // 是否已经入库
+  checkOptions?: ICheckOptions; // 指标检测的选项
+  priceScope?: IPriceScope; // 价格区间
 }
 }
 
 
 // 原来的列设置太复杂了,没什么必要
 // 原来的列设置太复杂了,没什么必要
@@ -303,6 +309,7 @@ export interface IProject extends ITreeScm {
   deleteDate?: number;
   deleteDate?: number;
   deleteBy?: string;
   deleteBy?: string;
   financialProjectID?: string; // 关联财审项目ID(不用财审项目关联此表,因为可能多个项目对应一个财审项目)
   financialProjectID?: string; // 关联财审项目ID(不用财审项目关联此表,因为可能多个项目对应一个财审项目)
+  edition?: string; // 数据版本号
   // 流程信息
   // 流程信息
   processInfo?: {
   processInfo?: {
     currentApprovalID: string; // 当前正处于哪个审批流中
     currentApprovalID: string; // 当前正处于哪个审批流中
@@ -394,6 +401,8 @@ export interface IProjectLog {
   cooperationCount?: number;
   cooperationCount?: number;
   // 是否与我协作
   // 是否与我协作
   cooperateWithMe?: boolean;
   cooperateWithMe?: boolean;
+  // 版本号
+  edition?: string;
 }
 }
 
 
 // 导入状态
 // 导入状态
@@ -423,13 +432,15 @@ export interface ISaveProjectInfo {
   unitID?: string;
   unitID?: string;
   singleID?: string;
   singleID?: string;
   constructionID?: string;
   constructionID?: string;
-  indexTypes: string[];
+  indexType: string; // 工程分类
+  indexTypes: string[]; // 自身的工程分类以及祖先项的分类数组
   projLocation: string;
   projLocation: string;
   year: string;
   year: string;
   month: string;
   month: string;
   fileType: FileType;
   fileType: FileType;
   unit?: string;
   unit?: string;
   quantity?: string;
   quantity?: string;
+  sourceName: string;
 }
 }
 
 
 export interface ICommonIndex {
 export interface ICommonIndex {
@@ -437,8 +448,10 @@ export interface ICommonIndex {
   parentID: string;
   parentID: string;
   seq: number;
   seq: number;
   type: ProjectType;
   type: ProjectType;
+  sourceName: string;
   name?: string;
   name?: string;
   constructionID?: string;
   constructionID?: string;
+  indexType: string; // 工程分类
   indexTypes: string[];
   indexTypes: string[];
   projLocation: string;
   projLocation: string;
   year: string;
   year: string;
@@ -447,5 +460,6 @@ export interface ICommonIndex {
   unit?: string;
   unit?: string;
   quantity?: string;
   quantity?: string;
   composite: string; // 综合指标
   composite: string; // 综合指标
-  dynamicIndex: Record<string, string>; // 动态指标,年-月为key 综合指标的映射
+  engineeringCost: number;
+  dynamicIndex: Record<string, string>; // 动态指标,年-月为key  这里的值 保存的是动态总造价,动态的综合指标实时算,前端动态计算时不方便拿quantity
 }
 }

+ 1 - 1
wise-cost-util/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@sc/wise-cost-util",
   "name": "@sc/wise-cost-util",
-  "version": "1.1.5",
+  "version": "1.1.6",
   "description": "wise-cost项目前后端业务通用工具包",
   "description": "wise-cost项目前后端业务通用工具包",
   "main": "./dist/index.cjs.js",
   "main": "./dist/index.cjs.js",
   "module": "./dist/index.esm.js",
   "module": "./dist/index.esm.js",

+ 161 - 1
wise-cost-util/src/glj.ts

@@ -1,5 +1,20 @@
-import { GljType, IBaseGlj, IInfoPriceItem, TaxType } from '@sc/types';
+/* eslint-disable no-param-reassign */
+import {
+  ConfigMaterialKey,
+  GljType,
+  IBaseGlj,
+  ICalcOption,
+  IComponent,
+  IConfigMaterial,
+  IDecimal,
+  IInfoPriceItem,
+  IProjectGlj,
+  IProperty,
+  ITenderSetting,
+  TaxType,
+} from '@sc/types';
 import { roundForObj } from '@sc/util';
 import { roundForObj } from '@sc/util';
+import { find } from 'lodash';
 
 
 export const getInfoMarketPrice = (info: IInfoPriceItem, taxType: TaxType) => {
 export const getInfoMarketPrice = (info: IInfoPriceItem, taxType: TaxType) => {
   // 1: 一般计税 2: 简易计税
   // 1: 一般计税 2: 简易计税
@@ -50,3 +65,148 @@ export const isMachine = (type: GljType) => {
   const rootType = +String(type).charAt(0);
   const rootType = +String(type).charAt(0);
   return rootType === 3;
   return rootType === 3;
 };
 };
+
+/**
+ * 判断工料机类型是否有组成物
+ *
+ * @param projectGlj 可以不传这个,默认会按glj去取
+ *
+ */
+export const hasComponent = (projectGlj?: IProjectGlj) => {
+  // 有组成物的类型
+  const typeMap: { [key: number]: boolean } = {
+    202: true,
+    203: true,
+    204: true,
+    301: true,
+    304: true,
+    4: true,
+  };
+  if (projectGlj) {
+    return typeMap[projectGlj.type] === true && projectGlj.components && projectGlj.components.length > 0;
+  }
+  return false;
+};
+
+const getProjectGlj = (glj: IBaseGlj, projectGljMap: Record<string, IBaseGlj>, index?: string) => {
+  index = index || getIndex(glj);
+  const projectGlj = projectGljMap[index] as IProjectGlj;
+  if (projectGlj) return projectGlj;
+  return undefined;
+};
+
+/**
+ *
+ * @param fieldID 如"glj.unitPrice"
+ *
+ */
+export const getDecimal = (fieldID: string, decimal?: any) => {
+  if (decimal) {
+    if (fieldID.indexOf('.') !== -1) {
+      const keyArray = fieldID.split('.');
+      return decimal[keyArray[0]][keyArray[1]];
+    }
+    return decimal[fieldID];
+  }
+
+  return 0;
+};
+
+export const getMarketPrice = (
+  projectGlj: IProjectGlj,
+  tenderCoe = 1,
+  projectGljMap: Record<string, IBaseGlj>,
+  decimalObj: IDecimal
+) => {
+  if (hasComponent(projectGlj)) {
+    let parentPrice = 0;
+    for (const c of projectGlj.components as IComponent[]) {
+      const cProjectGlj = getProjectGlj(c, projectGljMap);
+      if (cProjectGlj) {
+        let cMarketPrice = getMarketPrice(cProjectGlj, 1, projectGljMap, decimalObj);
+        if (tenderCoe !== 1) cMarketPrice = roundForObj(cMarketPrice * tenderCoe, decimalObj.glj.unitPrice);
+        const quantity = roundForObj(c.consumption, decimalObj.glj.quantity);
+        const sumPrice = roundForObj(cMarketPrice * quantity, decimalObj.process);
+        parentPrice = roundForObj(parentPrice + sumPrice, decimalObj.process);
+      }
+    }
+    return roundForObj(parentPrice, decimalObj.glj.unitPriceHasMix);
+  }
+  const marketPrice = roundForObj(projectGlj.marketPrice, decimalObj.glj.unitPrice);
+  // 调价的时候还要乘以调价系数
+  if (tenderCoe !== 1) return roundForObj(marketPrice * tenderCoe, decimalObj.glj.unitPrice);
+  return marketPrice;
+};
+
+// 取工料机基价(定额价)
+export const getBasePrice = (projectGlj: IProjectGlj, decimalObj: IDecimal) => {
+  let decimalKey = 'glj.unitPrice';
+  if (hasComponent(projectGlj)) decimalKey = 'glj.unitPriceHasMix';
+  const decimal = getDecimal(decimalKey, decimalObj);
+  return roundForObj(projectGlj.basePrice, decimal);
+};
+
+export const getTenderPriceCoe = (projectGlj: IProjectGlj, tenderSetting?: ITenderSetting) => {
+  let coe = 1;
+
+  if (projectGlj.noAdjustPrice === false && tenderSetting) {
+    coe = tenderSetting.gljPriceTenderCoe ? tenderSetting.gljPriceTenderCoe : 1;
+  }
+
+  return coe;
+};
+
+// 判断是否暂估
+export const isEvaluate = (projectGljID: string, configMaterials: IConfigMaterial) => {
+  const materials = configMaterials[ConfigMaterialKey.EVALUATE];
+
+  return !!find(materials, { isRelated: true, projectGljID });
+};
+
+// 判断是否计算价差
+export const calcPriceDiff = (projectGlj: IProjectGlj, configMaterials: IConfigMaterial, calcOption?: ICalcOption) => {
+  if (calcOption) {
+    const { calcEst, calcMain, calcAdd } = calcOption;
+    if (isEvaluate(projectGlj.ID, configMaterials)) return calcEst; // 先按是否暂估判断
+    // 再判断是否是主材和设备
+    if (projectGlj.type === GljType.MAIN_MATERIAL || projectGlj.type === GljType.EQUIPMENT) return calcMain;
+    // 再判断是否新增
+    if (projectGlj.isAdd) return calcAdd;
+  }
+  return true;
+};
+
+// 取工料机的价格在确定subject数据已经获取全的情况下使用
+export const getPrice = (
+  glj: IBaseGlj,
+  projectGljMap: Record<string, IBaseGlj>,
+  unitProperty: { tenderSetting?: ITenderSetting },
+  constructionProperty: { decimal: IDecimal; calcOption?: ICalcOption },
+  configMaterial: IConfigMaterial,
+  tender?: boolean
+) => {
+  let marketPrice = 0;
+  let basePrice = 0;
+  let tenderPrice = 0; // 调后价
+  let adjustPrice = 0; // 调整价
+  const projectGlj = getProjectGlj(glj, projectGljMap);
+  if (projectGlj) {
+    marketPrice = getMarketPrice(projectGlj, 1, projectGljMap, constructionProperty.decimal);
+    tenderPrice = marketPrice;
+
+    if (tender === true) {
+      const tenderCoe = getTenderPriceCoe(projectGlj, unitProperty.tenderSetting);
+      tenderPrice = getMarketPrice(projectGlj, tenderCoe, projectGljMap, constructionProperty.decimal);
+    }
+
+    if (calcPriceDiff(projectGlj, configMaterial, constructionProperty.calcOption)) {
+      // 计取价差
+      basePrice = getBasePrice(projectGlj, constructionProperty.decimal);
+    } else {
+      // 不计价差时 基价也为市场价
+      basePrice = marketPrice;
+    }
+    adjustPrice = basePrice;
+  }
+  return { marketPrice, basePrice, tenderPrice, adjustPrice, projectGlj };
+};