Files
tjt_czjs_ui/src/views/tjt/shared/planning.ts
2026-04-25 18:10:45 +08:00

337 lines
11 KiB
TypeScript

export type Option<T = string> = {
label: string
value: T
}
export const OWNERSHIP_TYPE = {
major: '专业所',
comprehensive: '综合所',
subcontract: '专业分包'
} as const
export const CALCULATION_METHOD = {
guidancePrice: '指导价法',
contractPrice: '合同价法',
virtualOutput: '虚拟产值法'
} as const
export const VIRTUAL_CALCULATION_METHOD = {
guidancePrice: '指导单价法',
guidanceTotalPrice: '指导总价法',
workingDay: '工日法'
} as const
export const DESIGN_STAGE = {
scheme: '方案',
constructionDrawing: '施工图',
schemeAndConstructionDrawing: '方案+施工图'
} as const
export const DESIGN_PART = {
realEstate: '地上部分',
underground: '地下部分'
} as const
export const PROJECT_TYPE = {
building: '建筑工程',
decoration: '精装工程',
comprehensive: '综合工程',
special: '专项设计',
bim: 'BIM设计',
other: '其他'
} as const
export const PROJECT_CATEGORY = {
residential: '住宅',
publicBuilding: '公建',
industry: '工业',
landscape: '园林景观',
other: '其他'
} as const
export const PROJECT_STATUS = {
inProgress: '进行中',
completed: '完成',
paused: '暂停',
terminated: '中止'
} as const
export const EMPLOYEE_GENDER = {
male: '男',
female: '女'
} as const
export const EMPLOYEE_STATUS = {
active: '在职',
resigned: '离职',
suspended: '停职'
} as const
const normalizeValue = (value: string | undefined, validValues: string[]) =>
value && validValues.includes(value) ? value : undefined
const findLabel = <T>(options: Array<Option<T>>, value?: T | string) =>
options.find((item) => String(item.value) === String(value))?.label
export const normalizeOwnershipType = (value?: string) =>
normalizeValue(value, Object.values(OWNERSHIP_TYPE))
export const normalizeCalculationMethod = (value?: string) =>
normalizeValue(value, Object.values(CALCULATION_METHOD))
export const normalizeVirtualCalculationMethod = (value?: string) =>
normalizeValue(value, Object.values(VIRTUAL_CALCULATION_METHOD))
export const normalizeDesignStage = (value?: string) =>
normalizeValue(value, Object.values(DESIGN_STAGE))
export const normalizeDesignPart = (value?: string) =>
normalizeValue(value, Object.values(DESIGN_PART))
export const normalizeProjectType = (value?: string) =>
normalizeValue(value, Object.values(PROJECT_TYPE))
export const normalizeProjectCategory = (value?: string) =>
normalizeValue(value, Object.values(PROJECT_CATEGORY))
export const normalizeProjectStatus = (value?: string) =>
normalizeValue(value, Object.values(PROJECT_STATUS))
export const OWNERSHIP_TYPE_OPTIONS: Option[] = [
{ label: OWNERSHIP_TYPE.major, value: OWNERSHIP_TYPE.major },
{ label: OWNERSHIP_TYPE.comprehensive, value: OWNERSHIP_TYPE.comprehensive },
{ label: OWNERSHIP_TYPE.subcontract, value: OWNERSHIP_TYPE.subcontract }
]
export const CALCULATION_METHOD_OPTIONS: Option[] = [
{ label: CALCULATION_METHOD.guidancePrice, value: CALCULATION_METHOD.guidancePrice },
{ label: CALCULATION_METHOD.contractPrice, value: CALCULATION_METHOD.contractPrice },
{ label: CALCULATION_METHOD.virtualOutput, value: CALCULATION_METHOD.virtualOutput }
]
export const VIRTUAL_CALCULATION_METHOD_OPTIONS: Option[] = [
{
label: VIRTUAL_CALCULATION_METHOD.guidancePrice,
value: VIRTUAL_CALCULATION_METHOD.guidancePrice
},
{
label: VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice,
value: VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice
},
{ label: VIRTUAL_CALCULATION_METHOD.workingDay, value: VIRTUAL_CALCULATION_METHOD.workingDay }
]
export const DESIGN_STAGE_OPTIONS: Option[] = [
{ label: DESIGN_STAGE.scheme, value: DESIGN_STAGE.scheme },
{ label: DESIGN_STAGE.constructionDrawing, value: DESIGN_STAGE.constructionDrawing },
{
label: DESIGN_STAGE.schemeAndConstructionDrawing,
value: DESIGN_STAGE.schemeAndConstructionDrawing
}
]
export const DESIGN_PART_OPTIONS: Option[] = [
{ label: DESIGN_PART.realEstate, value: DESIGN_PART.realEstate },
{ label: DESIGN_PART.underground, value: DESIGN_PART.underground }
]
export const CONTRACT_SIGN_OPTIONS: Option<boolean>[] = [
{ label: '已签约', value: true },
{ label: '未签约', value: false }
]
export const PROJECT_TYPE_OPTIONS: Option[] = [
{ label: PROJECT_TYPE.building, value: PROJECT_TYPE.building },
{ label: PROJECT_TYPE.decoration, value: PROJECT_TYPE.decoration },
{ label: PROJECT_TYPE.comprehensive, value: PROJECT_TYPE.comprehensive },
{ label: PROJECT_TYPE.special, value: PROJECT_TYPE.special },
{ label: PROJECT_TYPE.bim, value: PROJECT_TYPE.bim },
{ label: PROJECT_TYPE.other, value: PROJECT_TYPE.other }
]
export const PROJECT_CATEGORY_OPTIONS: Option[] = [
{ label: PROJECT_CATEGORY.residential, value: PROJECT_CATEGORY.residential },
{ label: PROJECT_CATEGORY.publicBuilding, value: PROJECT_CATEGORY.publicBuilding },
{ label: PROJECT_CATEGORY.industry, value: PROJECT_CATEGORY.industry },
{ label: PROJECT_CATEGORY.landscape, value: PROJECT_CATEGORY.landscape },
{ label: PROJECT_CATEGORY.other, value: PROJECT_CATEGORY.other }
]
export const PROJECT_STATUS_OPTIONS: Option[] = [
{ label: PROJECT_STATUS.inProgress, value: PROJECT_STATUS.inProgress },
{ label: PROJECT_STATUS.completed, value: PROJECT_STATUS.completed },
{ label: PROJECT_STATUS.paused, value: PROJECT_STATUS.paused },
{ label: PROJECT_STATUS.terminated, value: PROJECT_STATUS.terminated }
]
export const EMPLOYEE_GENDER_OPTIONS: Option[] = [
{ label: EMPLOYEE_GENDER.male, value: EMPLOYEE_GENDER.male },
{ label: EMPLOYEE_GENDER.female, value: EMPLOYEE_GENDER.female }
]
export const EMPLOYEE_STATUS_OPTIONS: Option[] = [
{ label: EMPLOYEE_STATUS.active, value: EMPLOYEE_STATUS.active },
{ label: EMPLOYEE_STATUS.resigned, value: EMPLOYEE_STATUS.resigned },
{ label: EMPLOYEE_STATUS.suspended, value: EMPLOYEE_STATUS.suspended }
]
export const EMPLOYEE_JOB_TITLE = {
junior: '初级',
intermediate: '中级',
viceSenior: '副高级',
senior: '正高级'
} as const
export const EMPLOYEE_JOB_TITLE_OPTIONS: Option[] = [
{ label: EMPLOYEE_JOB_TITLE.junior, value: EMPLOYEE_JOB_TITLE.junior },
{ label: EMPLOYEE_JOB_TITLE.intermediate, value: EMPLOYEE_JOB_TITLE.intermediate },
{ label: EMPLOYEE_JOB_TITLE.viceSenior, value: EMPLOYEE_JOB_TITLE.viceSenior },
{ label: EMPLOYEE_JOB_TITLE.senior, value: EMPLOYEE_JOB_TITLE.senior }
]
export const DEFAULT_INNOVATION_OUTPUT_RATE = 0.01
export const DEFAULT_WORKING_DAY_UNIT_PRICE = 1000
export const QUARTER_OPTIONS: Option<number>[] = [
{ label: '一季度', value: 1 },
{ label: '二季度', value: 2 },
{ label: '三季度', value: 3 },
{ label: '四季度', value: 4 }
]
export const OUTPUT_SPLIT_SPECIALTY_OPTIONS: Option[] = [
{ label: '建筑', value: 'arch' },
{ label: '装饰', value: 'decor' },
{ label: '结构', value: 'struct' },
{ label: '给排水', value: 'water' },
{ label: '电气', value: 'elec' },
{ label: '暖通', value: 'hvac' },
{ label: '数字化设计', value: 'digital' }
]
export const SPECIALTY_ROLE_OPTIONS: Option[] = [
{ label: '专业负责人', value: 'director' },
{ label: '校对', value: 'check' },
{ label: '审核', value: 'review' },
{ label: '审定', value: 'approve' },
{ label: '设计', value: 'design' }
]
export const isMajorOwnership = (value?: string) =>
normalizeOwnershipType(value) === OWNERSHIP_TYPE.major
export const isComprehensiveOwnership = (value?: string) =>
normalizeOwnershipType(value) === OWNERSHIP_TYPE.comprehensive
export const isSubcontractOwnership = (value?: string) =>
normalizeOwnershipType(value) === OWNERSHIP_TYPE.subcontract
export const isGuidancePriceMethod = (value?: string) =>
normalizeCalculationMethod(value) === CALCULATION_METHOD.guidancePrice
export const isContractPriceMethod = (value?: string) =>
normalizeCalculationMethod(value) === CALCULATION_METHOD.contractPrice
export const isVirtualOutputMethod = (value?: string) =>
normalizeCalculationMethod(value) === CALCULATION_METHOD.virtualOutput
export const isVirtualGuidanceMethod = (value?: string) =>
normalizeVirtualCalculationMethod(value) === VIRTUAL_CALCULATION_METHOD.guidancePrice
export const isVirtualGuidanceTotalPriceMethod = (value?: string) =>
normalizeVirtualCalculationMethod(value) === VIRTUAL_CALCULATION_METHOD.guidanceTotalPrice
export const isWorkingDayMethod = (value?: string) =>
normalizeVirtualCalculationMethod(value) === VIRTUAL_CALCULATION_METHOD.workingDay
export const getOwnershipTypeLabel = (value?: string) =>
findLabel(OWNERSHIP_TYPE_OPTIONS, normalizeOwnershipType(value)) || '-'
export const getCalculationMethodLabel = (value?: string) =>
findLabel(CALCULATION_METHOD_OPTIONS, normalizeCalculationMethod(value)) || '-'
export const getProjectTypeLabel = (value?: string) =>
findLabel(PROJECT_TYPE_OPTIONS, normalizeProjectType(value)) || '-'
export const getProjectCategoryLabel = (value?: string) =>
findLabel(PROJECT_CATEGORY_OPTIONS, normalizeProjectCategory(value)) || '-'
export const getProjectStatusLabel = (value?: string) =>
findLabel(PROJECT_STATUS_OPTIONS, normalizeProjectStatus(value)) || '-'
export const getDesignStageLabel = (value?: string) =>
findLabel(DESIGN_STAGE_OPTIONS, normalizeDesignStage(value)) || '-'
export const getDesignPartLabel = (value?: string) =>
findLabel(DESIGN_PART_OPTIONS, normalizeDesignPart(value)) || '-'
export const getVirtualCalculationMethodLabel = (value?: string) =>
findLabel(VIRTUAL_CALCULATION_METHOD_OPTIONS, normalizeVirtualCalculationMethod(value)) || '-'
export const getCalculationRatioLabel = (ownershipType?: string) => {
if (isComprehensiveOwnership(ownershipType)) {
return '协作比例'
}
if (isSubcontractOwnership(ownershipType)) {
return '分包比例'
}
return '比例'
}
export const getReviewOutsourceDefaultPercent = (
ownershipType?: string,
reviewOutsourceFlag?: boolean
) => {
if (!reviewOutsourceFlag) {
return 0
}
if (isMajorOwnership(ownershipType)) {
return 6
}
return 25
}
export const getCalculationRatioDefaultPercent = (ownershipType?: string) => {
if (isComprehensiveOwnership(ownershipType)) {
return 8
}
if (isSubcontractOwnership(ownershipType)) {
return 4
}
return undefined
}
export const toPercentValue = (value?: number | string | null, digits = 2) => {
if (value === undefined || value === null || value === '') {
return undefined
}
const numericValue = Number(value)
if (Number.isNaN(numericValue)) {
return undefined
}
return Number((numericValue * 100).toFixed(digits))
}
export const fromPercentValue = (value?: number | string | null, digits = 4) => {
if (value === undefined || value === null || value === '') {
return undefined
}
const numericValue = Number(value)
if (Number.isNaN(numericValue)) {
return undefined
}
return Number((numericValue / 100).toFixed(digits))
}
export const formatAmountText = (value?: number | string | null) => {
if (value === undefined || value === null || value === '') {
return '0.00'
}
const numericValue = Number(value)
if (Number.isNaN(numericValue)) {
return '0.00'
}
return numericValue.toFixed(2)
}
export const formatAreaText = (value?: number | string | null) => `${formatAmountText(value)}`
export const formatPercentText = (value?: number | string | null, digits = 2) => {
const percentValue = toPercentValue(value, digits)
return `${(percentValue ?? 0).toFixed(digits)}%`
}