From af23f61991df81972bd6b61858a53a02c1a82900 Mon Sep 17 00:00:00 2001 From: ctexthuang Date: Tue, 25 Feb 2025 18:01:14 +0800 Subject: [PATCH] feat : coupon template --- app/Constants/Common/CouponCode.php | 40 +++++ app/Controller/Admin/CouponController.php | 99 ++++++++++++ app/Model/CouponDispenseLog.php | 46 ++++++ app/Model/CouponTemplate.php | 49 ++++++ .../Admin/Coupon/DispenseAddService.php | 21 +++ .../Admin/Coupon/DispenseConfirmService.php | 153 ++++++++++++++++++ app/Service/Admin/Coupon/DispenseService.php | 21 +++ app/Service/Admin/Coupon/TemplateService.php | 118 ++++++++++++++ .../Admin/CouponDispenseTrait.php | 128 +++++++++++++++ 9 files changed, 675 insertions(+) create mode 100644 app/Constants/Common/CouponCode.php create mode 100644 app/Controller/Admin/CouponController.php create mode 100644 app/Model/CouponDispenseLog.php create mode 100644 app/Model/CouponTemplate.php create mode 100644 app/Service/Admin/Coupon/DispenseAddService.php create mode 100644 app/Service/Admin/Coupon/DispenseConfirmService.php create mode 100644 app/Service/Admin/Coupon/DispenseService.php create mode 100644 app/Service/Admin/Coupon/TemplateService.php create mode 100644 app/Service/ServiceTrait/Admin/CouponDispenseTrait.php diff --git a/app/Constants/Common/CouponCode.php b/app/Constants/Common/CouponCode.php new file mode 100644 index 0000000..a01b93e --- /dev/null +++ b/app/Constants/Common/CouponCode.php @@ -0,0 +1,40 @@ +add(); + } + + /** + * @return array|null + */ + #[RequestMapping(path: "template_list", methods: "GET")] + #[Scene(scene: "template_list")] + public function templateList() + { + return (new TemplateService)->handle(); + } + + /** + * @return array + */ + #[RequestMapping(path: "template_edit", methods: "POST")] + #[Scene(scene: "template_edit")] + public function templateEdit() + { + return (new TemplateService)->edit(); + } + + /** + * @return array + */ + #[RequestMapping(path: "template_change_status", methods: "GET")] + #[Scene(scene: "template_change_status")] + public function templateChangeStatus() + { + return (new TemplateService)->changeStatus(); + } + + /** + * @return array + */ + #[RequestMapping(path: "template_info", methods: "GET")] + #[Scene(scene: "template_info")] + public function templateInfo() + { + return (new TemplateService)->info(); + } + + #[RequestMapping(path: "dispense_list", methods: "GET")] + #[Scene(scene: "dispense_list")] + public function dispenseList() + { + + } + + #[RequestMapping(path: "dispense_add", methods: "POST")] + #[Scene(scene: "dispense_add")] + public function dispenseAdd() + { + return (new DispenseAddService)->handle(); + } + + #[RequestMapping(path: "dispense_confirm", methods: "POST")] + #[Scene(scene: "dispense_confirm")] + public function dispenseConfirm() + { + return (new DispenseConfirmService)->handle(); + } + + #[RequestMapping(path: "dispense_info", methods: "GET")] + #[Scene(scene: "dispense_info")] + public function dispenseInfo() + { + + } +} diff --git a/app/Model/CouponDispenseLog.php b/app/Model/CouponDispenseLog.php new file mode 100644 index 0000000..215fe11 --- /dev/null +++ b/app/Model/CouponDispenseLog.php @@ -0,0 +1,46 @@ + 'integer', 'coupon_template_id' => 'integer', 'send_count' => 'integer', 'receive_count' => 'integer', 'left_count' => 'integer', 'item_count' => 'integer', 'appoint_group' => 'integer', 'claim_rule' => 'integer', 'appoint_city_id' => 'integer', 'validity_time_type' => 'integer']; +} diff --git a/app/Model/CouponTemplate.php b/app/Model/CouponTemplate.php new file mode 100644 index 0000000..4910cb6 --- /dev/null +++ b/app/Model/CouponTemplate.php @@ -0,0 +1,49 @@ + 'integer', 'coupon_type' => 'integer', 'is_admin_edit' => 'integer', 'status' => 'integer']; + + const string CREATED_AT = 'created_time'; + const string UPDATED_AT = 'updated_time'; + + /** + * @param int $id + * @return CouponTemplate|\Hyperf\Database\Model\Model|array|null + */ + public function getInfoById(int $id): CouponTemplate|\Hyperf\Database\Model\Model|array|null + { + return $this->find($id); + } +} diff --git a/app/Service/Admin/Coupon/DispenseAddService.php b/app/Service/Admin/Coupon/DispenseAddService.php new file mode 100644 index 0000000..7009038 --- /dev/null +++ b/app/Service/Admin/Coupon/DispenseAddService.php @@ -0,0 +1,21 @@ +res = []; + + if (empty($this->request->input('appoint_value'))) throw new Exception('请选择指定值'); + + match ($this->groupType = (int)$this->request->input('appoint_group',CouponCode::DISPENSE_APPOINT_GROUP_ALL_PEOPLE)) + { + CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_USERS => $this->handleDesignatedUsers(), + CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_SITES => $this->handleDesignatedSites(), + CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_GOODS => $this->handleDesignatedGoods(), + CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_SITES_AND_GOODS => $this->handleDesignatedSitesAndGoods(), + default => throw new Exception('不需要渲染用户数据') + }; + + return $this->return->success('success',['list' => $this->res]); + }catch (Exception $e) { + throw new ErrException($e->getMessage()); + } + } + + private function handleDesignatedUsers() + { + + } + + private function handleDesignatedSitesAndGoods() + { + $this->getValueAndCheckDate(); + + $this->checkSite(); + + $this->checkSku(); + + $this->getUserData(); + } + + private function handleDesignatedSites() + { + $this->getValueAndCheckDate(); + + $this->checkSite(); + + $this->getUserData(); + } + + private function handleDesignatedGoods() + { + $this->getValueAndCheckDate(); + + $this->checkSku(); + + $this->getUserData(); + } + +} \ No newline at end of file diff --git a/app/Service/Admin/Coupon/DispenseService.php b/app/Service/Admin/Coupon/DispenseService.php new file mode 100644 index 0000000..59079a4 --- /dev/null +++ b/app/Service/Admin/Coupon/DispenseService.php @@ -0,0 +1,21 @@ +request->input('limit', 10); + + $list = $this + ->couponTemplateModel + ->when($searchName = $this->request->input('query_name'), function ($query) use ($searchName) { + $query->where('name', 'like', "$searchName%"); + }) + ->when($status = $this->request->input('query_status'), function ($query) use ($status) { + $query->where('id', $status); + }) + ->paginate($limit,['chinese_name','id','mobile','status'])->toArray(); + + return $this->return->success('success',$list); + } + + /** + * @return array + * @throws ErrException + */ + public function add(): array + { + $insertModel = new CouponTemplate(); + + $insertModel->name = $this->request->input('name'); + $insertModel->coupon_type = $this->request->input('coupon_type'); + $insertModel->amount = $this->request->input('amount','0.00'); + $insertModel->ratio = $this->request->input('ratio','0.00'); + $insertModel->is_admin_edit = CouponCode::IS_ADMIN_EDIT; + $insertModel->status = CouponCode::COUPON_TEMPLATE_STATUS_NORMAL; + + if (!$insertModel->save()) throw new ErrException('保存优惠券模板失败'); + + return $this->return->success(); + } + + /** + * @return array + * @throws ErrException + */ + public function edit(): array + { + $id = (int)$this->request->input('id'); + + $info = $this->couponTemplateModel->getInfoById($id); + if (!$info) throw new ErrException('优惠券模板不存在'); + + if ($info->is_admin_edit != CouponCode::IS_ADMIN_EDIT) throw new ErrException('该优惠券模板不允许修改,请联系运维或者后端工程师在不影响程序的情况下进行修改'); + + $info->name = $this->request->input('name'); + $info->coupon_type = $this->request->input('coupon_type'); + $info->amount = $this->request->input('amount','0.00'); + $info->ratio = $this->request->input('ratio','0.00'); + + if (!$info->save()) throw new ErrException('保存优惠券模板失败'); + + return $this->return->success(); + } + + /** + * @return array + */ + public function changeStatus(): array + { + $id = (int)$this->request->input('id'); + + $info = $this->couponTemplateModel->getInfoById($id); + if (!$info) throw new ErrException('优惠券模板不存在'); + + $info->status = $info->status == CouponCode::COUPON_TEMPLATE_STATUS_NORMAL ? CouponCode::COUPON_TEMPLATE_STATUS_ENABLE : CouponCode::COUPON_TEMPLATE_STATUS_NORMAL; + + if (!$info->save()) throw new ErrException('保存优惠券模板失败'); + + return $this->return->success(); + } + + /** + * @return array + */ + public function info(): array + { + $id = (int)$this->request->input('id'); + + $info = $this->couponTemplateModel->getInfoById($id); + + return $this->return->success('success',$info->toArray()); + } +} \ No newline at end of file diff --git a/app/Service/ServiceTrait/Admin/CouponDispenseTrait.php b/app/Service/ServiceTrait/Admin/CouponDispenseTrait.php new file mode 100644 index 0000000..1f9f327 --- /dev/null +++ b/app/Service/ServiceTrait/Admin/CouponDispenseTrait.php @@ -0,0 +1,128 @@ +request->input('appoint_cycle_id'))) { + throw new Exception('未选中点餐周期'); + } + + $cycleInfo = $this->cycleModel->getInfoById((int)$cycleId); + + if (empty($cycleInfo)) throw new Exception('未找到该点餐周期'); + + $this->cycleId = $cycleInfo->id; + $this->appointValue = explode(',', $this->request->input('appoint_value')); + unset($cycleInfo); + } + + /** + * @return void + * @throws Exception + */ + protected function checkSite(): void + { + $siteCount = $this->siteModel->whereIn('id',$this->appointValue)->count(); + + if ($siteCount != count($this->appointValue)) throw new Exception('请选择正确的站点'); + } + + /** + * @return void + * @throws Exception + */ + protected function checkSku(): void + { + $skuCount = $this->skuModel->whereIn('id',$this->appointValue)->count(); + + if ($skuCount!= count($this->appointValue)) throw new Exception('请选择正确的商品'); + } + + /** + * @return array + * @throws Exception + */ + protected function getUserData(): array + { + $userIds = []; + + switch ($this->groupType) { + case CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_SITES: + $userIds = $this->orderModel + ->where('cycle_id',$this->cycleId) + ->whereIn('site_id',$this->appointValue) + ->where('status',OrderCode::FINISH) + ->pluck('user_id') + ->toArray(); + + break; + case CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_GOODS: + $orderIds = $this->orderModel + ->where('cycle_id',$this->cycleId) + ->where('status',OrderCode::FINISH) + ->pluck('user_id','order_id') + ->toArray(); + + if (empty($orderIds)) throw new Exception('未找到该周期的订单'); + + $skuOrderIds = $this->orderGoodModel + ->whereIn('order_id',array_keys($orderIds)) + ->whereIn('sku_id',$this->appointValue) + ->pluck('order_id') + ->toArray(); + $skuOrderIds = array_unique($skuOrderIds); + + // 将 $b 转为键数组,值无所谓(可以用 null 或任意值) + $skuOrderIds_keys = array_flip($skuOrderIds); + // 获取 $a 和 $b_keys 的交集 + $intersect = array_intersect_key($orderIds, $skuOrderIds_keys); + // 提取值 + $userIds = array_values($intersect); + + break; + case CouponCode::DISPENSE_APPOINT_GROUP_DESIGNATED_SITES_AND_GOODS: + $orderIds = $this->orderModel + ->where('cycle_id',$this->cycleId) + ->whereIn('site_id',$this->appointValue) + ->where('status',OrderCode::FINISH) + ->pluck('user_id','order_id') + ->toArray(); + + if (empty($orderIds)) throw new Exception('未找到该周期的订单'); + + $skuOrderIds = $this->orderGoodModel + ->whereIn('order_id',array_keys($orderIds)) + ->whereIn('sku_id',$this->appointValue) + ->pluck('order_id') + ->toArray(); + $skuOrderIds = array_unique($skuOrderIds); + + $skuOrderIds_keys = array_flip($skuOrderIds); + $intersect = array_intersect_key($orderIds, $skuOrderIds_keys); + $userIds = array_values($intersect); + break; + } + + return $userIds; + } + + /** + * @return void + */ + protected function getUserInfoByUserIds(array $userIds) + { + + } +} \ No newline at end of file