소스 검색

【Add】下单自动发放优惠券

liuxiangxin 6 달 전
부모
커밋
163ae94510

+ 8 - 2
app/Http/Controllers/Admin/Coupon.php

@@ -133,8 +133,12 @@ class Coupon extends Auth{
 				$customs 			= $FilesManager->excelToCode(request()->file('custom_file'),$Custom);
 				// 客户范围不存在
 				if( !$customs )		return json_send(['code'=>'error','msg'=>'请上传可用的客户范围']);
+				// 去重
+				$customs			= array_values(array_unique($customs));
 				// 客户数量
 				if( count($customs) > 10000 ) return json_send(['code'=>'error','msg'=>'客户范围请勿超过10000']);
+				// 如果超过数量,不允许发放
+				if( $data['issue_total'] < count($customs) ) return json_send(['code'=>'error','msg'=>'客户数量请勿超过发行数量']);
 			}
 			// 组合数据,写入订单表,子表
 			DB::beginTransaction();
@@ -279,12 +283,14 @@ class Coupon extends Auth{
 			$customs				= [];
 			// 如果是客户范围,并且上传了文件
 			if( $data['is_appt'] == 1 && request()->hasFile('custom_file') ) {
-				// 读取文件获取指定的客户范围
-				$customs 			= $FilesManager->excelToCode(request()->file('custom_file'),$Custom);
 				// 客户范围不存在
 				if( !$customs )		return json_send(['code'=>'error','msg'=>'请上传可用的客户范围']);
+				// 去重
+				$customs			= array_values(array_unique($customs));
 				// 客户数量
 				if( count($customs) > 10000 ) return json_send(['code'=>'error','msg'=>'客户范围请勿超过10000']);
+				// 如果超过数量,不允许发放
+				if( $data['issue_total'] < count($customs) ) return json_send(['code'=>'error','msg'=>'客户数量请勿超过发行数量']);
 			}
 			// 组合数据,写入订单表,子表
 			DB::beginTransaction();

+ 165 - 0
app/Http/Controllers/Admin/CouponRewardProduct.php

@@ -0,0 +1,165 @@
+<?php namespace App\Http\Controllers\Admin;
+
+use App\Http\Requests\Admin\CouponRewardProduct as Request;
+use App\Models\Product;
+use App\Models\CouponRewardProduct as Model;
+use App\Models\CouponRewardRule;
+
+/**
+ * 优惠券自动发放规则产品范围
+ *
+ * @author    刘相欣
+ *
+ */
+class CouponRewardProduct extends Auth{
+	
+	protected function _initialize(){
+		parent::_initialize();
+		$this->assign('breadcrumb1','发放配置');
+		$this->assign('breadcrumb2','产品范围');
+	}
+
+	/**
+	 * 列表页
+	 * 
+	 * */
+    public function index(Model $Model,CouponRewardRule $CouponRewardRule,Product $Product){
+		// 接收参数
+		$rewardRuleId			= request('reward_rule_id',0);
+		$productCode			= request('product_code','');
+		$productId				= $Product->codeToId($productCode);
+		// 查询条件
+		$map 					= [];
+		// 组合条件
+		if( $rewardRuleId )		$map[] = ['reward_rule_id','=',$rewardRuleId];
+		if( $productId )		$map[] = ['product_id','=',$productId];
+		// 查询数据
+		$list					= $Model->query()->where($map)->orderByDesc('id')->paginate(config('page_num',10));
+		// 循环处理数据
+		foreach ($list as $key => $value) {
+			// 产品编码
+			$value['product_code'] = $Product->idToCode($value['product_id']);
+			// 产品编码
+			$value['product_name'] = $Product->query()->where([['id','=',$value['product_id']]])->value('name');
+			// 重组
+			$list[$key]			= $value;
+		}
+		// 获取列表
+		$ruleList 				= $CouponRewardRule->query()->get(['id','name'])->toArray();
+		// 分配数据
+		$this->assign('empty', '<tr><td colspan="20">~~暂无数据</td></tr>');
+		$this->assign('ruleList',$ruleList);
+		$this->assign('list',$list);
+		// 加载模板
+		return 					$this->fetch();
+    }
+
+	/**
+	 * 添加
+	 * 
+	 * */
+	public function add(Request $request,Model $Model,Product $Product,CouponRewardRule $CouponRewardRule){
+		if( request()->isMethod('post') ){
+			// 验证参数
+			$request->scene('add')->validate();
+			// 接收数据
+			$productCode			= request('product_code','');
+			$data['product_id']		= $Product->codeToId($productCode);
+			$data['reward_rule_id']	= request('reward_rule_id',0);
+			$data['product_units']	= request('product_units',0);
+			// 如果操作失败
+			if( !$data['product_id'] ) return json_send(['code'=>'error','msg'=>'请填写正确的产品编码']);
+			// 查询产品ID是否存在
+			$oldId					= $Model->query()->where([['reward_rule_id','=',$data['reward_rule_id']],['product_id','=',$data['product_id']]])->value('id');
+			// 重复提醒
+			if( $oldId ) 			return json_send(['code'=>'error','msg'=>'产品编码已存在']);
+			// 写入数据表
+			$id						= $Model->add($data);
+			// 如果操作失败
+			if( !$id ) 				return json_send(['code'=>'error','msg'=>'新增失败']);
+			// 记录行为
+			$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,1,[],$data);
+			// 告知结果
+			return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+		}
+		// 获取列表
+		$ruleList 					= $CouponRewardRule->query()->get(['id','name'])->toArray();
+		// 分配数据
+		$this->assign('ruleList',$ruleList);
+		$this->assign('crumbs','新增');
+		// 加载模板
+		return						$this->fetch(); 
+	}
+
+	/**
+	 * 修改
+	 * 
+	 * */
+	public function edit(Request $request,Model $Model,Product $Product,CouponRewardRule $CouponRewardRule){
+		// 接收参数
+		$id							= request('id',0);
+		// 查询用户
+		$oldData					= $Model->where(['id'=>$id])->first();
+		// 修改
+		if(request()->isMethod('post')){
+			// 验证参数
+			$request->scene('edit')->validate();
+			// 接收数据
+			$productCode			= request('product_code','');
+			$data['product_id']		= $Product->codeToId($productCode);
+			$data['reward_rule_id']	= request('reward_rule_id',0);
+			$data['product_units']	= request('product_units',0);
+			// 如果操作失败
+			if( !$data['product_id'] ) return json_send(['code'=>'error','msg'=>'请填写正确的产品编码']);
+			// 查询产品ID是否存在
+			$oldId					= $Model->query()->where([['reward_rule_id','=',$data['reward_rule_id']],['product_id','=',$data['product_id']]])->value('id');
+			// 重复提醒
+			if( $oldId && $oldId != $id ) return json_send(['code'=>'error','msg'=>'产品编码已存在']);
+			// 写入数据表
+			$result					= $Model->edit($id,$data);
+			// 如果操作失败
+			if( !$result ) 			return json_send(['code'=>'error','msg'=>'新增失败']);
+			// 记录行为
+			$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,$oldData,$data);
+			// 告知结果
+			return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+		}
+		// 错误告知
+		if( !$oldData )				return $this->error('查无数据');
+		// 产品编码
+		$oldData['product_code'] 	= $Product->idToCode($oldData['product_id']);
+		// 获取列表
+		$ruleList 					= $CouponRewardRule->query()->get(['id','name'])->toArray();
+		// 分配数据
+		$this->assign('ruleList',$ruleList);
+		$this->assign('oldData',$oldData);
+		$this->assign('crumbs','修改');
+		// 加载模板
+		return						$this->fetch();
+	}
+
+	/**
+	 * 修改状态
+	 * 
+	 * */
+	public function set_status(Request $request,Model $Model){
+		// 验证参数
+		$request->scene('set_status')->validate();
+		// 设置状态
+		$id				= request('id',0);
+		$status			= request('status',0);
+		// 查询用户
+		$oldData		= $Model->where(['id'=>$id])->first();
+		// 如果用户不存在
+		if( !$oldData )	return json_send(['code'=>'error','msg'=>'数据不存在']);
+		// 执行修改
+		$result			= $Model->edit($id,['status'=>$status]);		
+		// 提示新增失败
+		if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+		// 记录行为
+		$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,$oldData,['status'=>$status]);
+		// 告知结果
+		return 			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+	}
+
+}

+ 211 - 0
app/Http/Controllers/Admin/CouponRewardRule.php

@@ -0,0 +1,211 @@
+<?php namespace App\Http\Controllers\Admin;
+
+use App\Http\Requests\Admin\CouponRewardRule as Request;
+use App\Models\Coupon;
+use App\Models\CouponRewardRule as Model;
+use App\Models\Custom;
+use App\Models\City;
+
+/**
+ * 优惠券自动发放规则
+ *
+ * @author    刘相欣
+ *
+ */
+class CouponRewardRule extends Auth{
+	
+	protected function _initialize(){
+		parent::_initialize();
+		$this->assign('breadcrumb1','优惠券发放');
+		$this->assign('breadcrumb2','规则配置');
+	}
+
+	/**
+	 * 列表页
+	 * 
+	 * */
+    public function index(Model $Model,Coupon $Coupon){
+		// 查询条件
+		$map 					= [];
+		// 查询数据
+		$list					= $Model->query()->where($map)->orderByDesc('id')->paginate(config('page_num',10));
+		// 循环处理数据
+		foreach ($list as $key => $value) {
+			// 优惠券名称
+			$value['coupon_name']	= $Coupon->query()->where([['id','=',$value['coupon_id']]])->value('name');
+			// 重组
+			$list[$key]			= $value;
+		}
+		// 分配数据
+		$this->assign('empty', '<tr><td colspan="20">~~暂无数据</td></tr>');
+		$this->assign('list',$list);
+		// 加载模板
+		return 					$this->fetch();
+    }
+
+	/**
+	 * 添加
+	 * 
+	 * */
+	public function add(Request $request,Model $Model,Coupon $Coupon,Custom $Custom,City $City){
+		if( request()->isMethod('post') ){
+			// 验证参数
+			$request->scene('add')->validate();
+			// 接收数据
+			$couponCode				= request('coupon_code','');
+			$data['coupon_id']		= $Coupon->codeToId($couponCode);
+			$data['name']			= request('name','');
+			$data['std_num']		= request('std_num',0);
+			$data['start_time']		= request('start_time','');
+			$data['end_time']		= request('end_time','');
+			$data['start_time']		= $data['start_time'] ? strtotime($data['start_time']) : 0;
+			$data['end_time']		= $data['end_time'] ? strtotime($data['end_time']) : 0;
+			$data['status']			= 1;
+			$cityIds				= request('city_ids',[]);
+			$data['city_ids']		= implode(',',$cityIds);
+			$removeCustom			= request('remove_custom','');
+			// 循环处理
+			if( $removeCustom )		{
+				// 兼容逗号问题
+				$removeCustom		= str_ireplace(',',',',$removeCustom);
+				// 转数组处理
+				$removeCustom		= explode(',',$removeCustom);
+				// 循环处理
+				foreach ($removeCustom as $key=>$value) {
+					// 转ID
+					$customUid			= $Custom->codeToId($value);
+					// id有问题
+					if( !$customUid )	return json_send(['code'=>'error','msg'=>'客户编码'.$value.'不存在']);
+					// 重组
+					$removeCustom[$key] = $customUid;
+				}
+				// 去重
+				$removeCustom		= array_unique($removeCustom);
+			}
+			// 排除数据
+			$data['remove_custom']	= is_array($removeCustom) ? implode(',',$removeCustom) : $removeCustom;
+			// 写入数据表
+			$id						= $Model->add($data);
+			// 如果操作失败
+			if( !$id ) 				return json_send(['code'=>'error','msg'=>'新增失败']);
+			// 记录行为
+			$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,1,[],$data);
+			// 告知结果
+			return					json_send(['code'=>'success','msg'=>'新增成功','action'=>'add']);
+		}
+		// 获取列表
+		$cityList					= $City->getCityList();
+		// 分配数据
+		$this->assign('cityList',$cityList);
+		$this->assign('crumbs','新增');
+		// 加载模板
+		return						$this->fetch(); 
+	}
+
+	/**
+	 * 修改
+	 * 
+	 * */
+	public function edit(Request $request,Model $Model,Coupon $Coupon,Custom $Custom,City $City){
+		// 接收参数
+		$id							= request('id',0);
+		// 查询用户
+		$oldData					= $Model->where(['id'=>$id])->first();
+		// 修改
+		if(request()->isMethod('post')){
+			// 验证参数
+			$request->scene('edit')->validate();
+			// 接收数据
+			$couponCode				= request('coupon_code','');
+			$data['coupon_id']		= $Coupon->codeToId($couponCode);
+			$data['name']			= request('name','');
+			$data['std_num']		= request('std_num',0);
+			$data['start_time']		= request('start_time','');
+			$data['end_time']		= request('end_time','');
+			$data['start_time']		= $data['start_time'] ? strtotime($data['start_time']) : 0;
+			$data['end_time']		= $data['end_time'] ? strtotime($data['end_time']) : 0;
+			$cityIds				= request('city_ids',[]);
+			$data['city_ids']		= implode(',',$cityIds);
+			$removeCustom			= request('remove_custom','');
+			// 循环处理
+			if( $removeCustom )		{
+				// 兼容逗号问题
+				$removeCustom		= str_ireplace(',',',',$removeCustom);
+				// 转数组处理
+				$removeCustom		= explode(',',$removeCustom);
+				// 循环处理
+				foreach ($removeCustom as $key=>$value) {
+					// 转ID
+					$customUid			= $Custom->codeToId($value);
+					// id有问题
+					if( !$customUid )	return json_send(['code'=>'error','msg'=>'客户编码'.$value.'不存在']);
+					// 重组
+					$removeCustom[$key] = $customUid;
+				}
+				// 去重
+				$removeCustom		= array_unique($removeCustom);
+			}
+			// 排除数据
+			$data['remove_custom']	= is_array($removeCustom) ? implode(',',$removeCustom) : $removeCustom;
+			// 写入数据表
+			$result					= $Model->edit($id,$data);
+			// 如果操作失败
+			if( !$result ) 			return json_send(['code'=>'error','msg'=>'修改失败']);
+			// 记录行为
+			$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,$oldData,$data);
+			// 告知结果
+			return					json_send(['code'=>'success','msg'=>'修改成功','action'=>'edit']);
+		}
+		// 错误告知
+		if( !$oldData )				return $this->error('查无数据');
+		// 优惠券编码
+		$oldData['coupon_code']		= $Coupon->idToCode($oldData['coupon_id']);
+		// 排除客户
+		if( $oldData['remove_custom'] ) {
+			// 列表
+			$removeCustom			= [];
+			// 循环处理
+			foreach (explode(',',$oldData['remove_custom']) as $key => $value) {
+				// id转编码下发
+				$removeCustom[]		= $Custom->idToCode($value);
+			}
+			// 排除用户
+			$oldData['remove_custom']	= implode(',',$removeCustom);
+		}
+		// 获取城市ID
+		$oldData['city_ids']		= explode(',',$oldData['city_ids']);
+		// 获取列表
+		$cityList					= $City->getCityList();
+		// 分配数据
+		$this->assign('cityList',$cityList);
+		$this->assign('oldData',$oldData);
+		$this->assign('crumbs','修改');
+		// 加载模板
+		return						$this->fetch();
+	}
+
+	/**
+	 * 修改状态
+	 * 
+	 * */
+	public function set_status(Request $request,Model $Model){
+		// 验证参数
+		$request->scene('set_status')->validate();
+		// 设置状态
+		$id				= request('id',0);
+		$status			= request('status',0);
+		// 查询用户
+		$oldData		= $Model->where(['id'=>$id])->first();
+		// 如果用户不存在
+		if( !$oldData )	return json_send(['code'=>'error','msg'=>'数据不存在']);
+		// 执行修改
+		$result			= $Model->edit($id,['status'=>$status]);
+		// 提示新增失败
+		if( !$result )	return json_send(['code'=>'error','msg'=>'设置失败']);
+		// 记录行为
+		$this->addAdminHistory(admin('uid'),$Model->getTable(),$id,2,$oldData,['status'=>$status]);
+		// 告知结果
+		return 			json_send(['code'=>'success','msg'=>'设置成功','path'=>'']);
+	}
+
+}

+ 63 - 0
app/Http/Controllers/Api/Orders.php

@@ -225,6 +225,8 @@ class Orders extends Api{
 				// 购物车
 				if( $isCart )			$ShopCart->query()->where([['custom_uid','=',$uid]])->whereIn('skuid',array_column($buyList,'product_skuid'))->delete();
 			}
+			// 自动发放优惠券
+			$this->autoCoupon($uid);
 			// 提交数据
 			DB::commit();
 			// 返回结果
@@ -299,5 +301,66 @@ class Orders extends Api{
 		return						json_send(['code'=>'success','msg'=>'获取成功','data'=>$data]);
 	}
 
+	/**
+	 * 自动发放优惠券
+	 * 
+	 */
+	private function autoCoupon($uid){
+		// 模型实例
+		$Rule 					= new \App\Models\CouponRewardRule();
+		// 获取配置列表
+		$ruleList				= $Rule->getList();
+		// 如果没有信息的话
+		if( !$ruleList )		return ['success'=>'暂无活动'];
+		// 其他实例
+		$RuleProduct 			= new \App\Models\CouponRewardProduct();
+		$OrdersProduct 			= new \App\Models\OrdersProduct();
+		$Custom					= new \App\Models\Custom();
+		$Coupon					= new \App\Models\Coupon();
+		$CustomCoupon			= new \App\Models\CustomCoupon();
+		// 获取客户城市ID
+		$customCityId			= (int) $Custom->getValue($uid,'city_id');
+		// 循环配置列表
+		foreach ( $ruleList as 	$value ) {
+			// 如果存在城市范围,并且不在城市范围,不参与这个活动
+			if( $value['city_ids'] && !in_array($customCityId,explode(',',$value['city_ids'])) ) continue;
+			// 未到开始时间
+			if( $value['start_time'] > time() )  continue;
+			// 通过配置ID获取对应的商品范围
+			$productList 		= $RuleProduct->getListByRule($value['id']);
+			// 如果不存在产品范围,跳过
+			if( !$productList ) continue;
+			// 获取客户 规定时段内订单的商品ID以及购买数量
+			$orderList 			= $OrdersProduct->query()->where([['custom_uid','=',$uid],['status','=',1],['insert_time','>=',$value['start_time']],['insert_time','<=',$value['end_time']]])->get(['product_id','buy_num'])->toArray();
+			// 如果没有订单总数
+			if( !$orderList ) 	continue;
+			// 计算商品总量
+			$total				= 0;
+			// 循环商品范围
+			foreach ($productList as $scope) {
+				// 循环订单产品
+				foreach ($orderList as $order) {
+					// 如果产品不相等
+					if( $scope['product_id'] != $order['product_id'] ) continue;
+					// 相等的计算总量
+					$total		+= $scope['product_units'] * $order['buy_num'];
+				}
+			}
+			// 判断总数是不是达标
+			if( $total < $value['std_num'] )  continue;
+			// 达标的是否已经发送过优惠券
+			$havaCoupon			= $CustomCoupon->query()->where([['custom_uid','=',$uid],['coupon_id','=',$value['coupon_id']]])->first(['status']);
+			// 已经发过优惠券的,不发
+			if( $havaCoupon )   continue;
+			// 获取优惠券的可用时间
+			$expTime			= $Coupon->query()->where([['id','=',$value['coupon_id']]])->value('exp_time');
+			// 时间转时间
+			$expTime			= $Coupon->getExpTime($expTime);
+			// 发送优惠券
+			$CustomCoupon->add(['coupon_id'=>$value['coupon_id'],'custom_uid'=>$uid,'exp_time'=>$expTime]);
+		}
+		// 返回成功
+		return					['success'=>'操作成功'];
+	}
 
 }

+ 64 - 1
app/Http/Controllers/Api/Test.php

@@ -16,7 +16,70 @@ class Test extends Api{
 	 * 
 	 * */
 	public function sync_user(){
-        
+        $uid 		= 2;
+
+		 return		$this->autoCoupon($uid);
     }
 
+	/**
+	 * 自动发放优惠券
+	 * 
+	 */
+	private function autoCoupon($uid){
+		// 模型实例
+		$Rule 					= new \App\Models\CouponRewardRule();
+		$RuleProduct 			= new \App\Models\CouponRewardProduct();
+		$OrdersProduct 			= new \App\Models\OrdersProduct();
+		$Custom					= new \App\Models\Custom();
+		$Coupon					= new \App\Models\Coupon();
+		$CustomCoupon			= new \App\Models\CustomCoupon();
+		// 获取配置列表
+		$ruleList				= $Rule->getList();
+		// 如果没有信息的话
+		if( !$ruleList )		return ['success'=>'暂无活动'];
+		// 获取客户城市ID
+		$customCityId			= (int) $Custom->getValue($uid,'city_id');
+		// 循环配置列表
+		foreach ( $ruleList as 	$value ) {
+			// 如果存在城市范围,并且不在城市范围,不参与这个活动
+			if( $value['city_ids'] && !in_array($customCityId,explode(',',$value['city_ids'])) ) continue;
+			// 未到开始时间
+			if( $value['start_time'] > time() )  continue;
+			// 通过配置ID获取对应的商品范围
+			$productList 		= $RuleProduct->getListByRule($value['id']);
+			// 如果不存在产品范围,跳过
+			if( !$productList ) continue;
+			// 获取客户 规定时段内订单的商品ID以及购买数量
+			$orderList 			= $OrdersProduct->query()->where([['custom_uid','=',$uid],['status','=',1],['insert_time','>=',$value['start_time']],['insert_time','<=',$value['end_time']]])->get(['product_id','buy_num'])->toArray();
+			// 如果没有订单总数
+			if( !$orderList ) 	continue;
+			// 计算商品总量
+			$total				= 0;
+			// 循环商品范围
+			foreach ($productList as $scope) {
+				// 循环订单产品
+				foreach ($orderList as $order) {
+					// 如果产品不相等
+					if( $scope['product_id'] != $order['product_id'] ) continue;
+					// 相等的计算总量
+					$total		+= $scope['product_units'] * $order['buy_num'];
+				}
+			}
+			// 判断总数是不是达标
+			if( $total < $value['std_num'] )  continue;
+			// 达标的是否已经发送过优惠券
+			$havaCoupon			= $CustomCoupon->query()->where([['custom_uid','=',$uid],['coupon_id','=',$value['coupon_id']]])->first(['status']);
+			// 已经发过优惠券的,不发
+			if( $havaCoupon )   continue;
+			// 获取优惠券的可用时间
+			$expTime			= $Coupon->query()->where([['id','=',$value['coupon_id']]])->value('exp_time');
+			// 时间转时间
+			$expTime			= $Coupon->getExpTime($expTime);
+			// 发送优惠券
+			$CustomCoupon->add(['coupon_id'=>$value['coupon_id'],'custom_uid'=>$uid,'exp_time'=>$expTime]);
+		}
+		// 返回成功
+		return					['success'=>'操作成功'];
+	}
+
 }

+ 52 - 0
app/Http/Requests/Admin/CouponRewardProduct.php

@@ -0,0 +1,52 @@
+<?php namespace App\Http\Requests\Admin;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 发放规则验证器
+ * 
+ */
+class CouponRewardProduct extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+	        'product_code' 		=> 'required',
+            'reward_rule_id' 	=> 'required',
+	        'id'                => 'required|integer|gt:0',
+        ];
+    }
+
+    
+    // 场景列表
+    protected   $scenes         = [
+		'add'  		            => ['name'],
+        'edit'  		        => ['id','name'],
+        'set_status'  		    => ['id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'product_code.required'     => '产品编码必填',
+            'reward_rule_id.required'	=> '配置ID必选',
+            'id.required'               => 'ID未知',
+            'id.integer'                => 'ID格式错误',
+            'id.gt'   		            => 'ID格式错误',
+        ];
+    }
+    
+}

+ 51 - 0
app/Http/Requests/Admin/CouponRewardRule.php

@@ -0,0 +1,51 @@
+<?php namespace App\Http\Requests\Admin;
+
+use App\Http\Requests\BaseRequest;
+
+/**
+ * 发放规则验证器
+ * 
+ */
+class CouponRewardRule extends BaseRequest
+{
+    /**
+     * 获取应用于请求的规则
+     *
+     * @return array
+     */
+    public function rules()
+    {
+        // 返回结果
+        return      [
+            // 有时候我们希望某个字段在第一次验证失败后就停止运行验证规则,只需要将 bail 添加到规则中:
+            // 验证字段,验证规则,提示信息
+	        'name' 			    => 'required|unique:coupon_reward_rule,name,'.request('id',0),
+	        'id'                => 'required|integer|gt:0',
+        ];
+    }
+
+    
+    // 场景列表
+    protected   $scenes         = [
+		'add'  		            => ['name'],
+        'edit'  		        => ['id','name'],
+        'set_status'  		    => ['id'],
+	];
+
+    /**
+     * 获取已定义验证规则的错误消息
+     *
+     * @return array
+     */
+    public function messages()
+    {
+        return [
+            'name.required'     => '配置名称必填',
+            'name.unique'	    => '配置名称已经存在',
+            'id.required'       => 'ID未知',
+            'id.integer'        => 'ID格式错误',
+            'id.gt'   		    => 'ID格式错误',
+        ];
+    }
+    
+}

+ 101 - 0
app/Models/CouponRewardProduct.php

@@ -0,0 +1,101 @@
+<?php namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 发放规则产品范围模型
+ * 
+ */
+class CouponRewardProduct extends Model
+{
+    use HasFactory;
+
+    // 与模型关联的表名
+    protected $table = 'coupon_reward_product';
+    // 是否主动维护时间戳
+    public $timestamps = false;
+    // 定义时间戳字段名
+    // const CREATED_AT = 'insert_time';
+    // const UPDATED_AT = 'update_time';
+
+    /**
+     * 添加数据
+     * 
+     */
+    public function add($data)
+    {
+        // 时间
+        $data['insert_time']				= time();
+        $data['update_time']				= time();
+        // 写入数据表
+        $id						            = $this->query()->insertGetId($data);
+        // 如果操作失败
+        if( !$id )                          return $id;
+        // 更新缓存
+        $this->getList(true);
+        // 返回结果
+        return                              $id;
+    }
+
+    /**
+     * 添加数据
+     * 
+     */
+    public function edit($id,$data)
+    {
+        // 更新时间
+        $data['update_time']                = time();
+        // 写入数据表
+        $result						        = $this->query()->where(['id'=>$id])->update($data);
+        // 如果操作失败
+        if( !$result )                      return $result;
+        // 更新缓存
+        $this->getList(true);
+        // 返回结果
+        return                              $result;
+    }
+
+    /**
+     * 获取列表
+     * @param   Bool    $force  是否强制更新
+     * 
+     */
+    public function getList($force = false)
+    {
+        // 结果数据
+        $list                  = $force ? [] : cache('admin:coupon:reward:product:list');
+        // 不存在数据
+        if ( !$list ) {
+            // 从数据库获取数据
+            $data              = $this->query()->where(['status'=>0])->get(['id','product_id','product_units','status','reward_rule_id']);
+            // 是否有数据
+            $data              = $data ? $data->toArray() : [];
+            // 循环处理数据
+            $list              = [];
+            // 进行更新
+            foreach ($data as $value) {
+                // 重组数据
+                $list[$value['reward_rule_id']][$value['id']] = $value;
+            }
+            // 存起来
+            cache(['admin:coupon:reward:product:list'=>$list]);
+        }
+        // 返回结果
+        return                  $list;
+    }
+
+    /**
+     * 获取配置平台对应的应用数据
+     * 
+     * @param   int    $ruleId   规则ID
+     */
+    public function getListByRule($ruleId)
+    {
+        // 获取列表数据
+        $data                  = $this->getList();
+        // 返回值
+        return                  isset($data[$ruleId]) ? $data[$ruleId] : [];
+    }
+
+}

+ 105 - 0
app/Models/CouponRewardRule.php

@@ -0,0 +1,105 @@
+<?php namespace App\Models;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+/**
+ * 发放规则模型
+ * 
+ */
+class CouponRewardRule extends Model
+{
+    use HasFactory;
+
+    // 与模型关联的表名
+    protected $table = 'coupon_reward_rule';
+    // 是否主动维护时间戳
+    public $timestamps = false;
+    // 定义时间戳字段名
+    // const CREATED_AT = 'insert_time';
+    // const UPDATED_AT = 'update_time';
+
+    /**
+     * 添加数据
+     * 
+     */
+    public function add($data)
+    {
+        // 时间
+        $data['insert_time']				= time();
+        $data['update_time']				= time();
+        // 写入数据表
+        $id						            = $this->query()->insertGetId($data);
+        // 如果操作失败
+        if( !$id )                          return $id;
+        // 更新缓存
+        $this->getList(true);
+        // 返回结果
+        return                              $id;
+    }
+
+    /**
+     * 添加数据
+     * 
+     */
+    public function edit($id,$data)
+    {
+        // 更新时间
+        $data['update_time']                = time();
+        // 写入数据表
+        $result						        = $this->query()->where(['id'=>$id])->update($data);
+        // 如果操作失败
+        if( !$result )                      return $result;
+        // 更新缓存
+        $this->getList(true);
+        // 返回结果
+        return                              $result;
+    }
+
+    /**
+     * 获取列表
+     * @param   Bool    $force  是否强制更新
+     * 
+     */
+    public function getList($force = false)
+    {
+        // 结果数据
+        $list                  = $force ? [] : cache('admin:coupon:reward:rule:list');
+        // 不存在数据
+        if ( !$list ) {
+            // 从数据库获取数据
+            $data              = $this->query()->where(['status'=>0])->get(['id','name','std_num','remove_custom','city_ids','status','start_time','end_time','coupon_id']);
+            // 是否有数据
+            $data              = $data ? $data->toArray() : [];
+            // 循环处理数据
+            $list              = [];
+            // 进行更新
+            foreach ($data as $value) {
+                // 重组数据
+                $list[$value['id']] = $value;
+            }
+            // 存起来
+            cache(['admin:coupon:reward:rule:list'=>$list]);
+        }
+        // 返回结果
+        return                  $list;
+    }
+
+    /**
+     * 获取配置平台对应的应用数据
+     * 
+     * @param   Array      用户ID
+     * @param   String     指定字段
+     * 
+     */
+    public function getOne($id,$field='')
+    {
+        // 获取列表数据
+        $list                   = $this->getList();
+        // 获取数据
+        $one                    = isset($list[$id]) ? $list[$id] : [];
+        // 返回值
+        return                  empty($field) ? $one : ( isset($one[$field]) ? $one[$field] : null);
+    }
+
+}

+ 28 - 0
resources/views/admin/coupon_reward_product/add.blade.php

@@ -0,0 +1,28 @@
+@extends('admin.public.base')
+@section('body_class')
+style="margin: 0 auto;width: 96%;padding: 30px 0px;"
+@endsection
+@section('content')
+<form class="post-form" action="" method="post">
+	<div class="form-group col-sm-12">
+		<label class="control-label">所属配置</label>
+		<select name="reward_rule_id" required="required" class="form-control" >
+			@foreach ($ruleList as $value)
+				<option value="{{$value['id']}}" @if( request('reward_rule_id',0) == $value['id'] ) selected @endif>{{$value['name']}}</option>
+			@endforeach
+		</select>
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">商品编码</label>
+		<input class="form-control" required="required" type="text" placeholder="商品编码" name="product_code" value="" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">商品盒数</label>
+		<input class="form-control" required="required" type="number" placeholder="产品单位数量,一套盒数" name="product_units" value="" />
+	</div>
+	<div class="form-group col-sm-12">
+		@csrf
+		<input id="send" type="submit" value="提交" class="btn btn-primary btn-block" />
+	</div>
+</form>
+@endsection

+ 29 - 0
resources/views/admin/coupon_reward_product/edit.blade.php

@@ -0,0 +1,29 @@
+@extends('admin.public.base')
+@section('body_class')
+style="margin: 0 auto;width: 96%;padding: 30px 0px;"
+@endsection
+@section('content')
+<form class="post-form" action="" method="post">
+	<div class="form-group col-sm-12">
+		<label class="control-label">所属配置</label>
+		<select name="reward_rule_id" required="required" class="form-control" >
+			@foreach ($ruleList as $value)
+				<option value="{{$value['id']}}" @if( $oldData['reward_rule_id'] == $value['id'] ) selected @endif>{{$value['name']}}</option>
+			@endforeach
+		</select>
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">商品编码</label>
+		<input class="form-control" required="required" type="text" placeholder="商品编码" name="product_code" value="{{$oldData['product_code']}}" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">商品盒数</label>
+		<input class="form-control" required="required" type="number" placeholder="产品单位数量,一套盒数" name="product_units" value="{{$oldData['product_units']}}" />
+	</div>
+	<div class="form-group col-sm-12">
+		@csrf
+		<input type="hidden" name="id" id="id" value="{{$oldData['id']}}" />
+		<input id="send" type="submit" value="提交" class="btn btn-primary btn-block" />
+	</div>
+</form>
+@endsection

+ 82 - 0
resources/views/admin/coupon_reward_product/index.blade.php

@@ -0,0 +1,82 @@
+@extends('admin.public.base')
+@section('body_class')
+style="margin: 0 auto;width: 96%;padding: 30px 0px;"
+@endsection
+@section('content')
+
+@if(check_auth('admin/coupon_reward_product/add'))
+	<div class="page-header">
+		<a href="{{url('admin/coupon_reward_product/add?'.http_build_query(['reward_rule_id'=>request('reward_rule_id',0)]))}}" class="btn btn-primary">新增</a>
+	</div>
+@endif
+
+<form action="" method="get" class="form-horizontal form-line">
+	<div class="form-group col col-lg-2 col-md-2 col-sm-2 col-xs-2" style="margin-right: 2px;">
+		<select name="reward_rule_id" required="required" class="form-control" >
+			<option value="0" > 选择配置 </option>
+			@foreach ($ruleList as $value)
+				<option value="{{$value['id']}}" @if( request('reward_rule_id',0) == $value['id'] ) selected @endif>{{$value['name']}}</option>
+			@endforeach
+		</select>
+	</div>
+	<div class="form-group col col-lg-2 col-md-2 col-sm-2 col-xs-2" style="margin-right: 2px;">
+		<input type="text" class="form-control" name="product_code" value="{{request('product_code','')}}" placeholder="请输入产品编码查询" />
+	</div>
+	<input type="submit" class="btn btn-sm btn-primary" value="查询"/>
+	<a href="{{url('admin/coupon_reward_product/index')}}" class="btn btn-sm btn-default" >重置</a>
+</form>
+
+<div class="row">
+	<div class="col-xs-12">	
+		<div class="table-responsive">
+			<table class="table table-striped table-bordered table-hover">
+				<thead>
+					<tr>
+						<th>范围ID</th>
+						<th>商品编码</th>
+						<th>商品名称</th>
+						<th>商品盒数</th>
+						<th>所属配置</th>
+						<th>状态</th>
+						<th>修改时间</th>
+						<th>操作</th>									
+					</tr>
+				</thead>
+				
+				<tbody>
+						@foreach ($list as $a)
+						<tr>
+							<th>{{$a['id']}}</th>
+							<td>{{$a['product_code']}}</td>
+							<td>{{$a['product_name']}}</td>
+							<td>{{$a['product_units']}}</td>
+							<td>{{$a['product_units']}}</td>
+							<td>{{$a['status']?'停用':'启用'}}</td>
+							<td> {{date('Y/m/d H:i:s',$a['update_time'])}}</td>
+							<td>
+								@if(check_auth('admin/coupon_reward_product/edit'))
+								<a href="{{url('admin/coupon_reward_product/edit?'.http_build_query(['id'=>$a['id']]))}}" class="btn btn-sm btn-warning" >编辑</a>
+								@endif
+								@if(check_auth('admin/coupon_reward_product/set_status'))
+									@if($a['status'])
+									<a data-url="{{url('admin/coupon_reward_product/set_status?'.http_build_query(['id'=>$a['id'],'status'=>0]))}}" class="set_status btn btn-sm btn-success" >启用</a>
+									@else
+									<a data-url="{{url('admin/coupon_reward_product/set_status?'.http_build_query(['id'=>$a['id'],'status'=>1]))}}" class="set_status btn btn-sm btn-danger" >停用</a>
+									@endif
+								@endif
+							</td>							
+						</tr>  
+						@endforeach
+						<tr>
+							<td colspan="20" class="page">{{$list->render()}}</td>
+						</tr>
+						<tr>
+							<td colspan="20">总计 {{$list->total()}} 个商店</td>
+						</tr>
+				</tbody>
+				
+			</table>
+		</div>
+	</div>
+</div>
+@endsection

+ 48 - 0
resources/views/admin/coupon_reward_rule/add.blade.php

@@ -0,0 +1,48 @@
+@extends('admin.public.base')
+@section('body_class')
+style="margin: 0 auto;width: 96%;padding: 30px 0px;"
+@endsection
+@section('content')
+<form class="post-form" action="" method="post">
+	<div class="form-group col-sm-12">
+		<label class="control-label">配置名称</label>
+		<input class="form-control" required="required" type="text" placeholder="配置名称" name="name" maxlength="50" value="" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">达标总数</label>
+		<input class="form-control" required="required" type="text" placeholder="达标总数" maxlength="11" name="std_num" value="" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">优惠券编码</label>
+		<input class="form-control" required="required" type="text" placeholder="优惠券编码" name="coupon_code" value="" />
+	</div>
+	<div class="form-group col-sm-6">
+		<label class="control-label">开始时间</label>
+		<input class="form-control" required="required" type="datetime-local" placeholder="开始时间"  name="start_time" value="" />
+	</div>
+	<div class="form-group col-sm-6">
+		<label class="control-label">结束时间</label>
+		<input class="form-control" required="required" type="datetime-local" placeholder="结束时间" name="end_time" value="" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">活动城市</label>
+		<select name="city_ids[]" class="form-control selectpicker" data-live-search="true" data-live-search-placeholder="搜索城市" data-none-results-text="未搜索到 {0}" title="选择城市" multiple>
+			@foreach ($cityList as $group)
+			<optgroup label="{{$group['name']}}">
+				@foreach ($group['city'] as $city)
+				<option value="{{$city['id']}}" >{{$city['name']}}</option>
+				@endforeach
+			</optgroup>
+			@endforeach
+		</select>
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">排除客户</label>
+		<textarea class="form-control" name="remove_custom" rows="10" placeholder="需要排除的客户编码,多个使用英文逗号 , 隔开" ></textarea>
+	</div>
+	<div class="form-group col-sm-12">
+		@csrf
+		<input id="send" type="submit" value="提交" class="btn btn-primary btn-block" />
+	</div>
+</form>
+@endsection

+ 49 - 0
resources/views/admin/coupon_reward_rule/edit.blade.php

@@ -0,0 +1,49 @@
+@extends('admin.public.base')
+@section('body_class')
+style="margin: 0 auto;width: 96%;padding: 30px 0px;"
+@endsection
+@section('content')
+<form class="post-form" action="" method="post">
+	<div class="form-group col-sm-12">
+		<label class="control-label">配置名称</label>
+		<input class="form-control" required="required" type="text" placeholder="配置名称" name="name" maxlength="50" value="{{$oldData['name']}}" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">达标总数</label>
+		<input class="form-control" required="required" type="text" placeholder="达标总数" maxlength="11" name="std_num" value="{{$oldData['std_num']}}" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">优惠券编码</label>
+		<input class="form-control" required="required" type="text" placeholder="优惠券编码" name="coupon_code" value="{{$oldData['coupon_code']}}" />
+	</div>
+	<div class="form-group col-sm-6">
+		<label class="control-label">开始时间</label>
+		<input class="form-control" required="required" type="datetime-local" placeholder="开始时间"  name="start_time" value="{{date('Y-m-d H:i',$oldData['start_time'])}}" />
+	</div>
+	<div class="form-group col-sm-6">
+		<label class="control-label">结束时间</label>
+		<input class="form-control" required="required" type="datetime-local" placeholder="结束时间" name="end_time" value="{{date('Y-m-d H:i',$oldData['end_time'])}}" />
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">活动城市</label>
+		<select name="city_ids[]" class="form-control selectpicker" data-live-search="true" data-live-search-placeholder="搜索城市" data-none-results-text="未搜索到 {0}" title="选择城市" multiple>
+			@foreach ($cityList as $group)
+			<optgroup label="{{$group['name']}}">
+				@foreach ($group['city'] as $city)
+				<option value="{{$city['id']}}" @if(in_array($city['id'],$oldData['city_ids'])) selected @endif >{{$city['name']}}</option>
+				@endforeach
+			</optgroup>
+			@endforeach
+		</select>
+	</div>
+	<div class="form-group col-sm-12">
+		<label class="control-label">排除客户</label>
+		<textarea class="form-control" name="remove_custom" rows="10" placeholder="需要排除的客户编码,多个使用英文逗号 , 隔开" >{{$oldData['remove_custom']}}</textarea>
+	</div>
+	<div class="form-group col-sm-12">
+		@csrf
+		<input type="hidden" name="id" id="id" value="{{$oldData['id']}}" />
+		<input id="send" type="submit" value="提交" class="btn btn-primary btn-block" />
+	</div>
+</form>
+@endsection

+ 79 - 0
resources/views/admin/coupon_reward_rule/index.blade.php

@@ -0,0 +1,79 @@
+@extends('admin.public.base')
+@section('body_class')
+style="margin: 0 auto;width: 96%;padding: 30px 0px;"
+@endsection
+@section('content')
+
+@if(check_auth('admin/coupon_reward_rule/add'))
+	<div class="page-header">
+		<a href="{{url('admin/coupon_reward_rule/add')}}" class="btn btn-primary">新增</a>
+	</div>
+@endif
+
+<form action="" method="get" class="form-horizontal form-line">
+	<div class="form-group col col-lg-2 col-md-2 col-sm-2 col-xs-2" style="margin-right: 2px;">
+		<input type="text" class="form-control" name="name" value="{{request('name','')}}" placeholder="请输入配置名称查询" />
+	</div>
+	<input type="submit" class="btn btn-sm btn-primary" value="查询"/>
+	<a href="{{url('admin/coupon_reward_rule/index')}}" class="btn btn-sm btn-default" >重置</a>
+</form>
+
+<div class="row">
+	<div class="col-xs-12">	
+		<div class="table-responsive">
+			<table class="table table-striped table-bordered table-hover">
+				<thead>
+					<tr>
+						<th>配置ID</th>
+						<th>配置名称</th>
+						<th>达标总数</th>
+						<th>开始时间</th>
+						<th>结束时间</th>
+						<th>优惠券</th>
+						<th>配置状态</th>
+						<th>修改时间</th>
+						<th>操作</th>									
+					</tr>
+				</thead>
+				
+				<tbody>
+						@foreach ($list as $a)
+						<tr>
+							<th>{{$a['id']}}</th>
+							<td>{{$a['name']}}</td>
+							<td>{{$a['std_num']}}</td>
+							<td> {{date('Y/m/d H:i:s',$a['start_time'])}}</td>
+							<td> {{date('Y/m/d H:i:s',$a['end_time'])}}</td>
+							<td>{{$a['coupon_name']}}</td>
+							<td>{{$a['status']?'停用':'启用'}}</td>
+							<td> {{date('Y/m/d H:i:s',$a['update_time'])}}</td>
+							<td>
+								@if(check_auth('admin/coupon_reward_product/index'))
+								<a href="{{url('admin/coupon_reward_product/index?'.http_build_query(['reward_rule_id'=>$a['id']]))}}" class="btn btn-sm btn-primary" >商品范围</a>
+								@endif
+								@if(check_auth('admin/coupon_reward_rule/edit'))
+								<a href="{{url('admin/coupon_reward_rule/edit?'.http_build_query(['id'=>$a['id']]))}}" class="btn btn-sm btn-warning" >编辑</a>
+								@endif
+								@if(check_auth('admin/coupon_reward_rule/set_status'))
+									@if($a['status'])
+									<a data-url="{{url('admin/coupon_reward_rule/set_status?'.http_build_query(['id'=>$a['id'],'status'=>0]))}}" class="set_status btn btn-sm btn-success" >启用</a>
+									@else
+									<a data-url="{{url('admin/coupon_reward_rule/set_status?'.http_build_query(['id'=>$a['id'],'status'=>1]))}}" class="set_status btn btn-sm btn-danger" >停用</a>
+									@endif
+								@endif
+							</td>							
+						</tr>  
+						@endforeach
+						<tr>
+							<td colspan="20" class="page">{{$list->render()}}</td>
+						</tr>
+						<tr>
+							<td colspan="20">总计 {{$list->total()}} 个商店</td>
+						</tr>
+				</tbody>
+				
+			</table>
+		</div>
+	</div>
+</div>
+@endsection

+ 21 - 0
routes/web.php

@@ -194,6 +194,27 @@ Route::middleware('admin')->prefix('admin')->group(function(){
     // 状态
     Route::any('custom_coupon/set_status',[App\Http\Controllers\Admin\CustomCoupon::class,'set_status']);
 
+
+    /* 优惠券发放规则 */
+    // 列表
+    Route::any('coupon_reward_rule/index',[App\Http\Controllers\Admin\CouponRewardRule::class,'index']);
+    // 详情
+    Route::any('coupon_reward_rule/add',[App\Http\Controllers\Admin\CouponRewardRule::class,'add']);
+    // 详情
+    Route::any('coupon_reward_rule/edit',[App\Http\Controllers\Admin\CouponRewardRule::class,'edit']);
+    // 状态
+    Route::any('coupon_reward_rule/set_status',[App\Http\Controllers\Admin\CouponRewardRule::class,'set_status']);
+
+    /* 优惠券发放规则-商品范围 */
+    // 列表
+    Route::any('coupon_reward_product/index',[App\Http\Controllers\Admin\CouponRewardProduct::class,'index']);
+    // 详情
+    Route::any('coupon_reward_product/add',[App\Http\Controllers\Admin\CouponRewardProduct::class,'add']);
+    // 详情
+    Route::any('coupon_reward_product/edit',[App\Http\Controllers\Admin\CouponRewardProduct::class,'edit']);
+    // 状态
+    Route::any('coupon_reward_product/set_status',[App\Http\Controllers\Admin\CouponRewardProduct::class,'set_status']);
+
     /* 商业公司 */
     // 列表
     Route::any('business/index',[App\Http\Controllers\Admin\Business::class,'index']);