calc.go 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package quote
  2. import (
  3. "zhiyuan/models/quote"
  4. "zhiyuan/pkg/db"
  5. "zhiyuan/pkg/utils"
  6. "zhiyuan/services/form"
  7. "zhiyuan/services/structs"
  8. )
  9. func CalcBidItemMoney(param form.QuoteOrderParam, bidItem *quote.Item, setting structs.MaterialBidCalcSetting, form form.QuoteCalc, price float64) float64 {
  10. windowArea := utils.FloatMul(param.Window, bidItem.CalcParamDecode.WindowHeight, -1)
  11. holeArea := utils.FloatMul(param.Hole, bidItem.CalcParamDecode.HoleHeight, -1)
  12. wallArea := utils.FloatMul(param.Round, bidItem.CalcParamDecode.WallHeight, -1)
  13. switch bidItem.CalcType {
  14. case 1: // 地面面积*单价
  15. return utils.FloatMul(param.Area, price, 4)
  16. case 2: // 固定数*单价
  17. return utils.FloatMul(bidItem.CalcParamDecode.FixNum, price, 4)
  18. case 4: // 墙面面积*单价
  19. return utils.FloatMul(utils.FloatSub(wallArea, holeArea, -1), price, 4)
  20. case 6: // 地面面积*损耗系数*单价
  21. return utils.FloatMulSlice([]float64{param.Area, bidItem.CalcParamDecode.LossRate, price}, 4)
  22. case 7: // 基础房间*房间单价
  23. money := utils.ToFloat64(bidItem.CalcParamDecode.BaseMoney)
  24. if setting.RoomNum > bidItem.CalcParamDecode.RoomNum {
  25. money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddRoomMoney, utils.ToFloat64(setting.RoomNum-bidItem.CalcParamDecode.RoomNum), -1), -1)
  26. }
  27. if setting.ToiletNum > bidItem.CalcParamDecode.ToiletNum {
  28. money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddToiletMoney, utils.ToFloat64(setting.ToiletNum-bidItem.CalcParamDecode.ToiletNum), -1), -1)
  29. }
  30. if setting.KitchenNum > bidItem.CalcParamDecode.KitchenNum {
  31. money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddKitchenMoney, utils.ToFloat64(setting.KitchenNum-bidItem.CalcParamDecode.KitchenNum), -1), -1)
  32. }
  33. if setting.RestaurantNum > bidItem.CalcParamDecode.RestaurantNum {
  34. money = utils.FloatAdd(money, utils.FloatMul(bidItem.CalcParamDecode.AddRestaurantMoney, utils.ToFloat64(setting.RestaurantNum-bidItem.CalcParamDecode.RestaurantNum), -1), -1)
  35. }
  36. return utils.FloatRound(money, 4)
  37. case 8: // 全房建筑面积*单价
  38. return utils.FloatMul(param.Area, price, 4)
  39. case 9: // (地面面积+墙面面积-窗户面积)*单价
  40. if param.RoomType == 1 {
  41. wallArea = utils.FloatAdd(wallArea, utils.FloatMul(1.6, bidItem.CalcParamDecode.WallHeight, -1), -1)
  42. }
  43. return utils.FloatMul(utils.FloatSubSlice([]float64{utils.FloatAdd(param.Area, wallArea, -1), holeArea, windowArea}, -1), price, 4)
  44. case 10: // 门洞*单价
  45. return utils.FloatMul(param.Hole, price, 4)
  46. case 11: // 地面周长*单价
  47. return utils.FloatMul(utils.FloatSub(param.Round, param.Hole, -1), price, 4)
  48. case 12: // 门洞周长*单价
  49. return utils.FloatMul(utils.FloatAddSlice([]float64{bidItem.CalcParamDecode.HoleHeight, bidItem.CalcParamDecode.HoleHeight, param.Hole}, -1), price, 4)
  50. case 13: // 门洞面积*单价
  51. return utils.FloatMulSlice([]float64{bidItem.CalcParamDecode.HoleHeight, param.Hole, price}, 4)
  52. case 14: // 墙面面积*损耗系数*单价
  53. return utils.FloatMulSlice([]float64{utils.FloatSub(wallArea, holeArea, -1), bidItem.CalcParamDecode.LossRate, price}, 4)
  54. case 15: // 窗台石
  55. return utils.FloatMul(utils.FloatAdd(3, utils.FloatMul(utils.ToFloat64(setting.RoomNum), 1.9, -1), -1), price, 4)
  56. case 16: // 窗宽*单价
  57. return utils.FloatMul(param.Window, price, 4)
  58. case 17: // (地面面积+客餐厅墙面面积-窗面积)*单价
  59. balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1)
  60. KitchenHoleArea := utils.FloatMul(setting.KitchenHole, bidItem.CalcParamDecode.HoleHeight, -1)
  61. return utils.FloatMul(utils.FloatSubSlice([]float64{utils.FloatAdd(param.Area, wallArea, -1), holeArea, balconyHoleArea, KitchenHoleArea, windowArea}, -1), price, 4)
  62. case 18: // 客餐厅地面周长*单价
  63. return utils.FloatMul(utils.FloatSubSlice([]float64{param.Round, param.Hole, setting.KitchenHole, setting.BalconyHole}, -1), price, 4)
  64. case 19: // (客餐厅墙面面积-窗面积)*单价
  65. balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1)
  66. KitchenHoleArea := utils.FloatMul(setting.KitchenHole, bidItem.CalcParamDecode.HoleHeight, -1)
  67. return utils.FloatMul(utils.FloatSubSlice([]float64{wallArea, holeArea, balconyHoleArea, KitchenHoleArea, windowArea}, -1), price, 4)
  68. case 20: // 地面周长*损耗系数*单价
  69. return utils.FloatMulSlice([]float64{utils.FloatSub(param.Round, param.Hole, -1), bidItem.CalcParamDecode.LossRate, price}, 4)
  70. case 21: // 客餐厅地面周长*损耗系数*单价
  71. return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{param.Round, param.Hole, setting.KitchenHole, setting.BalconyHole}, -1), bidItem.CalcParamDecode.LossRate, price}, 4)
  72. case 24: // (地面周长-固定数)*损耗系数*单价
  73. return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{param.Round, bidItem.CalcParamDecode.FixNum}, -1), bidItem.CalcParamDecode.LossRate, price}, 4)
  74. case 25: // (阳台墙面面积-阳台窗户面积)*单价
  75. balconyWallArea := utils.FloatMul(setting.BalconyRound, bidItem.CalcParamDecode.WallHeight, -1)
  76. balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1)
  77. balconyWindowArea := utils.FloatMul(setting.BalconyWindow, bidItem.CalcParamDecode.WindowHeight, -1)
  78. return utils.FloatMul(utils.FloatSubSlice([]float64{balconyWallArea, balconyHoleArea, balconyWindowArea}, -1), price, 4)
  79. case 26: // (墙面面积-窗户面积)*单价
  80. if param.RoomType == 1 {
  81. wallArea = utils.FloatAdd(wallArea, utils.FloatMul(1.6, bidItem.CalcParamDecode.WallHeight, -1), -1)
  82. }
  83. return utils.FloatMul(utils.FloatSubSlice([]float64{wallArea, holeArea, windowArea}, -1), price, 4)
  84. case 27: // 阳台地面面积*单价
  85. return utils.FloatMul(setting.BalconyArea, price, 4)
  86. case 28: // 阳台门洞周长*单价
  87. return utils.FloatMul(utils.FloatAddSlice([]float64{bidItem.CalcParamDecode.HoleHeight, bidItem.CalcParamDecode.HoleHeight, setting.BalconyHole}, -1), price, 4)
  88. case 29: // (墙面面积-窗户面积)*损耗系数*单价
  89. if param.RoomType == 1 {
  90. wallArea = utils.FloatAdd(wallArea, utils.FloatMul(1.6, bidItem.CalcParamDecode.WallHeight, -1), -1)
  91. }
  92. return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{wallArea, holeArea, windowArea}, -1), bidItem.CalcParamDecode.LossRate, price}, 4)
  93. case 30: // (地面周长+门洞)*单价
  94. return utils.FloatMul(param.Round, price, 4)
  95. case 31: // (阳台墙面面积-阳台窗户面积)*损耗系数*单价
  96. balconyWallArea := utils.FloatMul(setting.BalconyRound, bidItem.CalcParamDecode.WallHeight, -1)
  97. balconyHoleArea := utils.FloatMul(setting.BalconyHole, bidItem.CalcParamDecode.HoleHeight, -1)
  98. balconyWindowArea := utils.FloatMul(setting.BalconyWindow, bidItem.CalcParamDecode.WindowHeight, -1)
  99. return utils.FloatMulSlice([]float64{utils.FloatSubSlice([]float64{balconyWallArea, balconyHoleArea, balconyWindowArea}, -1), bidItem.CalcParamDecode.LossRate, price}, 4)
  100. default:
  101. return 0
  102. }
  103. }
  104. func Calc(forms form.QuoteCalc) structs.QuoteReturn {
  105. var ret structs.QuoteReturn
  106. ret.Categorys = make(map[int64]float64)
  107. itemList := make([]*quote.Item, 0)
  108. db.GetModel(map[string]interface{}{}, &itemList)
  109. itemListMap := make(map[int64][]*quote.Item)
  110. for _, v := range itemList {
  111. if _, ok := itemListMap[v.RoomType]; !ok {
  112. itemListMap[v.RoomType] = make([]*quote.Item, 0)
  113. }
  114. if v.CalcParam != "" {
  115. utils.JsonDecode(v.CalcParam).To(&v.CalcParamDecode)
  116. }
  117. itemListMap[v.RoomType] = append(itemListMap[v.RoomType], v)
  118. }
  119. calcSetting := structs.MaterialBidCalcSetting{RoomNum: 0, ToiletNum: 0, RestaurantNum: 0, KitchenNum: 0}
  120. for _, v := range forms.Param {
  121. switch v.RoomType {
  122. case 1:
  123. calcSetting.RoomNum++
  124. case 2:
  125. calcSetting.RestaurantNum++
  126. case 3:
  127. calcSetting.KitchenNum++
  128. case 4:
  129. calcSetting.ToiletNum++
  130. }
  131. if v.RoomType == 3 {
  132. calcSetting.KitchenHole = v.Hole
  133. } else if v.RoomType == 5 {
  134. calcSetting.BalconyArea = v.Area
  135. calcSetting.BalconyHole = v.Hole
  136. calcSetting.BalconyRound = v.Round
  137. calcSetting.BalconyWindow = v.Window
  138. }
  139. }
  140. for _, v := range forms.Param {
  141. if v.RoomType == 3 {
  142. calcSetting.KitchenHole = v.Hole
  143. } else if v.RoomType == 5 {
  144. calcSetting.BalconyArea = v.Area
  145. calcSetting.BalconyHole = v.Hole
  146. calcSetting.BalconyRound = v.Round
  147. calcSetting.BalconyWindow = v.Window
  148. }
  149. }
  150. for _, v := range forms.Param {
  151. orderReturn := structs.QuoteOrderReturn{RoomType: v.RoomType, RoomName: v.RoomName, Categorys: make(map[int64]float64), Total: 0}
  152. itemMap := make(map[int64]form.QuoteOrderItem)
  153. for _, i := range v.Items {
  154. itemMap[i.ID] = i
  155. }
  156. items, ok := itemListMap[v.RoomType]
  157. if !ok {
  158. break
  159. }
  160. for _, i := range items {
  161. price := i.Price
  162. if p, ok := itemMap[i.ID]; ok {
  163. price = p.Price
  164. }
  165. total := CalcBidItemMoney(v, i, calcSetting, forms, price)
  166. itemReturn := structs.QuoteOrderItemReturn{ID: i.ID, Category: i.Category, Name: i.Name, Price: price, Description: i.Description, Total: total}
  167. orderReturn.Items = append(orderReturn.Items, itemReturn)
  168. orderReturn.Total += total
  169. if _, ok := orderReturn.Categorys[i.Category]; !ok {
  170. orderReturn.Categorys[i.Category] = 0
  171. }
  172. orderReturn.Categorys[i.Category] += total
  173. if _, ok := ret.Categorys[i.Category]; !ok {
  174. ret.Categorys[i.Category] = 0
  175. }
  176. ret.Categorys[i.Category] += total
  177. }
  178. ret.Rooms = append(ret.Rooms, orderReturn)
  179. ret.Total += orderReturn.Total
  180. }
  181. return ret
  182. }