feat(command): new command

增加 sms:notusedorder 命令行,给待使用订单发送提醒短信
This commit is contained in:
liuyuhang 2024-07-10 17:16:48 +08:00
parent 74343c59ac
commit 224c437e7f
8 changed files with 275 additions and 0 deletions

View File

@ -0,0 +1,78 @@
<?php
namespace app\command;
use app\common\Error;
use app\model\Orders as OrdersModel;
use app\server\Orders;
use support\Redis;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Output\OutputInterface;
class NotUsedOrderSms extends Command
{
protected static $defaultName = 'sms:notusedorder';
protected static $defaultDescription = '给带使用订单发送短信。';
/**
* @return void
*/
protected function configure()
{
// $this->addArgument('name', InputArgument::OPTIONAL, 'Name description');
}
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->output($output, self::$defaultName . " started");
$orders = $this->orders();
$total = count($orders);
$this->output($output, "got {$total} orders");
if (1 > $total) {
return self::SUCCESS;
}
foreach($orders as $order) {
if (empty($order->mobile)) {
continue;
}
$result = Orders::reminderOrders($order);
$text = '已发送提醒。';
if (Error::is($result)) {
$text = '发送短信失败,' . $result['message'] ?? '';
}
$this->output($output, "单号 {$order->sn} {$text}");
}
return self::SUCCESS;
}
private function output(OutputInterface $output, string $message)
{
$output->writeln(sprintf('{"time":"%s", "message":"%s"}', date('Y-m-d H:i:s'), $message));
}
/**
* @return OrdersModel[]
*/
private function orders(): array
{
$list = OrdersModel::where('admin_id', '>', 0)->whereRaw(OrdersModel::AllOssStatusSql[1])->select()->all();
return $list;
}
}

View File

@ -10,6 +10,7 @@ use app\model\Orders;
use app\server\Douyin; use app\server\Douyin;
use app\server\Meituan; use app\server\Meituan;
use app\server\Kuaishou; use app\server\Kuaishou;
use app\server\Orders as ServerOrders;
use app\server\SMS; use app\server\SMS;
use stdClass; use stdClass;
use support\Log; use support\Log;
@ -338,9 +339,13 @@ class SpiderDy extends Command
break; break;
} }
// 待使用订单提醒
$reminder_orders = [];
foreach ($list as $order) { foreach ($list as $order) {
$item = Orders::where('os', $order->os)->where('sn', $order->sn)->find(); $item = Orders::where('os', $order->os)->where('sn', $order->sn)->find();
if (empty($item)) { if (empty($item)) {
$order->is_zhibo = $this->zhibo($order->product_name, $order->os); $order->is_zhibo = $this->zhibo($order->product_name, $order->os);
@ -362,6 +367,9 @@ class SpiderDy extends Command
($order->os == 2 && array_key_exists($order->order_status, [2 => 2, 3 => 3, 4 => 4])) || ($order->os == 2 && array_key_exists($order->order_status, [2 => 2, 3 => 3, 4 => 4])) ||
($order->os == 3 && $order->order_status == 1)) { ($order->os == 3 && $order->order_status == 1)) {
// $this->sms($admin_id, $order); // $this->sms($admin_id, $order);
// 待使用订单提醒
$reminder_orders[] = $order;
} }
//新获得一个用户的,提示管理员有新的订单 //新获得一个用户的,提示管理员有新的订单
Redis::incrBy('CRM:USER:ONLINE:NEW:' . $admin_id, 1); Redis::incrBy('CRM:USER:ONLINE:NEW:' . $admin_id, 1);
@ -380,7 +388,10 @@ class SpiderDy extends Command
if ($back) { if ($back) {
$this->_finance(0, $item->id, $item->asset_price); $this->_finance(0, $item->id, $item->asset_price);
} }
}
if (!empty($reminder_orders)) {
ServerOrders::reminderOrders(...$reminder_orders);
} }
$page++; $page++;

View File

@ -10,6 +10,7 @@ use app\model\Orders;
use app\server\Douyin; use app\server\Douyin;
use app\server\Meituan; use app\server\Meituan;
use app\server\Kuaishou; use app\server\Kuaishou;
use app\server\Orders as ServerOrders;
use app\server\SMS; use app\server\SMS;
use stdClass; use stdClass;
use support\Log; use support\Log;
@ -373,6 +374,9 @@ class SpiderMt extends Command
break; break;
} }
// 待使用订单提醒
$reminder_orders = [];
foreach ($list as $order) { foreach ($list as $order) {
$item = Orders::where('os', $order->os)->where('sn', $order->sn)->find(); $item = Orders::where('os', $order->os)->where('sn', $order->sn)->find();
@ -397,6 +401,9 @@ class SpiderMt extends Command
($order->os == 2 && array_key_exists($order->order_status, [2 => 2, 3 => 3, 4 => 4])) || ($order->os == 2 && array_key_exists($order->order_status, [2 => 2, 3 => 3, 4 => 4])) ||
($order->os == 3 && $order->order_status == 1)) { ($order->os == 3 && $order->order_status == 1)) {
$this->sms($admin_id, $order); $this->sms($admin_id, $order);
// 待使用订单提醒
$reminder_orders[] = $order;
} }
//新获得一个用户的,提示管理员有新的订单 //新获得一个用户的,提示管理员有新的订单
Redis::incrBy('CRM:USER:ONLINE:NEW:' . $admin_id, 1); Redis::incrBy('CRM:USER:ONLINE:NEW:' . $admin_id, 1);
@ -415,7 +422,10 @@ class SpiderMt extends Command
if ($back) { if ($back) {
$this->_finance(0, $item->id, $item->asset_price); $this->_finance(0, $item->id, $item->asset_price);
} }
}
if (!empty($reminder_orders)) {
ServerOrders::reminderOrders(...$reminder_orders);
} }
$page++; $page++;

View File

@ -0,0 +1,28 @@
<?php
namespace app\common;
class Error {
const ERR_UNDEFINED = ['code' => -9999, 'message' => ''];
const ERR_SMS_BLACKS = ['code' => 100001, 'message' => 'mobile is in blacks'];
const ERR_SMS_SEND_FAIL = ['code' => 100002, 'message' => 'send error'];
public static function undefined(string $message)
{
return ['code' => self::ERR_UNDEFINED, 'message' => $message];
}
public static function setMessage(string $message, array $err)
{
return ['code' => $err['code'] ?? 0, 'message' => $message];
}
public static function is(array $err): bool
{
return isset($err['code']) && $err['code'] != 0;
}
public static function compare(array $err, array $needle): bool
{
return isset($err['code']) && isset($needle['code']) && $err['code'] === $needle['code'];
}
}

View File

@ -0,0 +1,45 @@
<?php
namespace app\common;
use support\Log;
use ReflectionClass;
/**
* @method static string SUPPORT_BLACKS()
*/
class Keys {
const SUPPORT_BLACKS = "SUPPORT:BLACKS";
//
// ------------------------------------------------------------------------------
// 请 在 上 方 设 置 Redis Key
// ------------------------------------------------------------------------------
private static $instance = null;
/**
* 简单的使用魔术函数sprintf() 输出
* @param $name
* @param $arguments
* @return string
*/
public static function __callStatic($name, $arguments)
{
if (is_null(self::$instance)) {
try {
self::$instance = (new ReflectionClass(__CLASS__))->getConstants();
} catch (\ReflectionException $e) {
Log::error(__METHOD__, [$e->getMessage(),$e->getCode()]);
}
}
if (isset(self::$instance[$name])) {
$format = self::$instance[$name];
} else {
$format = '';
}
return vsprintf($format, $arguments);
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace app\server;
use app\common\Keys;
use support\Redis;
use think\facade\Db;
class Blacks {
public static function CExists(string $mobile, bool $refresh = false): bool
{
$key = Keys::SUPPORT_BLACKS();
if ($refresh || !Redis::exists($key)) {
$list = Db::table('blacks')->column('id', 'mobile');
if (!empty($list)) {
$chunks = array_chunk($list, 50, true);
foreach($chunks as $mobiles) {
Redis::hMSet($key, $mobiles);
}
Redis::expire($key, 3600);
}
}
return Redis::hExists($key, $mobile);
}
}

View File

@ -0,0 +1,71 @@
<?php
namespace app\server;
use app\common\Error;
use app\model\Admins as AdminsModel;
use app\model\Orders as OrdersModel;
use support\Log;
use support\Redis;
class Orders {
/**
* @params []OrdersModel $order
* @return array
*/
public static function reminderOrders(OrdersModel ...$orders)
{
$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 = [];
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;
}
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] = [];
}
return count($orders) > 1 ? $result : reset($result);
}
}

View File

@ -2,6 +2,8 @@
namespace app\server; namespace app\server;
class SMS { class SMS {
const JUHE_TMP_REMINDER_ORDER = 263585;
static function juhe_sms_send($mobile, $tempid, $vars) static function juhe_sms_send($mobile, $tempid, $vars)
{ {
foreach($vars as &$v) { foreach($vars as &$v) {