feat: 添加阿里云短信服务支持并优化验证码逻辑

- 引入 alibabacloud/dysmsapi-20170525 依赖,集成阿里云短信服务
- 将短信验证码从6位改为4位,优化用户体验
- 添加聚水潭商品按时间范围同步功能,支持分页拉取
- 增强Cron任务异常处理,添加错误日志记录
- 修复系统附件服务中图片路径处理逻辑
- 更新阿里云SDK相关组件至最新版本
- 添加think-trace调试扩展,便于问题排查
- 优化跨域中间件,使用str_contains替代strpos
This commit is contained in:
2026-04-30 15:19:40 +08:00
parent 0334fef6c1
commit c7f85ffbda
565 changed files with 59742 additions and 3391 deletions

View File

@@ -215,7 +215,7 @@ class Login
$verifyCode = CacheService::get('code_' . $phone);
if (!$verifyCode)
return app('json')->fail('请先获取验证码');
$verifyCode = substr($verifyCode, 0, 6);
$verifyCode = substr($verifyCode, 0, 4);
if ($verifyCode != $code) {
CacheService::delete('code_' . $phone);
return app('json')->fail('验证码错误');
@@ -262,7 +262,7 @@ class Login
$verifyCode = CacheService::get('code_' . $phone);
if (!$verifyCode)
return app('json')->fail('请先获取验证码');
$verifyCode = substr($verifyCode, 0, 6);
$verifyCode = substr($verifyCode, 0, 4);
if ($verifyCode != $code) {
CacheService::delete('code_' . $phone);
return app('json')->fail('验证码错误');

View File

@@ -996,37 +996,163 @@ class StoreProduct extends AuthController
public function sync_jst_product()
{
[$spuStr, $sync] = $this->request->postMore([
[$spuStr, $sync, $startTime, $endTime] = $this->request->postMore([
['spu_str', ""],
['sync', 0]
['sync', 0],
['start_time', ""],
['end_time', ""]
], true);
$traceId = uniqid('jst_sync_', true);
Log::info('admin.manual.jst.product.sync.request', [
'trace_id' => $traceId,
'admin_id' => $this->adminId,
'admin_type' => $this->adminType,
'supplier_id' => $this->supplierId,
'client_ip' => $this->request->ip(),
'sync' => (int)$sync,
'spu_str' => (string)$spuStr,
'start_time' => (string)$startTime,
'end_time' => (string)$endTime,
'start_time_is_iso' => is_string($startTime) && str_contains($startTime, 'T'),
'end_time_is_iso' => is_string($endTime) && str_contains($endTime, 'T'),
]);
if ($startTime && $endTime) {
$startTs = strtotime((string)$startTime);
$endTs = strtotime((string)$endTime);
if (!$startTs || !$endTs) {
Log::warning('admin.manual.jst.product.sync_by_time.invalid_time', [
'trace_id' => $traceId,
'start_time' => $startTime,
'end_time' => $endTime,
]);
return $this->fail('时间格式错误');
}
if ($endTs < $startTs) {
Log::warning('admin.manual.jst.product.sync_by_time.invalid_range', [
'trace_id' => $traceId,
'start_time' => $startTime,
'end_time' => $endTime,
]);
return $this->fail('时间范围错误');
}
if (($endTs - $startTs) > 7 * 86400) {
Log::info('admin.manual.jst.product.sync_by_time.range_too_large', [
'trace_id' => $traceId,
'start_time' => $startTime,
'end_time' => $endTime,
'range_seconds' => $endTs - $startTs,
]);
return $this->fail('时间范围不能超过7天');
}
$startTime = date('Y-m-d H:i:s', $startTs);
$endTime = date('Y-m-d H:i:s', $endTs);
if ($sync) {
Log::info('admin.manual.jst.product.sync_by_time.run', [
'trace_id' => $traceId,
'start_time' => $startTime,
'end_time' => $endTime,
'supplier_id' => $this->supplierId,
]);
$result = (new ProductSyncErp())->syncProductByTime($startTime, $endTime, (int)$this->supplierId, $traceId, 'sync');
if (!is_array($result) || empty($result['ok'])) {
return $this->fail('同步失败,请检查日志');
}
return $this->success('同步完成', $result);
} else {
Log::info('admin.manual.jst.product.sync_by_time.dispatch', [
'trace_id' => $traceId,
'start_time' => $startTime,
'end_time' => $endTime,
'supplier_id' => $this->supplierId,
]);
ProductSyncErp::dispatchDo('syncProductByTime', [$startTime, $endTime, (int)$this->supplierId, $traceId]);
return $this->success('正在按时间范围同步中,请稍后查看', ['trace_id' => $traceId]);
}
}
if (!$spuStr) {
return $this->fail('请输入ERP商品SPU');
return $this->fail('请输入ERP商品SPU或选择时间范围');
}
$spus = array_unique(array_filter(explode(',', $spuStr)));
$traceId = uniqid('jst_', true);
$spusLog = $spus;
$spusTotal = count($spus);
if ($spusTotal > 50) {
$spusLog = array_slice($spus, 0, 50);
}
Log::info('admin.manual.jst.product.sync.dispatch', [
'trace_id' => $traceId,
'admin_id' => $this->adminId,
'admin_type' => $this->adminType,
'supplier_id' => $this->supplierId,
'client_ip' => $this->request->ip(),
'count' => count($spus),
'spus' => $spus
'count' => $spusTotal,
'spus' => $spusLog,
'spus_truncated' => $spusTotal > 50
]);
if ($sync) {
$stats = [
'ok' => true,
'mode' => 'spu',
'trace_id' => $traceId,
'spu_count' => $spusTotal,
'fetched' => 0,
'created' => 0,
'updated' => 0,
'skipped' => 0,
'failed' => 0,
];
foreach ($spus as $spu) {
(new ProductSyncErp())->productFromErp($spu, (int)$this->supplierId);
$rt = (new ProductSyncErp())->productFromErp($spu, (int)$this->supplierId, $traceId);
if (is_array($rt)) {
foreach (['fetched', 'created', 'updated', 'skipped', 'failed'] as $k) {
$stats[$k] += (int)($rt[$k] ?? 0);
}
}
}
return $this->success('同步完成');
return $this->success('同步完成', $stats);
} else {
foreach ($spus as $spu) {
ProductSyncErp::dispatchDo('productFromErp', [$spu, (int)$this->supplierId]);
ProductSyncErp::dispatchDo('productFromErp', [$spu, (int)$this->supplierId, $traceId]);
}
return $this->success('正在同步中,请稍后查看');
return $this->success('正在同步中,请稍后查看', ['trace_id' => $traceId, 'task_count' => $spusTotal]);
}
}
public function upload_jst_itemsku()
{
[$ids] = $this->request->postMore([
['ids', []],
], true);
if (is_string($ids)) {
$ids = array_filter(explode(',', $ids));
}
$ids = is_array($ids) ? array_values(array_unique(array_map('intval', $ids))) : [];
if (!$ids) {
return $this->fail('请选择商品');
}
$traceId = uniqid('jst_itemsku_', true);
Log::info('admin.manual.jst.itemsku.upload.start', [
'trace_id' => $traceId,
'admin_id' => $this->adminId,
'admin_type' => $this->adminType,
'supplier_id' => $this->supplierId,
'client_ip' => $this->request->ip(),
'product_count' => count($ids),
'product_ids' => $ids,
]);
$rt = app()->make(\app\haichao\HaichaoJstServices::class)->uploadItemSkuByProductIds($ids);
Log::info('admin.manual.jst.itemsku.upload.end', [
'trace_id' => $traceId,
'upload_count' => $rt['upload_count'] ?? null,
]);
return $this->success($rt);
}
/**
* 商品批量操作
* @param StoreProductBatchProcessServices $batchProcessServices

View File

@@ -14,6 +14,7 @@ namespace app\controller\admin\v1\statistic;
use app\controller\admin\AuthController;
use app\services\statistic\OrderStatisticServices;
use think\annotation\Inject;
use think\facade\Log;
class OrderStatistic extends AuthController
{
@@ -36,6 +37,10 @@ class OrderStatistic extends AuthController
if($this->supplierId > 0){
$where['supplier_id'] = $this->supplierId;
}
$params = $this->request->param();
$paramsJson = json_encode($params, JSON_UNESCAPED_UNICODE);
$whereJson = json_encode($where, JSON_UNESCAPED_UNICODE);
Log::info('adminapi.statistic.order.get_basic supplierId:' . (int)$this->supplierId . ' params:' . ($paramsJson === false ? '' : $paramsJson) . ' where:' . ($whereJson === false ? '' : $whereJson));
$data = $this->services->getBasic($where);
return app('json')->success($data);
}