model = new Coupon(); $this->validate = true; $this->validateClass = new CouponValidate(); } /** * @Desc 列表 * @Author Gorden * @Date 2024/3/28 15:01 * * @param Request $request * @return Response * @throws \support\exception\BusinessException */ public function select(Request $request): Response { $joinCouponCategoryId = $request->get('join_coupon_category_id', []); [$where, $format, $limit, $field, $order] = $this->selectInput($request); if (!empty($joinCouponCategoryId)) { $where['join_coupon_category_id'] = ['in', implode(',', $joinCouponCategoryId)]; } $order = $request->get('order', 'desc'); $field = $field ?? 'coupon_addtimes'; $query = $this->doSelect($where, $field, $order); return $this->doFormat($query, $format, $limit); } protected function doSelect(array $where, string $field = null, string $order = 'desc') { $model = $this->model->with([ 'category' => function ($query) { $query->select('category_id', 'category_name'); }, 'user', 'detail' ]); foreach ($where as $column => $value) { if (is_array($value)) { if ($value[0] === 'like' || $value[0] === 'not like') { $model = $model->where($column, $value[0], "%$value[1]%"); } elseif (in_array($value[0], ['>', '=', '<', '<>'])) { $model = $model->where($column, $value[0], $value[1]); } elseif ($value[0] == 'in' && !empty($value[1])) { $valArr = $value[1]; if (is_string($value[1])) { $valArr = explode(",", trim($value[1])); } $model = $model->whereIn($column, $valArr); } elseif ($value[0] == 'not in' && !empty($value[1])) { $valArr = $value[1]; if (is_string($value[1])) { $valArr = explode(",", trim($value[1])); } $model = $model->whereNotIn($column, $valArr); } elseif ($value[0] == 'null') { $model = $model->whereNull($column); } elseif ($value[0] == 'not null') { $model = $model->whereNotNull($column); } elseif ($value[0] !== '' || $value[1] !== '') { $model = $model->whereBetween($column, $value); } } else { $model = $model->where($column, $value); } } if ($field) { $model = $model->orderBy($field, $order); } return $model; } protected function afterQuery($items) { foreach ($items as &$item) { if (!empty($item['coupon_json'])) { $couponJson = json_decode($item['coupon_json'], true); if (isset($couponJson['member'])) { if (isset($couponJson['member']['list']) && !empty($couponJson['member']['list'])) { $item['coupon_use_member'] = 'member'; $item['memberList'] = $couponJson['member']['list']; } else if (isset($couponJson['member']['where']) && !empty($couponJson['member']['where'])) { if (trim($couponJson['member']['where']) == '1') { $item['coupon_use_member'] = 'all'; } else { $item['coupon_use_member'] = 'condition'; $where = str_replace('`', '', urldecode($couponJson['member']['where'])); $whereArr = explode('=', $where); // dump($whereArr); if (isset($whereArr[0]) && trim($whereArr[0]) == 'member_is_vip') { $item['condition'] = 'is_vip'; } else if (isset($whereArr[0]) && trim($whereArr[0]) == 'member_classify') { if (isset($whereArr[1]) && str_replace("'", '', trim($whereArr[1])) == 'MEMBER') { $item['condition'] = 'is_member'; } else if (isset($whereArr[1]) && str_replace("'", '', trim($whereArr[1])) == 'EMPLOY') { $item['condition'] = 'is_employ'; } } } } } if (isset($couponJson['premises'])) { $item['premises'] = $couponJson['premises']; } else { $item['premises_range'] = 'all'; } } if (!empty($item['coupon_validdate_begin']) && !empty($item['coupon_validdate_end'])) { $item['coupon_use_time'] = 'date'; } elseif ($item['coupon_validdate_day']) { $item['coupon_use_time'] = 'day'; } $item['member_count'] = 0; $item['pending_count'] = 0; $item['used_count'] = 0; if (!empty($item['detail'])) { foreach ($item['detail'] as $detail) { if (!empty($detail['join_coupon_detail_member_id'])) { $item['member_count'] += 1; } if ($detail['coupon_detail_status'] == 'PENDING') { $item['pending_count'] += 1; } elseif ($detail['coupon_detail_status'] == 'USED') { $item['used_count'] += 1; } } } } return $items; } public function selectList() { $coupons = Coupon::where('coupon_status', 'ACTIVED') ->select('coupon_id', 'coupon_name') ->orderBy('coupon_addtimes','DESC') ->get() ->toArray(); return json_success('', $coupons); } // public function afterQuery($items) // { // foreach ($items as &$item) { // $item->coupon_begindate = date('Y-m-d H:i:s', $item->coupon_begindate); // $item->coupon_enddate = date('Y-m-d H:i:s', $item->coupon_enddate); // } // // return $items; // } /** * @Desc 添加优惠券 * @Author Gorden * @Date 2024/8/14 15:16 * * @param Request $request * @return Response */ public function insert(Request $request): Response { if ($this->validate && !$this->validateClass->scene('add')->check($request->post())) { return json_fail($this->validateClass->getError()); } $goods = $request->post('goodsContentList', []); if (empty($goods)) { return json_fail("请选择关联的产品"); } Db::beginTransaction(); try { $data = $this->insertInput($request); $data['coupon_creator_user_id'] = JwtToken::getCurrentId(); $this->doInsert($data); // 关联优惠券和商品、规格 $this->insertCouponGoods($goods, $data['coupon_id']); if ($data['coupon_number'] > 0) { $this->generateCouponDetail($data['coupon_id'], $data['coupon_status'], $data['coupon_number']); } Db::commit(); return json_success('success'); } catch (BusinessException $customException) { Db::rollBack(); dump($customException->getMessage()); return json_fail($customException->getMessage()); } catch (\Exception $e) { Db::rollBack(); dump($e->getMessage()); return json_fail('数据写入失败'); } } /** * @Desc 关联优惠券、产品、规格 * @Author Gorden * @Date 2024/8/14 14:32 * * @param $goods * @param $couponId * @return void * @throws BusinessException */ public function insertCouponGoods($goods, $couponId) { try { foreach ($goods as $good) { CouponGoods::insert([ 'join_goods_coupon_id' => $couponId, 'join_coupon_goods_id' => $good['goods_id'], 'join_coupon_goods_sku_id' => $good['sku_id'], 'coupon_goods_json' => '[]', 'coupon_goods_extend_json' => '[]', 'coupon_goods_addtimes' => time() ]); } } catch (\Exception $e) { throw new BusinessException("关联产品失败"); } } protected function insertInput(Request $request): array { $params = $request->post(); $data = $this->inputFilter($params); $data['coupon_id'] = "CU" . str_pad(SysSerial::getSerial(), 6, '0') . random_string(6, 'up'); if (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'date') { $data['coupon_validdate_day'] = 0; $data['coupon_validdate_begin'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_begin'])); $data['coupon_validdate_end'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_end'])); } elseif (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'day') { $data['coupon_validdate_begin'] = ''; $data['coupon_validdate_end'] = ''; } $couponJson = []; if ($params['coupon_use_member'] == 'member' && isset($params['member_list'])) { $couponJson['member']['list'] = $params['member_list']; $couponJson['member']['range'] = ''; $couponJson['member']['where'] = ''; } else if ($params['coupon_use_member'] == 'condition') { $couponJson['member']['list'] = []; if (isset($params['condition']) && $params['condition'] == 'is_vip') { $couponJson['member']['range'] = 'VIP会员'; $couponJson['member']['where'] = urlencode(" `member_is_vip` = 'Y'"); } elseif (isset($params['condition']) && $params['condition'] == 'is_employ') { $couponJson['member']['range'] = '公司员工'; $couponJson['member']['where'] = urlencode(" `member_classify` = 'EMPLOY'"); } elseif (isset($params['condition']) && $params['condition'] == 'is_member') { $couponJson['member']['range'] = '会员'; $couponJson['member']['where'] = urlencode(" `member_classify` = 'MEMBER'"); } } else if ($params['coupon_use_member'] == 'all') { $couponJson['member']['list'] = []; $couponJson['member']['range'] = '全部员工'; $couponJson['member']['where'] = ''; } if (!empty($params['premises_range']) && $params['premises_range'] == 'all') { $couponJson['premises_range'] = '所有门店可用'; } elseif (!empty($params['premises_range']) && $params['premises_range'] == 'part') { $couponJson['premises'] = $params['premises']; $couponJson['premises_range'] = '部分门店可用'; } $data['coupon_json'] = json_encode($couponJson, JSON_UNESCAPED_UNICODE); return $data; } /** * @Desc 修改优惠券 * @Author Gorden * @Date 2024/8/14 15:48 * * @param Request $request * @return Response */ public function update(Request $request): Response { if ($this->validate && !$this->validateClass->scene('update')->check($request->post())) { return json_fail($this->validateClass->getError()); } $params = $request->post(); Db::beginTransaction(); try { [$id, $data] = $this->updateInput($request); $originCouponNumber = $data['origin_coupon_number']; $originCouponValiddateDay = $data['origin_coupon_validdate_day']; $originCouponValiddateEnd = $data['origin_coupon_validdate_end']; unset($data['origin_coupon_number'], $data['origin_coupon_validdate_day'], $data['origin_coupon_validdate_end']); $this->updateCouponGoods($request->post('goodsContentList'), $id); if ($originCouponNumber == 0 && $data['coupon_number'] != 0) { // 查已领取多少了 $detailCount = CouponDetail::where('join_detail_coupon_id', $id)->count(); if ($detailCount < $data['coupon_number']) { $this->generateCouponDetail($id, $data['coupon_status'], $data['coupon_number'] - $detailCount); } } else if ($originCouponNumber < $data['coupon_number']) { $this->generateCouponDetail($id, $data['coupon_status'], $data['coupon_number'] - $originCouponNumber); } else if ($originCouponNumber > $data['coupon_number']) { CouponDetail::where('join_detail_coupon_id', $id) ->where('join_coupon_detail_member_id', '') ->limit($originCouponNumber - $data['coupon_number']) ->delete(); } // 修改时间了 if ($params['coupon_use_time'] == 'day' && $originCouponValiddateDay != $data['coupon_validdate_day']) { $this->updateDetailTimeForDay($id, $data['coupon_validdate_day']); } elseif ($params['coupon_use_time'] == 'date' && $originCouponValiddateEnd != $data['coupon_validdate_end']) { $this->updateDetailTimeForDate($id, $data['coupon_validdate_end']); } // 激活状态,初始改为待领取 if ($data['coupon_status'] == 'ACTIVED') { CouponDetail::where('join_detail_coupon_id', $id)->where('coupon_detail_status', 'INIT')->update(['coupon_detail_status' => 'PENDING']); } elseif ($data['coupon_status'] == 'DISABLED') { // 禁用状态,未领取未使用的都是禁用 CouponDetail::where('join_detail_coupon_id', $id)->where('coupon_detail_status', '<>', 'USED')->update(['coupon_detail_status' => 'DISABLED']); } $this->doUpdate($id, $data); Db::commit(); return json_success('success'); } catch (BusinessException $e) { Db::rollBack(); return json_fail($e->getMessage()); } catch (\Exception $e) { Db::rollBack(); dump($e->getMessage()); return json_fail('数据更新失败'); } } public function updateDetailTimeForDay($couponId, $day) { $details = CouponDetail::where('join_detail_coupon_id', $couponId) ->where('coupon_detail_status', '<>', 'USED') ->where('coupon_detail_deadline_datetime', '<>', '') ->get() ->toArray(); try { foreach ($details as $detail) { $couponDetailGainDatetime = strtotime($detail['coupon_detail_gain_datetime']); CouponDetail::where('coupon_detail_id', $detail['coupon_detail_id']) ->update([ 'coupon_detail_deadline_datetime' => date('Y-m-d H:i:s', $couponDetailGainDatetime + ($day * 24 * 3600)) ]); } } catch (\Exception $e) { dump($e->getMessage()); throw new BusinessException("优惠券更新失败"); } } public function updateDetailTimeForDate($couponId, $endDate) { $details = CouponDetail::where('join_detail_coupon_id', $couponId) ->where('coupon_detail_status', '<>', 'USED') ->where('coupon_detail_deadline_datetime', '<>', '') ->get() ->toArray(); try { foreach ($details as $detail) { CouponDetail::where('coupon_detail_id', $detail['coupon_detail_id']) ->update([ 'coupon_detail_deadline_datetime' => $endDate ]); } } catch (\Exception $e) { dump($e->getMessage()); throw new BusinessException("优惠券更新失败"); } } public function updateCouponGoods($goods, $couponId) { try { $couponGoodsIds = CouponGoods::where('join_goods_coupon_id', $couponId)->pluck('join_coupon_goods_id')->toArray(); $goodsIds = array_column($goods, 'goods_id'); // 新的差集 $goodsDiff = array_diff($goodsIds, $couponGoodsIds); // 旧的差集 $couponDiff = array_diff($couponGoodsIds, $goodsIds); foreach ($goods as $good) { // 更新两个中都有的 if (in_array($good['goods_id'], $couponGoodsIds)) { CouponGoods::where('join_goods_coupon_id', $couponId)->where('join_coupon_goods_id', $good['goods_id'])->update(['join_coupon_goods_sku_id' => $good['sku_id']]); } elseif (in_array($good['goods_id'], $goodsDiff)) { // 新加的 CouponGoods::insert([ 'join_goods_coupon_id' => $couponId, 'join_coupon_goods_id' => $good['goods_id'], 'join_coupon_goods_sku_id' => $good['sku_id'], 'coupon_goods_json' => '[]', 'coupon_goods_extend_json' => '[]', 'coupon_goods_addtimes' => time() ]); } } if (!empty($couponDiff)) { // 去掉的 foreach ($couponDiff as $item) { CouponGoods::where('join_goods_coupon_id', $couponId)->where('join_coupon_goods_id', $item)->delete(); } } } catch (\Exception $e) { throw new BusinessException('关联产品更新失败'); } } protected function updateInput(Request $request): array { $params = $request->post(); $primary_key = $this->model->getKeyName(); $id = $request->post($primary_key); $data = $this->inputFilter($params); if (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'date') { $data['coupon_validdate_day'] = 0; $data['coupon_validdate_begin'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_begin'])); $data['coupon_validdate_end'] = date("Y-m-d H:i:s", strtotime($data['coupon_validdate_end'])); } elseif (!empty($params['coupon_use_time']) && $params['coupon_use_time'] == 'day') { $data['coupon_validdate_begin'] = ''; $data['coupon_validdate_end'] = ''; } $model = $this->model->find($id); // 原数量 $data['origin_coupon_number'] = $model->coupon_number; // 原优惠天数 $data['origin_coupon_validdate_day'] = $model->coupon_validdate_day; // 原结束时间 $data['origin_coupon_validdate_end'] = $model->coupon_validdate_end; if (!$model) { throw new BusinessException('记录不存在', 2); } $couponJson = []; if (!empty($model->coupon_json)) { $couponJson = json_decode($model->coupon_json, true); } if ($params['coupon_use_member'] == 'member' && isset($params['member_list'])) { $couponJson['member']['list'] = $params['member_list']; // if (isset($couponJson['member']['range'])) { $couponJson['member']['range'] = ''; // } // if (isset($couponJson['member']['where'])) { $couponJson['member']['where'] = ''; // } } else if ($params['coupon_use_member'] == 'condition') { if (isset($params['condition']) && $params['condition'] == 'is_vip') { $couponJson['member']['range'] = 'VIP会员'; $couponJson['member']['where'] = urlencode(" `member_is_vip` = 'Y'"); } elseif (isset($params['condition']) && $params['condition'] == 'is_employ') { $couponJson['member']['range'] = '公司员工'; $couponJson['member']['where'] = urlencode(" `member_classify` = 'EMPLOY'"); } elseif (isset($params['condition']) && $params['condition'] == 'is_member') { $couponJson['member']['range'] = '会员'; $couponJson['member']['where'] = urlencode(" `member_classify` = 'MEMBER'"); } // if (isset($couponJson['member']['list'])) { $couponJson['member']['list'] = []; // } } else if ($params['coupon_use_member'] == 'all') { $couponJson['member']['list'] = []; $couponJson['member']['range'] = '全部员工'; $couponJson['member']['where'] = ''; if (isset($couponJson['member']['list'])) { $couponJson['member']['list'] = []; } } if (!empty($params['premises_range']) && $params['premises_range'] == 'all') { $couponJson['premises_range'] = '所有门店可用'; unset($couponJson['premises']); } elseif (!empty($params['premises_range']) && $params['premises_range'] == 'part') { $couponJson['premises'] = $params['premises']; $couponJson['premises_range'] = '部分门店可用'; } if (empty($data['coupon_validdate_day'])) { $data['coupon_validdate_day'] = 0; } $data['coupon_json'] = json_encode($couponJson, JSON_UNESCAPED_UNICODE); unset($data[$primary_key]); return [$id, $data]; } /** * 优惠券详情 */ public function info(Request $request): Response { $couponId = $request->get('coupon_id', ''); if (!$couponId) { return json_fail('参数异常'); } $coupon = Coupon::where('coupon_id', $couponId)->first(); if (!$coupon) { return json_fail('数据异常'); } // 拼选择的商品 $couponGoods = CouponGoods::with([ 'goods' => function ($query) { $query->select('goods_id', 'goods_id as id', 'goods_name as name', 'join_goods_category_id as pid', 'goods_classify', 'goods_sales_price', 'goods_cover'); }, 'skus', 'sku' ])->where('join_goods_coupon_id', $couponId) ->get() ->toArray(); $goodsIds = []; $goodsContent = []; foreach ($couponGoods as $couponGood) { $goodsIds[] = $couponGood['join_coupon_goods_id']; $content = [ 'goods_id' => $couponGood['join_coupon_goods_id'], 'sku_id' => $couponGood['join_coupon_goods_sku_id'], ]; if (isset($couponGood['goods'])) { $content['goods_name'] = $couponGood['goods']['name']; $content['goods_classify'] = $couponGood['goods']['goods_classify']; $content['goods_cover'] = getenv('STORAGE_DOMAIN') . $couponGood['goods']['goods_cover']; } if (isset($couponGood['sku']) && isset($couponGood['sku']['goods_sku_specs_json'])) { // $skuSpecsJson = json_decode($couponGood['sku']['goods_sku_specs_json'], true); // $skuName = ''; // foreach ($skuSpecsJson as $item) { // if (is_array($item)) { // $item = implode('', $item); // } // $skuName .= $item . ','; // } // $content['sku_name'] = rtrim($skuName, ','); $content['goods_sales_price'] = $couponGood['sku']['goods_sku_sales_price']; } if (isset($couponGood['skus'])) { foreach ($couponGood['skus'] as $key => $skus) { if (!empty($skus['goods_sku_specs_json'])) { $skuSpecsJson = json_decode($skus['goods_sku_specs_json'], true); $skuName = ''; foreach ($skuSpecsJson as $item) { if (is_array($item)) { $item = implode('', $item); } $skuName .= $item . ','; } $couponGood['skus'][$key]['sku_name'] = rtrim($skuName, ','); } } $content['skus'] = $couponGood['skus']; } $goodsContent[] = $content; } // 选中的会员 $memberLists = []; // 可用门店 $premises = []; if (!empty($coupon->coupon_json)) { $couponJson = json_decode($coupon->coupon_json, true); if (isset($couponJson['member']) && isset($couponJson['member']['list']) && !empty($couponJson['member']['list'])) { $res = Db::table('member') ->leftjoin('member_cert', 'member.member_id', '=', 'member_cert.join_cert_member_id') ->leftjoin('member_info', 'member.member_id', '=', 'member_info.join_info_member_id') ->select('member.member_id', 'member.member_mobile', 'member_cert.member_cert_name', 'member_info.member_info_nickname') ->where('member_status', 'ACTIVED') ->whereIn('member_id', $couponJson['member']['list']) ->get(); $memberLists = []; foreach ($res as $item) { $name = ''; if (!empty($item->member_cert_name)) { $name = $item->member_cert_name; } else if (!empty($item->member_info_nickname)) { $name = $item->member_info_nickname; } $value = !empty($name) ? $name . '-' : ''; if ($item->member_mobile != '0000') { $value .= $item->member_mobile; } if (empty($value)) { $value = $item->member_mobile; } $value = rtrim($value, '-'); $memberLists[] = [ 'key' => $item->member_id, 'value' => $value, ]; } } if (isset($couponJson['premises']) && !empty($couponJson['premises'])) { $premises = SysDept::whereIn('dept_id', $couponJson['premises']) ->select('dept_id', 'dept_name') ->get() ->toArray(); } } $data = [ 'goods_ids' => $goodsIds, 'goods_content' => $goodsContent, 'member_lists' => $memberLists, 'premises_list' => $premises ]; return json_success('', $data); } /** * 删除 * @param Request $request * @return Response * @throws BusinessException */ public function delete(Request $request): Response { $ids = $this->deleteInput($request); Db::beginTransaction(); try { // 删除优惠券关联的产品 foreach ($ids as $id) { $couponDetail = CouponDetail::with([ 'coupon' => function ($query) { $query->select('coupon_id', 'coupon_name'); } ])->where('join_detail_coupon_id', $id) ->where('join_coupon_detail_member_id', '<>', '') ->first(); if (!empty($couponDetail)) { Db::rollBack(); return json_fail($couponDetail->coupon && $couponDetail->coupon->coupon_name ? $couponDetail->coupon->coupon_name . "已被领取,无法删除,请禁用" : "删除的优惠券中有已被领取的,无法删除,请禁用"); } CouponGoods::where('join_goods_coupon_id', $id)->delete(); // CouponDetail::where('join_detail_coupon_id', $id) // ->whereIn('coupon_detail_status',['INIT','PENDING','ACTIVED']) // ->delete(); // CouponDetail::where('join_detail_coupon_id', $id) // ->where('coupon_detail_status','WAITING') // ->update(['coupon_detail_status'=>'DISABLED']); } $this->doDelete($ids); Db::commit(); return json_success('success'); } catch (\Exception $e) { dump($e->getMessage()); Db::rollBack(); return json_fail('删除失败'); } } private function generateCouponDetail($couponId, $couponStatus, $nbr) { for ($i = 0; $i < intval($nbr); $i++) { CouponDetail::insert([ 'coupon_detail_id' => 'CUDT' . str_pad(SysSerial::getSerial(), 6, '0') . random_string(6, 'up'), 'join_detail_coupon_id' => $couponId, 'coupon_detail_status' => $couponStatus == 'ACTIVED' ? 'PENDING' : 'INIT', 'coupon_detail_addtimes' => time() ]); } } }