DiverseYouthNightSchool/application/common/model/school/classes/activity/Activity.php

1607 lines
56 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\model\school\classes\activity;
use app\admin\model\manystore\Shop;
use app\common\library\Virtual;
use app\common\model\manystore\UserAuth;
use app\common\model\school\classes\activity\order\Order;
use app\common\model\BaseModel;
use app\common\model\dyqc\ManystoreShop;
use app\common\model\school\Area;
use app\common\model\school\classes\Cate;
use app\common\model\school\classes\ClassesLib;
use app\common\model\school\classes\ClassesSpec;
use app\common\model\school\classes\Collect;
use app\common\model\school\classes\Label;
use app\common\model\school\classes\Type;
use app\common\model\school\classes\Verification;
use app\common\model\school\classes\VirtualUser;
use app\manystore\model\Manystore;
use think\Model;
use traits\model\SoftDelete;
class Activity extends BaseModel
{
use SoftDelete;
// 表名
protected $name = 'school_classes_activity';
// 自动写入时间戳字段
protected $autoWriteTimestamp = 'integer';
// 定义时间戳字段名
protected $createTime = 'createtime';
protected $updateTime = 'updatetime';
protected $deleteTime = 'deletetime';
// 追加属性
protected $append = [
'address_type_text',
'start_time_text',
'end_time_text',
'sign_start_time_text',
'sign_end_time_text',
'status_text',
'recommend_text',
'hot_text',
'new_text',
'selfhot_text',
'expirestatus_text',
'add_type_text',
'has_expire',
'has_sign_expire',
];
public $no_auth_fields = ["status","weigh","recommend","hot","new","selfhot","feel","start_time","end_time","sign_start_time","sign_end_time","longitude","latitude","address_city","province","city","district","address","address_detail","address_type","title",'headimage','images','content',"price"];
public function getHasSignExpireAttr($value, $data)
{
$sign_start_time = (isset($data['sign_start_time']) ? $data['sign_start_time'] : '');
$sign_end_time = (isset($data['sign_end_time']) ? $data['sign_end_time'] : '');
if(!$sign_end_time) return '2';
if( $sign_end_time < time()) {
return '1';
}else{
return '2';
}
}
public function getHasExpireAttr($value, $data)
{
$end_time = (isset($data['end_time']) ? $data['end_time'] : '');
if(!$end_time) return '2';
if( $end_time < time()) {
return '1';
}else{
return '2';
}
}
public function getDistanceTextAttr($value, $data) {
$distance_text = '';
$distance = $data['distance'] ?? 0;
switch (true) {
case $distance >= 1000;
$distance_text = round(($distance / 1000), 2) . 'km';
break;
default :
$distance_text = $distance . 'm';
break;
}
return $distance_text;
}
public function getHasExpireList()
{
return ['1' => __('Has_expire 1'), '2' => __('Has_expire 2')];
}
protected static function init()
{
self::afterInsert(function ($row) {
if (!$row['weigh']) {
$pk = $row->getPk();
// $row->getQuery()->where($pk, $row[$pk])->update(['weigh' => $row[$pk]]);
$row->getQuery()->where($pk, $row[$pk])->update(['weigh' => 0]);
}
});
}
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 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 getExpirestatusList()
{
return ['1' => __('Expirestatus 1'), '2' => __('Expirestatus 2')];
}
public function getAddTypeList()
{
return ['1' => __('Add_type 1'), '2' => __('Add_type 2')];
}
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 getStartTimeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['start_time']) ? $data['start_time'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
public function getEndTimeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['end_time']) ? $data['end_time'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
public function getSignStartTimeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['sign_start_time']) ? $data['sign_start_time'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
}
public function getSignEndTimeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['sign_end_time']) ? $data['sign_end_time'] : '');
return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $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 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] : '';
}
public function getExpirestatusTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['expirestatus']) ? $data['expirestatus'] : '');
$list = $this->getExpirestatusList();
return isset($list[$value]) ? $list[$value] : '';
}
public function getAddTypeTextAttr($value, $data)
{
$value = $value ? $value : (isset($data['add_type']) ? $data['add_type'] : '');
$list = $this->getAddTypeList();
return isset($list[$value]) ? $list[$value] : '';
}
protected function setStartTimeAttr($value)
{
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
}
protected function setEndTimeAttr($value)
{
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
}
protected function setSignStartTimeAttr($value)
{
return $value === '' ? null : ($value && !is_numeric($value) ? strtotime($value) : $value);
}
protected function setSignEndTimeAttr($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 setImagesAttr($value, $data)
{
$imagesArray = $value;
if (!empty($value) && is_array($value)) {
//转成逗号拼接字符串
$imagesArray = implode(',', $value);
}
return $imagesArray;
}
public function manystore()
{
return $this->belongsTo(Manystore::class, 'manystore_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
public function shop()
{
return $this->belongsTo(ManystoreShop::class, 'shop_id', 'id', [], 'LEFT')->setEagerlyType(0);
}
public function items()
{
return $this->hasMany(ActivityItem::class,'classes_activity_id')->order("weigh desc,id desc");
}
public function activityCheck(&$params,$shop_id=null,$row=null,$oper_type='user',$oper_id=0)
{
if($row){
//统一时间格式成时间戳
if( is_string($row["start_time"]))$row["start_time"]=strtotime($row["start_time"]);
if( is_string($row["end_time"]))$row["end_time"]=strtotime($row["end_time"]);
if( is_string($row["sign_start_time"]))$row["sign_start_time"]=strtotime($row["sign_start_time"]);
if( is_string($row["sign_end_time"]))$row["sign_end_time"]=strtotime($row["sign_end_time"]);
}
$params["status"] = $params["status"] ?? '3';
if(!$shop_id)$shop_id = $params["shop_id"] ?? 0;
if(empty($params["weigh"]))$params["weigh"] = 0;
$manystore = Manystore::where("shop_id",$shop_id)->find();
if(!$manystore){
throw new \Exception("店铺不存在");
}
if(!(new \app\common\model\dyqc\ManystoreShop)->checkFull($shop_id))throw new \Exception("对方的认证信息未完善,请您先去帮忙完善!");
$params["manystore_id"] = $manystore["id"];
//开始和结束时间不能为空
$time = $params["time"];
if(empty($time))throw new \Exception("{$params["title"]}请选择开始和结束时间".$time);
$split_line = " - ";
$time_arr = explode($split_line,$time);
$params["start_time"] = $time_arr[0] ;
$params["end_time"] = $time_arr[1];
unset($params["time"]);
$start_time = $params["start_time"];
$end_time = $params["end_time"];
if(empty($start_time) || empty($end_time)){
throw new \Exception("{$params["title"]}请选择开始和结束时间".$time);
}
//转化时间戳
$start_time = $params["start_time"] && !is_numeric($params["start_time"]) ? strtotime($params["start_time"]) : $params["start_time"];
$end_time = $params["end_time"] && !is_numeric($params["end_time"]) ? strtotime($params["end_time"]) : $params["end_time"];
//结束时间不能小于开始时间
if($end_time<=$start_time){
throw new \Exception("{$params["title"]}结束时间不能小于开始时间");
}
//开始和结束时间不能为空
$time = $params["sign_time"];
if(empty($time))throw new \Exception("{$params["title"]}请选择开始和结束时间".$time);
$split_line = " - ";
$time_arr = explode($split_line,$time);
$params["sign_start_time"] = $time_arr[0] ;
$params["sign_end_time"] = $time_arr[1];
unset($params["sign_time"]);
$start_time = $params["sign_start_time"];
$end_time = $params["sign_end_time"];
if(empty($start_time) || empty($end_time)){
throw new \Exception("{$params["title"]}请选择开始和结束时间".$time);
}
//转化时间戳
$start_time = $params["sign_start_time"] && !is_numeric($params["sign_start_time"]) ? strtotime($params["sign_start_time"]) : $params["sign_start_time"];
$end_time = $params["sign_end_time"] && !is_numeric($params["sign_end_time"]) ? strtotime($params["sign_end_time"]) : $params["sign_end_time"];
//结束时间不能小于开始时间
if($end_time<=$start_time){
throw new \Exception("{$params["title"]}结束时间不能小于开始时间");
}
//课时必须大于等于1
// if($params["classes_num"] < 1) throw new \Exception("课时必须大于等于1");
if($params["price"] < 0) throw new \Exception("售价必须大于0");
//独立地点需传定位信息
if($params["address_type"] == "2"){
if(empty($params["address_city"])
&& !empty($params["province"])
&& !empty($params["city"])
&& !empty($params["district"])){
$province_name = Area::where("id" ,$params['province'])->value("name");
if(!$province_name) throw new \Exception("省份不存在");
$city_name = Area::where("id" ,$params['city'])->value("name");
if(!$city_name) throw new \Exception("市不存在");
$district_name = Area::where("id" ,$params['district'])->value("name");
if(!$district_name) throw new \Exception("区县不存在");
$params['address_city'] = $province_name."/".$city_name."/".$district_name;
}
if(empty($params["address_city"])
|| empty($params["province"])
|| empty($params["city"])
|| empty($params["district"])
|| empty($params["longitude"])
|| empty($params["latitude"])
|| empty($params["address"])
|| empty($params["address_detail"])
) throw new \Exception("独立地点需传定位信息");
}else{
//地址取机构的
$shop = ManystoreShop::where("id",$shop_id)->find();
if(!$shop){
throw new \Exception("店铺不存在");
}
if(empty($shop["address_city"])
|| empty($shop["province"])
|| empty($shop["city"])
|| empty($shop["district"])
|| empty($shop["longitude"])
|| empty($shop["latitude"])
|| empty($shop["address"])
|| empty($shop["address_detail"])
) throw new \Exception("当前机构地址并未完善,请在机构处完善!");
$params["address_city"] = $shop["address_city"];
$params["province"] = $shop["province"];
$params["city"] = $shop["city"];
$params["district"] = $shop["district"];
$params["longitude"] = $shop["longitude"];
$params["latitude"] = $shop["latitude"];
$params["address"] = $shop["address"];
$params["address_detail"] = $shop["address_detail"];
//address
// var_dump($params);
}
;
//收费免费判断
if($params["price"]==0){
$params["feel"] = "1";
}else{
//个人认证无法下付费课程
$shop = ManystoreShop::where("id",$shop_id)->find();
if($shop["type"]=="1"){
throw new \Exception("这个机构属于个人认证,无法发布付费活动!");
}
$params["feel"] = "0";
}
$rule = [
'manystore_id'=>'require',
'shop_id'=>'require',
'headimage' => 'require',
'title' => 'require',
'images' => 'require',
'address' => 'require',
'address_detail' => 'require',
'longitude' => 'require',
'latitude' => 'require',
'province' => 'require',
'city' => 'require',
'district' => 'require',
'address_city' => 'require',
'address_type' => 'require',
'content' => 'require',
'price' => 'require',
];
$rule_msg = [
"manystore_id.require"=>'机构id必填',
"shop_id.require"=>'机构id必填',
"headimage.require"=>'课程活动头图必填',
'title.require' => '活动名称必须填写',
'images.require' => '活动轮播图必须上传',
'address.require' => '地址必填',
'address_detail.require' => '详细地址必填',
'longitude.require' => '经度必填',
'latitude.require' => '纬度必填',
'province.require' => '省编号必填',
'city.require' => '市编号必填',
'district.require' => '县区编号必填',
'address_city.require' => '城市选择必填',
'address_type.require'=> '地址类型必填',
'content.require'=> '活动详情必填',
'price.require'=> '活动售价必填',
];
self::check($params,$rule,$rule_msg);
//统一时间格式成时间戳
if( is_string($params["start_time"]))$params["start_time"]=strtotime($params["start_time"]);
if( is_string($params["end_time"]))$params["end_time"]=strtotime($params["end_time"]);
if( is_string($params["sign_start_time"]))$params["sign_start_time"]=strtotime($params["sign_start_time"]);
if( is_string($params["sign_end_time"]))$params["sign_end_time"]=strtotime($params["sign_end_time"]);
//更新
if($row){
$this->have_auth = false;
if($this->need_auth){
//判断更新的变动数据
$this->no_auth_fields_check($params,$row);
if($this->have_auth){
// $params['status'] = "3";
}
}
$this->updateCheck($row->id,$params,$row);
//名称title不能与其他课程重复
$check_title = self::where('id','<>',$row["id"])->where('title',$params["title"])->find();
if($check_title){
throw new \Exception("活动名称已存在或被其他机构占用,请更改!");
}
//如果存在课程规格,验证每个课时规格的合法性
if(isset($params["item_json"])){
//如果存在&quot;的HTML转义字符先反转义再解析json
$params["item_json"] = html_entity_decode($params["item_json"]);
$spec = json_decode($params["item_json"],true);
if(empty($spec))throw new \Exception("请至少添加一个课时规格");
foreach ($spec as $k=>&$v){
unset($v["limit"]);
unset($v["status_name"]);
unset($v["visible"]);
$v["classes_activity_id"] = $row->id;
$v["manystore_id"] = $params["manystore_id"];
$v["shop_id"] = $shop_id;
//先不进行判定,交给提交后再判定
$classesSpec = new ActivityItem();
$classesSpec->specCheck($v,$shop_id,empty($v["id"])? null : ActivityItem::get($v["id"]),false,$oper_type,$oper_id);
}
$params["item_json"] = $spec;
}
}else{
//新增
//名称title不能重复
$check_title = self::where('title',$params["title"])->find();
if($check_title){
throw new \Exception("活动名称已存在或被其他机构占用,请更改!");
}
//如果存在课程规格,验证每个课时规格的合法性
if(isset($params["item_json"])){
//如果存在&quot;的HTML转义字符先反转义再解析json
$params["item_json"] = html_entity_decode($params["item_json"]);
$spec = json_decode($params["item_json"],true);
if(empty($spec))throw new \Exception("请至少添加一个课时规格");
foreach ($spec as $k=>&$v){
unset($v["limit"]);
unset($v["status_name"]);
unset($v["id"]);
$v["classes_activity_id"] = 0;
$v["manystore_id"] = $params["manystore_id"];
$v["shop_id"] = $shop_id;
(new ActivityItem)->specCheck($v,$shop_id,null,true,$oper_type,$oper_id);
}
$params["item_json"] = $spec;
}
}
$params["delete_spec_ids"] = [];
//按前端顺序分配显示权重
if(isset($params["item_json"]) && $params["item_json"]){
//数组倒过来
$params["item_json"] = array_reverse($params["item_json"]);
$insert_spec = [];
$need_up = false;
foreach ($params["item_json"] as $k=>&$v){
$v["weigh"] = $k + 1;
if(!empty($v["id"]))$insert_spec[] = $v["id"];
if($v["status"] == '1'){
$need_up = true;
}
}
if($insert_spec && $row){
$params["delete_spec_ids"] = ActivityItem::where("classes_activity_id",$row->id)->where("id","not in",$insert_spec)->column("id");
}
if(!$need_up)throw new \Exception("新添加的活动请先至少添加一个活动规格后再上架!");
}
//存在需要删除的规格则判断规格是否能删除
if($params["delete_spec_ids"] && $row){
$check_spec = ActivityItem::where("classes_activity_id",$row->id)->where("id","in",$params["delete_spec_ids"])->select();
foreach ($check_spec as $k=>$vv){
(new ActivityItem)->updateCheck($vv->id);
}
$params["delete_spec_ids"] = $check_spec;
}
//如果是上架,判断是否拥有课时规格,没有则无法上架
if(empty($params["item_json"])){
if(!$row)throw new \Exception("新添加的活动请先至少添加一个活动规格后再上架!");
//判断是否拥有课时规格,没有则无法上架
$check_spec = ActivityItem::where("classes_activity_id",$row->id)->where("status",'1')->count();
if(!$check_spec)throw new \Exception("新添加的活动请先至少添加一个上架的活动规格后再上架!");
}
}
public function updateCheck($id,$params=[],$row=null){
if($params && $row){
if(!$this->no_auth_fields_check($params,$row)){
return true;
}
}
// 课程存在售后订单则不允许操作
$order = Order::where("classes_activity_id",$id)->where("status","not in","-3,6,9")->find();
if($order)throw new \Exception("存在正在使用中的订单报名学员,规格无法继续操作,如规格有误请下架!");
}
//审核通过后
public function successAuth($id,$trans=false){
$activityAuth = ActivityAuth::where("id",$id)->find();
if(!$activityAuth)throw new \Exception("未找到该记录");
$itemauths = $activityAuth->itemauths;
if(!$itemauths)throw new \Exception("规格不全");
//判断逻辑
if($trans){
self::beginTrans();
}
$res = true;
try{
$need_create=false;
if(!$activityAuth["classes_activity_id"]){
$need_create=true;
}else{
$activity = self::get($activityAuth["classes_activity_id"]);
if(!$activity)$need_create=true;
}
if($need_create){ //创建:创建活动
//如果未创建则创建活动
$activityData = $activityAuth->toArray();
unset($activityData["id"]);
$activity = self::where("title",$activityData["title"])->find();
if(!$activity)$activity = new self;
$activity->allowField(true)->save($activityData);
//添加活动规格
foreach ($itemauths as $k=>$itemauth){
$itemauthData = $itemauth->toArray();
unset($itemauthData["id"]);
$itemauthData["classes_activity_id"] = $activity->id;
$item = new ActivityItem;
$item->allowField(true)->save($itemauthData);
$itemauth["classes_activity_item_id"] = $item->id;
$itemauth->save();
}
}else{
//更新活动
$activityData = $activityAuth->toArray();
unset($activityData["id"]);
$activity->allowField(true)->save($activityData);
$delete_spec_ids = [];
//按前端顺序分配显示权重
//数组倒过来
$insert_auth_spec = [];
$update_ids = [];
$update_spec = [];
$delete_spec = [];
foreach ($itemauths as $k=>$v){
if(!empty($v["classes_activity_item_id"])){
$update_ids[] = $v["classes_activity_item_id"];
}else{
$insert_auth_spec[] = $v;
}
}
if($update_ids){
$update_spec = ActivityItem::where("id","in",$update_ids)->select();
$delete_spec_ids = ActivityItem::where("classes_activity_id",$activity->id)->where("id","not in",$update_ids)->column("id");
}else{
$delete_spec_ids = ActivityItem::where("classes_activity_id",$activity->id)->column("id");
}
//存在需要删除的规格则判断规格是否能删除
if($delete_spec_ids){
$check_spec = ActivityItem::where("classes_activity_id",$activity->id)->where("id","in",$delete_spec_ids)->select();
foreach ($check_spec as $k=>$vv){
(new ActivityItem)->updateCheck($vv->id);
}
$delete_spec = $check_spec;
}
//需要新增的项
foreach ($insert_auth_spec as $k=>$itemauth){
$itemauthData = $itemauth->toArray();
unset($itemauthData["id"]);
$itemauthData["classes_activity_id"] = $activity->id;
$item = new ActivityItem;
$item->allowField(true)->save($itemauthData);
$itemauth["classes_activity_item_id"] = $item->id;
$itemauth->save();
}
//需要更新的项
foreach ($update_spec as $k=>$item){
foreach ($itemauths as $j=>$v){
if($v["classes_activity_item_id"] == $item->id){
$itemData = $v->toArray();
unset($itemData["id"]);
$item->allowField(true)->save($itemData);
}
}
}
//需要删除的项
foreach ($delete_spec as $k=>$item){
$item->delete();
}
}
$activityAuth["classes_activity_id"] = $activity->id;
$activityAuth->save();
//activity置空
$activity["classes_activity_auth_id"] = 0;
$activity->save();
self::update_classes($activity["id"]);
if($trans){
self::commitTrans();
}
}catch (\Exception $e){
if($trans){
self::rollbackTrans();
}
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
}
return $activity;
}
//审核不通过后
public function errorAuth($id,$trans=false){
$activityAuth = ActivityAuth::where("id",$id)->find();
if(!$activityAuth)throw new \Exception("未找到该记录");
$itemauths = $activityAuth->itemauths;
$activity = null;
if(!$itemauths)throw new \Exception("规格不全");
//判断逻辑
if($trans){
self::beginTrans();
}
$res = true;
try{
$need_create=false;
if(!$activityAuth["classes_activity_id"]){
$need_create=true;
}else{
$activity = self::get($activityAuth["classes_activity_id"]);
if(!$activity)$need_create=true;
}
if($trans){
self::commitTrans();
}
}catch (\Exception $e){
if($trans){
self::rollbackTrans();
}
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
}
return $activity;
}
/** 提交申请认证
* @param $id
* @param $trans
* @return true
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function applyAuth($id,$params,$trans=false){
$activity = self::where("id",$id)->find();
if(!$activity)throw new \Exception("未找到该记录");
//尝试找出classes_activity_auth_id 指向最新的审核记录
if($activity['classes_activity_auth_id']){
$activityAuth = ActivityAuth::where("id",$activity['classes_activity_auth_id'])->find();
if(!$activityAuth || $activityAuth['auth_status']==2){ //不存在或状态为不通过
$activity['classes_activity_auth_id'] = 0;
}
}
$spec = $params["item_json"] ?? [];
// var_dump($spec);
$delete_spec_ids = $params["delete_spec_ids"] ?? [];
unset($params["item_json"]);
unset($params["delete_spec_ids"]);
//判断逻辑
if($trans){
self::beginTrans();
}
$res = true;
try{
//如果没有则创建新的记录
if(!$activity['classes_activity_auth_id']){
//创建新的审核记录
$activityAuth = new ActivityAuth;
$activityAuthData = $activity->toArray();
$activityAuthData = array_merge($activityAuthData,$params);
$activityAuthData["auth_status"] = 0;
$activityAuthData["classes_activity_id"] = $activity["id"];
unset($activityAuthData["id"]);
$activityAuth->allowField(true)->save($activityAuthData);
//创建审核的项
foreach ($spec as $k=>$v){
$v["classes_activity_auth_id"] = $activityAuth["id"];
$v["classes_activity_id"] = $activity["id"];
$v["classes_activity_item_id"] = $v["id"] ?? 0;
$v["manystore_id"] = $params["manystore_id"];
$v["shop_id"] = $params["shop_id"];
unset($v["id"]);
(new \app\common\model\school\classes\activity\ActivityItemAuth())->allowField(true)->save($v);
}
//并更新activity的classes_activity_auth_id 指向最新的审核记录
$activity["classes_activity_auth_id"] = $activityAuth["id"];
$activity->save();
}else{
//如果存在记录,则更新旧纪录信息为最新提交的认证信息
$activityAuthData = $activity->toArray();
$activityAuthData = array_merge($activityAuthData,$params);
$activityAuthData["auth_status"] = 0;
$activityAuthData["classes_activity_id"] = $activity["id"];
unset($activityAuthData["id"]);
$activityAuth->allowField(true)->save($activityAuthData);
//为了方便直接删除旧数据里的所有规格再添加新的规格因为只要classes_activity_id不变不会影响原订单
ActivityItemAuth::where( "classes_activity_auth_id",$activityAuth["id"])->delete();
//创建审核的项
foreach ($spec as $k=>$v){
$v["classes_activity_auth_id"] = $activityAuth["id"];
$v["classes_activity_id"] = $activity["id"];
$v["classes_activity_item_id"] = $v["id"] ?? 0;
$v["manystore_id"] = $params["manystore_id"];
$v["shop_id"] = $params["shop_id"];
unset($v["id"]);
(new \app\common\model\school\classes\activity\ActivityItemAuth())->allowField(true)->save($v);
}
}
//因为是批量添加,所有规格重新进行检测,防止出现时间重叠
$specss = \app\common\model\school\classes\activity\ActivityItemAuth::where("classes_activity_auth_id",$activityAuth["id"])->select();
foreach ($specss as $k=>$specs){
$params =$specs;
(new \app\common\model\school\classes\activity\ActivityItemAuth)->specCheck($params,null,$specs);
}
if($trans){
self::commitTrans();
}
}catch (\Exception $e){
if($trans){
self::rollbackTrans();
}
throw new \Exception($e->getMessage().$e->getFile().$e->getLine());
}
return $res;
}
/**得到基础条件
* @param $status
* @param null $model
* @param string $alisa
*/
public static function getBaseWhere($whereData = [], $model = null, $alisa = '',$with = false)
{
if (!$model) {
$model = new static;
if ($alisa&&!$with) $model = $model->alias($alisa);
}
if ($alisa) $alisa = $alisa . '.';
$tableFields = (new static)->getTableFields();
foreach ($tableFields as $fields)
{
if(in_array($fields, ['status','title','address_city','address','address_detail','start_time','end_time','sign_start_time','sign_end_time']))continue;
// if (isset($whereData[$fields]) && $whereData[$fields]) $model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
if (isset($whereData[$fields]) && $whereData[$fields]){
if(is_array($whereData[$fields])){
$model = $model->where("{$alisa}{$fields}", $whereData[$fields][0], $whereData[$fields][1]);
}else{
$model = $model->where("{$alisa}{$fields}", '=', $whereData[$fields]);
}
}
}
if (isset($whereData['status']) && $whereData['status']) $model = $model->where("{$alisa}status", 'in', $whereData['status']);
if (isset($whereData['not_status']) && $whereData['not_status']) $model = $model->where("{$alisa}status", 'not in', $whereData['not_status']);
if (isset($whereData['keywords'])&&$whereData['keywords']) $model = $model->where("{$alisa}title|{$alisa}id|{$alisa}address|{$alisa}address_detail", '=', $whereData['keywords']);
if (isset($whereData['time'])&&$whereData['time']){
$model = $model->time(["{$alisa}createtime",$whereData['time']]);
}
return $model;
}
/** 课程详情
* @param $id
* @throws \think\exception\DbException
*/
public function detail($id,$user_id=0,$oper_type='user',$trans=false){
$self = $this->get($id,['shop','items']);
//是否收藏
$self['is_collect'] = 0;
//是否购买
$self['have_buy'] = 0;
if($user_id){
//判断是否收藏
$self['is_collect'] = Collect::where("user_id",$user_id)->where("classes_activity_id",$id)->count() ? 1:0 ;
//判断用户是否已报名
$self['have_buy'] = Order::where("classes_activity_id",$id)
->where("user_id",$user_id)
->where("status","not in",["-3","6","9"])
->count() ? 1 : 0 ;
}
//
$this->setViews($id,$user_id,$oper_type,$user_id,$trans);
// $self->getRelation('user')->visible(['nickname','realname','mobile','avatar']);
//参与人数 = 虚拟人数 + 平台人数
return $self;
}
/**设置浏览量
* @param $id
* @param int $user_id
* @param bool $check
* @param bool $trans
* @throws \Exception
*/
public function setViews($id,$user_id,$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{
//事务逻辑
$classes_lib->views = $classes_lib->views + 1;
//查询是否已收藏
$classes_lib->save();
//调用事件
$data = ['activity' => $classes_lib,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
\think\Hook::listen('activity_view_after', $data);
if($trans){
self::commitTrans();
}
}catch (\Exception $e){
if($trans){
self::rollbackTrans();
}
throw new \Exception($e->getMessage());
}
return $classes_lib;
}
/**课程规格
* @param $id
*
*/
public function spec($id,$user_id=0){
//课程规格
$spec_data = ActivityItem::where("classes_activity_id",$id)->where("status",'1')->order("weigh desc,id desc")->select();
foreach ($spec_data as &$spec){
//默认未下单预约
$spec["user_reservation"] = null;
if($user_id){
$spec["user_reservation"] = Order::where("classes_activity_id",$id)->where("classes_activity_item_id",$spec['id'])->where("user_id",$user_id)->where("status","not in",["-3","6","9"])->find();
}
}
return $spec_data;
}
/**
* 获取所有活动列表
*/
public static function getVaildList($params) {
extract($params);
$a = (new self)->getWithAlisaName().'.';
$with = ['items'];
// if (isset($has_shop) && $has_shop) {
$with[] = 'shop';
// }
// $cate_list = Cate::where("status",'1')->column("name","id");
// $label_list = Label::where("status",'1')->column("name","id");
// $type_list = Type::where("status",'1')->column("name","id");
$selfetch = self::with($with);
// 查询自提点
if($status == "-2"){
$selfetch = $selfetch->where($a.'status', '1');
}
// if($auth_status == "-2"){
// $selfetch = $selfetch->where("{$a}auth_status",1);
// }
$order = $order?? 'normal';
$per_page = $limit ?? 10;
$field = "{$a}start_time,{$a}end_time,{$a}sign_start_time,{$a}sign_end_time,{$a}id,{$a}shop_id,{$a}title,{$a}headimage,{$a}images,{$a}address_type,{$a}province,{$a}city,{$a}district,{$a}address,{$a}address_detail,{$a}longitude,{$a}latitude,{$a}sale,{$a}price,{$a}status,{$a}weigh,{$a}recommend,{$a}hot,{$a}new,{$a}selfhot,{$a}createtime,{$a}feel,{$a}sign_num,{$a}verification_num";
//得到距离
if (isset($latitude) && isset($longitude) && $latitude && $longitude) {
$field .= ', '.getDistanceBuilder($latitude, $longitude,$a);
}else{
$field .= ', 0 as distance';
}
//得到每个
$selfetch = $selfetch->field($field);
if (isset($keywords) && $keywords) {
$selfetch = $selfetch->where("{$a}title|{$a}address|{$a}address_detail|{$a}address_city", 'like', '%' . $keywords . '%');
}
if(isset($start_time) && isset($end_time) && ($end_time || $start_time)) {
if($start_time){
$selfetch = $selfetch->where("{$a}start_time", '>=', $start_time);
}
if($end_time){
$selfetch = $selfetch->where("{$a}end_time", '<=', $end_time);
}
}
if(isset($sign_start_time) && isset($sign_end_time) && ($sign_end_time || $sign_start_time)) {
if($sign_start_time){
$selfetch = $selfetch->where("{$a}sign_start_time", '>=', $sign_start_time);
}
if($sign_end_time){
$selfetch = $selfetch->where("{$a}sign_end_time", '<=', $sign_end_time);
}
}
// is_expire 是否查过期1只查过期,2只查不过期,0全查
if(isset($is_expire) && $is_expire) {
if($is_expire == 1){
$selfetch = $selfetch->where("{$a}end_time", '<', time());
}else{
$selfetch = $selfetch->where("{$a}end_time", '>=', time());
}
}
// is_expire 是否查过期1只查过期,2只查不过期,0全查
if(isset($is_sign_expire) && $is_sign_expire) {
if($is_sign_expire == 1){
$selfetch = $selfetch->where("{$a}sign_end_time", '<', time());
}else{
$selfetch = $selfetch->where("{$a}sign_end_time", '>=', time());
}
}
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($auth_status) && $auth_status != -1 && $auth_status != -2){
// $selfetch = $selfetch->where("{$a}auth_status", 'in', ''.$auth_status);
// }
//设置订单信息
if(isset($status) && $status != -1 && $status != -2){
$selfetch = $selfetch->where("{$a}status", 'in', ''.$status);
}
//区域搜索
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_type) && $classes_type) {
// $classes_type = implode("|",explode(',',$classes_type));
// $selfetch = $selfetch->whereRaw(" {$a}classes_type REGEXP '({$classes_type})'");
// }
// 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_activity_id");
//专查我的收藏
if(isset($collect) && $collect){
$selfetch = $selfetch->where("{$a}id","in",$collect_classes_lib_ids);
}
}
if(isset($order) && $order == "distance"){
$selfetch = $selfetch->where("{$a}longitude","not null")
->where("{$a}latitude","not null")
->where("{$a}longitude","<>","")
->where("{$a}latitude","<>","")
->where("{$a}longitude","<>","null")
->where("{$a}latitude","<>","null");
}
//排序
switch ($order) {
case "normal": //综合排序(推薦優先)
$selfetch = $selfetch->order("{$a}recommend desc,{$a}hot desc,{$a}new desc,{$a}weigh desc,{$a}start_time desc,{$a}id 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 "recommend": //推薦优先
$selfetch = $selfetch->order("{$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;
case "views": //浏览量优先
$selfetch = $selfetch->order("{$a}views desc,{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc");
break;
case "collect": //收藏量优先
$selfetch = $selfetch->order("{$a}collect desc,{$a}recommend desc,{$a}weigh desc,{$a}verification_num desc,{$a}sale desc");
break;
default:
throw new \Exception("不支持的排序类型");
}
if(isset($nearby) && $nearby) {
// throw new \Exception("现版本不支持");
$selfetch = $selfetch->having("distance <= {$nearby}");
}
$selfetch = $selfetch->page($page,$limit)->select();
foreach ($selfetch as $row) {
// $row->getRelation('manystore')->visible(['nickname']);
$row->getRelation('shop')->visible(['name','logo']);
}
$rows = $selfetch;
// $total = $selfetch->total();
//额外附加数据
foreach ($rows as &$row) { //迭代器魔术方法遍历,填值自动引用传值
//设置是否已收藏
$row->is_collect = in_array($row->id,$collect_classes_lib_ids) ? 1 : 0;
if($row->is_collect){
$row["collect"] = Collect::where("user_id",$my_user_id)->where("classes_activity_id",$row->id)->find();
}
// $classes_label_ids = $row['classes_label_ids'];
// $classes_cate_ids = $row['classes_cate_ids'];
// $classes_type_ids = $row['classes_type'];
// $classes_label = $classes_cate = $classes_type = [];
// foreach (explode(",", $classes_label_ids) as $classes_label_id){
// if(isset($label_list[$classes_label_id]))$classes_label[] = $label_list[$classes_label_id];
// }
// foreach (explode(",", $classes_cate_ids) as $classes_cate_id){
// if(isset($cate_list[$classes_cate_id]))$classes_cate[] = $cate_list[$classes_cate_id];
// }
//
// foreach (explode(",", $classes_type_ids) as $classes_type_id){
// if(isset($type_list[$classes_type_id]))$classes_type[] = $type_list[$classes_type_id];
// }
//
//
// $row['classes_label'] = $classes_label;
// $row['classes_cate'] = $classes_cate;
// $row['classes_type_name'] = $classes_type;
}
$result = array("data" => $rows);
return $result;
}
protected $classes_activity_ids = [];
/** 管理的活动ids
* @param $user_id
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getActivityAuthIds($user_id){
//必须是授权过的用户
if(config("site.shop_auth_user_check")){
$auth_shop_ids = UserAuth::where("status" ,1)->where("user_id",$user_id)->column("shop_id");
$shop_where = ["shop_id" ,"in" ,$auth_shop_ids];
}else{
$shop_where = [[]];
}
//核销员有核销全部课程权力
$classes_lib_ids = [];
$shop_id = Verification::where("user_id",$user_id)->where(...$shop_where)->where("status",'1')->value("shop_id");
if($shop_id){
$classes_libids = self::where("shop_id",$shop_id)->column("id");
if($classes_libids)$classes_lib_ids[] = implode(",", $classes_libids);
}
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_activity_ids[] = $v;
}
}
}
$this->classes_activity_ids = array_unique($this->classes_activity_ids);
return $this->classes_activity_ids;
}
/**设置收藏
* @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_activity_id"=>$id,
// "weigh"=>$classes_lib["weigh"],
];
//查询是否已收藏
$res1 = Collect::where($where)->find();
if($collect){
if(!$res1){
$where["weigh"] = $classes_lib["weigh"];
//未收藏,添加收藏
$res1 = new Collect();
$res1->allowField(true)->save($where);
}
self::update_classes($classes_lib["id"]);
//调用事件
$data = ['activity' => $classes_lib,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
\think\Hook::listen('activity_collect_success_after', $data);
}else{
unset($where["weigh"]);
//取消收藏
$res1 = Collect::where($where)->delete();
self::update_classes($classes_lib["id"]);
//调用事件
$data = ['activity' => $classes_lib,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id];
\think\Hook::listen('activity_collect_cancel_after', $data);
}
if($trans){
self::commitTrans();
}
}catch (\Exception $e){
if($trans){
self::rollbackTrans();
}
throw new \Exception($e->getMessage());
}
$where["is_collect"] = $collect;
return $where;
}
public static function update_classes($classes_lib_id){
//更新课程规格库存
$classes_lib = self::get($classes_lib_id);
if($classes_lib){
$classes_lib->sale = Order::where("classes_activity_id",$classes_lib["id"])->where("status","not in",["-3","6"])->count();
//遍历课程课时规格,更新课时统计数据
$specs = $classes_lib->items;
if($specs){
foreach ($specs as $item){
// '已核销人数',
$item->verification_num = Order::where("classes_activity_item_id",$item["id"])->where("status","=","9")->count();
//已报名人数
$item->sign_num = Order::where("classes_activity_item_id",$item["id"])->where("status","not in",["-3","6"])->count();
$item->save();
}
}
//统计课程总报名和总核销
$classes_lib->sign_num = Order::where("classes_activity_id",$classes_lib["id"])->where("status","not in",["-3","6"])->count();
$classes_lib->verification_num = Order::where("classes_activity_id",$classes_lib["id"])->where("status","=","9")->count();
//所有课时加起来
$classes_lib->stock = ActivityItem::where("classes_activity_id",$classes_lib_id)->sum( "limit_num");
//更新课程信息开始和结束时间信息
//课程开始和结束时间等于所有课时的最早开始和最晚结束时间
// $classes_lib->start_time = ClassesSpec::where("classes_lib_id",$classes_lib_id)->min("start_time");
// $classes_lib->end_time = ClassesSpec::where("classes_lib_id",$classes_lib_id)->max("end_time");
//设置课程收藏
$classes_lib->collect = Collect::where("classes_activity_id",$classes_lib_id)->count();
$classes_lib->save();
//将课程信息和课时信息同步到所有已下单的订单信息中
self::orderInfoSync($classes_lib_id);
}
return $classes_lib;
}
public static function orderInfoSync($classes_lib_id){
$classes_lib = self::get($classes_lib_id);
if($classes_lib){
//查询所有课程订单更新课程单信息
$order = \app\common\model\school\classes\activity\order\OrderDetail::where("classes_activity_id",$classes_lib_id)->select();
foreach ($order as $row){
$update = $classes_lib->toArray();
$update_data = $row->checkAssemblyParameters($update,["id","status","createtime","updatetime"]);
$row->save($update_data);
}
//同步更新订单课时信息
$specs = $classes_lib->items;
foreach ($specs as $item){
$hourorders = \app\common\model\school\classes\activity\order\OrderItem::where("classes_activity_item_id",$item->id)->select();
foreach ($hourorders as $hourorder){
$update = $item->toArray();
$update_data = $hourorder->checkAssemblyParameters($update,["id","status","createtime","updatetime"]);
$hourorder->save($update_data);
}
}
}
}
public static function getPath($id){
return Virtual::getPath("activity",["activity_id"=>$id]);
}
public static function getMiniQrcodeLink($id){
return Virtual::getMiniQrcodeLink("activity",["activity_id"=>$id]);
}
}