From 6d52444847d27a4d562701e53aca18cb53dcea37 Mon Sep 17 00:00:00 2001 From: qinzexin <“731344816@qq.com”> Date: Thu, 3 Jul 2025 17:58:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B4=BB=E5=8A=A8=E7=AE=A1=E7=90=86=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/api/controller/Crontab.php | 2 +- .../api/controller/school/NewActivity.php | 145 ++++++++++ .../school/newactivity/ActivityDrafts.php | 1 + application/common/hooks.php | 3 + .../common/listener/activity/ActivityHook.php | 51 ++++ .../common/model/school/activity/Activity.php | 252 +++++++++++++++++- .../model/school/activity/order/Order.php | 3 +- 7 files changed, 452 insertions(+), 5 deletions(-) diff --git a/application/api/controller/Crontab.php b/application/api/controller/Crontab.php index bfd4784..39e93e7 100644 --- a/application/api/controller/Crontab.php +++ b/application/api/controller/Crontab.php @@ -113,7 +113,7 @@ class Crontab extends Api // $res = Order::timeoutCheck(true); // $res = \app\common\model\school\classes\activity\order\Order::timeoutCheck(true); - \app\common\model\school\activity\order\Order::timeoutCheck(0,true); + \app\common\model\school\activity\order\Order::timeoutCheck(0,0,true); Activity::timeoutCheck(true); SettleLog::timeoutCheck(null,null,true); // \app\common\model\school\activity\order\Order::timeoutCheck(0,true); diff --git a/application/api/controller/school/NewActivity.php b/application/api/controller/school/NewActivity.php index 2869322..9a4d6dc 100644 --- a/application/api/controller/school/NewActivity.php +++ b/application/api/controller/school/NewActivity.php @@ -3,7 +3,9 @@ namespace app\api\controller\school; +use app\common\model\school\activity\Activity; use app\common\model\school\activity\Cate; +use app\common\model\school\activity\order\SettleLog; use app\common\model\school\activity\Refund; /** @@ -247,6 +249,8 @@ class NewActivity extends Base * @ApiMethod(POST) * @ApiParams(name = "cate_ids", type = "string",required=true,description = "平台分类ids 多值逗号拼接") * @ApiParams(name = "refund_id", type = "int",required=true,description = "退款策略id") + * @ApiParams(name = "original_activity_id", type = "int",required=false,description = "复制活动需要传的原活动id-非必填") + * @ApiParams(name = "activity_drafts_id", type = "int",required=false,description = "根据草稿箱添加的草稿箱id-非必填") * @ApiParams(name = "title", type = "string",required=true,description = "标题") * @ApiParams(name = "sign_time", type = "string",required=true,description = "报名区间示例: 2025-04-08 00:01:00 - 2025-04-08 15:29:00") * @ApiParams(name = "time", type = "string",required=true,description = "活动区间示例: 2025-04-09 00:01:00 - 2025-04-09 15:29:00") @@ -280,7 +284,9 @@ class NewActivity extends Base $params["refund_id"] = $this->request->post('refund_id/d', ''); //课程标签 $params["platform"] = $this->request->post('platform/s', 'wechat_miniapp'); //课程标签 + $params["original_activity_id"] = $this->request->post('original_activity_id/d', 0); //课程标签 + $params["activity_drafts_id"] = $this->request->post('activity_drafts_id/d', 0); //课程标签 $params["title"] = $this->request->post('title/s', ''); //老师id $params["images"] = $this->request->post('images/s', ''); //老师id $params["image"] = $this->request->post('image/s', ''); //老师id @@ -320,6 +326,92 @@ class NewActivity extends Base + /** + * @ApiTitle(活动编辑) + * @ApiSummary(活动编辑) + * @ApiMethod(POST) + * @ApiRoute (/api/school.new_activity/edit/ids/{ids}) + * @ApiParams (name="ids", type="string", required=true, description="需要编辑的id") + * @ApiParams(name = "cate_ids", type = "string",required=true,description = "平台分类ids 多值逗号拼接") + * @ApiParams(name = "refund_id", type = "int",required=true,description = "退款策略id") + * @ApiParams(name = "original_activity_id", type = "int",required=false,description = "复制活动需要传的原活动id-非必填") + * @ApiParams(name = "activity_drafts_id", type = "int",required=false,description = "根据草稿箱添加的草稿箱id-非必填") + * @ApiParams(name = "title", type = "string",required=true,description = "标题") + * @ApiParams(name = "sign_time", type = "string",required=true,description = "报名区间示例: 2025-04-08 00:01:00 - 2025-04-08 15:29:00") + * @ApiParams(name = "time", type = "string",required=true,description = "活动区间示例: 2025-04-09 00:01:00 - 2025-04-09 15:29:00") + * @ApiParams(name = "platform", type = "string",required=false,description = "上架平台:wechat_miniapp=微信小程序,tt_miniapp=抖音小程序") + * @ApiParams(name = "images", type = "string",required=true,description = "轮播图多值逗号拼接") + * @ApiParams(name = "address", type = "string",required=false,description = "地图定位地址") + * @ApiParams(name = "address_detail", type = "string",required=false,description = "手录详细地址") + * @ApiParams(name = "longitude", type = "string",required=false,description = "经度") + * @ApiParams(name = "latitude", type = "string",required=false,description = "纬度") + * @ApiParams(name = "content", type = "string",required=false,description = "活动详情") + * @ApiParams(name = "price", type = "string",required=false,description = "报名单价 0为免费") + * @ApiParams(name = "stock", type = "string",required=false,description = "活动限制人数") + * @ApiParams(name = "image", type = "string",required=false,description = "入群二维码") + * @ApiReturn({ + * + *}) + */ + public function edit($ids = null){ + if(!$ids) $ids = $this->request->post('ids/d', 0); + + $this->transactionCheck(); + + //敏感词过滤 + $this->checkSensitivewords(["title","content"]); + + $user_id = 73; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $params = []; + $params["user_id"] = $user_id; //老师id + $params["cate_ids"] = $this->request->post('cate_ids/s', ''); //课程标签 + $params["refund_id"] = $this->request->post('refund_id/d', ''); //课程标签 + + $params["platform"] = $this->request->post('platform/s', 'wechat_miniapp'); //课程标签 + $params["original_activity_id"] = $this->request->post('original_activity_id/d', 0); //课程标签 + + $params["activity_drafts_id"] = $this->request->post('activity_drafts_id/d', 0); //课程标签 + $params["title"] = $this->request->post('title/s', ''); //老师id + $params["images"] = $this->request->post('images/s', ''); //老师id + $params["image"] = $this->request->post('image/s', ''); //老师id + + $params["stock"] = $this->request->post('stock/d', 0); //核销次数 + // + + + $params["address"] = $this->request->post('address/s', ''); //老师id + $params["address_detail"] = $this->request->post('address_detail/s', ''); //老师id + $params["longitude"] = $this->request->post('longitude/s', 0); //老师id + $params["latitude"] = $this->request->post('latitude/s', 0); //老师id + $params["content"] = $this->request->post('content/s', ''); //老师id + + $params["price"] = $this->request->post('price/f', 0); //老师id + + + $params["sign_time"] = $this->request->post('sign_time/s', 0); + $params["time"] = $this->request->post('time/s', 0); + + + //classes_type + + try{ + if(!config("site.miniapp_activity_swtich")) $this->error("已关闭发布渠道,请联系管理员后台添加!"); + + $res = $this->model->edit($ids,$params,$user_id,'user',$user_id,true); + }catch (\Throwable $e){ + $this->error($e->getMessage(),[ + "errcode"=>$e->getCode() + ]); + } + $this->success('编辑成功,等待审核', $res); + } + + + + + /** * @ApiTitle( 退款策略列表) @@ -409,5 +501,58 @@ class NewActivity extends Base $this->success('活动更换入群二维码成功', $res); } + + + + /** + * @ApiTitle( 活动删除) + * @ApiSummary(活动删除)) + * @ApiMethod(POST) + * @ApiParams(name = "id", type = "string",required=true,description = "活动id") + * @ApiReturn({ + * + *}) + */ + public function del(){ + $this->transactionCheck(); + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $id = $this->request->post('id/d', 0); //订单号 + if(!$id) $this->error("请传入活动id"); + try{ + //当前申请状态 + $res = $this->model->activity_delete($id,'user',$user_id,true); + }catch (\Throwable $e){ + $this->error($e->getMessage().$e->getFile() .$e->getLine()); + } + $this->success('活动删除成功'); + } + + + + /** + * 用户活动及订单主动触发检测 + */ + public function activity_check() + { + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + try{ + + \app\common\model\school\activity\order\Order::timeoutCheck(0,$user_id,true); + Activity::userTimeoutCheck($user_id,true); + SettleLog::timeoutCheck(null,$user_id,true); + + }catch (\Exception $e){ + $this->error("执行失败:".$e->getMessage()); + } + $this->success("执行成功"); + } + + + + } diff --git a/application/api/controller/school/newactivity/ActivityDrafts.php b/application/api/controller/school/newactivity/ActivityDrafts.php index 42168bf..ee55d4b 100644 --- a/application/api/controller/school/newactivity/ActivityDrafts.php +++ b/application/api/controller/school/newactivity/ActivityDrafts.php @@ -272,6 +272,7 @@ class ActivityDrafts extends Base *}) */ public function edit($ids = null){ + if(!$ids) $ids = $this->request->post('ids/d', 0); //敏感词过滤 $this->checkSensitivewords(["title","content"]); diff --git a/application/common/hooks.php b/application/common/hooks.php index df705d0..852d325 100644 --- a/application/common/hooks.php +++ b/application/common/hooks.php @@ -266,6 +266,9 @@ $newactivityHooks = [ 'new_activity_cancel_success_after' => [ // 活动取消后 'app\\common\\listener\\activity\\ActivityHook' ], + 'new_activity_delete_success_after' => [ // 活动删除后 + 'app\\common\\listener\\activity\\ActivityHook' + ], ]; diff --git a/application/common/listener/activity/ActivityHook.php b/application/common/listener/activity/ActivityHook.php index 4744a32..4f4bcdc 100644 --- a/application/common/listener/activity/ActivityHook.php +++ b/application/common/listener/activity/ActivityHook.php @@ -235,6 +235,57 @@ class ActivityHook + public function newActivityDeleteSuccessAfter(&$params) + { + ['activity' => $activity,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + + $user = User::where("id",$activity["user_id"])->find(); +//课程推送给老师 + $mini_type = "activity_apply"; + $to_id = $user["id"]; + $status ="activity"; + $params=[ + "event"=>"new_activity_delete_success_after", + "activity_id"=>$activity["id"], + "title"=>$activity["title"], + "images"=>$activity["images"], + //活动名 + //活动头像 + ]; + + $param = [ + "realname"=> $user["realname"], + "nickname"=> $user["nickname"], + "mobile"=> $user["mobile"], + "title" => $activity['title'], + "address"=>$activity["address"]."(".$activity["address_detail"].")", + "price" => $activity["price"], + "start_time" => date("Y-m-d H:i",$activity["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "end_time" => date("Y-m-d H:i",$activity["end_time"]), + "sign_start_time" => date("Y-m-d H:i",$activity["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "sign_end_time" => date("Y-m-d H:i",$activity["sign_end_time"]), + "reason" => $activity['reason'], + ]; + + //发给用户 + (new MessageConfig) + ->setTemplate($params["event"]) + ->setTemplateData($param) + ->setToUid($to_id) + ->setMessageStatus($status) + ->setMessageMiniType($mini_type) + ->setMessageParams($params) + ->sendMessage(); + + } + + + + + + + diff --git a/application/common/model/school/activity/Activity.php b/application/common/model/school/activity/Activity.php index affccb9..70428ab 100644 --- a/application/common/model/school/activity/Activity.php +++ b/application/common/model/school/activity/Activity.php @@ -608,8 +608,14 @@ class Activity extends BaseModel }else{ //新增 + $original_activity_id = $params["original_activity_id"] ?? 0; //不在已结束和已取消的活动名title不允许重复 - $title = self::where("status","not in","-1,5")->where("title",$params["title"])->find(); + if($original_activity_id){ + $title = self::where("id","<>",$original_activity_id)->where("status","not in","-1,5")->where("title",$params["title"])->find(); + }else{ + $title = self::where("status","not in","-1,5")->where("title",$params["title"])->find(); + } + if($title) throw new \Exception("活动名不允许重复"); } @@ -684,6 +690,7 @@ class Activity extends BaseModel // $params["auth_status"] = 0; + } @@ -706,6 +713,7 @@ class Activity extends BaseModel // throw new \Exception("{$params["title"]}审核通过的活动只允许手动关闭,不允许修改!"); //允许提交的字段 $allowField = [ + "feel", "title", "cate_ids", "image", @@ -714,17 +722,33 @@ class Activity extends BaseModel "address", "longitude", "latitude", -// "price", + "price", "stock", "content", -// "refund_id", + "refund_id", + "start_time", + "end_time", + "sign_start_time", + "sign_end_time", "show", "platform", + "status" ]; //非允许提交的字段去掉 $params = array_intersect_key($params, array_flip($allowField)); + //报名时间需晚于当前时间 + $now_time = time(); + if($now_time > $sign_start_time){ + throw new \Exception("报名时间必须是未来时间!"); + } + //如果存在订单则不允许修改,如果已进入报名阶段,也不允许修改 + $order = Order::where("activity_id",$row["id"])->find(); + if($order){ + throw new \Exception("{$params["title"]}已存在订单,不允许修改!"); + } + } if(!isset($params["auth_status"])){ //前台提交 @@ -1317,6 +1341,13 @@ class Activity extends BaseModel if($params){ $res = $row->allowField(true)->save($params); } + //如果审核状态是审核中,并且时间已经到了3=待开始,4=进行中,则活动自动取消 + if(($row["status"]=='3' || $row["status"]=='4') && $row["audit_status"]=='0'){ + //直接取消 + $row = $this->cancel($id,"2",false,'admin',0); + } + + //如果活动状态是已结束,则完成所有未核销或者未核销完的订单 //if(in_array($order["status"],["2",'3']) && (in_array($order["server_status"],['0'])) && !$order['finishtime']){ if($row["status"]=='5'){ @@ -1396,6 +1427,9 @@ class Activity extends BaseModel $res = true; try{ + + + // //是否采用模型验证 // if ($this->modelValidate) { // $name = str_replace("\\model\\", "\\validate\\", get_class($this)); @@ -1404,12 +1438,34 @@ class Activity extends BaseModel // } $row = new self; $this->update_check($params,null); + + + $original_activity_id = $params["original_activity_id"] ?? 0; + unset($params["original_activity_id"]); + + $activity_drafts_id = $params["activity_drafts_id"] ?? 0; + unset($params["activity_drafts_id"]); + + $result = $row->allowField(true)->save($params); $this->update_classes($row["id"]); $row->reason = ""; //调用审核事件触发 $data = ['activity' => $row,"user_id"=>$params["user_id"],"oper_type"=>$oper_type,"oper_id"=>$oper_id]; \think\Hook::listen('new_activity_auth_need_after', $data); + + //如果原活动没有订单,且是状态:1=未开始,2=报名中,则先取消该活动,再删除该活动 + if($original_activity_id){ + $delete_activity = self::getHaveActivityDelete($original_activity_id); + if($delete_activity){ + $this->activity_delete($original_activity_id,$oper_type,$oper_id,$trans=false); + } + } + //删除对应草稿箱 + if($activity_drafts_id){ + (new ActivityDrafts)->del($activity_drafts_id,$params["user_id"],$oper_type,$oper_id,$trans=false); + } + if($trans){ self::commitTrans(); } @@ -1425,6 +1481,131 @@ class Activity extends BaseModel + + + /** 编辑活动 + * @param $params + * @param $trans + * @return $this + * @throws \Exception + */ + public function edit($id,$params,$user_id,$oper_type='user',$oper_id=0,$trans=false){ + + if (empty($params)) { + throw new \Exception(__('Parameter %s can not be empty', '')); + } + $row = self::where("user_id",$user_id)->where("id",$id)->find(); + if (!$row) { + throw new \Exception(__('No Results were found')); + } + + + + if($id)$params["id"] = $id; + + +//判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + + + + + + +// //是否采用模型验证 +// if ($this->modelValidate) { +// $name = str_replace("\\model\\", "\\validate\\", get_class($this)); +// $validate = is_bool($this->modelValidate) ? ($this->modelSceneValidate ? $name . '.add' : $name) : $this->modelValidate; +// $this->validateFailException()->validate($validate); +// } +// $row = new self; + $this->update_check($params,$row); + + $original_activity_id = $params["original_activity_id"] ?? 0; + unset($params["original_activity_id"]); + + $activity_drafts_id = $params["activity_drafts_id"] ?? 0; + unset($params["activity_drafts_id"]); + + + //强制触发审核 + $params["auth_status"] = 0; + $params["reason"] = ""; + $result = $row->allowField(true)->save($params); + $this->update_classes($row["id"]); + $row->reason = ""; + //调用审核事件触发 + $data = ['activity' => $row,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('new_activity_auth_need_after', $data); + + //如果原活动没有订单,且是状态:1=未开始,2=报名中,则先取消该活动,再删除该活动 + if($original_activity_id){ + $delete_activity = self::getHaveActivityDelete($original_activity_id); + if($delete_activity){ + $this->activity_delete($original_activity_id,$oper_type,$oper_id,$trans=false); + } + } + //删除对应草稿箱 + if($activity_drafts_id){ + (new ActivityDrafts)->del($activity_drafts_id,$params["user_id"],$oper_type,$oper_id,$trans=false); + } + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $row; + } + + + + + /** + * 个人活动检测 + */ + public static function userTimeoutCheck($user_id,$trans = false){ + $count = 0; + + //得到所有过期的队列 + $list = self::where("user_id",$user_id)->where("status",'not in',['-1'])->select(); + + if ($trans) { + self::beginTrans(); + } + try { + + + foreach ($list as $activity) + { + //更新课程状态 + (new self)->updateStatus($activity["id"]); + $count++; + } + if ($trans) { + self::commitTrans(); + } + } catch (\Exception $e) { + if ($trans) { + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $count; + } + + + + /** * 超时检测 */ @@ -1948,4 +2129,69 @@ class Activity extends BaseModel } + +public static function getHaveActivityDelete($id){ + //如果原活动没有订单,且是状态:1=未开始,2=报名中,才可删除 + $have_activity = self::where("id",$id)->where("status","in",["1","2","-1"])->find(); + if($have_activity){ + $have_order = Order::where("activity_id",$id)->find(); + if($have_order) return false; + } + return $have_activity; +} + + + + /**活动删除 + * @param $id + * @param int $user_id + * @param int $collect 0取消收藏 1收藏 + * @param bool $check + * @param bool $trans + * @throws \Exception + */ + public function activity_delete($id,$oper_type='user',$oper_id=0,$trans=false){ + $activity = self::getHaveActivityDelete($id); + if(!$activity)throw new \Exception("可删除活动不存在!"); + + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + + try{ + + //如果活动未取消,先取消活动,再删除活动 + if($activity["status"]!= "-1") { + //执行取消活动 + $activity = $this->cancel($id,'1',false,$oper_type,$oper_id); + } + + //调用事件 + $data = ['activity' => $activity,"user_id"=>$activity["user_id"] ,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('new_activity_delete_success_after', $data); + + + //执行活动删除 + $activity->delete(); + + + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + + return true; + } + + + } diff --git a/application/common/model/school/activity/order/Order.php b/application/common/model/school/activity/order/Order.php index 369f4d2..3fabf76 100644 --- a/application/common/model/school/activity/order/Order.php +++ b/application/common/model/school/activity/order/Order.php @@ -1512,7 +1512,7 @@ class Order extends BaseModel /** * 超时取消检测(未支付取消) */ - public static function timeoutCheck($order_id=0,$trans = false){ + public static function timeoutCheck($order_id=0,$user_id=0,$trans = false){ $count = 0; $unpaid_order_expire_time = config("site.unpaid_activity_cancel_time"); if(!$unpaid_order_expire_time|| $unpaid_order_expire_time < 0)return $count; @@ -1520,6 +1520,7 @@ class Order extends BaseModel //得到所有过期的队列 $model = self::where("status",'in',['0'])->where("createtime","<=",$unpaid_order_expire_time); if($order_id)$model = $model->where("id|order_no",$order_id); + if($user_id)$model = $model->where("user_id",$user_id); $list = $model->select(); if ($trans) {