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

852 lines
30 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\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\ClassesSpec;
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',
];
public function getHasExpireList()
{
return ['1' => __('Has_expire 1'), '2' => __('Has_expire 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';
}
}
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 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 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)
{
$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($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 = [];
foreach ($params["item_json"] as $k=>&$v){
$v["weigh"] = $k + 1;
if(!empty($v["id"]))$insert_spec[] = $v["id"];
}
if($insert_spec && $row){
$params["delete_spec_ids"] = ActivityItem::where("classes_activity_id",$row->id)->where("id","not in",$insert_spec)->column("id");
}
}
//存在需要删除的规格则判断规格是否能删除
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)->count();
if(!$check_spec)throw new \Exception("新添加的活动请先至少添加一个活动规格后再上架!");
}
}
public function updateCheck($id,$params=[],$row=null){
if($params && $row){
// var_dump($this->no_auth_fields_check($params,$row));
if(!$this->no_auth_fields_check($params,$row)){
return true;
}
}
// 课程存在售后订单则不允许操作
$order = Order::where("classes_activity_item_id",$id)->where("status","not in","-3,6,9")->find();
if($order)throw new \Exception("{$order['name']}存在正在使用中的订单报名学员,规格无法继续操作,如规格有误请下架!");
}
//审核通过后
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 = 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();
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;
}
}