package pkg2024 import ( "math" "zhiyuan/models/final" "zhiyuan/pkg/utils" ) const ( 拆除 int = iota 水电 泥工 木工 油漆 防水 封包管道 其他 水电基础 水电安装 水电材料 油漆材料 木工材料 沙石材料 开工形象 开关面板 杂费 ) type ItemStringFunction func(context *ItemContext) (string, error) type ItemNumberFunction func(context *ItemContext) (float64, error) type ItemTotalFunction func(context *ItemContext, number float64) (float64, error) type ItemJudgmentFunction func(context *ItemContext) (bool, error) type ItemIntFunction func(context *ItemContext) (int64, error) type ItemPersonalFunction func(context *ItemContext) ([]PersonalItem, error) type ItemMaterialFunction func(context *ItemContext) ([]MaterialItem, error) type SplitItem struct { Type int Price float64 PriceCalc ItemNumberFunction TotalCalc ItemTotalFunction } type BuildItem struct { Name string Type int Price float64 PriceCalc ItemNumberFunction MaterialNumberCalc ItemJudgmentFunction Unit string Remark string Splits []SplitItem SpecialProject bool SpecialProjectCalc ItemJudgmentFunction } func (item BuildItem) GetPrice(context *ItemContext) (float64, error) { if item.PriceCalc != nil { return item.PriceCalc(context) } return item.Price, nil } func (item BuildItem) GetSpecialProject(context *ItemContext) (bool, error) { if item.SpecialProjectCalc != nil { return item.SpecialProjectCalc(context) } return item.SpecialProject, nil } type PkgItemObject struct { Item string ItemSelect ItemStringFunction Number float64 NumberCalc ItemNumberFunction PkgNumber float64 PkgNumberCalc ItemNumberFunction Loss float64 LossCalc ItemNumberFunction Convert float64 ConvertCalc ItemNumberFunction MaterialNumberCalc ItemNumberFunction Region string Unit string UnitCalc ItemStringFunction MaterialType string MaterialRound bool ControlPrice map[int]float64 ControlPriceCalc ItemNumberFunction DeductionPrice map[int]float64 DeductionPriceCalc ItemNumberFunction DiffPrice map[int]float64 DiffPriceCalc ItemNumberFunction MaterialAdditionalItemCalc ItemPersonalFunction AdditionalMaterialCalc ItemMaterialFunction CostLoss float64 CostLossCalc ItemNumberFunction NoUpgrade bool } func (pkgItem PkgItemObject) GetLoss(context *ItemContext) (float64, error) { if pkgItem.LossCalc != nil { return pkgItem.LossCalc(context) } if pkgItem.Loss == 0 { return 1, nil } return pkgItem.Loss, nil } func (pkgItem PkgItemObject) GetCostLoss(context *ItemContext) (float64, error) { if pkgItem.CostLossCalc != nil { return pkgItem.CostLossCalc(context) } if pkgItem.CostLoss != 0 { return pkgItem.CostLoss, nil } return pkgItem.GetLoss(context) } func (pkgItem PkgItemObject) GetConvert(context *ItemContext) (float64, error) { if pkgItem.ConvertCalc != nil { return pkgItem.ConvertCalc(context) } if pkgItem.Convert == 0 { return 1, nil } return pkgItem.Convert, nil } func (pkgItem PkgItemObject) GetLossNumber(context *ItemContext) (float64, error) { number, err := pkgItem.GetNumber(context) if err != nil { return 0, err } loss, err := pkgItem.GetLoss(context) if err != nil { return 0, err } return utils.FloatMul(number, loss, -1), nil } func (pkgItem PkgItemObject) GetCostLossNumber(context *ItemContext) (float64, error) { number, err := pkgItem.GetNumber(context) if err != nil { return 0, err } if number < 0 { number = 0 } loss, err := pkgItem.GetCostLoss(context) if err != nil { return 0, err } return utils.FloatMul(number, loss, -1), nil } func (pkgItem PkgItemObject) GetCostMaterialNumber(context *ItemContext) (float64, error) { if pkgItem.MaterialNumberCalc != nil { return pkgItem.MaterialNumberCalc(context) } number, err := pkgItem.GetCostLossNumber(context) if err != nil { return 0, err } convert, err := pkgItem.GetConvert(context) if err != nil { return 0, err } number = utils.FloatMul(number, convert, -1) if pkgItem.MaterialRound { number = math.Ceil(number) } return number, nil } func (pkgItem PkgItemObject) GetMaterialNumber(context *ItemContext) (float64, error) { if pkgItem.MaterialNumberCalc != nil { return pkgItem.MaterialNumberCalc(context) } number, err := pkgItem.GetLossNumber(context) if err != nil { return 0, err } convert, err := pkgItem.GetConvert(context) if err != nil { return 0, err } number = utils.FloatMul(number, convert, -1) if pkgItem.MaterialRound { number = math.Ceil(number) } return number, nil } func (pkgItem PkgItemObject) GetItem(context *ItemContext) (string, error) { if pkgItem.ItemSelect != nil { return pkgItem.ItemSelect(context) } return pkgItem.Item, nil } func (pkgItem PkgItemObject) GetNumber(context *ItemContext) (float64, error) { number := pkgItem.Number if pkgItem.NumberCalc != nil { var err error number, err = pkgItem.NumberCalc(context) if err != nil { return number, nil } } if number < 0 { number = 0 } return number, nil } func (pkgItem PkgItemObject) GetPkgNumber(context *ItemContext) (float64, error) { if pkgItem.PkgNumberCalc != nil { return pkgItem.PkgNumberCalc(context) } if pkgItem.PkgNumber != 0 { return pkgItem.PkgNumber, nil } if pkgItem.NumberCalc != nil { return pkgItem.NumberCalc(context) } return pkgItem.Number, nil } func (pkgItem PkgItemObject) GetControlPrice(context *ItemContext) (float64, error) { if pkgItem.ControlPriceCalc != nil { return pkgItem.ControlPriceCalc(context) } return pkgItem.ControlPrice[context.Pkg.RoomData.Pkg.Type], nil } func (pkgItem PkgItemObject) GetDeductionPrice(context *ItemContext) (float64, error) { if pkgItem.DeductionPriceCalc != nil { return pkgItem.DeductionPriceCalc(context) } return pkgItem.DeductionPrice[context.Pkg.RoomData.Pkg.Type], nil } func (pkgItem PkgItemObject) GetUnit(context *ItemContext) (string, error) { if pkgItem.UnitCalc != nil { return pkgItem.UnitCalc(context) } return pkgItem.Unit, nil } func (pkgItem PkgItemObject) GetMatUnit(context *ItemContext, mat *final.FinalMat) (string, error) { unit, err := pkgItem.GetUnit(context) if err != nil { return unit, err } if unit != "" { return unit, nil } if mat != nil { typ, ok := context.MatTypeCache[mat.TypeId] if ok { return typ.Unit, nil } } return "", nil } func (pkgItem PkgItemObject) GetMatPrice(context *ItemContext, mat *final.FinalMat) (float64, error) { convert, err := pkgItem.GetConvert(context) if err != nil { return 0, err } matPrice := utils.FloatMul(mat.Price, convert, 3) return matPrice, nil } func (pkgItem PkgItemObject) GetMatSalesPrice(context *ItemContext, salesPrice float64) (float64, error) { convert, err := pkgItem.GetConvert(context) if err != nil { return 0, err } matMatSalesPrice := utils.FloatMul(salesPrice, convert, -1) return matMatSalesPrice, nil } func (pkgItem PkgItemObject) GetMatPurchasePrice(context *ItemContext, mat *final.FinalMat) (float64, error) { convert, err := pkgItem.GetConvert(context) if err != nil { return 0, err } matMatPurchasePrice := utils.FloatMul(final.PurchasePrice(mat.PurchasePrice, mat.Price), convert, -1) return matMatPurchasePrice, nil } func (pkgItem PkgItemObject) GetUpgradePrice(context *ItemContext, matControlPrice float64) (float64, error) { if pkgItem.NoUpgrade { return 0, nil } controlPrice, err := pkgItem.GetControlPrice(context) if err != nil { return 0, err } convert, err := pkgItem.GetConvert(context) if err != nil { return 0, err } matControlPrice = utils.FloatMul(matControlPrice, convert, -1) if matControlPrice > controlPrice { return math.Ceil(utils.FloatDiv(utils.FloatSub(matControlPrice, controlPrice, -1), 0.84, -1)*100) / 100, nil } return 0, nil } func (pkgItem PkgItemObject) GetUpgradeNumber(context *ItemContext) (float64, error) { lossNumber, err := pkgItem.GetLossNumber(context) if err != nil { return 0, err } pkgNumber, err := pkgItem.GetPkgNumber(context) if err != nil { return 0, err } if lossNumber > pkgNumber { return pkgNumber, nil } return lossNumber, nil } func (pkgItem PkgItemObject) GetPkgLossNumber(context *ItemContext) (float64, error) { number, err := pkgItem.GetPkgNumber(context) if err != nil { return 0, err } loss, err := pkgItem.GetLoss(context) if err != nil { return 0, err } return utils.FloatMul(number, loss, -1), nil } func (pkgItem PkgItemObject) GetAdditionalNumber(context *ItemContext) (float64, error) { lossNumber, err := pkgItem.GetLossNumber(context) if err != nil { return 0, err } pkgLossNumber, err := pkgItem.GetPkgLossNumber(context) if err != nil { return 0, err } if lossNumber > pkgLossNumber { return utils.FloatSub(lossNumber, pkgLossNumber, -1), nil } return 0, nil } func (pkgItem PkgItemObject) GetDiffPrice(context *ItemContext) (float64, error) { if pkgItem.DiffPriceCalc != nil { return pkgItem.DiffPriceCalc(context) } return pkgItem.DiffPrice[context.Pkg.RoomData.Pkg.Type], nil } func (pkgItem PkgItemObject) GetDiffNumber(context *ItemContext) (float64, error) { number, err := pkgItem.GetNumber(context) if err != nil { return 0, err } pkgNumber, err := pkgItem.GetPkgNumber(context) if err != nil { return 0, err } if number > pkgNumber { return pkgNumber, nil } return number, nil } type SubsidyItemObject struct { Name string Unit string Number float64 NumberCalc ItemNumberFunction Price float64 PriceCalc ItemNumberFunction } func (subsidyItem SubsidyItemObject) GetNumber(context *ItemContext) (float64, error) { if subsidyItem.NumberCalc != nil { return subsidyItem.NumberCalc(context) } return subsidyItem.Number, nil } func (subsidyItem SubsidyItemObject) GetPrice(context *ItemContext) (float64, error) { if subsidyItem.PriceCalc != nil { return subsidyItem.PriceCalc(context) } return subsidyItem.Price, nil }