50], [['logo'], 'string', 'max' => 255], [['allow_member_levels', 'introduce'], 'string', 'max' => 1000], [['relay_customize_text'], 'string', 'max' => 20], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'mall_id' => '商城id', 'name' => '课程名称', 'cat_id' => '课程分类id', 'price' => '课程价格', 'line_off_price' => '划线价格', 'member_price' => '会员价格', 'logo' => '课程封面logo图片保存地址', 'allow_member_levels' => '指定会员观看,会员等级之间用逗号连接', 'can_download' => '是否允许下载 默认允许下载 1:是 0:否', 'can_comment' => '是否允许评论 默认允许评论 1:是 0:否', 'introduce' => '课程介绍', 'detail' => '课程详情', 'sales' => '课程销量', 'is_open_vm' => '是否开启虚拟数据 默认开启 1:开启 0:不开启', 'vm_likes' => '课程虚拟点赞数', 'vm_shares' => '课程虚拟分享数', 'vm_downloads' => '课程虚拟下载数', 'vm_views' => '课程虚拟播放次数', 'likes' => '课程实际点赞数', 'shares' => '课程实际分享数', 'downloads' => '课程实际下载数', 'views' => '课程实际播放次数', 'comments' => '课程实际评论数', 'sell_type' => '课程售卖方式,1:按照课程设置的售价付费观看,2:指定会员观看,3:免费,4:转发一定次数免费观看', 'relays' => '预设置转发次数,达到转发次数后可以免费观看', 'relay_customize_text' => '转发按钮自定义文字', 'relay_times' => '课程被所有的会员转发的总次数,在此做冗余', 'status' => '课程状态 默认是1(上架) 1:上架 0:下架,-1是删除', 'created_at' => '创建时间', 'updated_at' => '修改时间', 'sort' => '排序值,数值越大排的越前', ]; } public static function getCourseListWithMemberPrice($user, int $mall_id, $course_ids = null, array $andWhere = [], string $field = '', $limit = null, $order = null) { try { $where[] = ['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]; $select = 'id,name as course_name,logo,introduce,vm_views,views,vm_likes,likes,vm_shares,shares,vm_downloads,downloads,price,line_off_price,is_open_vm,can_download,can_comment'; if (!empty($course_ids)) { $where[] = ['id' => $course_ids]; } if (!empty($andWhere)) { $where[] = $andWhere; } if (!empty($field)) { if ('*' == $field) { $select = '*'; } else { $select .= ',' . $field; } } $params = [ 'select' => $select, 'order' => $order ?? 'sort desc,created_at desc', 'where' => $where, ]; if (!empty($limit)) { $params['limit'] = $limit; } $list = self::listPage($params, false, true); if (empty($user)) { $discount = 1; } else { $discount = self::getCurrMemberDiscount($user, $mall_id); } if (!empty($list['list'])) { foreach ($list['list'] as $lk => &$lv) { if (isset($lv['is_open_vm']) && !empty($lv['is_open_vm'])) { $lv['likes'] += $lv['vm_likes']; $lv['shares'] += $lv['vm_shares']; $lv['downloads'] += $lv['vm_downloads']; $lv['views'] += $lv['vm_views']; } $list['list'][$lk]['member_price'] = bcmul($lv['price'], $discount, 2); $list['list'][$lk]['allow_member_levels'] = trim($lv['allow_member_levels'], ','); // $list['list'][$lk]['views'] = self::numberFormat($lv['views']); } } return $list; } catch (\Exception $e) { self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 获取当前会员折扣 * @param {*} * @return {*} */ public static function getCurrMemberDiscount($user, $mall_id) { if ($user->level == 0) { $discount = 10; } else { $where[] = ['mall_id' => $mall_id]; $where[] = ['level' => $user->level]; $member_level_info = UserLevel::getUserLevelOne($where, [], 1); // 当前会员折扣 $discount = $member_level_info['discount']; } $discount = $discount * 10 / 100; return $discount; } public static function setData(int $mall_id, array $data) { if (!empty($data['allow_member_levels']) && is_array($data['allow_member_levels'])) { $data['allow_member_levels'] = implode(',', array_keys(array_flip(array_filter($data['allow_member_levels'])))); } if (!empty($data['id'])) { $model = self::findOne(['mall_id' => $mall_id, 'status' => [StatusEnum::ENABLED, StatusEnum::DISABLED], 'id' => $data['id']]); if (empty($model)) { self::$static_error = '数据异常'; return false; } } else { $model = new self(); $model->loadDefaultValues(); $model->mall_id = $mall_id; $model->status = StatusEnum::ENABLED; } foreach ($data as $key => $val) { $model->$key = $val; } if (!$model->save()) { self::$static_error = '保存数据失败:' . $model->getErrorMessage(); return false; } return $model; } /** * 获取课程详情 * * @param int $id 课程ID * @return mixed | Yii\web\response */ public static function getDetail(int $id, int $mall_id, string $field = '*', bool $as_array = false, $status = [StatusEnum::ENABLED]) { $result = self::find() ->select($field) ->where(['id' => $id, 'status' => $status, 'mall_id' => $mall_id]) ->asArray($as_array) ->one(); if (empty($result)) { self::$static_error = '课程不存在'; return false; } if (!empty($result) && !empty($result['is_open_vm'])) { $result['views'] = $result['views'] + $result['vm_views']; $result['downloads'] = $result['downloads'] + $result['vm_downloads']; $result['likes'] = $result['likes'] + $result['vm_likes']; $result['shares'] = $result['shares'] + $result['vm_shares']; } if (!empty($result['allow_member_levels'])) { $result['allow_member_levels'] = explode(',', $result['allow_member_levels']); } elseif ($result['allow_member_levels'] == 0) { $result['allow_member_levels'] = [0]; } return $result; } /** * @name: * @msg: 检查某个用户是否可以播放课程 * @param {int} $course_id 课程 id * @param {int} $mall_id 商城 id * @param {int} $user_id 用户 id * @return {array} is_can_play 1:可以播放,2:用户未购买课程,3:用户不在课程指定的会员等级内, 4:转发次数不够; */ public static function courseCanPlay(int $course_id, int $mall_id, $user): array { $course = self::find() ->select('id,sell_type,allow_member_levels,relays') ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $course_id]) ->asArray() ->one(); //后台发放课程(任何类型课程)后,用户可直接播放视频 if (!empty($user)) { if (self::courseIsBought($course_id, $mall_id, $user['id'])) { $is_can_play = 1; $is_can_play = ['is_can_play' => 1, 'need_relays' => 0, 'current_user_relayed_times' => 0]; return $is_can_play; } } switch ($course['sell_type']) { case CourseEnum::COURSE_SELL_TYPE_1: // 当前会员是否购买改课程 if (empty($user)) { $is_can_play = 2; } else { if (self::courseIsBought($course_id, $mall_id, $user['id'])) { $is_can_play = 1; } else { $is_can_play = 2; } } $is_can_play = ['is_can_play' => $is_can_play]; break; case CourseEnum::COURSE_SELL_TYPE_2: $level_arr = explode(',', $course['allow_member_levels']); if ($course['allow_member_levels'] == 0 && is_numeric($course['allow_member_levels'])) { // 全部会员可以看 $is_can_play = 1; } elseif (!empty($level_arr[0]) && in_array($user['level'], $level_arr)) { // 当前会员在课程指定的会员等级内 $is_can_play = 1; } else { // 课程未选择可以看的会员等级,所有会员不可以看;或者当前会员等级不在课程指定的会员等级内 $is_can_play = 3; } $is_can_play = ['is_can_play' => $is_can_play]; break; case CourseEnum::COURSE_SELL_TYPE_3: // 课程免费 // $is_can_play = 1; $is_can_play = ['is_can_play' => 1]; break; case CourseEnum::COURSE_SELL_TYPE_4: if (!empty($user)) { $current_user_relayed_times = AddonsCourseRelays::find() ->where(['mall_id' => $mall_id, 'user_id' => $user['id'], 'course_id' => $course_id]) ->count(); } else { $current_user_relayed_times = 0; } if ($current_user_relayed_times >= $course['relays']) { $is_can_play = 1; } else { $is_can_play = 4; } // 当前还需要转发的次数 $need_relays = $course['relays'] - $current_user_relayed_times >= 0 ? $course['relays'] - $current_user_relayed_times : 0; $is_can_play = ['is_can_play' => $is_can_play, 'need_relays' => $need_relays, 'current_user_relayed_times' => $current_user_relayed_times]; break; default: $is_can_play = ['is_can_play' => 2]; break; } return $is_can_play; } /** * @name: * @msg: 检查某一个会员是否购买某一个课程 * @param {int} $course_id 课程 id * @param {int} $user_id 用户 id * @param {int} $mall_id 商城 id * @return {int} $is_bought 1:用户已购买该课程,0: 用户未购买该课程 */ public static function courseIsBought(int $course_id, int $mall_id, int $user_id): int { $bought_info = AddonsCourseBought::findOne(['mall_id' => $mall_id, 'course_id' => $course_id, 'user_id' => $user_id, 'is_pay' => CourseEnum::IS_PAY_YES, 'status' => StatusEnum::ENABLED]); $is_bought = empty($bought_info) ? 0 : 1; return $is_bought; } /** * @name: * @msg: 获取课程列表,不获取课程的会员价信息 * @param {int} $mall_id * @param {*} $ids * @param {string} $field * @return {*} */ public static function getList(int $mall_id, $ids = null, string $field = 'id,name') { if (!empty($ids)) { $where = ['status' => StatusEnum::ENABLED, 'mall_id' => $mall_id, 'id' => $ids]; } else { $where = ['status' => StatusEnum::ENABLED, 'mall_id' => $mall_id]; } $list = self::find() ->select($field) ->where($where) ->asArray() ->all(); return $list; } /** * 获取会员价 * * @param array $user 会员信息 * @param int $use_discount 使用折扣 * @return float */ public function getMemberPrice($user, &$use_discount = false) { $discount = self::getCurrMemberDiscount($user, $user['mall_id']); if ($discount == 1) { $use_discount = false; } return (float)$discount * $this->price; } /** Undocumented function * 维护课程销量 * @param [type] $course_id * @param [type] $sales * @return bool */ public static function updateSales($course_id, $sales) { $lock_key = RedisKeyEnum::suffix(RedisKeyEnum::LOCK_COURSE, $course_id); $identification = uniqid(); try { if (!LockHelper::lock($lock_key, $identification, 30, 60)) throw new Exception('当前访问人数过多'); $course = AddonsCourse::findOne(['id' => $course_id]); $course->sales += $sales; $course->save(); LockHelper::uLock($lock_key, $identification); return true; } catch (Exception $e) { LockHelper::uLock($lock_key, $identification); if (isset($trans)) $trans->rollback(); self::$static_error = $e->getMessage(); return false; } } /** * @name: * @msg: 获取经销设置 * @param {int} $mall_id * @param {int} $course_id * @return {*} */ public static function getAgentConfig(int $mall_id, int $course_id) : array { $addons_name = AddonsEnum::ADDONS_NAME_AGENT; $is_install = MallAddons::isInstall($mall_id, $addons_name); if (!$is_install) { $agent_enable = 0; $item_setting = []; $agent_levels = []; $agent_details = []; $agent_config = compact('agent_enable', 'item_setting', 'agent_levels', 'agent_details'); } else { $agent_enable = 1; $item_setting = AgentCommissionItemSetting::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $course_id, 'item_type' => CourseEnum::ADDONS_NAME, 'commission_type' => 'commission']) ->one(); if (!empty($item_setting)) { $agent_details = array_values(ArrayHelper::toArray($item_setting->detail)); $item_setting = ArrayHelper::toArray($item_setting); } else { $item_setting = []; $agent_details = []; } $agent_levels = AgentLevel::find() ->select('id,name,level') ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]) ->orderBy('level asc') ->asArray() ->all(); $agent_config = compact('agent_enable', 'item_setting', 'agent_levels', 'agent_details'); } return $agent_config; } /** * @name: * @msg: 获取分销设置 * @param {int} $mall_id * @param {int} $course_id * @return {*} */ public static function getDistributionConfig(int $mall_id, int $course_id) : array { $addons_name = AddonsEnum::ADDONS_NAME_DISTRIBUTION ?? ''; $is_install = MallAddons::isInstall($mall_id, $addons_name); if (!$is_install) { $item_setting = []; $level_names = []; $distribution_levels = []; $distribution_details = []; $distribution_enable = 0; } else { $distribution_enable = 1; $level_names = [ [ 'name' => '一级分销', 'value' => 'commission_first', ], [ 'name' => '二级分销', 'value' => 'commission_second', ], // [ // 'name' => '三级分销', // 'value' => 'commission_third', // ], ]; $distribution_levels = DistributionLevel::find() ->select('id,level,name') ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED]) ->orderBy('level asc') ->asArray() ->all(); $item_setting = DistributionCommissionItemSetting::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $course_id]) ->asArray() ->one(); if (empty($item_setting)) { $distribution_details = []; } else { $distribution_details = DistributionCommissionItemSettingDetail::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'distribution_commission_item_setting_id' => $item_setting['id']]) ->asArray() ->all(); } } $distribution_config = compact('item_setting', 'level_names', 'distribution_levels', 'distribution_details', 'distribution_enable'); return $distribution_config; } /** * @name: * @msg: 保存经销设置 * @param {int} $mall_id * @param {array} $data * @return {*} */ public static function AgentSetting(int $mall_id, array $data) : bool { $transaction = \Yii::$app->db->beginTransaction(); $item_setting = $data['item_setting']; $item_setting['item_id'] = $data['course_id']; $item_setting['commission_type'] = 'commission'; $item_setting['item_type'] = CourseEnum::ADDONS_NAME; if (!empty($item_setting['id'])) { $item_settting_model = AgentCommissionItemSetting::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $item_setting['id']]) ->one(); } else { $item_settting_model = AgentCommissionItemSetting::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $data['course_id'], 'item_type' => CourseEnum::ADDONS_NAME]) ->one(); if (empty($item_settting_model)) { $item_settting_model = new AgentCommissionItemSetting(); $item_settting_model->loadDefaultValues(); $item_settting_model->mall_id = $mall_id; } unset($item_setting['id']); } foreach ($item_setting as $key => $val) { $item_settting_model->$key = $val; } $res_agent_item_setting = $item_settting_model->save(); if (false === $res_agent_item_setting) { $transaction->rollBack(); self::$static_error = $item_settting_model->getErrorMessage(); return false; } $detail_settings = []; unset($data['item_setting'], $data['_csrf'], $data['course_id']); // 团队奖 foreach ($data['team_prize_info'] as $key => $setting) { // dd($key, $settings); $prize_info = [ 'mall_id' => $mall_id, 'agent_commission_item_setting_id' => $item_settting_model->id, 'level' => $setting['level'], 'agent_team_prize' => $setting['agent_team_prize'] ?? 0, 'status' => StatusEnum::ENABLED, ]; $detail_settings[$setting['level']] = $prize_info; } // 平级将 foreach ($data['equal_prize_info'] as $key => $setting) { // dd($key, $settings); $prize_info = [ 'mall_id' => $mall_id, 'agent_commission_item_setting_id' => $item_settting_model->id, 'level' => $setting['level'], 'agent_equal_prize' => $setting['agent_equal_prize'] ?? 0, 'status' => StatusEnum::ENABLED, ]; $detail_settings[$setting['level']] = array_merge($detail_settings[$setting['level']], $prize_info); } // 越级奖 foreach ($data['over_prize_info'] as $key => $setting) { // dd($key, $settings); $prize_info = [ 'mall_id' => $mall_id, 'agent_commission_item_setting_id' => $item_settting_model->id, 'level' => $setting['level'], 'agent_over_prize' => $setting['agent_over_prize'] ?? 0, 'status' => StatusEnum::ENABLED, ]; $detail_settings[$setting['level']] = array_merge($detail_settings[$setting['level']], $prize_info); } // 额外奖 foreach ($data['extra_prize_info'] as $key => $setting) { // dd($key, $settings); $prize_info = [ 'mall_id' => $mall_id, 'agent_commission_item_setting_id' => $item_settting_model->id, 'level' => $setting['level'], 'agent_extra_prize' => $setting['agent_extra_prize'] ?? 0, 'status' => StatusEnum::ENABLED, ]; $detail_settings[$setting['level']] = array_merge($detail_settings[$setting['level']], $prize_info); } // dd($detail_settings); $insert_data = []; $time = time(); foreach ($detail_settings as $setting) { $insert_data[] = [ $setting['mall_id'], $setting['agent_commission_item_setting_id'], $setting['level'], $setting['agent_team_prize'], $setting['agent_equal_prize'], $setting['agent_over_prize'], $setting['agent_extra_prize'], $setting['status'], $time, $time, ]; } if (!empty($insert_data)) { $res_delete = AgentCommissionItemSettingDetail::deleteAll(['mall_id' => $mall_id, 'agent_commission_item_setting_id' => $item_settting_model->id]); if (false === $res_delete) { $transaction->rollBack(); self::$static_error = '清理原有的设置数据失败:' . $item_settting_model->getErrorMessage(); return false; } $fields = ['mall_id', 'agent_commission_item_setting_id', 'level', 'agent_team_prize', 'agent_equal_prize', 'agent_over_prize', 'agent_extra_prize', 'status', 'created_at', 'updated_at']; $res = \Yii::$app->db->createCommand()->batchInsert(AgentCommissionItemSettingDetail::tableName(), $fields, $insert_data)->execute(); if (false === $res) { $transaction->rollBack(); self::$static_error = '保存设置详情失败'; return false; } } $transaction->commit(); return true; } /** * @name: * @msg: 保存分销设置 * @param {int} $mall_id * @param {array} $data * @return {*} */ public static function distributionSetting(int $mall_id, array $data) : bool { $transaction = \Yii::$app->db->beginTransaction(); $item_setting = $data['item_setting']; $item_setting['item_id'] = $data['course_id']; $item_setting['item_type'] = CourseEnum::ADDONS_NAME; $item_setting['settings'] = 0; $item_setting['commission_type'] = 'commission'; $item_setting['status'] = StatusEnum::ENABLED; if (!empty($item_setting['id'])) { $item_settting_model = DistributionCommissionItemSetting::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'id' => $item_setting['id']]) ->one(); } else { $item_settting_model = DistributionCommissionItemSetting::find() ->where(['mall_id' => $mall_id, 'status' => StatusEnum::ENABLED, 'item_id' => $data['course_id'], 'item_type' => CourseEnum::ADDONS_NAME]) ->one(); if (empty($item_settting_model)) { $item_settting_model = new DistributionCommissionItemSetting(); $item_settting_model->loadDefaultValues(); $item_settting_model->mall_id = $mall_id; } unset($item_setting['id']); } foreach ($item_setting as $key => $val) { $item_settting_model->$key = $val; } $res_distribution_item_setting = $item_settting_model->save(); if (false === $res_distribution_item_setting) { $transaction->rollBack(); self::$static_error = $item_settting_model->getErrorMessage(); return false; } $details = $data['distribution_level_list']; // dd($details); $insert_data = []; $time = time(); if (!empty($details)) { foreach ($details as $detail) { $insert_data[] = [ $mall_id, $item_settting_model->id, $detail['level'], $detail['value'][0] ?? 0, $detail['value'][1] ?? 0, $detail['value'][2] ?? 0, StatusEnum::ENABLED, $time, $time, ]; } } if (!empty($insert_data)) { $res_delete = DistributionCommissionItemSettingDetail::deleteAll(['mall_id' => $mall_id, 'distribution_commission_item_setting_id' => $item_settting_model->id]); if (false === $res_delete) { $transaction->rollBack(); self::$static_error = '清理原有的设置数据失败:' . $item_settting_model->getErrorMessage(); return false; } $fields = ['mall_id', 'distribution_commission_item_setting_id', 'level', 'first_prize', 'second_prize', 'third_prize','status', 'created_at', 'updated_at']; $res = \Yii::$app->db->createCommand()->batchInsert(DistributionCommissionItemSettingDetail::tableName(), $fields, $insert_data)->execute(); if (false === $res) { $transaction->rollBack(); self::$static_error = '保存设置详情失败'; return false; } } $transaction->commit(); return true; } //供公共调用 public static function getCapitalLogList($params){ if (!isset($params['list']) || !is_array($params['list'])) return []; $source_table_id_arr_by_course_orders = []; foreach ($params['list'] as $item) { if (strpos($item['source_table'],'{{%addons_course_orders}}')!==false) { $source_table_id_arr_by_course_orders[] = $item['source_table_id']; } } if(!empty($source_table_id_arr_by_course_orders)){ $order_detail_arr = []; $cond = []; $cond['where'] = [['id' => $source_table_id_arr_by_course_orders]]; $cond['with'] = [ 'user' => function ($query) { $query->select('id,nickname,avatar_url'); }, 'course' => function ($query) { $query->select('id,name,price'); } ]; $course_order_list = AddonsCourseOrders::lists($cond); foreach ($course_order_list as $value) { $order_detail_arr[$value['id']] = [ 'goods_name' => $value['course']['name'], 'goods_price' => $value['course']['price'], 'created_at' => date('Y-m-d H:i:s', $value['created_at']), 'order_no' => $value['order_no'], 'user_id' => $value['user']['id'], 'nickname' => $value['user']['nickname'], 'avatar_url' => $value['user']['avatar_url'], ]; } foreach ($params['list'] as &$item) { if (strpos($item['source_table'],'{{%addons_course_orders}}')!==false) { $item['user_id'] = ''; $item['nickname'] = ''; $item['avatar_url'] = ''; $item['order_no'] = ''; $item['created_at'] = ''; $item['goods_price'] = ''; $item['goods_name'] = ''; if (!empty($order_detail_arr[$item['source_table_id']])) { $item['user_id'] = $order_detail_arr[$item['source_table_id']]['user_id']; $item['nickname'] = $order_detail_arr[$item['source_table_id']]['nickname']; $item['avatar_url'] = $order_detail_arr[$item['source_table_id']]['avatar_url']; $item['order_no'] = $order_detail_arr[$item['source_table_id']]['order_no']; $item['created_at'] = $order_detail_arr[$item['source_table_id']]['created_at']; $item['goods_price'] = $order_detail_arr[$item['source_table_id']]['goods_price']; $item['goods_name'] = $order_detail_arr[$item['source_table_id']]['goods_name']; } } } } return $params['list']; } }