OwnerPriceLogisticService.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. namespace App\Services;
  3. use App\Owner;
  4. use App\OwnerPriceLogistic;
  5. use App\OwnerPriceLogisticDetail;
  6. use App\Services\common\QueryService;
  7. use Illuminate\Database\Eloquent\Builder;
  8. use Illuminate\Support\Facades\DB;
  9. use App\Traits\ServiceAppAop;
  10. class OwnerPriceLogisticService
  11. {
  12. use ServiceAppAop;
  13. protected $modelClass=OwnerPriceLogistic::class;
  14. public function paginate($id = null)
  15. {
  16. $query = OwnerPriceLogistic::query()->with(["owners","logistics","unit","otherUnit"]);
  17. if ($id)$query->where("id",$id);
  18. return $query->paginate(50);
  19. }
  20. public function create(array $params)
  21. {
  22. $params["operation"] = "C";
  23. return OwnerPriceLogistic::query()->create($params);
  24. }
  25. public function find($id, $withs=[])
  26. {
  27. return OwnerPriceLogistic::query()->with($withs)->find($id);
  28. }
  29. public function update(array $params, array $values)
  30. {
  31. $query = OwnerPriceLogistic::query();
  32. foreach ($params as $column=>$param){
  33. $query->where($column,$params);
  34. }
  35. return $query->update($values);
  36. }
  37. /**
  38. * 拷贝目标数据
  39. *
  40. * @param object|int $model
  41. * @param array $values
  42. * @param array|null $owners
  43. * @param array|null $logistics
  44. * @param array $items
  45. * @param bool $isLoadItem
  46. *
  47. * @return object|null
  48. */
  49. public function copy($model, $values = [], $owners = null, $logistics = null, $items = [], $isLoadItem = true)
  50. {
  51. if (is_integer($model))$model = OwnerPriceLogistic::query()->find($model);
  52. if (!$model)return null;
  53. $values["operation"] = "U";
  54. $values["target_id"] = $model->id;
  55. foreach ($model->getFillable() as $column){
  56. if (!array_key_exists($column,$values))$values[$column] = $model[$column];
  57. }
  58. /** @var OwnerPriceLogistic $copyModel */
  59. $copyModel = OwnerPriceLogistic::query()->create($values);
  60. if ($owners===null){
  61. $query = DB::raw("SELECT * FROM owner_price_logistic_owner WHERE owner_price_logistic_id = {$model->id}");
  62. $owners = array_column(DB::select($query),"owner_id");
  63. }
  64. $copyModel->owners()->sync($owners);
  65. if ($logistics===null){
  66. $query = DB::raw("SELECT * FROM owner_price_logistic_logistic WHERE owner_price_logistic_id = {$model->id}");
  67. $logistics = array_column(DB::select($query),"logistic_id");
  68. }
  69. $copyModel->logistics()->sync($logistics);
  70. $insert = [];
  71. if ($isLoadItem){
  72. $model->loadMissing("details");
  73. /** @var \stdClass $model */
  74. foreach ($model->details as $item){
  75. $columns = ["unit_id", "range", "province_id", "city_id", "unit_price", "delivery_fee", "initial_fee", "initial_amount", "rate",];
  76. if ($items[$item->id] ?? false){
  77. foreach ($columns as $column){
  78. if (!array_key_exists($column,$items[$item->id]))$items[$item->id][$column] = $item[$column];
  79. }
  80. $obj = $items[$item->id];
  81. unset($items[$item->id]);
  82. }else{
  83. /** @var OwnerPriceLogisticDetail $item */
  84. $obj = $item->toArray();
  85. unset($obj["id"]);
  86. }
  87. $obj["owner_price_logistic_id"] = $copyModel->id;
  88. $insert[] = $obj;
  89. }
  90. }else{
  91. foreach ($items as $item){
  92. $item["owner_price_logistic_id"] = $copyModel->id;
  93. $insert[] = $item;
  94. }
  95. }
  96. if ($insert)OwnerPriceLogisticDetail::query()->insert($insert);
  97. return $copyModel;
  98. }
  99. /**
  100. * 审核或恢复目标集
  101. *
  102. * @param bool $isAudit
  103. * @param integer|null|array $ownerId
  104. * @param integer|null|array $ids
  105. */
  106. public function auditOrRecover($isAudit = true, $ownerId = null, $ids = null)
  107. {
  108. if (!$ownerId && !$ids)return;
  109. $result = app(QueryService::class)->priceModelAuditOrRecoverQuery($isAudit,OwnerPriceLogistic::query(),$ownerId,$ids);
  110. if ($result["delete"])$this->destroy($result["delete"]);
  111. if ($result["update"])OwnerPriceLogistic::query()->whereIn("id",$result["update"])->update(["operation"=>null,"target_id"=>null]);
  112. }
  113. public function destroy($id)
  114. {
  115. if (!is_array($id))$id = [$id];
  116. OwnerPriceLogisticDetail::query()->whereIn("owner_price_logistic_id",$id)->delete();
  117. DB::table("owner_price_logistic_owner")->whereIn("owner_price_logistic_id",$id)->delete();
  118. DB::table("owner_price_logistic_logistic")->whereIn("owner_price_logistic_id",$id)->delete();
  119. return OwnerPriceLogistic::destroy($id);
  120. }
  121. public function updateDetail(array $params, array $values)
  122. {
  123. $query = OwnerPriceLogisticDetail::query();
  124. foreach ($params as $column => $param){
  125. $query->where($column,$param);
  126. }
  127. return $query->update($values);
  128. }
  129. public function isExistDetail(array $params)
  130. {
  131. $query = OwnerPriceLogisticDetail::query();
  132. foreach ($params as $column => $param){
  133. $query->where($column,$param);
  134. }
  135. return $query->count();
  136. }
  137. public function createDetail(array $params)
  138. {
  139. return OwnerPriceLogisticDetail::query()->create($params);
  140. }
  141. public function destroyDetail($id)
  142. {
  143. return OwnerPriceLogisticDetail::destroy($id);
  144. }
  145. public function checkRange($range):bool
  146. {
  147. $arrRanges = explode(",",$range);
  148. $len = count($arrRanges);
  149. if ($len==0)return false; //范围为空 false
  150. $previous = []; //慢指针数组 不记录第一个值
  151. foreach ($arrRanges as $index => $value){
  152. if ($index == $len-1)$preg = "/\d*\-/"; //最后一个范围不允许封闭
  153. else $preg = "/\d*\-\d*/";
  154. preg_match($preg, $value, $match);
  155. if (!$match || $match[0]!=$value)return false;//匹配结果不等于值 false
  156. $arr = explode("-",$value); //二次切割判断是否连续
  157. if ($index != 0){
  158. if ($index == $len-1){
  159. if ((int)$arr[0] != (int)$previous[$index-1][1])return false; //最后一个范围只需要判断起始值
  160. }else{
  161. if ((int)$arr[0] != (int)$previous[$index-1][1] || (int)$arr[1] <= (int)$arr[0])return false; //普通范围起始值必须为上一个结束值 当前结束值必须大于起始值
  162. }
  163. }else{
  164. if ((int)$arr[1] <= (int)$arr[0])return false; //第一个范围只需判断当前结束值大于起始值
  165. }
  166. $previous[] = $arr;
  167. }
  168. return true;
  169. }
  170. /**
  171. *
  172. * @param double $amount
  173. * @param integer $ownerId
  174. * @param integer $logisticId
  175. * @param integer $unitId
  176. * @param integer $provinceId
  177. * @param integer $cityId
  178. * @return array
  179. */
  180. public function matching(float $amount, int $ownerId, int $logisticId, int $unitId, int $provinceId, int $cityId):array
  181. {
  182. $model = OwnerPriceLogistic::query()->with(["details"=>function($query)use($provinceId,$cityId){
  183. /** @var Builder $query */
  184. $query->where("province_id",$provinceId)->where("city_id",$cityId);
  185. }])->where(function ($query)use($unitId){
  186. /** @var Builder $query */
  187. $query->where("unit_id",$unitId)->orWhere("other_unit_id",$unitId);
  188. })->whereHas("owners",function ($query)use($ownerId){
  189. /** @var Builder $query */
  190. $query->where("id",$ownerId);
  191. })->whereHas("logistics",function ($query)use($logisticId){
  192. /** @var Builder $query */
  193. $query->where("id",$logisticId);
  194. })->where(function(Builder $query){
  195. $query->whereNull("operation")->orWhere("operation","");
  196. })->first();
  197. if (!$model || !$model->details)return array(null,null);
  198. $money = null;
  199. $GLOBALS["FEE_INFO"]["pick_fee"] = $model->pick_up_price;
  200. $GLOBALS["FEE_INFO"]["fuel_fee"] = $model->fuel_price;
  201. $GLOBALS["FEE_INFO"]["info_fee"] = $model->service_price;
  202. $GLOBALS["FEE_INFO"]["other_fee"] = 0;
  203. $fee = $model->pick_up_price + $model->fuel_price + $model->service_price; //服务费
  204. foreach ($model->details as $detail){
  205. if ($unitId != $detail->unit_id)continue;
  206. $arr = explode("-",$detail->range);
  207. if (count($arr) < 2 || !$arr[1]){
  208. if ($amount >= $arr[0])$money = $this->calculation($amount,$detail,$fee);
  209. }else{
  210. if ($amount >= $arr[0] && $amount < $arr[1])$money = $this->calculation($amount,$detail,$fee);
  211. }
  212. if ($money)break;
  213. }
  214. $taxRate = app("OwnerService")->getTaxRateFee($model, $ownerId);
  215. $taxFee = $money*($taxRate/100);
  216. $GLOBALS["FEE_INFO"]["tax_rate"] = $taxRate;
  217. $GLOBALS["FEE_INFO"]["total_fee"] = $money;
  218. return array($money,$taxFee);
  219. }
  220. private function calculation($amount, $detail, $fee)
  221. {
  222. $GLOBALS["FEE_INFO"]["interval"] = $detail->range;
  223. $GLOBALS["FEE_INFO"]["price"] = $detail->unit_price;
  224. $GLOBALS["FEE_INFO"]["delivery_fee"] = $detail->delivery_fee;
  225. $GLOBALS["FEE_INFO"]["initial_fee"] = $detail->initial_fee;
  226. $GLOBALS["FEE_INFO"]["initial_amount"] = $detail->initial_amount;
  227. if ($amount < $detail->initial_amount)$amount = $detail->initial_amount; //小于起始数以起始数为准
  228. $money = $amount * $detail->unit_price;
  229. if ($money < $detail->initial_fee)$money = $detail->initial_fee; //小于起始计费以起始计费为准
  230. return $money+$detail->delivery_fee+$fee;
  231. }
  232. }