= 1000; $distance_text = round(($distance / 1000), 2) . 'km'; break; default : $distance_text = $distance . 'm'; break; } return $distance_text; } protected static function init() { self::afterInsert(function ($row) { if (!$row['weigh']) { $pk = $row->getPk(); $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]); } }); } public function getAddTypeList() { return ['1' => __('Add_type 1'), '2' => __('Add_type 2')]; } public function getTypeList() { return ['out' => __('Type out'), 'in' => __('Type in')]; } public function getAddressTypeList() { return ['1' => __('Address_type 1'), '2' => __('Address_type 2')]; } public function getStatusList() { return ['1' => __('Status 1'), '2' => __('Status 2'), '3' => __('Status 3')]; } public function getAuthStatusList() { return ['0' => __('Auth_status 0'), '1' => __('Auth_status 1'), '2' => __('Auth_status 2')]; } public function getRecommendList() { return ['0' => __('Recommend 0'), '1' => __('Recommend 1')]; } public function getHotList() { return ['0' => __('Hot 0'), '1' => __('Hot 1')]; } public function getNewList() { return ['0' => __('New 0'), '1' => __('New 1')]; } public function getSelfhotList() { return ['0' => __('Selfhot 0'), '1' => __('Selfhot 1')]; } public function getAddTypeTextAttr($value, $data) { $value = $value ? $value : (isset($data['add_type']) ? $data['add_type'] : ''); $list = $this->getAddTypeList(); return isset($list[$value]) ? $list[$value] : ''; } public function getTypeTextAttr($value, $data) { $value = $value ? $value : (isset($data['type']) ? $data['type'] : ''); $list = $this->getTypeList(); return isset($list[$value]) ? $list[$value] : ''; } public function getAddressTypeTextAttr($value, $data) { $value = $value ? $value : (isset($data['address_type']) ? $data['address_type'] : ''); $list = $this->getAddressTypeList(); return isset($list[$value]) ? $list[$value] : ''; } public function getStatusTextAttr($value, $data) { $value = $value ? $value : (isset($data['status']) ? $data['status'] : ''); $list = $this->getStatusList(); return isset($list[$value]) ? $list[$value] : ''; } public function getAuthStatusTextAttr($value, $data) { $value = $value ? $value : (isset($data['auth_status']) ? $data['auth_status'] : ''); $list = $this->getAuthStatusList(); return isset($list[$value]) ? $list[$value] : ''; } public function getAuthTimeTextAttr($value, $data) { $value = $value ? $value : (isset($data['auth_time']) ? $data['auth_time'] : ''); return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value; } public function getRecommendTextAttr($value, $data) { $value = $value ? $value : (isset($data['recommend']) ? $data['recommend'] : ''); $list = $this->getRecommendList(); return isset($list[$value]) ? $list[$value] : ''; } public function getHotTextAttr($value, $data) { $value = $value ? $value : (isset($data['hot']) ? $data['hot'] : ''); $list = $this->getHotList(); return isset($list[$value]) ? $list[$value] : ''; } public function getNewTextAttr($value, $data) { $value = $value ? $value : (isset($data['new']) ? $data['new'] : ''); $list = $this->getNewList(); return isset($list[$value]) ? $list[$value] : ''; } public function getSelfhotTextAttr($value, $data) { $value = $value ? $value : (isset($data['selfhot']) ? $data['selfhot'] : ''); $list = $this->getSelfhotList(); return isset($list[$value]) ? $list[$value] : ''; } protected function setAuthTimeAttr($value) { return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value); } public function getHeadimageAttr($value, $data) { if (!empty($value)) return cdnurl($value, true); } public function getImagesAttr($value, $data) { $imagesArray = []; if (!empty($value)) { $imagesArray = explode(',', $value); foreach ($imagesArray as &$v) { $v = cdnurl($v, true); } return $imagesArray; } return $imagesArray; } public function manystore() { return $this->belongsTo('app\admin\model\Manystore', 'manystore_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function shop() { return $this->belongsTo(ManystoreShop::class, 'shop_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function user() { return $this->belongsTo('app\common\model\User', 'user_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function admin() { return $this->belongsTo('app\admin\model\Admin', 'admin_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function teacher() { return $this->belongsTo('app\common\model\school\classes\Teacher', 'teacher_id', 'id', [], 'LEFT')->setEagerlyType(0); } public function specs() { return $this->hasMany(ClassesSpec::class,'classes_lib_id'); } /** 课程详情 * @param $id * @return ClassesLib|null * @throws \think\exception\DbException */ public function detail($id,$user_id=0){ $self = $this->get($id,['shop','teacher']); //是否收藏 $self['is_collect'] = 0; //是否购买 $self['have_buy'] = 0; if($user_id){ //判断是否收藏 $self['is_collect'] = Collect::where("user_id",$user_id)->where("classes_lib_id",$id)->count(); //判断用户是否已报名 $self['have_buy'] = \app\common\model\school\classes\order\Order::where("classes_lib_id",$id) ->where("user_id",$user_id) ->where("status","in",["3","6","9"]) ->count() ? 1 : 0 ; //$self['virtual_people'] = $self['virtual_people'] + 1; //有用户进来,参与人数+1 if(!$self['have_buy'])$self['virtual_people'] = $self['virtual_people'] + 1; } //下架判断 // if($self['status'] != '1'){ // $this->error("该课程已下架"); // } // //参与人数 = 虚拟人数 + 平台人数 return $self; } /**课程参与人员信息 * @param $id * */ public function virtualParticipants($id,$user_id=0){ //虚拟用户生成数量 $v_num = 10; $unpaid_user_data = $paid_user_data = []; $selfuser = null; if($user_id){ $selfuser = User::get($user_id); } $user_unpaid_order = $user_paid_order =null; if($selfuser){ $user_unpaid_order = \app\common\model\school\classes\order\Order::where("classes_lib_id",$id) ->where("status","in",["0",'-3']) ->where("user_id",$user_id) ->order("createtime desc") ->value("createtime"); $user_paid_order = \app\common\model\school\classes\order\Order::where("classes_lib_id",$id) ->where("status","in",["3",'6','9']) ->where("user_id",$user_id) ->order("createtime desc") ->value("createtime"); } //参与者头像 //先从订单里取出最新的10个未支付的用户,不足的用虚拟用户填充 $user_ids = \app\common\model\school\classes\order\Order::where("classes_lib_id",$id)->where("status","in",["0",'-3'])->order("createtime desc")->limit($v_num)->column("createtime","user_id"); if($user_ids){ $users = User::where("id","in",array_keys($user_ids))->select(); foreach ($users as $user){ $unpaid_user_data[] = [ "nickname"=>$user['nickname'], "head_image"=>$user['avatar'], "classes_lib_id"=>$id, "time"=>$user_ids[$user['id']], "jointype"=>'1', "havetype"=>'0' ]; } } if(!$user_paid_order && $selfuser){ if($user_unpaid_order){ $unpaid_user_data[] = [ "nickname"=>$selfuser['nickname'], "head_image"=>$selfuser['avatar'], "classes_lib_id"=>$id, "time"=>$user_unpaid_order, "jointype"=>'1', "havetype"=>'0' ]; $user_ids[$selfuser['id']] = $user_unpaid_order; }else{ $unpaid_user_data[] = [ "nickname"=>$selfuser['nickname'], "head_image"=>$selfuser['avatar'], "classes_lib_id"=>$id, "time"=>time(), "jointype"=>'1', "havetype"=>'0' ]; $user_ids[$selfuser['id']] = time(); } } //计算需要生成的虚拟用户数量 $v_num = $v_num - count($user_ids); if($v_num<0)$v_num =0; if($v_num){ $unpaid_user = VirtualUser::where("classes_lib_id",$id)->where("jointype",'1')->order("time desc")->limit($v_num)->select(); $unpaid_user_data = array_merge($unpaid_user_data,$unpaid_user); } //再从订单里取出最新的10个使用中,已完成 和 已退款 的用户,不足的用虚拟用户填充 $user_ids = \app\common\model\school\classes\order\Order::where("classes_lib_id",$id)->where("status","in",["3",'6','9'])->order("createtime desc")->limit($v_num)->column("createtime","user_id"); if($user_ids){ $users = User::where("id","in",array_keys($user_ids))->select(); foreach ($users as $user){ $paid_user_data[] = [ "nickname"=>$user['nickname'], "head_image"=>$user['avatar'], "classes_lib_id"=>$id, "time"=>$user_ids[$user['id']], "jointype"=>'0', "havetype"=>'1' ]; } } //计算需要生成的虚拟用户数量 $v_num = 10; $v_num = $v_num - count($user_ids); if($v_num<0)$v_num =0; if($v_num){ $unpaid_user = VirtualUser::where("classes_lib_id",$id)->where("havetype",'1')->order("time desc")->limit($v_num)->select(); $paid_user_data = array_merge($paid_user_data,$unpaid_user); } //进行昵称加*和按时间重新排序 array_multisort(array_column($unpaid_user_data, 'time'), SORT_ASC, $unpaid_user_data); array_multisort(array_column($paid_user_data, 'time'), SORT_ASC, $paid_user_data); foreach ($unpaid_user_data as &$userss){ //substr_replace($username, '****', 3, 4); $userss["nickname"] = $this->nickname_filter($userss["nickname"]); } foreach ($paid_user_data as &$usersss){ //substr_replace($username, '****', 3, 4); $usersss["nickname"] = $this->nickname_filter($usersss["nickname"]); } return compact("unpaid_user_data","paid_user_data"); } public function nickname_filter($nickname){ $nickname_len = mb_strlen($nickname); if($nickname_len<=2){ return $nickname; }else{ return mb_substr($nickname,0,1).str_repeat("*",$nickname_len-2).mb_substr($nickname,-1); } } /**课程规格 * @param $id * */ public function spec($id){ //课程规格 $spec_data = ClassesSpec::where("classes_lib_id",$id)->where("status",'1')->order("weigh desc")->select(); return $spec_data; } /** 管理的课程ids * @param $user_id * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException * @throws \think\exception\DbException */ public function getClassesAuthIds($user_id){ $classes_lib_ids = Verification::where("user_id",$user_id)->where("status",'1')->column("classes_lib_ids"); if($classes_lib_ids){ //遍历课程ids foreach ($classes_lib_ids as $classes_lib_id){ $classes_lib_id_arr = explode(",",$classes_lib_id)?:[]; foreach ($classes_lib_id_arr as $v){ $this->classes_lib_ids[] = $v; } } } //判断是否有老师身份 $teacher = Teacher::where("user_id",$user_id)->find(); if($teacher){ $lib_ids = ClassesLib::where("teacher_id",$teacher['id'])->column('id'); $this->classes_lib_ids = array_merge($this->classes_lib_ids,$lib_ids); } $this->classes_lib_ids = array_unique($this->classes_lib_ids); return $this->classes_lib_ids; } /** * 获取所有课程列表 */ public static function getVaildList($params) { extract($params); $a = (new self)->getWithAlisaName().'.'; // 查询自提点 if(isset($status) && in_array($status, ['1','2','3'])){ $selfetch = self::with(['teacher']); }else{ $selfetch = self::with(['teacher'])->where($a.'status', '1')->where("{$a}auth_status",1); } $order = $order?? 'normal'; $per_page = $limit ?? 10; $field = "{$a}id,{$a}shop_id,{$a}user_id,{$a}teacher_id,{$a}classes_cate_ids,{$a}classes_label_ids,{$a}self_label_tag,{$a}title,{$a}headimage,{$a}type,{$a}classes_date_text,{$a}classes_time_text,{$a}virtual_num,{$a}sale,{$a}price,{$a}underline_price,{$a}virtual_collect,{$a}status,{$a}auth_status,{$a}weigh,{$a}recommend,{$a}hot,{$a}new,{$a}selfhot,{$a}createtime,{$a}virtual_people,{$a}feel,{$a}limit_num,{$a}sign_num,{$a}verification_num"; //得到距离 if (isset($latitude) && isset($longitude) && $latitude && $longitude) { $field .= ', '.getDistanceBuilder($latitude, $longitude); }else{ $field .= ', 0 as distance'; } //得到每个 $selfetch = $selfetch->field($field); if (isset($keyword) && $keyword) { $selfetch = $selfetch->where("{$a}title|{$a}address|{$a}address_detail|{$a}address_city", 'like', '%' . $keyword . '%'); } if (isset($manystore_id) && $manystore_id) { $selfetch = $selfetch->where("{$a}manystore_id", 'in', ''.$manystore_id); } if (isset($shop_id) && $shop_id) { $selfetch = $selfetch->where("{$a}shop_id", 'in', ''.$shop_id); } if (isset($user_id) && $user_id) { $selfetch = $selfetch->where("{$a}user_id", 'in', ''.$user_id); } if (isset($my) && $my && isset($my_user_id) && $my_user_id) { $selfetch = $selfetch->where("{$a}user_id", 'in', ''.$my_user_id); } if (isset($teacher_id) && $teacher_id) { $selfetch = $selfetch->where("{$a}teacher_id", 'in', ''.$teacher_id); } if (isset($type) && $type) { $selfetch = $selfetch->where("{$a}type", 'in', ''.$type); } if (isset($address_type) && $address_type) { $selfetch = $selfetch->where("{$a}address_type", 'in', ''.$address_type); } if (isset($recommend) && $recommend) { $selfetch = $selfetch->where("{$a}recommend", 'in', ''.$recommend); } if (isset($hot) && $hot) { $selfetch = $selfetch->where("{$a}hot", 'in', ''.$hot); } if (isset($new) && $new) { $selfetch = $selfetch->where("{$a}new", 'in', ''.$new); } if (isset($feel) && $feel) { $selfetch = $selfetch->where("{$a}feel", 'in', ''.$feel); } //区域搜索 if (isset($province) && $province) { $selfetch = $selfetch->where("{$a}province", 'in', ''.$province); } if (isset($city) && $city) { $selfetch = $selfetch->where("{$a}city", 'in', ''.$city); } if (isset($district) && $district) { $selfetch = $selfetch->where("{$a}district", 'in', ''.$district); } if (isset($self_label_tag) && $self_label_tag) { $self_label_tag = implode("|",explode(',',$self_label_tag)); $selfetch = $selfetch->whereRaw(" {$a}self_label_tag REGEXP '({$self_label_tag})'"); } if (isset($classes_cate_ids) && $classes_cate_ids) { $classes_cate_ids = implode("|",explode(',',$classes_cate_ids)); $selfetch = $selfetch->whereRaw(" {$a}classes_cate_ids REGEXP '({$classes_cate_ids})'"); } if (isset($classes_label_ids) && $classes_label_ids) { $classes_label_ids = implode("|",explode(',',$classes_label_ids)); $selfetch = $selfetch->whereRaw(" {$a}classes_label_ids REGEXP '({$classes_label_ids})'"); } $collect_classes_lib_ids = [-1]; //需登录查询条件: if(isset($my_user_id) && $my_user_id){ //得到我收藏的课程ids $collect_classes_lib_ids = Collect::where("user_id",$my_user_id)->column("classes_lib_id"); //专查我的收藏 if(isset($collect) && $collect){ $selfetch = $selfetch->where("{$a}id","in",$collect_classes_lib_ids); } } //排序 switch ($order) { case "normal": //综合排序(推薦優先) $selfetch = $selfetch->order("{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc,{$a}sign_num desc"); break; case "distance": //距离优先 权重 $selfetch = $selfetch->order("distance asc,{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc,{$a}sign_num desc"); break; case "hot": //熱門优先 $selfetch = $selfetch->order("{$a}hot desc,{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc,{$a}sign_num desc"); break; case "new": //平台最新优先 $selfetch = $selfetch->order("{$a}new desc,{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc,{$a}sign_num desc"); break; case "selfhot": //机构热门优先 $selfetch = $selfetch->order("{$a}selfhot desc,{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc,{$a}sign_num desc"); break; case "sale": //銷量优先 $selfetch = $selfetch->order("{$a}sale desc,{$a}verification_num desc,{$a}sign_num desc,{$a}recommend desc,{$a}weigh desc"); break; default: throw new \Exception("不支持的排序类型"); } if(isset($nearby) && $nearby) { $selfetch = $selfetch->having("distance <= {$nearby}"); } $selfetch = $selfetch->paginate($per_page); //额外附加数据 foreach ($selfetch as $row) { //迭代器魔术方法遍历,填值自动引用传值 //设置是否已收藏 $row->is_collect = in_array($row->id,$collect_classes_lib_ids) ? 1 : 0; } return $selfetch; } public static function update_classes($classes_lib_id){ //更新课程规格库存 $classes_lib = self::get($classes_lib_id); if($classes_lib){ //所有课时加起来 $classes_lib->limit_num = ClassesSpec::where("classes_lib_id",$classes_lib_id)->sum( "limit_num"); //更新虚拟用户数据 //得到课程所有虚拟参与者数量 $virtual_people = VirtualUser::where("jointype",'1')->where("classes_lib_id",$classes_lib_id)->count(); //如果课程虚拟参与者字段 数量小于 虚拟参与者实际数量 ,则等于虚拟参与者实际数量 $classes_lib->virtual_people = $classes_lib->virtual_people < $virtual_people ? $virtual_people : $classes_lib->virtual_people; //得到课程所有虚拟报名者数量 $virtual_num = VirtualUser::where("havetype",'1')->where("classes_lib_id",$classes_lib_id)->count(); //如果课程虚拟报名者字段 数量小于 虚拟报名者实际数量 ,则等于虚拟报名者实际数量 havetype $classes_lib->virtual_num = $classes_lib->virtual_num < $virtual_num ? $virtual_num : $classes_lib->virtual_num; $classes_lib->save(); } } public static function add_virtual_init($classes_lib_id){ //更新课程规格库存 $classes_lib = self::get($classes_lib_id); if($classes_lib){ //如果课程虚拟参与者字300-2000随机 $classes_lib->virtual_people = mt_rand(300, 2000); //如果课程虚拟报名者字段 $classes_lib->virtual_num = 0; $classes_lib->save(); //生成20个虚拟参与者 (new Virtual())->getVirtualUser(20,$classes_lib_id,time(),true); } } /**设置收藏 * @param $id * @param int $user_id * @param int $collect 0取消收藏 1收藏 * @param bool $check * @param bool $trans * @throws \Exception */ public function collect($id,$user_id,$collect,$oper_type='user',$oper_id=0,$trans=false){ $classes_lib = self::where("id",$id)->find(); if(!$classes_lib)throw new \Exception("找不到课程!"); //判断逻辑 if($trans){ self::beginTrans(); } try{ //事务逻辑 $where = [ "user_id"=>$user_id, "classes_lib_id"=>$id, "weigh"=>$classes_lib["weigh"], ]; //查询是否已收藏 $res1 = Collect::where($where)->find(); if($collect){ if(!$res1){ //未收藏,添加收藏 $res1 = new Collect(); $res1->allowField(true)->save($where); } }else{ //取消收藏 $res1 = Collect::where($where)->delete(); } if($trans){ self::commitTrans(); } }catch (\Exception $e){ if($trans){ self::rollbackTrans(); } throw new \Exception($e->getMessage()); } $where["is_collect"] = $collect; return $where; } }