| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905 |
- <?php
- namespace app\api\service;
- use app\admin\model\Admin;
- use app\admin\model\membership\Config;
- use app\admin\model\system\GrantVoucher;
- use app\api\model\massager\Comment;
- use app\api\model\massager\Massager;
- use app\api\model\order\Order;
- use app\api\model\service\Service;
- use app\api\model\Store;
- use app\api\model\system\Message;
- use app\api\model\User;
- use app\api\model\user\Area;
- use app\api\model\user\Voucher;
- use app\api\model\user\Wallet;
- use redis\RedLock;
- use think\Db;
- use think\Exception;
- class OrderService extends BaseService
- {
- private $model;
- private $massagerModel;
- private $storeModel;
- private $userModel;
- private $serviceModel;
- private $orderServiceModel;
- private $userAreaModel;
- private $userVoucherModel;
- private $massagerCommentModel;
- private $thirdPayService;
- private $walletService;
- public $lockKeys = [
- 'order_create' => "Order:create:"
- ];
- public function __construct()
- {
- $this->model = new Order();
- $this->massagerModel = new Massager();
- $this->storeModel = new Store();
- $this->userModel = new User();
- $this->serviceModel = new Service();
- $this->orderServiceModel = new \app\api\model\order\Service();
- $this->userAreaModel = new Area();
- $this->userVoucherModel = new Voucher();
- $this->massagerCommentModel = new Comment();
- $this->thirdPayService = new ThirdPayService();
- $this->walletService = new WalletService();
- }
- /**
- * 刷新订单金额
- * @param Order $order
- * @param $open_membership
- * @param null $total_service_amount
- * @param null $trip_amount
- * @param null $voucher_amount
- * @return Order|null
- * @throws \think\exception\DbException
- */
- private function updateOrderAmount(Order $order, $open_membership = true, $total_service_amount = null, $trip_amount = null, $voucher_amount = null)
- {
- $user = User::where("id", $order->user_id)->find();
- if ($user && $user["vip_invalid_time"] > time()) {
- $open_membership = true;
- }
- $change_trip_amount = $order->trip_amount;
- $change_voucher_amount = $order->voucher_amount;
- if (null != $total_service_amount)
- $change_total_service_amount = $total_service_amount;
- else {
- $services = $this->orderServiceModel->where("order_id", $order['id'])->select();
- $change_total_service_amount = array_reduce($services, function ($p, $cur) {
- $p += ($cur["amount"] * $cur["quantity"]);
- return $p;
- }, 0);
- }
- if (null !== $trip_amount)
- $change_trip_amount = $trip_amount;
- if (null !== $voucher_amount)
- $change_voucher_amount = $voucher_amount;
- $config = null;
- $membership_discount_rate = 100;
- $membership_discount_amount = 0;
- $membership_amount = 0;
- $total_amount = fixed2Float($change_total_service_amount + $change_trip_amount);
- if ($open_membership) {
- $user = $this->userModel->findById($order["user_id"]);
- $config = (new Config())->order("real_price", "ASC")->find();
- if (!$user || is_null($user["vip_invalid_time"]) || $user["vip_invalid_time"] < time()) { // 需要支付会员费
- $membership_amount = $config["real_price"];
- }
- $membership_discount_rate = config("site.membership_discount_rate");
- // 会员折扣
- $membership_discount_amount = fixed2Float($change_total_service_amount - ($change_total_service_amount * ($membership_discount_rate / 100)));
- // 服务费用减去会员折扣
- $change_total_service_amount = fixed2Float($change_total_service_amount * ($membership_discount_rate / 100));
- }
- $this->model->update([
- "open_membership" => $open_membership ? 1 : 0,
- "membership_config_id" => $config ? $config["id"] : null,
- "membership_amount" => $membership_amount,
- "membership_discount_rate" => $membership_discount_rate,
- "membership_discount_amount" => $membership_discount_amount,
- "total_amount" => $total_amount,
- "total_real_amount" => fixed2Float(($change_total_service_amount + $change_trip_amount) - $change_voucher_amount),
- "total_service_amount" => $change_total_service_amount,
- "trip_amount" => $change_trip_amount,
- "voucher_amount" => $change_voucher_amount
- ], ["id" => $order->id]);
- return $this->model->get($order->id);
- }
- /**
- * 获取单个订单详情
- * @param $id
- * @return array|bool|false|\PDOStatement|string|\think\Model|null
- */
- public function getOrder($id)
- {
- return $this->model->order_detail($id);
- }
- /**
- * 获取订单列表
- * @param $user_id
- * @param array $status
- * @param int $page
- * @param int $size
- * @return array
- * @throws \think\exception\DbException
- */
- public function fetchOrder($user_id, $status, $page = 1, $size = 10)
- {
- $paginate = $this->model->fetchOrder($user_id, $status, $page, $size);
- $items = $paginate->items();
- foreach ($items as $item) {
- $item->getRelation("massager")->visible(["id", "name", "photo_images"]);
- }
- return [$items, $paginate->total()];
- }
- /**
- * 创建订单
- * @param $user
- * @param array $option_service_ids
- * @param array $option_services
- * @param $m_id
- * @param $store_id
- * @param bool $is_app
- * @return \SResult
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function create($user, array $option_service_ids, array $option_services, $m_id = null, $store_id = null, bool $is_app = true): \SResult
- {
- $city_code = null;
- if ($is_app) { // 线上订单
- $massager = $this->massagerModel->getMassager($m_id);
- if (null === $massager)
- return $this->fail("助教信息不存在!");
- $city_code = $massager["city_code"];
- } else { // 球房订单
- $store = $this->storeModel->get($store_id);
- if (!$store) {
- return $this->fail("球房信息出现错误!");
- }
- $city_code = $store["city_code"];
- }
- $services = $this->serviceModel->findByIds($option_service_ids, [
- 'status' => \E_BASE_STATUS::Normal
- ]);
- $no = $this->model->genOrderNo($user->id, $store_id);
- $user_area_id = null;
- $user_address = null;
- $last_order = $this->model
- ->where("user_id", $user->id)
- ->where("user_area_id", ">", 0)
- ->order("id", "DESC")
- ->find();
- if ($last_order) {
- $user_area_id = $last_order["user_area_id"];
- $user_address = $last_order["user_address"];
- }
- $order = $this->model->create([
- "no" => $no,
- "user_id" => $user->id,
- "massager_id" => $m_id,
- "store_id" => $store_id,
- "total_amount" => 0,
- "total_real_amount" => 0,
- "total_service_amount" => 0,
- "trip_amount" => 0,
- "voucher_amount" => 0,
- "city_code" => $city_code,
- "channel_id" => $user->channel_id,
- "user_area_id" => $user_area_id,
- "user_address" => $user_address,
- ]);
- Db::startTrans();
- try {
- $db_service = [];
- foreach ($services as $service) {
- $quantity = $option_services[$service['id']]['quantity'];
- $db_service[] = [
- "order_id" => $order->id,
- "store_id" => $store_id,
- "service_id" => $service['id'],
- "service_name" => $service['name'],
- "cover_image" => $service['cover_image'],
- "amount" => $service["real_price"],
- "duration_minute" => $service["duration_minute"],
- "quantity" => $quantity,
- "status" => \E_BASE_STATUS::Normal,
- "createtime" => time(),
- "updatetime" => time(),
- ];
- }
- $total_service_amount = array_reduce($db_service, function ($p, $cur) {
- $p += ($cur["amount"] * $cur["quantity"]);
- return $p;
- }, 0);
- $this->orderServiceModel->insertAll($db_service);
- $this->updateOrderAmount($order, false, $total_service_amount);
- Db::commit();
- } catch (Exception $e) {
- Db::rollback();
- $this->model->where('id', $order->id)->delete();
- return $this->fail($e->getMessage());
- }
- if ($user_area_id) {
- $this->calculateTripAmount($user["id"], $order["id"]);
- }
- return $this->ok($this->model->order_detail($order->id));
- }
- public function reorder($order_id)
- {
- $old_order = $this->model->order_detail($order_id);
- if (null === $old_order)
- return $this->fail("订单不存在");
- if (time() - $old_order["updatetime"] > 3 * 24 * 60 * 60)
- return $this->fail("加钟订单不能超过原始订单的三天期限");
- $no = $this->model->genOrderNo($old_order["user_id"], $old_order["store_id"]);
- $redLock = new RedLock();
- $lock = $redLock->lock($this->lockKeys['order_create'] . $no);
- if (!is_array($lock))
- return $this->fail("请稍后再试!");
- $new_order = $this->model->create([
- "no" => $no,
- "user_id" => $old_order["user_id"],
- "user_area_id" => $old_order["user_area_id"],
- "store_id" => $old_order["store_id"],
- "massager_id" => $old_order["massager_id"],
- "total_amount" => 0,
- "total_real_amount" => 0,
- "total_service_amount" => 0,
- "trip_amount" => 0,
- "voucher_amount" => 0,
- "city_code" => $old_order["city_code"],
- "channel_id" => $old_order["channel_id"],
- "reorder" => 1,
- "user_address" => $old_order["user_address"],
- "massager_address" => $old_order["massager_address"],
- "createtime" => time(),
- "updatetime" => time()
- ]);
- Db::startTrans();
- try {
- $db_service = [];
- foreach ($old_order["services"] as $item) {
- $service = $this->serviceModel->get($item['service_id']);
- $db_service[] = [
- "order_id" => $new_order["id"],
- "store_id" => $service['store_id'],
- "service_id" => $service['id'],
- "service_name" => $service['name'],
- "cover_image" => $service['cover_image'],
- "amount" => $service["real_price"],
- "duration_minute" => $service["duration_minute"],
- "quantity" => 1,
- "status" => \E_BASE_STATUS::Normal,
- "createtime" => time(),
- "updatetime" => time()
- ];
- }
- $total_service_amount = array_reduce($db_service, function ($p, $cur) {
- $p += ($cur["amount"] * $cur["quantity"]);
- return $p;
- }, 0);
- $this->orderServiceModel->insertAll($db_service);
- $this->updateOrderAmount($new_order, true, $total_service_amount);
- Db::commit();
- } catch (Exception $e) {
- Db::rollback();
- $this->model->where('id', $new_order->id)->delete();
- return $this->fail($e->getMessage());
- } finally {
- $redLock->unlock($lock);
- }
- return $this->ok($this->model->order_detail($new_order->id));
- }
- /**
- * bind 地址
- * @param $user_id
- * @param $order_id
- * @param $user_area_id
- * @return \SResult
- * @throws \think\exception\DbException
- */
- public function bindUserArea($user_id, $order_id, $user_area_id): \SResult
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if ($order->user_id != $user_id)
- return $this->fail("非法修改!");
- if (\E_ORDER_STATUS::Default !== $order["status"])
- return $this->fail("订单当前状态不支持修改地点");
- if ($order->store_id > 0) {
- return $this->ok($this->model->order_detail($order->id));
- }
- $massager = $this->massagerModel->getMassager($order->massager_id);
- if (!$massager)
- return $this->fail("助教不存在, 请选择其他助教为您服务!");
- if (!is_numeric($massager->lng) || !is_numeric($massager->lat))
- return $this->fail("助教未完善地址信息无法计算距离, 请选择其他助教为您服务!");
- $userArea = $this->userAreaModel->getArea($user_id, $user_area_id);
- if (null === $userArea)
- return $this->fail("绑定的地址不存在!");
- // if ($userArea->city_code !== $order->city_code)
- // return $this->fail("距离太远,跨市无法下单!");
- $this->model->update([
- "user_area_id" => $user_area_id,
- "user_address" => $userArea->address . "-" . $userArea->door_no,
- ], ['id' => $order_id]);
- $this->calculateTripAmount($user_id, $order_id);
- return $this->ok($this->model->order_detail($order->id));
- }
- /**
- * 删减服务
- * @param int $order_id
- * @param array $option_service_ids
- * @param array $option_services
- * @return \SResult
- * @throws \think\exception\DbException
- */
- public function changeOrderService(int $order_id, array $option_service_ids, array $option_services)
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if (\E_ORDER_STATUS::Default !== $order["status"])
- return $this->fail("订单当前状态不支持修改地点");
- if ($order["massager_id"] > 0) {
- $massager = $this->massagerModel->getMassager($order['massager_id']);
- }
- $services = $this->serviceModel->findByIds($option_service_ids, [
- 'status' => \E_BASE_STATUS::Normal
- ]);
- Db::startTrans();
- try {
- $this->orderServiceModel->where("order_id", $order_id)->delete();
- $db_service = [];
- foreach ($services as $service) {
- $quantity = $option_services[$service['id']]['quantity'];
- $db_service[] = [
- "order_id" => $order_id,
- "store_id" => $order["store_id"],
- "service_id" => $service['id'],
- "service_name" => $service['name'],
- "cover_image" => $service['cover_image'],
- "amount" => $service["real_price"],
- "duration_minute" => $service["duration_minute"],
- "quantity" => $quantity,
- "status" => \E_BASE_STATUS::Normal,
- "createtime" => time(),
- "updatetime" => time(),
- ];
- }
- $total_service_amount = array_reduce($db_service, function ($p, $cur) {
- $p += ($cur["amount"] * $cur["quantity"]);
- return $p;
- }, 0);
- $this->orderServiceModel->insertAll($db_service);
- $this->updateOrderAmount($order, $order["open_membership"], $total_service_amount);
- Db::commit();
- } catch (Exception $e) {
- Db::rollback();
- return $this->fail($e->getMessage());
- }
- return $this->ok($this->model->order_detail($order->id));
- }
- /**
- * 绑定优惠券
- * @param $user_id
- * @param $order_id
- * @param $user_voucher_id
- * @return \SResult
- * @throws \think\db\exception\DataNotFoundException
- * @throws \think\db\exception\ModelNotFoundException
- * @throws \think\exception\DbException
- */
- public function bindVoucher($user_id, $order_id, $user_voucher_id)
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if ($order->user_id != $user_id)
- return $this->fail("非法修改!");
- if (\E_ORDER_STATUS::Default !== $order["status"])
- return $this->fail("订单当前状态不支持选择优惠券!");
- $voucher = $this->userVoucherModel->findById($user_voucher_id, ["user_id" => $user_id]);
- if (null === $voucher)
- return $this->fail("错误的优惠券");
- if ("normal" !== $voucher->status || time() > $voucher->expiretime || time() < $voucher->take_effect_time) {
- return $this->fail("该优惠券暂不可用!");
- }
- $order = $this->updateOrderAmount($order, $order["open_membership"]);
- if ($voucher->fullAmount > $order->total_amount) {
- return $this->fail("总金额不满足优惠券金额!");
- }
- if ($voucher->takeAmount >= $order->total_amount)
- return $this->fail("订单总金额小于优惠券立减金额");
- $this->updateOrderAmount($order, $order["open_membership"], null, null, $voucher->takeAmount);
- $this->model->update(["voucher_id" => $user_voucher_id], ["id" => $order->id]);
- return $this->ok($this->model->order_detail($order->id));
- }
- /**
- * 修改订单选项
- * @param $user_id
- * @param $order_id
- * @param $description
- * @param $trip_type
- * @param $service_start_date
- * @param $balance_deduction
- * @return \SResult
- * @throws \think\exception\DbException
- */
- public function modifyOrder($user_id, $order_id, $description = null, $trip_type = null, $service_start_date = null, $balance_deduction = null): \SResult
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if ($order->user_id != $user_id)
- return $this->fail("非法修改!");
- if (\E_ORDER_STATUS::Default !== $order["status"])
- return $this->fail("订单状态不支持修改!");
- $update = ["updatetime" => time()];
- if (null !== $description)
- $update["description"] = $description;
- if (null !== $trip_type) {
- $update["trip_type"] = $trip_type;
- }
- if (null !== $service_start_date) {
- $update["service_start_date"] = $service_start_date;
- }
- if (null !== $balance_deduction && $balance_deduction >= 0) {
- if ($balance_deduction >= $order["total_real_amount"])
- return $this->fail("余额抵扣金额错误!");
- $update["balance_deduction"] = $balance_deduction;
- }
- if (0 < count($update))
- $this->model->update($update, ["id" => $order->id]);
- if (null !== $trip_type || null !== $service_start_date)
- $this->calculateTripAmount($user_id, $order_id);
- return $this->ok($this->model->order_detail($order->id));
- }
- /**
- * @param $user_id
- * @param $order_id
- * @param $open_membership
- * @return \SResult
- * @throws \think\exception\DbException
- */
- public function updateOrderOpenMembership($user_id, $order_id, $open_membership): \SResult
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if ($order->user_id != $user_id)
- return $this->fail("非法修改!");
- $this->updateOrderAmount($order, $open_membership);
- return $this->ok($this->model->order_detail($order->id));
- }
- /**
- * 计算出行费用
- * @param $user_id
- * @param $order_id
- * @return \SResult
- * @throws \think\exception\DbException
- */
- public function calculateTripAmount($user_id, $order_id)
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if ($order->store_id > 0) {
- return $this->ok($this->model->order_detail($order->id));
- }
- if (null === $order->service_start_date)
- return $this->fail("请先选择服务时间!");
- $h = (int)date("H", strtotime($order->service_start_date));
- $massager = $this->massagerModel->getMassager($order->massager_id);
- if (!$massager)
- return $this->fail("助教不存在, 请选择其他助教为您服务!");
- if (!is_numeric($massager->lng) || !is_numeric($massager->lat))
- return $this->fail("助教未完善地址信息无法计算距离, 请选择其他助教为您服务!");
- $userArea = $this->userAreaModel->getArea($user_id, $order->user_area_id);
- if (null === $userArea)
- return $this->fail("绑定的地址不存在!");
- $trip_amount = 0;
- // 道路距离计算m
- $distanceRes = BDService::shortestPathsAlgorithm("$massager->lat,$massager->lng", "$userArea->lat,$userArea->lng");
- if (0 === $distanceRes->code()) {
- return $this->fail($distanceRes->msg());
- }
- // km
- $distance = ($distanceRes->data() / 1000);
- $is_free_travel = (
- $massager->free_travel === 1
- && (
- is_null($massager["free_travel_km"])
- ||
- (
- $massager["free_travel_km"] > 0
- && $distance <= $massager["free_travel_km"]
- )
- )
- )
- || $order["reorder"] == 1;
- if (!$is_free_travel) { // 计算出行费
- if ($distance > $massager["radius"]) {
- return $this->fail("该助教设置了服务距离不超过{$massager["radius"]}km,请重新找助教下单~");
- }
- $trip_taxi_km = config("site.trip_taxi_km") ?? 3; // 起步公里
- $residue_km = $distance > $trip_taxi_km ? ceil($distance - $trip_taxi_km) : 0;
- if (\E_TRIP_TYPE::Taxi === $order->trip_type) {
- $is_night = in_array($h, [0, 1, 2, 3, 4, 5, 21, 22, 23, 24]);
- if ($is_night) {
- $trip_flag_fall = config("site.trip_taxi_night_flag_fall");
- $trip_money_of_km = config("site.trip_taxi_night_money_of_km");
- } else {
- $trip_flag_fall = config("site.trip_taxi_daytime_flag_fall");
- $trip_money_of_km = config("site.trip_taxi_daytime_money_of_km");
- }
- } else {
- $trip_flag_fall = config("site.trip_bus_flag_fall");
- $trip_money_of_km = config("site.trip_bus_money_of_km");
- }
- $trip_amount = ($trip_flag_fall + (($residue_km) * $trip_money_of_km)) * ((int)config("site.trip_charge_rules")); //site.trip_charge_rules 1单程 2往返
- }
- $this->updateOrderAmount($order, $order["open_membership"], null, $trip_amount, null);
- $this->model->update(["massager_address" => $massager->address, "distance" => $distance], ["id" => $order->id]);
- return $this->ok($this->model->order_detail($order->id));
- }
- private function checkCanServiceWorkRange($massager_id, $order_id, $service_date)
- {
- $order_date_range = $this->model->fetchByJudgeMassagerWork($massager_id, $order_id);
- $now_time = time();
- $service_time = strtotime($service_date);
- if ($service_time <= $now_time)
- return false;
- foreach ($order_date_range as $range) {
- if (!is_null($range["service_start_date"]) && !is_null($range["service_start_date"])) {
- if (strtotime($range["service_start_date"]) <= $service_time && strtotime($range["service_end_date"]) >= $service_time)
- return false;
- }
- }
- return true;
- }
- /**
- * 支付
- * @param $user_id
- * @param $order_id
- * @param $payment_type
- * @param $platform
- * @param $description
- * @return \SResult
- * @throws \think\exception\DbException
- */
- public function payment($user_id, $order_id, $payment_type, $platform, $description = null): \SResult
- {
- $orderLock = new RedLock();
- $oLock = $orderLock->lock(Order::OKey($order_id));
- if (!is_array($oLock))
- return $this->fail("请稍后再试");
- try {
- $order = $this->model
- ->where("id", $order_id)
- ->with("services")
- ->find();
- if (!$order)
- return $this->fail("订单不存在!");
- if ($user_id != $order["user_id"])
- return $this->fail("您不是该笔订单的发起人");
- $user = $this->userModel->findById($user_id);
- if (!$user)
- return $this->fail("用户异常!");
- if (\E_ORDER_STATUS::Default !== $order["status"])
- return $this->fail("订单状态不支持支付!");
- if (null === $order->service_start_date)
- return $this->fail("请先选择服务时间!");
- if ($order["massager_id"] > 0) {
- $massager = $this->massagerModel->getMassager($order->massager_id);
- if (!$massager)
- return $this->fail("该助教一分钟前已被他人预约请重新选择时间段!");
- $is_can_option = $this->checkCanServiceWorkRange($massager->id, $order_id, $order->service_start_date);
- if (!$is_can_option)
- return $this->fail("助教服务时间冲突,请重新选择服务时间!");
- $userArea = $this->userAreaModel->getArea($user_id, $order->user_area_id);
- if (null === $userArea)
- return $this->fail("请输入服务地址!");
- if (!is_numeric($massager->lng) || !is_numeric($massager->lat))
- return $this->fail("助教未完善地址信息无法计算距离, 请选择其他助教为您服务!");
- if ((0 === $massager->free_travel && $order["reorder"] == 0) && 0 == $order->trip_amount)
- return $this->fail("出行费用错误, 请先更新出行费用!");
- }
- $openid = null;
- if ($platform == "app")
- $openid = $user["app_openid"];
- if ($platform == "web")
- $openid = $user["web_openid"];
- if ($platform == "applet")
- $openid = $user["applet_openid"];
- if ($payment_type === \E_ORDER_PAY_TYPE::Wechat) {
- if (is_null($openid) || mb_strlen($openid) === 0)
- return $this->fail("请先绑定微信再进行支付", 101);
- }
- $start_time = strtotime($order->service_start_date);
- $o_services = $order->getRelation("services");
- $t_minute = array_reduce($o_services, function ($p, $cur) {
- $p += ($cur->duration_minute * $cur->quantity);
- return $p;
- }, 0);
- // 余额抵扣
- if ($order["balance_deduction"] > 0 && $payment_type != \E_ORDER_PAY_TYPE::Balance) {
- if ($order["balance_deduction"] >= $order["total_real_amount"]) {
- return $this->fail("请使用余额支付!");
- }
- $userWalletModel = new Wallet();
- $wallet = $userWalletModel->getUserWallet($order->user_id);
- $after = fixed2Float($wallet["money"] - $order["balance_deduction"]);
- if ($after < 0) {
- return $this->fail("余额不足,无法抵扣!");
- }
- }
- $this->model->update([
- "parent_id" => $user["parent_id"],
- "pay_platform" => $platform,
- "service_end_date" => date("Y-m-d H:i:00", $start_time + ($t_minute * 60)),
- "description" => $description,
- "payment_type" => $payment_type
- ], ["id" => $order->id]);
- switch ($payment_type) {
- case \E_ORDER_PAY_TYPE::Wechat:
- $res = $this->thirdPayService->payWechat(
- $platform,
- $openid,
- $order["no"],
- fixed2Float($order["total_real_amount"] + $order["membership_amount"] - $order["balance_deduction"])
- );
- break;
- case \E_ORDER_PAY_TYPE::ALi:
- $res = $this->thirdPayService->payAli($order);
- break;
- default:
- $res = $this->walletService->payBalance($order);
- }
- (new CallbackService())->payOrderSuccess($order["no"]);
- return $res;
- } catch (Exception $e) {
- return $this->fail($e->getMessage());
- } finally {
- $orderLock->unlock($oLock);
- }
- }
- /**
- * 取消订单
- * @param $order_id
- * @param $reason
- * @param $platform
- * @return \SResult
- */
- public function cancel($order_id, $reason)
- {
- $orderLock = new RedLock();
- $oLock = $orderLock->lock(Order::OKey($order_id));
- if (!is_array($oLock))
- return $this->fail("请稍后再试");
- try {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if (\E_ORDER_STATUS::Purchase !== $order["status"])
- return $this->fail([
- \E_ORDER_STATUS::Default => "默认状态不支持取消订单",
- \E_ORDER_STATUS::Proceed => "助教已接单,不支持取消订单",
- \E_ORDER_STATUS::WaitFeedback => "助教已接单,不支持取消订单",
- \E_ORDER_STATUS::Finish => "已经完成的订单不支持取消",
- \E_ORDER_STATUS::Reject => "订单已被拒绝,无法取消订单",
- \E_ORDER_STATUS::Cancel => "订单已经取消请刷新页面",
- \E_ORDER_STATUS::AdminCancel => "平台已经取消订单,请刷新订单页面",
- \E_ORDER_STATUS::AutoCancel => "超时未接单取消订单,请刷新订单页面",
- ][$order["status"]]);
- $order_exceed_time_dont_refund = config("site.order_exceed_time_dont_refund") ?? 1000;
- if (($order["createtime"] + $order_exceed_time_dont_refund * 24 * 60 * 60) < time()) {
- return $this->fail("订单超过{$order_exceed_time_dont_refund}天不能发起退款!");
- }
- switch ($order["payment_type"]) {
- case \E_ORDER_PAY_TYPE::Wechat:
- $res = $this->thirdPayService->refundByWx(
- $order["pay_platform"],
- $order["no"],
- "用户取消订单退款",
- $order["total_real_amount"] + $order["membership_amount"] - $order["balance_deduction"],
- $order["status"] == \E_ORDER_STATUS::Purchase ? $order["total_real_amount"] - $order["balance_deduction"] : ($order["total_real_amount"] - $order["trip_amount"] - $order["balance_deduction"]));
- break;
- case \E_ORDER_PAY_TYPE::ALi:
- $res = $this->thirdPayService->refundByAli($order);
- break;
- default:
- $res = $this->walletService->refundByBalance($order, \E_ORDER_STATUS::Cancel);
- Message::sendSystemMessage(
- \E_IDENTITY_TYPE::User,
- ["to_user_id" => $order->user_id],
- "取消订单通知",
- "您的订单【{$order->no}】已取消,订单金额/优惠券将原路返回您的账户!"
- );
- }
- $this->model->update([
- "reason" => $reason,
- "refund_amount" => $order["status"] == \E_ORDER_STATUS::Purchase ? $order["total_real_amount"] : ($order["total_real_amount"] - $order["trip_amount"]),
- "is_refund_trip" => $order["status"] == \E_ORDER_STATUS::Purchase ? 1 : 0
- ], ["id" => $order["id"]]);
- return $res;
- } catch (Exception $e) {
- return $this->fail($e->getMessage());
- } finally {
- $orderLock->unlock($oLock);
- }
- }
- //评价订单
- public function comment($order_id, $params)
- {
- $orderLock = new RedLock();
- $oLock = $orderLock->lock(Order::OKey($order_id));
- if (!is_array($oLock))
- return $this->fail("请稍后再试");
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if (\E_ORDER_STATUS::WaitFeedback !== $order["status"])
- return $this->fail("服务未完成,等待助教完成服务!");
- $user = $this->userModel->get($order->user_id);
- if (is_null($user))
- return $this->fail("下单用户不存在");
- Db::startTrans();
- try {
- $this->massagerCommentModel->save([
- "user_id" => $order->user_id,
- "massager_id" => $order->massager_id > 0 ? $order->massager_id : null,
- "store_id" => $order->store_id > 0 ? $order->store_id : null,
- "is_anonymity" => $params["is_anonymity"] ?? 1,
- "tags" => $params["tags"] ?? null,
- "star" => $params["star"] ?? 5,
- "content" => $params["content"],
- "status" => \E_BASE_STATUS::Normal,
- "order_id" => $order->id,
- "negative" => $params["negative"],
- "city_code" => $order->city_code,
- "createtime" => time(),
- "updatetime" => time()
- ]);
- if ($order["massager_id"] > 0) {
- if ($params["negative"] == 1) {
- $this->massagerModel->where("id", $order["massager_id"])->setInc("negative_count");
- $agency = (new Admin())->findAgency($order["city_code"]);
- if ($agency) {
- Message::sendSystemMessage(\E_IDENTITY_TYPE::Agency, [
- "to_agency_id" => $agency["id"]
- ], '投诉提醒', "订单: {$order["no"]} 已被用户投诉,请及时处理!");
- }
- }
- $total_count = $this->massagerCommentModel->where([
- 'massager_id' => $order->massager_id,
- 'status' => \E_BASE_STATUS::Normal
- ])->count();
- $total_count += 1;
- $gte_3_count = $this->massagerCommentModel
- ->where([
- 'massager_id' => $order->massager_id,
- "status" => \E_BASE_STATUS::Normal
- ])
- ->where("star", ">=", 3)
- ->count();
- if ($params['star'] >= 3)
- $gte_3_count += 1;
- $praise_rate = 100;
- if ($total_count > 0 && $gte_3_count > 0)
- $praise_rate = fixed2Float((($gte_3_count / $total_count)) * 100);
- $this->massagerModel
- ->where('id', $order->massager_id)
- ->inc("order_count")
- ->inc("comment_count")
- ->update(['praise_rate' => $praise_rate]);
- }
- $this->orderServiceModel->update([
- "finish" => 1
- ], ["order_id" => $order->id]);
- // $res = (new ProfitService())->profit($order, $user, false);
- // if (!$res->code())
- // throw new Exception($res->msg());
- $this->model->update([
- "parent_id" => $user["parent_id"],
- "status" => \E_ORDER_STATUS::Finish,
- "updatetime" => time()
- ], ["id" => $order_id]);
- GrantVoucher::grant_voucher("buy", $order["user_id"]);
- // $this->userModel->update(['is_use_award' => 1], ["id" => $order["user_id"]]);
- $chat_session = \db("fastchat_session")->where("
- (user_id = '{$order["user_id"]}||user' AND session_type = 6 and session_user_id = {$order['massager_id']})
- OR (user_id = '{$order['massager_id']}||massager' AND session_type = 0 and session_user_id = {$order['user_id']})
- ")->find();
- if ($chat_session) {
- \db("fastchat_record")->where("session_id", $chat_session["id"])->update(["is_del" => 1]);
- }
- Db::commit();
- return $this->ok(true);
- } catch (Exception $e) {
- Db::rollback();
- return $this->fail($e->getMessage());
- } finally {
- (new MassagerService())->updateInteriorScore($order["massager_id"], date("Y"), date("m"));
- $orderLock->unlock($oLock);
- }
- }
- public function appeal($user_id, $order_id, $appeal_reason)
- {
- $order = $this->model->get($order_id);
- if (!$order)
- return $this->fail("订单不存在!");
- if ($user_id != $order["user_id"])
- return $this->fail("订单创建人不是本人,无法申诉");
- if (!in_array($order["status"], [\E_ORDER_STATUS::Proceed, \E_ORDER_STATUS::WaitFeedback]))
- return $this->fail("订单状态为进行中或者等待评价才能申诉订单!");
- if (1 == $order["is_appeal"])
- return $this->fail("订单正在申述中,请等待后台管理员处理~");
- $this->model->update([
- "is_appeal" => 1,
- "appeal_reason" => $appeal_reason
- ], ["id" => $order_id]);
- return $this->ok(true);
- }
- }
|