This commit is contained in:
Your Name
2026-04-07 18:13:03 +08:00
parent a780356908
commit fdf714f833
397 changed files with 15086 additions and 1043 deletions
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace app\common\command;
use think\console\Input;
use think\console\Output;
/**
* 定时:补全订单 creator_id(逻辑在 SyncWechatWorkBills::fillOrderCreatorsFromPayee
*/
class FillOrderCreatorFromPayee extends SyncWechatWorkBills
{
protected function configure()
{
$this->setName('fill_order_creator_from_payee')
->setDescription('补全订单创建人:creator_id 为空时按 payee_userid 匹配 zyt_admin.work_wechat_userid');
}
protected function execute(Input $input, Output $output)
{
$fixed = $this->fillOrderCreatorsFromPayee();
$output->writeln("补全创建人完成,共更新 {$fixed} 条订单");
}
}
@@ -5,9 +5,10 @@ declare(strict_types=1);
namespace app\common\command;
use app\adminapi\logic\order\OrderLogic;
use app\common\model\auth\Admin;
use app\common\model\Order;
use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\input\Option;
use think\console\Output;
use think\facade\Log;
@@ -23,11 +24,24 @@ class SyncWechatWorkBills extends Command
$this->setName('sync_wechat_work_bills')
->setDescription('同步企业微信对外收款到订单(按天拉取)')
->addOption('date', 'd', Option::VALUE_OPTIONAL, '指定日期 Y-m-d,默认今天', '')
->addOption('days', null, Option::VALUE_OPTIONAL, '拉取最近N天,每天单独请求', '1');
->addOption('days', null, Option::VALUE_OPTIONAL, '拉取最近N天,每天单独请求', '1')
->addOption(
'fill-order-creators-only',
null,
Option::VALUE_NONE,
'仅补全订单创建人:creator_id 为空时用 payee_userid 匹配 admin.work_wechat_userid(可单独做定时任务)'
);
}
protected function execute(Input $input, Output $output)
{
if ($input->getOption('fill-order-creators-only')) {
$fixed = $this->fillOrderCreatorsFromPayee();
$output->writeln("补全创建人完成,共更新 {$fixed} 条订单");
return;
}
$dateStr = $input->getOption('date');
$days = (int)$input->getOption('days');
$days = $days > 0 ? min($days, 31) : 1;
@@ -68,4 +82,32 @@ class SyncWechatWorkBills extends Command
}
}
}
/**
* creator_id 为空的订单,用 payee_userid 匹配管理员 work_wechat_userid 写入 creator_id
*/
protected function fillOrderCreatorsFromPayee(): int
{
$fixed = 0;
Order::whereRaw('(creator_id IS NULL OR creator_id = 0)')
->whereNotNull('payee_userid')
->where('payee_userid', '<>', '')
->chunk(200, function ($orders) use (&$fixed) {
foreach ($orders as $order) {
$payee = trim((string) $order->getAttr('payee_userid'));
if ($payee === '') {
continue;
}
$admin = Admin::where('work_wechat_userid', $payee)->whereNull('delete_time')->find();
if (!$admin) {
continue;
}
$order->creator_id = (int) $admin->getAttr('id');
$order->save();
$fixed++;
}
});
return $fixed;
}
}
@@ -14,16 +14,16 @@ use think\facade\Log;
/**
* 挂号单状态自动更新
* - 预约时间已过超过 35 分钟(且未满 8 小时):status -> 4(已过号)
* - 预约时间已过超过 8 小时status -> 2(已取消)
* - 不处理:status=3(已完成)、未到时间、刚过号未满 35 分钟的单子
* - 已预约(status=1) 且预约时间已过超过 35 分钟status=4(已过号)
* - 已过号(status=4) 且预约时间已过超过 8 小时status=2(已取消)
* - 不处理:status=3(已完成)、未到预约时间、距预约未满 35 分钟的单子
*/
class UpdateAppointmentStatus extends Command
{
protected function configure()
{
$this->setName('update_appointment_status')
->setDescription('自动更新挂号单状态:过号35分钟->4,超8小时->2已取消')
->setDescription('挂号单:已预约过号35分钟→已过号;已过号超8小时→已取消')
->addOption('dry', null, Option::VALUE_NONE, '仅预览不执行');
}
@@ -33,26 +33,30 @@ class UpdateAppointmentStatus extends Command
$now = time();
$table = (new Appointment())->getTable();
// 1. 超过8小时 -> 已取消(status=2)
$cancelWhere = "status = 1 AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) <= DATE_SUB(NOW(), INTERVAL 8 HOUR)";
$cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}";
$cancelCount = $dryRun ? 0 : Db::execute($cancelSql, [$now]);
$dtExpr = "CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00'))";
// 2. 已过预约时间超过 35 分钟且未满 8 小时 -> 已过号(status=4)
$missedWhere = "status = 1 AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) < DATE_SUB(NOW(), INTERVAL 35 MINUTE) AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) > DATE_SUB(NOW(), INTERVAL 8 HOUR)";
// 1. 已预约 → 已过号:预约时间早于「当前 − 35 分钟」
$missedWhere = "status = 1 AND {$dtExpr} < DATE_SUB(NOW(), INTERVAL 35 MINUTE)";
$missedSql = "UPDATE {$table} SET status = 4, update_time = ? WHERE {$missedWhere}";
$missedCount = $dryRun ? 0 : Db::execute($missedSql, [$now]);
// 2. 已过号 → 已取消:预约时间早于或等于「当前 − 8 小时」
$cancelWhere = "status = 4 AND {$dtExpr} <= DATE_SUB(NOW(), INTERVAL 8 HOUR)";
$cancelSql = "UPDATE {$table} SET status = 2, update_time = ? WHERE {$cancelWhere}";
if ($dryRun) {
$cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}");
$missedPreview = Db::query("SELECT id FROM {$table} WHERE {$missedWhere}");
$output->writeln('[预览] 将改为已取消: ' . count($cancelPreview) . ' 条');
$output->writeln('[预览] 将改为已过号: ' . count($missedPreview) . ' 条');
$cancelPreview = Db::query("SELECT id FROM {$table} WHERE {$cancelWhere}");
$output->writeln('[预览] 将改为已过号(1→4): ' . count($missedPreview) . ' 条');
$output->writeln('[预览] 将改为已取消(4→2,过号超8小时): ' . count($cancelPreview) . ' 条');
$output->writeln('[说明] 真实执行时先执行 1→4,再执行 4→2;同一次内刚由 1 变 4 且已超 8 小时的会再被改为 2。');
return;
}
$output->writeln("已取消(超8小时): {$cancelCount}");
$output->writeln("已过号: {$missedCount}");
Log::info("update_appointment_status: 已取消 {$cancelCount}, 已过号 {$missedCount}");
$missedCount = Db::execute($missedSql, [$now]);
$cancelCount = Db::execute($cancelSql, [$now]);
$output->writeln("已过号(1→4): {$missedCount}");
$output->writeln("已取消(4→2,过号超8小时): {$cancelCount}");
Log::info("update_appointment_status: 已过号 {$missedCount}, 已取消 {$cancelCount}");
}
}