2024-07-10 17:16:48 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace app\server;
|
|
|
|
|
|
|
|
use app\common\Error;
|
2024-10-12 19:16:04 +08:00
|
|
|
use app\model\Admins;
|
2024-07-10 17:16:48 +08:00
|
|
|
use app\model\Admins as AdminsModel;
|
2024-10-12 19:16:04 +08:00
|
|
|
use app\model\Blacks;
|
2024-09-01 13:38:02 +08:00
|
|
|
use app\model\FilterMobiles;
|
2024-07-11 15:38:18 +08:00
|
|
|
use app\model\Finances as FinancesModel;
|
2024-09-20 10:39:29 +08:00
|
|
|
use app\model\LiveRoomWorks;
|
2024-07-10 17:16:48 +08:00
|
|
|
use app\model\Orders as OrdersModel;
|
2024-10-12 19:16:04 +08:00
|
|
|
use app\model\Products;
|
2024-07-10 17:16:48 +08:00
|
|
|
use support\Log;
|
|
|
|
use support\Redis;
|
|
|
|
|
|
|
|
class Orders {
|
2024-10-12 19:16:04 +08:00
|
|
|
protected static $redisPool = [];
|
2024-08-11 17:37:32 +08:00
|
|
|
public static function isDaishiyong(OrdersModel $order): bool
|
2024-07-11 15:38:18 +08:00
|
|
|
{
|
|
|
|
// 根据 OrdersModel::AllOssStatusSql[1] 进行判断
|
|
|
|
// ((os=1 and order_status=3) or (os=2 and order_status=4) or (os=3 and order_status=1))
|
2024-09-12 22:46:16 +08:00
|
|
|
return (in_array($order->os, [1, 7]) && $order->order_status == 3)
|
2024-08-14 15:07:12 +08:00
|
|
|
|| ($order->os == 2 && $order->order_status == 4)
|
2024-09-19 10:06:53 +08:00
|
|
|
|| (in_array($order->os, [3, 5]) && in_array($order->order_status, [1, 5]))
|
2024-12-25 21:52:15 +08:00
|
|
|
|| (in_array($order->os, [6, 8]) && in_array($order->order_status, [200, 205, 210, 300, 310]));
|
2024-07-11 15:38:18 +08:00
|
|
|
}
|
|
|
|
|
2024-07-10 17:16:48 +08:00
|
|
|
/**
|
|
|
|
* @params []OrdersModel $order
|
|
|
|
* @return array
|
|
|
|
*/
|
2024-08-11 17:37:32 +08:00
|
|
|
public static function reminderOrders(OrdersModel ...$orders)
|
2024-07-10 17:16:48 +08:00
|
|
|
{
|
|
|
|
$admin_ids = [];
|
|
|
|
$sns = [];
|
|
|
|
|
|
|
|
foreach ($orders as $order) {
|
|
|
|
$admin_ids[] = $order->admin_id;
|
|
|
|
$sns[] = $order->sn;
|
|
|
|
}
|
|
|
|
|
|
|
|
$admins = AdminsModel::whereIn('id', $admin_ids)->select()->column('mobile', 'id');
|
|
|
|
|
|
|
|
if (empty($admins)) {
|
|
|
|
return array_fill_keys($sns, Error::undefined('admin check error'));
|
|
|
|
}
|
|
|
|
|
|
|
|
$ttl = 86400;
|
|
|
|
$result = [];
|
|
|
|
|
2024-08-11 17:37:32 +08:00
|
|
|
$admins = array_column($admins, null, 'id');
|
2024-07-10 17:16:48 +08:00
|
|
|
foreach($orders as $order) {
|
|
|
|
$admin_mobile = $admins[$order->admin_id] ?? '';
|
|
|
|
|
|
|
|
if (empty($order->mobile) || empty($admin_mobile)) {
|
|
|
|
$result[$order->sn] = Error::undefined('client mobile or admin mobile invalid');
|
|
|
|
continue;
|
|
|
|
}
|
2024-09-01 13:38:02 +08:00
|
|
|
if (FilterMobiles::isFilterMobile($order->mobile)) {
|
|
|
|
$result[$order->sn] = Error::undefined('刷单账单');
|
|
|
|
continue;
|
|
|
|
}
|
2024-08-11 17:37:32 +08:00
|
|
|
$admin_mobile = $admin_mobile['mobile'] ?? '';
|
2024-07-10 17:16:48 +08:00
|
|
|
|
|
|
|
if (Blacks::CExists($order->mobile)) {
|
|
|
|
$result[$order->sn] = Error::ERR_SMS_BLACKS;
|
|
|
|
Log::info(__METHOD__ . " blacks", [$order->mobile, $order->sn]);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$key = sprintf("CRM:%s:%s_%s", 'reminderOrders', $order->sn, $order->mobile);
|
|
|
|
$ok = Redis::set($key, time(), 'EX', $ttl, 'NX');
|
|
|
|
|
|
|
|
if (!$ok) {
|
|
|
|
$result[$order->sn] = Error::undefined('reminder cooldown');
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$res = SMS::juhe_sms_send($order->mobile, SMS::JUHE_TMP_REMINDER_ORDER, ['title' => $order->product_name, 'mobile' => $admin_mobile]);
|
|
|
|
$err_code = $res['error_code'] ?? 0;
|
|
|
|
|
|
|
|
if ($err_code != 0) {
|
|
|
|
Log::error(__METHOD__ . " send error", [$res, $order->mobile, $order->sn]);
|
|
|
|
$result[$order->sn] = Error::ERR_SMS_SEND_FAIL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$result[$order->sn] = [];
|
|
|
|
}
|
2024-08-11 17:37:32 +08:00
|
|
|
|
2024-07-10 17:16:48 +08:00
|
|
|
return count($orders) > 1 ? $result : reset($result);
|
|
|
|
}
|
2024-07-11 15:38:18 +08:00
|
|
|
|
|
|
|
public static function syncFromThird(OrdersModel $order)
|
|
|
|
{
|
2024-12-20 16:43:01 +08:00
|
|
|
$redisKey = 'sync_order:' . $order->sn;
|
|
|
|
if (Redis::exists($redisKey)) {
|
|
|
|
return 1;
|
|
|
|
}
|
2024-07-11 15:38:18 +08:00
|
|
|
$got = null;
|
2024-08-11 17:37:32 +08:00
|
|
|
|
2024-07-11 15:38:18 +08:00
|
|
|
switch ($order->os) {
|
|
|
|
case 1:
|
2024-09-04 21:03:05 +08:00
|
|
|
case 7:
|
|
|
|
$mt = new Meituan($order->os);
|
2024-07-11 15:38:18 +08:00
|
|
|
$it = $mt->get(1, null, null, $order->sn);
|
|
|
|
|
|
|
|
if ($it) {
|
|
|
|
$got = $it[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
case 3:
|
2024-08-16 21:12:33 +08:00
|
|
|
case 5:
|
|
|
|
$dy = new Douyin($order->os);
|
2024-08-20 23:45:58 +08:00
|
|
|
$it = $dy->get(1, null, null, $order->sn);
|
2024-07-11 15:38:18 +08:00
|
|
|
if ($it) {
|
|
|
|
$got = $it[0];
|
2024-08-08 09:56:28 +08:00
|
|
|
|
|
|
|
// 查询未预约状态
|
2024-09-02 17:41:24 +08:00
|
|
|
if ($order->appointment_status == 0) {
|
2024-08-08 09:56:28 +08:00
|
|
|
$appointment_status = $dy->_orderMakeAppointmentStatus($order->sn);
|
|
|
|
if ($appointment_status !== null) {
|
|
|
|
$got['appointment_status'] = 1;
|
|
|
|
}
|
|
|
|
}
|
2024-07-11 15:38:18 +08:00
|
|
|
}
|
|
|
|
|
2024-09-19 10:06:53 +08:00
|
|
|
break;
|
|
|
|
case 6:
|
2024-12-24 10:53:59 +08:00
|
|
|
case 8:
|
2024-09-19 10:06:53 +08:00
|
|
|
$tc = new Tongcheng($order->os);
|
|
|
|
$it = $tc->get(1, null, null, $order->sn);
|
|
|
|
|
|
|
|
if ($it) {
|
|
|
|
$got = $it[0];
|
|
|
|
}
|
2024-07-11 15:38:18 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_null($got)) {
|
|
|
|
Log::info(__METHOD__ . ": get from os is null", [$order]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$back = $order->save($got);
|
|
|
|
|
|
|
|
if ($back) {
|
|
|
|
self::finance(0, $order->id, $order->asset_price);
|
|
|
|
}
|
2024-12-20 16:43:01 +08:00
|
|
|
Redis::setEx($redisKey, 600, 1);
|
2024-07-11 15:38:18 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function finance($type = 1, $order_id = 0, $price = 0)
|
|
|
|
{
|
|
|
|
//总的关于这个订单的金额
|
2024-08-11 17:37:32 +08:00
|
|
|
$total = FinancesModel::where('order_id', $order_id)->sum('total');
|
2024-07-11 15:38:18 +08:00
|
|
|
//如果总金额大于提交上来的核销金额,那就是退费的
|
|
|
|
//如果提交上来的金额小于总金额,那就是核销的
|
|
|
|
|
|
|
|
if ($total > $price) {
|
|
|
|
$type = 2;
|
|
|
|
$fee = -($total - $price);
|
|
|
|
} elseif ($total < $price) {
|
|
|
|
$type = 1;
|
|
|
|
$fee = $price - $total;
|
|
|
|
} else {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
FinancesModel::create([
|
|
|
|
'order_id' => $order_id,
|
|
|
|
'type' => $type,
|
|
|
|
'total' => $fee,
|
|
|
|
'status' => 1
|
|
|
|
]);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2024-08-02 10:14:31 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 同步第三方返回
|
|
|
|
* @param OrdersModel $order
|
|
|
|
* @return mixed
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\DbException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
*/
|
|
|
|
public static function syncFromThirdV2(OrdersModel $order)
|
|
|
|
{
|
|
|
|
$got = null;
|
|
|
|
switch ($order->os) {
|
|
|
|
case 1:
|
2024-09-04 21:03:05 +08:00
|
|
|
case 7:
|
|
|
|
$mt = new Meituan($order->os);
|
2024-08-02 10:14:31 +08:00
|
|
|
$it = $mt->get(1, null, null, $order->sn);
|
|
|
|
|
|
|
|
if ($it) {
|
|
|
|
$got = $it[0];
|
|
|
|
}
|
|
|
|
|
2024-08-16 22:16:23 +08:00
|
|
|
break;
|
|
|
|
case 3:
|
2024-08-16 22:20:54 +08:00
|
|
|
case 5:
|
2024-08-16 22:16:23 +08:00
|
|
|
$dy = new Douyin($order->os);
|
2024-08-16 22:20:54 +08:00
|
|
|
$it = $dy->get(1, null, null, $order->sn);
|
2024-08-02 10:14:31 +08:00
|
|
|
if ($it) {
|
|
|
|
$got = $it[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_null($got)) {
|
|
|
|
Log::info(__METHOD__ . ": get from os is null", [$order]);
|
|
|
|
return $order;
|
|
|
|
}
|
|
|
|
|
|
|
|
$back = $order->save($got);
|
|
|
|
|
|
|
|
if ($back) {
|
|
|
|
self::finance(0, $order->id, $order->asset_price);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $order;
|
|
|
|
}
|
2024-09-20 10:39:29 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param int $orderCreateTime
|
|
|
|
* @param $productId
|
|
|
|
* @return array|mixed|\think\Model
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\DbException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
*/
|
|
|
|
public static function getLiveRoomWork(int $orderCreateTime, $productId) {
|
|
|
|
$orderCreateDate = date('Y-m-d H:i:s', $orderCreateTime/1000);
|
|
|
|
$roomWork = LiveRoomWorks::join('live_room', 'live_room_works.live_room_id=live_room.id')
|
|
|
|
->where('live_room_works.start', '<', $orderCreateDate)
|
|
|
|
->where('live_room_works.end', '>', $orderCreateDate)
|
|
|
|
->whereRaw(sprintf('find_in_set(%s, live_room.`product_ids`)', $productId))
|
|
|
|
->field(['live_room_works.id'])
|
|
|
|
->find();
|
|
|
|
|
|
|
|
return $roomWork;
|
|
|
|
}
|
2024-10-12 19:16:04 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 分配用户
|
|
|
|
* @param int $status
|
|
|
|
* @param string $categoryDesc
|
|
|
|
* @return int|string
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
public static function poolUser($status, $thirdProductId) {
|
2024-10-14 11:42:51 +08:00
|
|
|
$status .= $thirdProductId;
|
2024-10-12 19:16:04 +08:00
|
|
|
if (empty(self::$redisPool[$status])) {
|
|
|
|
self::$redisPool[$status] = Redis::hGetAll('CRM:Pool:' . $status);
|
|
|
|
$users = self::users($thirdProductId);
|
2024-10-15 09:12:25 +08:00
|
|
|
shuffle($users);
|
2024-10-12 19:16:04 +08:00
|
|
|
$_users = [];
|
|
|
|
if (empty(self::$redisPool[$status])) {
|
|
|
|
foreach ($users as $user) {
|
|
|
|
$_users[$user->username] = 0;
|
|
|
|
Redis::hSet('CRM:Pool:' . $status, $user->username, 0);
|
|
|
|
}
|
|
|
|
self::$redisPool[$status] = $_users;
|
|
|
|
} else {
|
|
|
|
asort(self::$redisPool[$status]);
|
|
|
|
$key_users = array_keys(self::$redisPool[$status]);
|
|
|
|
$username = $key_users[0];
|
|
|
|
$max = self::$redisPool[$status][$username];
|
|
|
|
$_users = [];
|
|
|
|
foreach ($users as $user) {
|
|
|
|
$_users[] = $user->username;
|
|
|
|
if (!in_array($user->username, $key_users)) {
|
|
|
|
self::$redisPool[$status][$username] = $max;
|
|
|
|
Redis::hSet('CRM:Pool:' . $status, $user->username, $max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
foreach (self::$redisPool[$status] as $username => $val) {
|
|
|
|
if (!in_array($username, $_users)) {
|
|
|
|
unset(self::$redisPool[$status][$username]);
|
|
|
|
Redis::hDel('CRM:Pool:' . $status, $username);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$username = null;
|
|
|
|
try {
|
|
|
|
$pool = self::$redisPool[$status];
|
|
|
|
if (empty($pool)) $pool = [];
|
|
|
|
asort($pool);
|
|
|
|
$keys = array_keys($pool);
|
|
|
|
if (empty($keys)) {
|
|
|
|
throw new \Exception('没有可以分配的用户');
|
|
|
|
}
|
|
|
|
$username = $keys[0];
|
|
|
|
self::$redisPool[$status][$username] += 1;
|
|
|
|
Redis::hIncrBy('CRM:Pool:' . $status, $username, 1);
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
Log::error(dirname(__FILE__) . __LINE__ . '没有可以分配的用户', func_get_args());
|
|
|
|
throw new \Exception('没有可以分配的用户');
|
|
|
|
}
|
|
|
|
return $username;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param $thirdProductId
|
|
|
|
* @return array
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\DbException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
*/
|
|
|
|
protected static function users($thirdProductId) {
|
|
|
|
$product = Products::query()->where('third_product_id', $thirdProductId)->find();
|
|
|
|
if (empty($product)) {
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
$users = Admins::where('status', 1)->where('is_order', 1)->whereFindInSet('product_ids', $product->id)->select();
|
|
|
|
$us = [];
|
|
|
|
foreach ($users as $u) {
|
|
|
|
$ru = Redis::get('CRM:USER:ONLINE:' . $u->id);
|
|
|
|
if (empty($ru)) continue;
|
|
|
|
|
|
|
|
$_u = new \stdClass();
|
|
|
|
$_u->username = $u->id;
|
|
|
|
$us[] = $_u;
|
|
|
|
};
|
|
|
|
|
|
|
|
return $us;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 发送订单短信
|
|
|
|
* @param $admin_id
|
|
|
|
* @param $order
|
|
|
|
* @throws \think\db\exception\DataNotFoundException
|
|
|
|
* @throws \think\db\exception\DbException
|
|
|
|
* @throws \think\db\exception\ModelNotFoundException
|
|
|
|
*/
|
|
|
|
public static function sendOrderSms($admin_id, $order)
|
|
|
|
{
|
|
|
|
$user = Admins::cache(true)->where('id', $admin_id)->find();
|
|
|
|
if ((!config('app.debug', true) || config('app.debug', true) === 'false') && (time() * 1000 - $order->create_at) / 1000 < 2 * 24 * 3600) {
|
|
|
|
$has = Blacks::where('mobile', $order->mobile)->find();
|
|
|
|
if (empty($has) && !empty($order->mobile)) {
|
2024-10-22 17:42:17 +08:00
|
|
|
if (env('SMS_JUMP_URL')) {
|
|
|
|
SMS::juhe_sms_send($order->mobile, 265867, ['title' => $order->product_name, 'mobile' => $user->mobile, 'url' => env('SMS_JUMP_URL')]);
|
|
|
|
} else {
|
|
|
|
SMS::juhe_sms_send($order->mobile, 261607, ['title' => $order->product_name, 'mobile' => $user->mobile]);
|
|
|
|
}
|
2024-10-12 19:16:04 +08:00
|
|
|
} else {
|
|
|
|
sleep(10);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Log::info('订单未发送短息:' . json_encode([$order->mobile, 261607, ['title' => $order->product_name, 'mobile' => $user->mobile]]));
|
|
|
|
}
|
|
|
|
}
|
2024-07-10 17:16:48 +08:00
|
|
|
}
|