diff --git a/application/api/controller/Crontab.php b/application/api/controller/Crontab.php index fc49976..2c70ea6 100644 --- a/application/api/controller/Crontab.php +++ b/application/api/controller/Crontab.php @@ -5,6 +5,7 @@ use addons\epay\library\Service; use app\common\controller\Api; use app\common\library\NightSchoolBigData; use app\common\model\school\activity\Activity; +use app\common\model\school\activity\order\SettleLog; use app\common\model\school\classes\order\Order; use app\common\model\school\classes\VisitDistribution; use bw\UrlLock; @@ -110,7 +111,8 @@ class Crontab extends Api // $res = Order::timeoutCheck(true); // $res = \app\common\model\school\classes\activity\order\Order::timeoutCheck(true); Activity::timeoutCheck(true); - + SettleLog::timeoutCheck(null,null,true); + \app\common\model\school\activity\order\Order::timeoutCheck(0,true); // $lock = new UrlLock(2,"mock-lock-suffix",5,"您的请求过于频繁,请您稍后再试!"); // $lock->lock(); diff --git a/application/api/controller/school/newactivity/Order.php b/application/api/controller/school/newactivity/Order.php index 3854de1..28c805b 100644 --- a/application/api/controller/school/newactivity/Order.php +++ b/application/api/controller/school/newactivity/Order.php @@ -4,6 +4,8 @@ namespace app\api\controller\school\newactivity; use app\api\controller\school\Base; use app\common\model\school\activity\order\Order as OrderModel; +use app\common\model\school\activity\order\OrderCode; + /** * 用户端:新活动订单接口 */ @@ -137,4 +139,104 @@ class Order extends Base } + + /** + * @ApiTitle( 订单确认/订单计算接口) + * @ApiSummary(订单确认/订单计算接口【有过期时间】) + * @ApiMethod(POST) + * @ApiParams(name = "activity_id", type = "int",required=true,description = "活动id") + * @ApiParams(name = "order_no", type = "string",required=false,description = "缓存key") + * @ApiParams(name = "num", type = "int",required=true,description = "购买人数") + * @ApiParams(name = "is_compute", type = "int",required=false,description = "是否重新计算并更新缓存 默认传1") + * @ApiReturn({ + * + *}) + */ + public function confirm(){ + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $activity_id = $this->request->post('activity_id/d', 0); //课程id + $num = $this->request->post('num/d', 0); //想同时约的课时id +// $param = urldecode($this->request->post('param/s', "{}")); //参数 + $param = []; + + //参数 + $order_no = $this->request->post('order_no/s', ''); //订单号 + $is_compute = $this->request->post('is_compute/d', 1); //是否重新计算并更新缓存 + try{ + //当前申请状态 + $res = $this->model->confirm($user_id, $activity_id,$num,$order_no,$param, $is_compute); + }catch (\Exception $e){ +// Log::log($e->getMessage()); + $this->error($e->getMessage(),['errcode'=>$e->getCode()]); + } + $this->success('执行成功,可用缓存key下单', $res); + } + + + /** + * @ApiTitle( 订单下单接口) + * @ApiSummary(订单下单接口) + * @ApiMethod(POST) + * @ApiParams(name = "order_no", type = "string",required=true,description = "缓存key") + * @ApiReturn({ + * + *}) + */ + public function create(){ + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $order_no = $this->request->post('order_no/s', ''); //订单号 + $remark = $this->request->post('remark/s', ''); //下单备注 + $this->setUrlLock("only"); +// repeat_filter("appointment\order\create".$user_id, 2); + try{ + //当前申请状态 + $res = $this->model->cacheCreateOrder($order_no,$user_id,$remark,true); + }catch (\Throwable $e){ +// file_put_contents("test.txt",$e->getMessage().$e->getFile().$e->getLine());//写入文件,一般做正式环境测试 +// Log::log($e->getMessage()); + $this->error($e->getMessage(),['errcode'=>$e->getCode()]);; + } + $this->success('订单创建成功,缓存key被消耗', $res); + } + + + + + + + + + /** + * @ApiTitle(免费单和未支付单取消接口) + * @ApiSummary(活动单取消接口(免费单和未支付单取消)) + * @ApiMethod(POST) + * @ApiParams(name = "order_no", type = "string",required=true,description = "订单号") + * @ApiReturn({ + * + *}) + */ + public function freecancel(){ + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $order_no = $this->request->post('order_no/s', ''); //订单号 + try{ + //当前申请状态 + $res = $this->model->freeCancel($order_no,$user_id,true,'user',0,true); + }catch (\Throwable $e){ + $this->error($e->getMessage()); + } + $this->success('活动订单取消成功', $res); + } + + + + + + + } \ No newline at end of file diff --git a/application/api/controller/school/newactivity/Pay.php b/application/api/controller/school/newactivity/Pay.php new file mode 100644 index 0000000..6188efa --- /dev/null +++ b/application/api/controller/school/newactivity/Pay.php @@ -0,0 +1,327 @@ +model = new OrderModel; + parent::_initialize(); + $this->setUrlLock(); + //判断登录用户是否是员工 + } + + + /** + * @ApiTitle( 活动第三方支付) + * @ApiSummary(活动第三方支付(微信等支付)) + * @ApiMethod(POST) + * @ApiParams(name = "order_no", type = "string",required=true,description = "订单id或订单号") + * @ApiParams(name = "type", type = "string",required=true,description = "服务商:alipay=支付宝,wechat=微信") + * @ApiParams(name = "platform", type = "string",required=true,description = "平台:web=PC网页支付,wap=H5手机网页支付,app=APP支付,scan=扫码支付,mp=微信公众号支付,miniapp=微信小程序支付") + * @ApiParams(name = "openid", type = "string",required=false,description = "用户openid(非必填)") + * @ApiReturn({ + * + *}) + */ + public function payment() + { + $order_no = $this->request->post('order_no/s'); + $type = $this->request->post('type/s'); + $method = $this->request->post('platform/s'); + $openid = $this->request->post('openid/s', ""); + $platform = $method; + try { + //订单支付前校验 + $this->model->checkPay($order_no,$type); + $order = OrderModel::where('order_no', $order_no)->find(); + $amount = $order["totalprice"]; + } catch (\Exception $e) { + $this->error($e->getMessage()); + } + + + + + + if (!$amount || $amount < 0) { + $this->error("支付金额必须大于0"); + } + + if (!$type || !in_array($type, ['alipay', 'wechat'])) { + $this->error("支付类型不能为空"); + } + + if (in_array($method, ['miniapp', 'mp']) && !$openid) { + + // 微信公众号,小程序支付,必须有 openid + if (isset($openid) && $openid) { + // 如果传的有 openid + } else { + // 没有 openid 默认拿下单人的 openid + $oauth = Third::where([ + 'user_id' => $order->user_id, + 'platform' => $type, + 'apptype' => $platform + ])->find(); + + $openid = $oauth ? $oauth->openid : ''; + } + + if (!$openid) { + // 缺少 openid + $this->error("请您重新授权登录再下单"); + } + } + + //订单号 + $out_trade_no = $order_no; + + //订单标题 + $title = '活动订单['.$out_trade_no."]支付"; + + //回调链接 + $notifyurl = $this->request->root(true) . '/api/school.newactivity.pay/notifyx/paytype/' . $type. '/platform/' . $method; + $returnurl = $this->request->root(true) . '/api/school.newactivity.pay/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no; + + $response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid); + + $this->success('查询成功', ["paydata"=>$response]); + +// return $response; + } + + /** + * @ApiTitle( 第三方支付支付成功回调) + * @ApiSummary(第三方支付成功回调) + * @ApiMethod(GET) + * @ApiReturn({ + * + *}) + */ + public function notifyx() + { + $paytype = $this->request->param('paytype'); + $platform = $this->request->param('platform'); + $pay = Service::checkNotify($paytype); + if (!$pay) { + return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']); + } + $payment = $paytype; + // 获取回调数据,V3和V2的回调接收不同 + $data = Service::isVersionV3() ? $pay->callback() : $pay->verify(); + + + + Log::write('notifyx-result:'. json_encode($data)); + + $out_trade_no = $data['out_trade_no']; + $out_refund_no = $data['out_biz_no'] ?? ''; + + + + // 判断是否是支付宝退款(支付宝退款成功会通知该接口) + if ($paytype == 'alipay' // 支付宝支付 + && $data['notify_type'] == 'trade_status_sync' // 同步交易状态 + && $data['trade_status'] == 'TRADE_CLOSED' // 交易关闭 + && $out_refund_no // 退款单号 + ) { + // 退款回调 + +// $this->refundFinish($out_trade_no, $out_refund_no,$platform); + + return $pay->success()->send(); + } + + + + + + + // 判断支付宝微信是否是支付成功状态,如果不是,直接返回响应 + if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') { + // 不是交易成功的通知,直接返回成功 + return $pay->success()->send(); + } + if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) { + // 微信交易未成功,返回 false,让微信再次通知 + return false; + } + + + try { + //微信支付V3返回和V2不同 + if (Service::isVersionV3() && $paytype === 'wechat') { + $data = $data['resource']['ciphertext']; + $data['total_fee'] = $data['amount']['total']; + } + + \think\Log::record($data); + + $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100; + $out_trade_no = $data['out_trade_no']; + + \think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}"); + + //你可以在此编写订单逻辑 + + // 支付成功流程 + //获取支付金额、订单号 + $pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100; + + //你可以在此编写订单逻辑 + $order = OrderModel::getNopayOrder($out_trade_no); + + if (!$order || $order["status"] != '0') { + // 订单不存在,或者订单已支付 + return $pay->success()->send(); + } + $notify = [ + 'order_no' => $data['out_trade_no'], + 'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'], + 'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])), + 'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'], + 'payment_json' => json_encode($data->all()), + 'pay_fee' => $pay_fee, + 'pay_type' => $payment, // 支付方式 + 'platform' => $platform, + ]; + + $this->model->paySuccess($order['order_no'],$notify,$pay_fee,true,true); + + + + } catch (Exception $e) { + \think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error"); + } + + //下面这句必须要执行,且在此之前不能有任何输出 + if (Service::isVersionV3()) { + return $pay->success()->getBody()->getContents(); + } else { + return $pay->success()->send(); + } + } + + /** + * 支付返回,网页支付版本(小程序忽略) + */ + public function returnx() + { + $paytype = $this->request->param('paytype'); + $out_trade_no = $this->request->param('out_trade_no'); + $pay = Service::checkReturn($paytype); + if (!$pay) { + $this->error('签名错误', ''); + } + + //你可以在这里定义你的提示信息,但切记不可在此编写逻辑 + $this->success("请返回网站查看支付结果", addon_url("epay/index/index")); + } + + + /** + * 支付返回 + */ + public function notifyRefund($callback) + { + $pay = $this->getPay(); + + try { + $data = $pay->verify(null, true); // 是的,验签就这么简单! + + $result = $callback($data, $pay); + + // Log::debug('Wechat notify', $data->all()); + } catch (\Exception $e) { + // $e->getMessage(); + } + + return $result; + } + + + /** + * 退款成功回调 + */ + public function notifyr() + { + Log::write('notifyreturn-comein:'); + + $payment = $this->request->param('payment'); + $platform = $this->request->param('platform'); + + $config = Service::getConfig('wechat'); + + $notify_url = request()->domain() . '/api/school.newactivity.pay/notifyr/payment/' . $payment . '/platform/' . $platform; + + $config['notify_url'] = $notify_url; + $pay = \Yansongda\Pay\Pay::wechat($config); + + try { + $data = $pay->verify(null, true); // 是的,验签就这么简单! + + Log::write('notifyr-result:' . json_encode($data)); + + $out_refund_no = $data['out_refund_no']; + $out_trade_no = $data['out_trade_no']; + + // 退款 + $this->refundFinish($out_trade_no, $out_refund_no,$platform,$data); + + + return $pay->success()->send(); + // Log::debug('Wechat notify', $data->all()); + } catch (\Exception $e) { + Log::write('notifyreturn-error:' . $e->getMessage()); + $this->model::orderRefundFail($out_trade_no,$e->getMessage(),'user',0,true); + + } + return $pay->success()->send(); + } + + + private function refundFinish($out_trade_no, $out_refund_no,$platform,$refund_json) { + +// $order = Order::where('order_sn', $out_trade_no)->find(); +// $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find(); +// +// if (!$order || !$refundLog || $refundLog->status != 0) { +// // 订单不存在,或者订单已退款 +// return true; +// } +// +// $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find(); +// +// Db::transaction(function () use ($order, $item, $refundLog) { +// \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog); +// }); + $this->model::refundSuccess($out_refund_no,$refund_json,true); + return true; + } + + + +} \ No newline at end of file diff --git a/application/api/controller/school/newworker/activity/Order.php b/application/api/controller/school/newworker/activity/Order.php index 6684bd2..f84d090 100644 --- a/application/api/controller/school/newworker/activity/Order.php +++ b/application/api/controller/school/newworker/activity/Order.php @@ -5,6 +5,8 @@ namespace app\api\controller\school\newworker\activity; use app\api\controller\school\newworker\Base; use app\common\model\school\activity\order\Order as OrderModel; +use app\common\model\school\activity\order\OrderCode; + /** * 员工端:活动订单管理接口 */ @@ -131,5 +133,33 @@ class Order extends Base + /** + * @ApiTitle( 员工操作:订单核销接口) + * @ApiSummary(订单核销接口) + * @ApiMethod(POST) + * @ApiParams(name = "code", type = "string",required=true,description = "核销码") + * @ApiReturn({ + * + *}) + */ + public function verification(){ + $this->model = new OrderCode(); + + $this->setUrlLock(); + + $user_id = 0; + $user = $this->auth->getUser();//登录用户 + if($user)$user_id = $user['id']; + $code = $this->request->post('code/s', ''); //订单号 + try{ + //当前申请状态 + $res = $this->model->verification($code,0,true,'user',$user_id,true); + }catch (\Throwable $e){ + $this->error($e->getMessage()); + } + $this->success('预约课时核销成功', $res); + } + + } \ No newline at end of file diff --git a/application/common/hooks.php b/application/common/hooks.php index cc29edb..9ad4367 100644 --- a/application/common/hooks.php +++ b/application/common/hooks.php @@ -282,9 +282,14 @@ $newactivityOrderHooks = [ 'activity_order_payed_after' => [ // 订单支付成功 'app\\common\\listener\\activity\\OrderHook' ], -// 'classes_activity_order_cancel_after' => [ // 订单取消后 -// 'app\\common\\listener\\activityorder\\OrderHook' -// ], + + 'activity_order_verification_after' => [ // 订单核销成功后 + 'app\\common\\listener\\activity\\OrderHook' + ], + + 'activity_order_cancel_after' => [ // 订单取消后 + 'app\\common\\listener\\activity\\OrderHook' + ], // 'classes_activity_order_auth_success_after' => [ // 订单审核通过后 // 'app\\common\\listener\\activityorder\\OrderHook' // ], @@ -298,9 +303,9 @@ $newactivityOrderHooks = [ // 'classes_activity_order_refund_fail_after'=> [ // 订单审核失败后退款成功 // 'app\\common\\listener\\activityorder\\OrderHook' // ], -// 'classes_activity_order_finish_after' => [ // 订单完成后 -// 'app\\common\\listener\\activityorder\\OrderHook' -// ], + 'activity_order_finish_after' => [ // 订单完成后 + 'app\\common\\listener\\activity\\OrderHook' + ], ]; diff --git a/application/common/listener/activity/OrderHook.php b/application/common/listener/activity/OrderHook.php index 1ee9891..388bef9 100644 --- a/application/common/listener/activity/OrderHook.php +++ b/application/common/listener/activity/OrderHook.php @@ -131,6 +131,171 @@ class OrderHook } + public function activityOrderVerificationAfter(&$params) + { + ["order"=>$order] = $params; + + $order = Order::where("id" , $order["id"])->find(); + + $detail = $order->detail; + $user = $order->user; + //记录订单日志 + $mini_type = "activity_order"; + $to_id = $order["user_id"]; + $status ="activity"; + $params=[ + "event"=>"activity_order_verification_after", + "order_id"=>$order["id"], + "order_no"=>$order["order_no"], + "activity_id"=>$order["activity_id"], + ]; + $param = [ + "title"=>$detail["title"], + "order_no" => $order["order_no"], + "nickname" => $user["nickname"], + "realname" => $user["realname"], + "mobile" => $user["mobile"], + "price" => $order["totalprice"], + "payprice" => $order["payprice"], + "real_refundprice" => $order["real_refundprice"], + "sub_refundprice" => $order["sub_refundprice"], + "reason" => $order["reason"], + "address"=>$detail["address"]."(".$detail["address_detail"].")", + "start_time" => date("Y-m-d H:i",$detail["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "end_time" => date("Y-m-d H:i",$detail["end_time"]), + "sign_start_time" => date("Y-m-d H:i",$detail["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "sign_end_time" => date("Y-m-d H:i",$detail["sign_end_time"]), + ]; + + (new MessageConfig) + ->setTemplate($params["event"]) + ->setTemplateData($param) + ->setToUid($to_id) + ->setMessageStatus($status) + ->setMessageMiniType($mini_type) + ->setMessageParams($params) + ->sendMessage(); + + + + } + + + + + + + + // 订单核销完成后 + public function activityOrderFinishAfter(&$params) + { + ['order' => $order,"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id] = $params; + + + $order = Order::where("id" , $order["id"])->find(); + $detail = $order->detail; + $user = $order->user; + //记录订单日志 + $mini_type = "activity_order"; + $to_id = $order["user_id"]; + $status ="activity"; + $params=[ + "event"=>"activity_order_finish_after", + "order_id"=>$order["id"], + "order_no"=>$order["order_no"], + "activity_id"=>$order["activity_id"], + ]; + $param = [ + "title"=>$detail["title"], + "order_no" => $order["order_no"], + "nickname" => $user["nickname"], + "realname" => $user["realname"], + "mobile" => $user["mobile"], + "price" => $order["totalprice"], + "payprice" => $order["payprice"], + "real_refundprice" => $order["real_refundprice"], + "sub_refundprice" => $order["sub_refundprice"], + "reason" => $order["reason"], + "address"=>$detail["address"]."(".$detail["address_detail"].")", + "start_time" => date("Y-m-d H:i",$detail["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "end_time" => date("Y-m-d H:i",$detail["end_time"]), + "sign_start_time" => date("Y-m-d H:i",$detail["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "sign_end_time" => date("Y-m-d H:i",$detail["sign_end_time"]), + ]; + + //发用户 + (new MessageConfig) + ->setTemplate($params["event"]."_user") + ->setTemplateData($param) + ->setToUid($to_id) + ->setMessageStatus($status) + ->setMessageMiniType($mini_type) + ->setMessageParams($params) + ->sendMessage(); + //发所有核销员 + (new MessageConfig) + ->setTemplate($params["event"]."_verification") + ->setTemplateData($param) + ->setToUid($detail["user_id"]) + ->setMessageStatus($status) + ->setMessageMiniType($mini_type) + ->setMessageParams($params) + ->sendMessage(); + + } + + + + + // 订单取消成功后 + public function activityOrderCancelAfter(&$params) + { + ["order"=>$order] = $params; + + $order = Order::where("id" , $order["id"])->find(); + + $detail = $order->detail; + $user = $order->user; + //记录订单日志 + $mini_type = "activity_order"; + $to_id = $order["user_id"]; + $status ="activity"; + $params=[ + "event"=>"activity_order_cancel_after", + "order_id"=>$order["id"], + "order_no"=>$order["order_no"], + "activity_id"=>$order["activity_id"], + ]; + $param = [ + "title"=>$detail["title"], + "order_no" => $order["order_no"], + "nickname" => $user["nickname"], + "realname" => $user["realname"], + "mobile" => $user["mobile"], + "price" => $order["totalprice"], + "payprice" => $order["payprice"], + "real_refundprice" => $order["real_refundprice"], + "sub_refundprice" => $order["sub_refundprice"], + "reason" => $order["reason"], + "address"=>$detail["address"]."(".$detail["address_detail"].")", + "start_time" => date("Y-m-d H:i",$detail["start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "end_time" => date("Y-m-d H:i",$detail["end_time"]), + "sign_start_time" => date("Y-m-d H:i",$detail["sign_start_time"]), //格式化日期格式 $order["start_time"], //格式化日期格式 + "sign_end_time" => date("Y-m-d H:i",$detail["sign_end_time"]), + ]; + + (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 b3f3dd9..1f912c6 100644 --- a/application/common/model/school/activity/Activity.php +++ b/application/common/model/school/activity/Activity.php @@ -416,8 +416,9 @@ class Activity extends BaseModel } - - + //settlement_time 最后结算时间等于活动结束时间往后延长n秒,n取配置 + $activity_end_settle = config("site.activity_end_settle") ?:0; + $params["settlement_time"] = $end_time + $activity_end_settle; $rule = [ 'user_id'=>'require', @@ -1092,7 +1093,7 @@ class Activity extends BaseModel $res = true; try{ $row = self::get($id); - if(!$row)throw new \Exception("找不到活动!"); + if(!$row)return false; $now_time = time(); $sign_start_time = $row["sign_start_time"]; diff --git a/application/common/model/school/activity/order/Order.php b/application/common/model/school/activity/order/Order.php index dea7227..e18ff4f 100644 --- a/application/common/model/school/activity/order/Order.php +++ b/application/common/model/school/activity/order/Order.php @@ -433,6 +433,9 @@ class Order extends BaseModel // $data->user; $data->user->visible(['id','nickname','mobile','avatar','realname']); + //超时检测 + self::timeoutCheck($data["id"]); + //规格信息 $data->ordercode; @@ -533,11 +536,13 @@ class Order extends BaseModel //校验订单参数 //课程活动是否存在并上架 $activity = Activity::where('id',$activity_id)->find(); - if(!$activity || $activity['status']!='2' || $activity['auth_status']!='1') throw new \Exception("该活动不在可报名时间段!"); + if(!$activity ) throw new \Exception("该活动不存在!"); //默认校验订单是否已创建 if($check){ + if($activity['status']!='2' || $activity['auth_status']!='1') throw new \Exception("该活动不在可报名时间段!"); + //此为创建订单时判断 //判断订单是否已创建 $order_info = self::where(['order_no'=>$order_no])->find(); @@ -601,6 +606,8 @@ class Order extends BaseModel // $activity_info["used_price"] = 0; $totalprice = bcmul($num,$activity_info["price"],2); + + //组装订单下单数据 $order_data = []; $order_data["user_id"] = $user_id; @@ -612,6 +619,9 @@ class Order extends BaseModel $order_data["totalprice"] = $totalprice; $order_data["payprice"] = 0; $order_data["status"] = '0'; + $order_data["settle_log_time"] = $activity_info["settlement_time"]; + //根据手续费比例$activity_info["fee_scale"] 计算手续费 + $order_data["fee_price"] = bcmul($order_data["totalprice"],$order_data["fee_scale"],2); return compact('order_data','activity_info','user_data',"num"); @@ -667,7 +677,7 @@ class Order extends BaseModel * @throws \think\exception\DbException */ public static function getNopayOrder($order_no){ - $order = self::where('order_no|id|pay_no',$order_no)->where("status",'0')->find(); + $order = self::where('order_no|id|pay_no',$order_no)->where("status","in",['0',"-3"])->find(); if(!$order)throw new \Exception("待支付订单不存在"); return $order; } @@ -698,6 +708,9 @@ class Order extends BaseModel //不拆分订单,直接执行 self::paySetData($order,$notify); + //释放结算订单 + (new SettleLog)->generatorLog($order['id']); + // //如果需要快捷预约 // $classes_lib_spec_id = $order['classes_lib_spec_id']; // if($classes_lib_spec_id){ @@ -1009,6 +1022,478 @@ class Order extends BaseModel + /** + * 检测支付开关(待扩展) + */ + public static function checkPaySwitch($pay_type,$user_id){ + + + } + + + /**订单支付前判断 + * @param $order_no + * @param $pay_type + * @return array|false|\PDOStatement|string|Model + */ + public function checkPay($order_no,$pay_type,$password = null){ + $order = self::getNopayOrder($order_no); + + //支付前判断 + //TODO通用判 + + $this->orderVaild($order['user_id'],$order['activity_id'],$order['num'],$order['order_no'], []); + + //... + $user = User::where('id',$order['user_id'])->find(); + if(!$user)throw new \Exception("支付用户异常"); + + //是否开通此支付方式 + self::checkPaySwitch($pay_type,$order['user_id']); + + //各自币种判断 + switch ($pay_type) { + case "wechat": //微信支付 + //.. + break; + case "alipay": //支付宝支付 + //... + break; + case "offline": //线下支付 + //.. + break; + case "yue": //余额支付 + //支付密码判断 +// $res = User::checkPayPassword($order['user_id'],$password,true); +// if(!$res['is_setting'])throw new \Exception("您还未设置支付密码,请您先去设置支付密码"); +// if(!$res['is_right'])throw new \Exception("支付密码错误"); + //判断余额是否充足 + //得到支付余额 + $total_amount = $order['totalprice'] ?:0; + //得到用户余额 + $money = $user['money']; + if(bccomp($money,$total_amount)==-1)throw new \Exception("当前余额不足以完成本次支付!"); + break; + default: + throw new \Exception("不支持的支付类型验证"); + } + + return true; + } + + + + + + /** 课时订单操作权限检测 + * @param $order 订单 + * @param $oper_id 操作人id + * @param $oper_type 操作人类型:user-用户或员工,admin-管理员 + * @return void + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function checkOptionAuth($classes_order_id,$oper_id,$oper_type,$only_user=false,$only_shop=false,$only_admin=false){ + + //课程是否存在并上架 + $classesOrder = Order::where("id",$classes_order_id)->find(); + if(!$classesOrder)throw new \Exception("订单不存在!"); + + switch ($oper_type) { + case 'user': + if($only_admin)throw new \Exception("您无权操作该订单!"); + + //自己或操作员 + if($oper_id != $classesOrder["user_id"]){ + if($only_user) throw new \Exception("您无权操作该订单!"); + + //说明是操作员 + $help_user_info = User::where('id',$oper_id)->find(); + if(!$help_user_info) throw new \Exception("代下单员工不存在!"); + $classes_activity_ids = (new Activity())->getActivityAuthIds($oper_id); + //判断当前订单课程是否在此课程授权范围内 + if(!in_array($classesOrder["activity_id"],$classes_activity_ids)) throw new \Exception("该活动不在您的授权范围内,无法代操作!"); + }else{ + $classes_activity_ids = (new Activity())->getActivityAuthIds($oper_id); + //不是员工并且想操作只有机构能操作的单 + if(!in_array($classesOrder["activity_id"],$classes_activity_ids) && $only_shop)throw new \Exception("您无权操作该订单!"); + } + break; + case 'admin': + $admin_info = Admin::where('id',$oper_id)->find(); + if(!$admin_info) throw new \Exception("代下单管理员不存在!"); + break; + case 'shop': + if($only_admin)throw new \Exception("您无权操作该订单!"); + + if($only_user) throw new \Exception("您无权操作该订单!"); + + $admin_info = Manystore::where('id',$oper_id)->find(); + if(!$admin_info) throw new \Exception("代下单管理员不存在!"); + $classes_activity_ids = (new Activity())->getActivityAuthIds($admin_info["user_id"]); + //判断当前订单课程是否在此课程授权范围内 + if(!in_array($classesOrder["activity_id"],$classes_activity_ids)) throw new \Exception("该活动不在您的授权范围内,无法代操作!"); + + break; + default: + throw new \Exception("请选择正确的代下单类型!"); + } + + + } + + + + + + /** 检测订单完成状态 + * @param $order + * @return void + * @throws \think\Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function statisticsAndUpdateOrderFinish($order){ + if(is_string($order)||is_numeric($order))$order = self::getOrder($order); + $detail = $order->detail; + if(!$detail)throw new \think\Exception("订单信息缺失!"); + //得到当前订单的所有已完成课时订单 + $hourorderOrderCount = OrderCode::where("status","=",'6') + ->where("activity_order_id","=",$order["id"]) + ->count(); + //可完成的订单 + if(in_array($order["status"],["2",'3']) && (in_array($order["server_status"],['0'])) && !$order['finishtime']){ + //判定是否达成完成条件 + //条件:课程课时已全部完成 + if($hourorderOrderCount >= $order->num){ + //执行订单完成的更新逻辑 + self::updateFinish($order); + }elseif($order["status"] == "2"){ + //更新订单状态成核销中 + $order["status"] = '3'; + $order["reservation_time"] = time(); + $order->save(); + } + } + } + + /** 更新订单成已完成 + * @param $order + * @return void + */ + public static function updateFinish($order){ + if(is_string($order)||is_numeric($order))$order = self::getOrder($order); + + //检测未核销订单,强制核销 + $orderCodes = OrderCode::where("status","=",'3') + ->where("activity_order_id","=",$order["id"]) + ->select(); + foreach ($orderCodes as $k=>$orderCode){ + //强制核销 + (new OrderCode)->forceVerification($orderCode["code"],"admin",0,false); + } + + + + + + //更新订单 + $order["status"] = '9'; + + + $order["finishtime"] = time(); + + $order->save(); + //记录订单日志 + OrderLog::log($order['id'],"活动订单完成,人数已全部核销",'user',$order['user_id']); + + + //释放结算订单 + (new SettleLog)->generatorLog($order['id']); + + //调用支付成功事件 + $data = ['order' => $order]; + \think\Hook::listen('activity_order_finish_after', $data); + } + + + + + + + + + /**得到可取消的免费订单以及未支付取消 + * @param $order_no + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getHaveCancelFreeOrder($order_no){ +// $where = [self::STATUS_NOPAY,self::STATUS_PAYED]; + $order = self::where('order_no|id|pay_no',$order_no)->find(); + $detail = $order->detail; + if(!$detail) throw new \Exception("订单信息缺失!"); + if(!$order)throw new \Exception("订单信息缺失!"); + //非免费单进行中无法取消 + if($order['totalprice'] != 0){ + //非免费单只有未支付的单才可以取消 + if($order['status'] != '0'){ + throw new \Exception("只有未支付的单才可以取消!"); + } + }else{ + if(!in_array($order['status'],['0','2'])){ + throw new \Exception("免费单只有进行中订单可取消,已取消请忽重复取消!"); + } + } + + //活动开始后不可取消 + $time = time(); + if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消!"); + + return $order; + } + + + /**更新免费订单取消状态以及未支付取消 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateFreeCancel($order){ + if(is_string($order))$order = self::getHaveCancelFreeOrder($order); + $order->status = "-3";//refund_status + $order->canceltime = time(); + $order->save(); + return $order; + } + + /**免费订单取消以及未支付取消 + * @param $order_no + * @param int $user_id + * @param bool $check + * @param bool $trans + * @return bool + * @throws \Exception + */ + public function freeCancel($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ + //得到可取消订单 + $order = self::getHaveCancelFreeOrder($order_no); + if($check){ + //用户操作权限检测 + self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type); + + } + + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + + //更新订单取消状态 + $order = self::updateFreeCancel($order); + //插入订单取消日志 + if(!$user_id ||$order["user_id"] !=$user_id ){ + OrderLog::log($order['id'],"[系统操作]活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + OrderLog::log($order['id'],"活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + //调用订单取消事件 + $data = ['order' => self::where("id",$order['id'])->find(),"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('activity_order_cancel_after', $data); + //执行课时数更新 + $res1 = self::statisticsAndUpdateClassesNumber($order['id']); + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage().$e->getFile().$e->getLine()); + } + return $res1; + } + + + + + + + /** + * 超时取消检测(未支付取消) + */ + public static function timeoutCheck($order_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; + $unpaid_order_expire_time = time() - $unpaid_order_expire_time; + //得到所有过期的队列 + $model = self::where("status",'in',['0'])->where("createtime","<=",$unpaid_order_expire_time); + if($order_id)$model = $model->where("id",$order_id); + $list = $model->select(); + + if ($trans) { + self::beginTrans(); + } + try { + + + foreach ($list as $order) + { + //取消订单 + self::freeCancel($order['id'],0,false,'admin',0); + $count++; + } + if ($trans) { + self::commitTrans(); + } + } catch (\Exception $e) { + if ($trans) { + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $count; + } + + + + + + + + /**得到可取消的付费订单 + * @param $order_no + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getHaveCancelPaidOrder($order_no){ +// $where = [self::STATUS_NOPAY,self::STATUS_PAYED]; + $order = self::where('order_no|id|pay_no',$order_no)->find(); + $detail = $order->detail; + if(!$detail) throw new \Exception("订单信息缺失!"); + if(!$order)throw new \Exception("订单信息缺失!"); + //非免费单进行中无法取消 + if($order['totalprice'] != 0){ + //非免费单只有未退款可退 + if(!in_array($order['status'],["2","3"])){ + throw new \Exception("只有已报名和核销中的单才可以取消!"); + } + }else{ + throw new \Exception("免费单请走免费订单取消接口!"); + } + //根据不同退款策略判断当前时间点是否可取消并退款 + $refund_status = $detail["refund_status"]; + //活动开始后不可取消,只能走售后 + $time = time(); + switch ($refund_status){ + case "1": //不退款 + + throw new \Exception("当前活动不支持取消退款,请走售后流程!"); + break; + case "3": //开始前退 + case "5": //随时退 + if ($detail['start_time'] < $time) throw new \Exception("活动开始后不可取消,请走售后流程!"); + break; + default: + throw new \Exception("不支持的退款策略,请走售后流程!"); + + } + + + + + return $order; + } + + + /**更新免费订单取消状态以及未支付取消 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updatePaidCancel($order){ + if(is_string($order))$order = self::getHaveCancelFreeOrder($order); + $order->status = "-3";//refund_status + $order->canceltime = time(); + $order->save(); + return $order; + } + + /**免费订单取消以及未支付取消 + * @param $order_no + * @param int $user_id + * @param bool $check + * @param bool $trans + * @return bool + * @throws \Exception + */ + public function paidCancel($order_no,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ + //得到可取消订单 + $order = self::getHaveCancelFreeOrder($order_no); + if($check){ + //用户操作权限检测 + self::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type); + + } + + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + + //更新订单取消状态 + $order = self::updateFreeCancel($order); + //插入订单取消日志 + if(!$user_id ||$order["user_id"] !=$user_id ){ + OrderLog::log($order['id'],"[系统操作]活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + OrderLog::log($order['id'],"活动订单取消成功",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + //调用订单取消事件 + $data = ['order' => self::where("id",$order['id'])->find(),"user_id"=>$user_id,"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('activity_order_cancel_after', $data); + //执行课时数更新 + $res1 = self::statisticsAndUpdateClassesNumber($order['id']); + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage().$e->getFile().$e->getLine()); + } + return $res1; + } + + + + diff --git a/application/common/model/school/activity/order/OrderCode.php b/application/common/model/school/activity/order/OrderCode.php index cc21509..237a733 100644 --- a/application/common/model/school/activity/order/OrderCode.php +++ b/application/common/model/school/activity/order/OrderCode.php @@ -3,6 +3,7 @@ namespace app\common\model\school\activity\order; use app\common\model\BaseModel; +use app\common\model\school\activity\Activity; use think\Model; use traits\model\SoftDelete; @@ -68,4 +69,141 @@ class OrderCode extends BaseModel { return $this->belongsTo('app\common\model\User', 'verification_user_id', 'id', [], 'LEFT')->setEagerlyType(0); } + + + + /**更新订单核销状态 + * @param $order + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function updateVerification($code,$oper_id = 0,$oper_type='user',$check=true){ + if(is_string($code))$code = self::getHaveVerificationOrderCode($code,$check); + $code->status = "6";//refund_status + $code->verification_user_id = $oper_id; + $code->verification_type = $oper_type; + $code->verificationtime = time(); + $code->save(); + return $code; + } + + + + + + /**得到可核销订单 + * @param $order_no + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public static function getHaveVerificationOrderCode($code,$check=true){ +// $where = [self::STATUS_NOPAY,self::STATUS_PAYED]; + $ordercode = self::where('code',$code)->where("status","in",['3'])->find(); + if(!$ordercode)throw new \Exception("当前码已存在或核销过!"); + $order = $ordercode->order; + if(!$order)throw new \Exception("订单异常!"); + if(!$check) return $ordercode; + + if(!in_array($order["status"],['2','3']))throw new \Exception("当前订单不可核销!"); + //过了可核销时间段 + Activity::update_classes($order["activity_id"]); + $activity = $order->activity; + if(!$activity)throw new \Exception("活动异常!"); + if($activity["status"] != "4")throw new \Exception("当前活动还不能核销!"); + + return $ordercode; + } + + /** 强制核销订单 + * @param $code + * @param $oper_type + * @param $oper_id + * @return array|false|\PDOStatement|string|Model + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\ModelNotFoundException + * @throws \think\exception\DbException + */ + public function forceVerification($code,$oper_type='user',$oper_id=0,$check=true) + { + + $ordercode = self::updateVerification($code,$oper_id,$oper_type,$check); + $order = $ordercode->order; + if($check){ + + //插入订单取消日志 + if($oper_type!='user' || $order["user_id"] !=$oper_id ){ + OrderLog::log($order['id'],"[员工操作]活动订单成功核销一人",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + }else{ + OrderLog::log($order['id'],"活动订单成功核销一人",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + }else{ + OrderLog::log($order['id'],"活动结束订单强制完成核销(超时结算或特殊情况)",$oper_type ?: 'user', $oper_id ?: $order['user_id']); + } + + + //调用订单取消事件 + $data = ['order' => self::where("id",$order['id'])->find(),"user_id"=>$order["user_id"],"oper_type"=>$oper_type,"oper_id"=>$oper_id]; + \think\Hook::listen('activity_order_verification_after', $data); + + //过了可核销时间段 + Activity::update_classes($order["activity_id"]); + return $ordercode; + + } + + + /**订单核销 + * @param $code + * @param int $user_id + * @param bool $check + * @param bool $trans + * @return bool + * @throws \Exception + */ + public function verification($code,$user_id=0,$check=false,$oper_type='user',$oper_id=0,$trans=false){ + //得到可取消订单 + $ordercode = self::getHaveVerificationOrderCode($code); + $order = $ordercode->order; + if($check){ + //用户操作权限检测 + Order::checkOptionAuth($order['id'],$user_id ?: $oper_id,$oper_type); + + } + + //判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + //事务逻辑 + //更新订单状态 + + $ordercode = $this->forceVerification($code,$oper_type,$oper_id); + + //检测订单完成状态 + Order::statisticsAndUpdateOrderFinish($order['id']); + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $ordercode; + } + + + + + + } diff --git a/application/common/model/school/activity/order/SettleLog.php b/application/common/model/school/activity/order/SettleLog.php index 84d333e..5f82027 100644 --- a/application/common/model/school/activity/order/SettleLog.php +++ b/application/common/model/school/activity/order/SettleLog.php @@ -107,4 +107,171 @@ class SettleLog extends BaseModel { return $this->belongsTo('app\common\model\User', 'pay_user_id', 'id', [], 'LEFT')->setEagerlyType(0); } + + + /** 生成结算记录 + * @param $order_id + * @param $trans + * @return true + * @throws \Exception + */ + public function generatorLog($order_id,$trans=false){ + $order = Order::where("id" ,$order_id)->find(); + if(!$order) return false; + //免费的忽略 + if($order->payprice <= 0) return false; + $detail = $order->detail; + if(!$detail) return false; + $data = [ + "activity_order_id" => $order_id, + "withdrawal_log_id" =>0, + "to_user_id" => $detail->user_id, + "pay_user_id" => $order->user_id, + "status" =>'1', + "unfreezetime" => $detail->settlement_time, + "order_price" => $order->payprice, + "sub_refundprice" =>$order->sub_refundprice, + "fee_scale" => $order->fee_scale, + "fee_price" => $order->fee_price, + "settle_price" => bcsub($order->sub_refundprice,$order->fee_price,2) + ]; +//判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + $res =self::where([ + "activity_order_id" => $order_id, + "status" =>'1', + "to_user_id" => $detail->user_id, + ])->find(); + //保存 + if(!$res)$res = self::create($data); + //记录状态检测 + $this->settleCheck($res["id"]); + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage().$e->getFile().$e->getLine()); + } + return $res; + } + + + /** 结算冻结状态更新 + * @param $log_id + * @param $trans + * @return true + * @throws \Exception + */ + public function settleCheck($log,$trans=false){ + if(is_string($log)||is_numeric($log))$log = self::where("id" ,$log)->where("status",'1')->find(); + if(!$log) return false; +//判断逻辑 + if($trans){ + self::beginTrans(); + } + $res = true; + try{ + $time = time(); + if($log->unfreezetime < $time){ + //更新状态 + $res = self::where("id" ,$log["id"])->update(["status" =>'2']); + } + + + if($trans){ + self::commitTrans(); + } + }catch (\Exception $e){ + if($trans){ + self::rollbackTrans(); + } + throw new \Exception($e->getMessage().$e->getFile().$e->getLine()); + } + return $res; + } + + + /** + * 超时检测 + */ + public static function timeoutCheck($activity_order_id=null,$to_user_id=null,$trans = false){ + $count = 0; + $model = self::where("status",'1'); + if($activity_order_id)$model = $model->where("activity_order_id",$activity_order_id); + if($to_user_id)$model = $model->where("to_user_id",$to_user_id); + //得到所有过期的队列 + $list = $model->select(); + + if ($trans) { + self::beginTrans(); + } + try { + + foreach ($list as $log) + { + //更新结算状态 + (new self)->settleCheck($log,$trans=false); + $count++; + } + if ($trans) { + self::commitTrans(); + } + } catch (\Exception $e) { + if ($trans) { + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $count; + } + + + + /** + * 批量关闭 + */ + public static function allClose($activity_order_id=null,$to_user_id=null,$trans = false){ + $count = 0; + $model = self::where("status",'2'); + if($activity_order_id)$model = $model->where("activity_order_id",$activity_order_id); + if($to_user_id)$model = $model->where("to_user_id",$to_user_id); + //得到所有过期的队列 + $list = $model->select(); + + if ($trans) { + self::beginTrans(); + } + try { + + foreach ($list as $log) + { + + $log["status"] = "-1"; + $log["canceltime"] = time(); + $log->save(); + $count++; + } + if ($trans) { + self::commitTrans(); + } + } catch (\Exception $e) { + if ($trans) { + self::rollbackTrans(); + } + throw new \Exception($e->getMessage()); + } + return $count; + } + + + + } diff --git a/public/assets/js/backend/school/message_config_item.js b/public/assets/js/backend/school/message_config_item.js index 31705b7..30b9a26 100644 --- a/public/assets/js/backend/school/message_config_item.js +++ b/public/assets/js/backend/school/message_config_item.js @@ -30,8 +30,8 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin {field: 'id', title: __('Id')}, // {field: 'config.name', title: __('Config.name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'config.logo_image', title: __('Config.logo_image'), operate: false, events: Table.api.events.image, formatter: Table.api.formatter.image}, - {field: 'event', title: __('Event'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, - {field: 'event_two', title: __('Event_two'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'event', title: __('Event'), table: table, class: 'autocontent', formatter: Table.api.formatter.content}, + {field: 'event_two', title: __('Event_two'), table: table, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'name', title: __('Name'), operate: 'LIKE', table: table, class: 'autocontent', formatter: Table.api.formatter.content}, {field: 'wechat_wap', title: __('Wechat_wap'), searchList: {"1":__('Wechat_wap 1'),"2":__('Wechat_wap 2')}, formatter: Table.api.formatter.normal}, {field: 'message', title: __('Message'), searchList: {"1":__('Message 1'),"2":__('Message 2')}, formatter: Table.api.formatter.normal},