'ID', 'e_coupon_id' => '电子券id', 'receive_begin_time' => '领取开始时间', 'receive_end_time' => '领取结束时间', 'use_begin_time' => '使用开始时间', 'use_end_time' => '使用结束时间', 'price' => '金额', 'get_type' => '获取方式,1是领取,2是购买商品获得,3是系统发放', 'use_way' => '适用范围;1扫描核销', 'receive_times' => '领取次数', 'receive_amount' => '领取数量;未激活', 'active_amount' => '激活数量;', 'used_amount' => '兑换数量;即使用数量', 'num' => '电子卷总数', 'created_at' => '创建时间', 'updated_at' => '更新时间', 'mall_id' => '商城id', 'user_id' => '用户id', 'last_used_time' => '最新兑换时间', 'last_receive_time' => '最新领取时间', 'last_active_time' => '最新激活时间', 'is_proper' => '是否专有券', 'giver_id' => '赠送者id', 'proper_id' => '专有者id', 'goods_id' => '商品id', 'status' => '状态[-1:删除;0:禁用;1启用]', ]; } public function getUser() { return $this->hasOne(User::class, ['id' => 'user_id'])->select('id,mobile,nickname,avatar_url,username'); } // 专有者 public function getProperUser() { return $this->hasOne(User::class, ['id' => 'proper_id'])->select('id,mobile,nickname,avatar_url,username'); } // 赠送者 public function getGiver() { return $this->hasOne(User::class, ['id' => 'giver_id'])->select('id,mobile,nickname,avatar_url,username'); } // 购买商品 public function getGoods() { return $this->hasOne(Goods::class, ['id' => 'goods_id'])->select('id,goods_name'); } // 获取分页列表 public static function getListPage($condition, $mall_id) { $page_data = self::listPage($condition, false, true); $page_data['list'] = is_array($page_data['list']) ? $page_data['list'] : []; if ($page_data['list']) { // 关联电子券 $coupon_id_array = array_unique(array_filter(array_column($page_data['list'], 'e_coupon_id'))); $e_coupon = ElectronCoupon::find() ->select('id,name,pic,rules,is_give') ->where(['>=', 'status', StatusEnum::DISABLED]) ->where(['mall_id' => $mall_id]) ->where(['in', 'id', $coupon_id_array]) ->asArray() ->all(); $coupon_name_data = array_column($e_coupon, null, 'id'); } else { $coupon_name_data = []; } foreach ($page_data['list'] as $index => $item) { // 电子券 $item['e_coupon'] = $coupon_name_data[$item['e_coupon_id']] ?? ''; $page_data['list'][$index] = $item; } return $page_data; } /** * 数据设置 */ public static function setData(array $params) { try{ if (!isset($params['mall_id']) || empty($params['mall_id'])) throw new Exception('缺少商城ID'); $mall_id = $params['mall_id']; if (isset($params['id']) && !empty($params['id'])) { $model = self::findOne(['id' => $params['id'], 'mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]); if(empty($model)) throw new Exception('会员电子券不存在或已删除'); $bcmath = ['receive_times', 'receive_amount', 'active_amount', 'used_amount', 'num']; foreach ($bcmath as $field) { if (isset($params[$field])) { $model->$field += $params[$field]; if ($model->$field < 0) { throw new Exception('保存失败'); } unset($params[$field]); } } } else { $model = new self(); $model->loadDefaultValues(); $model->mall_id = $mall_id; } if (!$model->load($params,'') || !$model->save()) throw new Exception($model->getErrorMessage()); return $model; }catch(Exception $e){ self::setStaticError($e->getMessage()); return false; } } /** * 用户之间赠送电子券 * @param array $params * user_coupon_id 主键id * user_id 赠送者用户id * e_coupon_id 电子券id * receiver_user_id 获赠者会员id * amount 赠送数量 * status 赠送哪种状态的电子券 * mall_id 商城id * @return bool */ public static function userGiveCoupon(array $params) { $tran = Yii::$app->db->beginTransaction(); try { $must_keys = ['user_coupon_id', 'e_coupon_id', 'receiver_user_id', 'amount', 'status', 'mall_id', 'user_id']; foreach ($must_keys as $key) { if (!in_array($key, array_keys($params))) { throw new Exception('缺少必要的参数' . $key); } } $config = Yii::$app->services->setting->addons->get($params['mall_id'], ElectronCouponEnums::ADDONS_NAME, 'basic'); $is_open = $config['is_open'] ?? 0; if (!$is_open) { throw new Exception('暂时无法赠送好友'); } $is_allow_deal = $config['is_allow_deal'] ?? 0; if (!$is_allow_deal) { throw new Exception('暂时无法赠送好友'); } $customize_name = $config['customize_name'] ?? '电子券'; $source_transfer_permission = $config['source_transfer_permission'] ?? 0; if ($source_transfer_permission == 1) { $parent_give = UserPartitionRelationship::getParentIdArr($params['user_id']); $parent_receive = UserPartitionRelationship::getParentIdArr($params['receiver_user_id']); if (!in_array($params['receiver_user_id'], $parent_give) && !in_array($params['user_id'], $parent_receive)) { throw new Exception($customize_name . '仅支持赠送给团队成员'); } } $user_coupon = self::findOne(['id' => $params['user_coupon_id'], 'mall_id' => $params['mall_id'], 'status' => StatusEnum::ENABLED]); if (!$user_coupon) { throw new Exception($customize_name . '不存在'); } // 电子券信息 $coupon = ElectronCoupon::getOne([['id' => $user_coupon['e_coupon_id']], ['mall_id' => $params['mall_id']], ['<>', 'status', StatusEnum::DELETE]], true, '', '', ['id', 'name', 'is_give','share_expiry']); if (!$coupon) { throw new Exception($customize_name . '不存在'); } if(!empty($coupon['share_expiry'])&&!empty($user_coupon['giver_id'])){ throw new Exception($customize_name . '赠送券不支持赠送给好友'); } if (!$coupon['is_give']) { throw new Exception($customize_name . '不支持赠送给好友'); } if ($params['user_id'] != $user_coupon['user_id']) { throw new Exception($customize_name . '不存在'); } if (!in_array($params['status'], [ElectronCouponEnums::COUPON_STATUS_RECEIVE, ElectronCouponEnums::COUPON_STATUS_ACTIVE])) { throw new Exception('不支持的' . $customize_name . '状态'); } if ($params['status'] == ElectronCouponEnums::COUPON_STATUS_RECEIVE && $params['amount'] > $user_coupon['receive_amount']) { // 未激活 throw new Exception('未激活的' . $customize_name . '数量不足'); } if ($params['status'] == ElectronCouponEnums::COUPON_STATUS_ACTIVE && $params['amount'] > $user_coupon['active_amount']) { // 已激活 throw new Exception('激活的' . $customize_name . '数量不足'); } if ($user_coupon['use_end_time'] < time()) { throw new Exception($customize_name . '已过期'); } $receive_user = User::getOne([['id' => $params['receiver_user_id']]], true, '', '', 'id'); if (!$receive_user) { throw new Exception('用户不存在'); } // 获赠者的数据 $data = [ 'e_coupon_id' => $user_coupon['e_coupon_id'], 'receive_begin_time' => $user_coupon['receive_begin_time'], 'receive_end_time' => $user_coupon['receive_end_time'], 'use_begin_time' => $user_coupon['use_begin_time'], 'use_end_time' => $user_coupon['use_end_time'], 'price' => $user_coupon['price'], 'get_type' => $user_coupon['get_type'], 'use_way' => $user_coupon['use_way'], 'receive_times' => 0, 'receive_amount' => 0, 'active_amount' => 0, 'used_amount' => 0, 'num' => $params['amount'], 'mall_id' => $params['mall_id'], 'user_id' => $params['receiver_user_id'], 'last_used_time' => 0, 'is_proper' => $user_coupon['is_proper'], 'giver_id' => $user_coupon['user_id'], 'proper_id' => $user_coupon['proper_id'], // 专有者不发生改变 'goods_id' => $user_coupon['goods_id'], 'status' => $user_coupon['status'] ]; // 赠送者的数据 $give_data = [ 'id' => $user_coupon['id'], 'mall_id' => $user_coupon['mall_id'], 'num' => -1 * $params['amount'], ]; if ($params['status'] == ElectronCouponEnums::COUPON_STATUS_RECEIVE) { $data['receive_amount'] = $params['amount']; $data['last_receive_time'] = time(); $give_data['receive_amount'] = -1 * $params['amount']; } if ($params['status'] == ElectronCouponEnums::COUPON_STATUS_ACTIVE) { $data['active_amount'] = $params['amount']; $data['last_active_time'] = time(); $give_data['active_amount'] = -1 * $params['amount']; } // 赠送记录的数据 $log_data = [ 'mall_id' => $params['mall_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'user_id' => $params['receiver_user_id'], 'give_user_id' => $user_coupon['user_id'], 'e_coupon_name' => $coupon['name'], // 电子券名称 'amount' => $params['amount'], 'is_proper' => $user_coupon['is_proper'], 'proper_id' => $user_coupon['proper_id'], 'status' => StatusEnum::ENABLED ]; // 同一张电子券可转让给同一个会员多少张电子券,填 0 不限制 $transfer_num = $config['transfer_num'] ?? 0; if ($transfer_num > 0) { $log_give_num = (int) ElectronCouponGiveLog::find()->where([ 'mall_id' => $params['mall_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'user_id' => $params['receiver_user_id'], 'give_user_id' => $user_coupon['user_id'] ])->sum('amount'); if ($log_give_num >= $transfer_num) { throw new Exception('该' . $customize_name . '赠送给该好友的次数已达上限'); } } // 同一张电子券可接收不同会员的多少张电子券,填 0 不限制 $receive_num = $config['receive_num'] ?? 0; if ($receive_num > 0) { $log_receive_num = (int) ElectronCouponGiveLog::find()->where([ 'mall_id' => $params['mall_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'user_id' => $params['receiver_user_id'] ])->sum('amount'); if ($log_receive_num >= $receive_num) { throw new Exception('该好友获赠该' . $customize_name . '的次数已达上限'); } } // 获赠者有没有对应的电子券 $receive_user_coupon = self::getOne([ ['mall_id' => $data['mall_id']], ['user_id' => $data['user_id']], ['e_coupon_id' => $data['e_coupon_id']], ['get_type' => $data['get_type']], ['is_proper' => $data['is_proper']], ['proper_id' => $data['proper_id']], // 同一专有者 ['giver_id' => $data['giver_id']], // 同一赠送人 ['goods_id' => (int) $data['goods_id']], // 同一商品赠送 ['use_begin_time' => $data['use_begin_time']], // 同一使用开始时间 ['receive_end_time' => $data['receive_end_time']], // 同一使用结束时间 ['status' => StatusEnum::ENABLED] ], true, '', '', 'id'); if ($receive_user_coupon) { $data['id'] = $receive_user_coupon['id']; } else { $data['last_receive_time'] = time(); $data['last_active_time'] = time(); } // 赠送 $update_receive_coupon = self::setData($data); if ($update_receive_coupon == false) throw new Exception('赠送失败 ' . self::getStaticError()); // 赠送者减去赠送数量 $update_give_coupon = self::setData($give_data); if ($update_give_coupon == false) throw new Exception('赠送失败 ' . self::getStaticError()); // 赠送记录 $log = ElectronCouponGiveLog::setData($log_data); if ($log == false) throw new Exception('赠送失败 ' . ElectronCouponGiveLog::getStaticError()); // 赠送记录的数据 $time = time(); $log_data_s = [ 'mall_id' => $params['mall_id'], 'e_coupon_id' => $user_coupon['e_coupon_id'], 'user_coupon_id' => $user_coupon['id'], 'accept_user_e_coupon_id' => $update_receive_coupon['id'], 'user_id' => $params['receiver_user_id'], 'give_user_id' => $user_coupon['user_id'], 'active_time' => $params['status']==1?$user_coupon['last_active_time']:0, 'use_time' => 0, 'share_expiry' => $coupon['share_expiry'], 'created_at'=>$time, 'updated_at'=>$time, 'status' => StatusEnum::ENABLED ]; $res = ElectronCouponGiveLogs::setData($log_data_s,$params['amount']); if ($res == false) throw new Exception('赠送失败 ' . ElectronCouponGiveLogs::getStaticError()); $tran->commit(); return true; } catch (Exception $e) { $tran->rollBack(); self::setStaticError($e->getMessage()); return false; } } /** * 领券电子券操作 * e_coupon_id 电子券id * mall_id 商城id * user_id 领取人 * goods_id 购买的商品id * get_type 获取方式 * receive_times 领取次数,默认是领取一次 * */ public static function userReceiveCoupon(array $params) { $tran = Yii::$app->db->beginTransaction(); try { $must_keys = ['e_coupon_id', 'mall_id', 'user_id', 'get_type']; foreach ($must_keys as $key) { if (!in_array($key, array_keys($params))) { throw new Exception('缺少必要的参数' . $key); } } if (!in_array($params['get_type'], [ ElectronCouponEnums::COUPON_GET_TYPE_RECEIVE, ElectronCouponEnums::COUPON_GET_TYPE_GOODS, ElectronCouponEnums::COUPON_GET_TYPE_SYSTEM ])) { throw new Exception('不支持的获取方式'); } // 默认领取一次 $receive_times = $params['receive_times'] ?? 1; $config = Yii::$app->services->setting->addons->get($params['mall_id'], ElectronCouponEnums::ADDONS_NAME, 'basic'); $is_open = $config['is_open'] ?? 0; if (!$is_open) { throw new Exception('暂时无法领取'); } $customize_name = $config['customize_name'] ?? '电子券'; $coupon_info = ElectronCoupon::getOne([['id' => $params['e_coupon_id']], ['mall_id' => $params['mall_id']], ['>=', 'status', StatusEnum::DISABLED]], true); if (!$coupon_info) { throw new Exception($customize_name . '不存在或已下架'); } if($receive_times>($coupon_info['amount'] -$coupon_info['receive_amount'])){ throw new Exception($coupon_info['name'].'数量不足'); } $goods_id = $params['goods_id'] ?? 0; if ($params['get_type'] == ElectronCouponEnums::COUPON_GET_TYPE_GOODS && !$goods_id) { throw new Exception('商品ID不能为空'); } // 是否可以被领取 if ($params['get_type'] == ElectronCouponEnums::COUPON_GET_TYPE_RECEIVE && $coupon_info['is_can_receive'] == ElectronCouponEnums::IS_NOT_RECEIVE) { throw new Exception('该' . $customize_name . '暂时不支持领取'); } if ($coupon_info['receive_begin_time'] > time()) { throw new Exception('该' . $customize_name . '未到领取时间'); } if ($coupon_info['receive_end_time'] < time()) { throw new Exception('该' . $customize_name . '已过领取时间'); } $user_info = User::getOne([ ['id' => $params['user_id']], ['mall_id' => $params['mall_id']], ['status' => StatusEnum::ENABLED] ], true); if (empty($user_info)) { throw new Exception('领取会员ID不正确'); } // 领取级别 if ($coupon_info['receive_codition'] == ElectronCouponEnums::RECEIVE_CONDITION_LEVEL) { $level = $coupon_info['receive_member_level']; if ($level != $user_info['level']) { throw new Exception('您不符合领取条件'); } } $proper_id = $coupon_info['is_proper'] ? $params['user_id'] : 0; $pieces_amount = $params['pieces_amount'] ?? $coupon_info['pieces_amount']; $pieces_amount = $receive_times * $pieces_amount; // 判断领取的电子券+已领取的电子券是否大于总电子券数量 if ($coupon_info['receive_amount'] + $pieces_amount > $coupon_info['amount']) { throw new Exception('该' . $customize_name . '已超出领取数量'); } $user_coupon_data = [ 'e_coupon_id' => $params['e_coupon_id'], 'receive_begin_time' => $coupon_info['receive_begin_time'], 'receive_end_time' => $coupon_info['receive_end_time'], 'use_begin_time' => $coupon_info['use_begin_time'], 'use_end_time' => $coupon_info['use_end_time'], 'price' => $coupon_info['price'], 'get_type' => ElectronCouponEnums::COUPON_GET_TYPE_RECEIVE, 'use_way' => ElectronCouponEnums::USE_WAY, 'receive_times' => $receive_times, 'receive_amount' => 0, 'active_amount' => 0, 'used_amount' => 0, 'num' => $pieces_amount, 'mall_id' => $params['mall_id'], 'user_id' => $params['user_id'], 'is_proper' => $coupon_info['is_proper'], 'giver_id' => 0, 'proper_id' => $proper_id, 'goods_id' => $goods_id, 'status' => StatusEnum::ENABLED, 'last_receive_time' => 0, 'last_used_time' => 0, 'last_active_time' => 0 ]; // 如果是购买商品赠送的 || 后台送的,则无需激活 if (in_array($params['get_type'], [ElectronCouponEnums::COUPON_GET_TYPE_GOODS, ElectronCouponEnums::COUPON_GET_TYPE_SYSTEM]) && $coupon_info['price']<=0) { $user_coupon_data['active_amount'] = $pieces_amount; $user_coupon_data['last_active_time'] = time(); } else { $user_coupon_data['receive_amount'] = $pieces_amount; $user_coupon_data['last_receive_time'] = time(); } $user_coupon = ElectronCouponUserCoupon::getOne([ ['mall_id' => $user_coupon_data['mall_id']], ['user_id' => $user_coupon_data['user_id']], ['e_coupon_id' => $user_coupon_data['e_coupon_id']], ['get_type' => $user_coupon_data['get_type']], ['is_proper' => $user_coupon_data['is_proper']], ['proper_id' => $user_coupon_data['proper_id']], // 同一专有者 ['giver_id' => $user_coupon_data['giver_id']], ['goods_id' => $user_coupon_data['goods_id']], // 同一商品赠送 ['use_begin_time' => $user_coupon_data['use_begin_time']], // 同一使用开始时间 ['receive_end_time' => $user_coupon_data['receive_end_time']], // 同一使用结束时间 ['status' => StatusEnum::ENABLED] ], true); if ($user_coupon) { $user_coupon_data['id'] = $user_coupon['id']; // 有限领取次数 if ($coupon_info['unlimit_receive_times'] != ElectronCouponEnums::UNLIMIT_RECEIVE_TIMES && $user_coupon['receive_times'] >= $coupon_info['receive_times'] ) { throw new Exception('该' . $customize_name . '仅限领取' . $coupon_info['receive_times'] . '次, 您已超出次数'); } // 更新数据的话,去掉默认值 if ($user_coupon_data['last_receive_time'] == 0) { unset($user_coupon_data['last_receive_time']); } if ($user_coupon_data['last_active_time'] == 0) { unset($user_coupon_data['last_active_time']); } } else if ($params['get_type'] == ElectronCouponEnums::COUPON_GET_TYPE_GOODS) { $user_coupon_data['last_receive_time'] = time(); } // 插入赠送的电子券数据 $insert_user_coupon = self::setData($user_coupon_data); if ($insert_user_coupon == false) throw new Exception(self::getStaticError()); // 电子券更新已领取数量 $give_quantity= $coupon_info['give_quantity']; if(!empty($params['get_type'])&&$params['get_type']==ElectronCouponEnums::COUPON_GET_TYPE_SYSTEM){ $give_quantity+= $receive_times; } $update_coupon_data = ElectronCoupon::setData([ 'id' => $coupon_info['id'], 'mall_id' => $params['mall_id'], 'receive_amount' => $pieces_amount, 'give_quantity' => $give_quantity, ]); if ($update_coupon_data == false) { throw new Exception(ElectronCoupon::getStaticError()); } $coupon_info['receive_amount'] += $pieces_amount; $coupon_info['receive_percent'] = $coupon_info['amount'] > 0 ? bcdiv($coupon_info['receive_amount'] * 100, $coupon_info['amount'], 2) : 0; $tran->commit(); if ($params['get_type'] == ElectronCouponEnums::COUPON_GET_TYPE_RECEIVE) { return compact('coupon_info'); } } catch (Exception $e) { $tran->rollBack(); self::setStaticError($e->getMessage()); return false; } } }