307 lines
212 KiB
HTML
307 lines
212 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN" dir="ltr">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>定时任务 | RXThinkCMF 开发文档</title>
|
||
<meta name="description" content="定时任务系统由三部分组成:JobService(调度逻辑)+ BaseTask(任务处理器)+ Artisan 命令(job:run / job:daemon 命令行入口)。">
|
||
<meta name="generator" content="VitePress v1.3.4">
|
||
<link rel="preload stylesheet" href="/assets/style.DgIBCYhU.css" as="style">
|
||
|
||
<script type="module" src="/assets/app.DOgfdmj3.js"></script>
|
||
<link rel="preload" href="/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
|
||
<link rel="modulepreload" href="/assets/chunks/theme.CmCmt-Pd.js">
|
||
<link rel="modulepreload" href="/assets/chunks/framework.B-QBKwc1.js">
|
||
<link rel="modulepreload" href="/assets/zh_modules_job.md.2y2grIvc.lean.js">
|
||
<link rel="icon" type="image/svg+xml" href="/logo.svg">
|
||
<link rel="icon" type="image/png" href="/logo.png">
|
||
<meta property="twitter:card" content="summary_large_image">
|
||
<script src="/banner.js" async type="text/javascript"></script>
|
||
<script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"light",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
|
||
<script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
|
||
<script>var _hmt=_hmt||[];(function(){var e=document.createElement("script");e.src="https://hm.baidu.com/hm.js?8c4ed7e2f1d12bafe9e22e93e30237d4";var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t)})();</script>
|
||
<link rel="canonical" href="http://docs.laravel13.naivevue.rxthink.cn/zh/modules/job.html">
|
||
<meta property="og:type" content="article">
|
||
<meta property="og:site_name" content="RXThinkCMF">
|
||
<meta property="og:locale" content="zh_CN">
|
||
<meta property="og:title" content="定时任务">
|
||
<meta property="og:description" content="定时任务系统由三部分组成:JobService(调度逻辑)+ BaseTask(任务处理器)+ Artisan 命令(job:run / job:daemon 命令行入口)。">
|
||
<meta property="og:url" content="http://docs.laravel13.naivevue.rxthink.cn/zh/modules/job.html">
|
||
<meta property="og:image" content="http://docs.laravel13.naivevue.rxthink.cn/logo.png">
|
||
<meta property="twitter:title" content="定时任务">
|
||
<meta property="twitter:description" content="定时任务系统由三部分组成:JobService(调度逻辑)+ BaseTask(任务处理器)+ Artisan 命令(job:run / job:daemon 命令行入口)。">
|
||
<meta property="twitter:url" content="http://docs.laravel13.naivevue.rxthink.cn/zh/modules/job.html">
|
||
<meta property="twitter:image" content="http://docs.laravel13.naivevue.rxthink.cn/logo.png">
|
||
<script type="application/ld+json">[{"@context":"https://schema.org","@type":"TechArticle","headline":"6.11 定时任务","description":"定时任务系统由三部分组成:JobService(调度逻辑)+ BaseTask(任务处理器)+ Artisan 命令(job:run / job:daemon 命令行入口)。","url":"http://docs.laravel13.naivevue.rxthink.cn/zh/modules/job.html","inLanguage":"zh-CN","mainEntityOfPage":{"@type":"WebPage","@id":"http://docs.laravel13.naivevue.rxthink.cn/zh/modules/job.html"},"publisher":{"@type":"Organization","name":"RXThinkCMF","url":"https://www.rxthink.cn","logo":"http://docs.laravel13.naivevue.rxthink.cn/logo.png","sameAs":["https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue","https://www.rxthink.cn"]},"dateModified":"2026-10-11T19:06:33+08:00"},{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"首页","item":"http://docs.laravel13.naivevue.rxthink.cn/"},{"@type":"ListItem","position":2,"name":"6. 业务模块"},{"@type":"ListItem","position":3,"name":"6.11 定时任务","item":"http://docs.laravel13.naivevue.rxthink.cn/zh/modules/job.html"}]},{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"任务不执行?","acceptedAnswer":{"@type":"Answer","text":"A: 检查以下几点: 1. 任务状态是否为 1(运行中) 2. Cron 表达式格式是否正确(5 段) 3. Crontab 是否已配置且 cron 服务已启动 4. PHP 路径是否正确(建议使用绝对路径) 5. 手动执行 php artisan job:run 是否正常"}},{"@type":"Question","name":"任务重复执行?","acceptedAnswer":{"@type":"Answer","text":"A: Daemon 模式下检查 hasRunThisMinute 是否生效;Crontab 模式下确保只有一个 cron 在触发(crontab -l 检查重复项)。"}},{"@type":"Question","name":"任务执行超时?","acceptedAnswer":{"@type":"Answer","text":"A: 检查 PHP 的 max_execution_time 配置,长时间任务建议拆分或在处理器内调大 set_time_limit(0)。"}},{"@type":"Question","name":"如何查看任务执行日志?","acceptedAnswer":{"@type":"Answer","text":"A: 两种方式: 1. 控制台实时日志:Daemon 前台运行时,[执行]、[跳过]、[失败] 直接输出到终端 2. 数据库持久化日志:通过 GET /api/job/log/page 查询,或直接查 laravel_job_log 表"}},{"@type":"Question","name":"Daemon 控制台没有新日志输出,是卡住了吗?","acceptedAnswer":{"@type":"Answer","text":"A: 不是。Daemon 每分钟检查一次,没有到期任务时静默等待,不输出任何日志。"}},{"@type":"Question","name":"Windows 下 Daemon 如何启动和停止?","acceptedAnswer":{"@type":"Answer","text":"A: 项目根目录打开 CMD: :: 启动 php artisan job:daemon :: 停止(另开一个 CMD 窗口) php artisan job:daemon --stop 如提示 Daemon 已在运行中 (PID: xxx),先执行 php artisan job:daemon --stop 停止旧进程,或手动删除 storage/app/job_daemon.lock。"}},{"@type":"Question","name":"提示找不到 Task 类?","acceptedAnswer":{"@type":"Answer","text":"A: 确认 url 字段的类名与 app/Task/ 下的类文件一致(命名空间 App\\Task),且类名采用大驼峰(SendSms → SendSmsTask)。"}}]}]</script>
|
||
</head>
|
||
<body>
|
||
<div id="app"><div class="Layout" data-v-d8b57b2d><!--[--><!--]--><!--[--><span tabindex="-1" data-v-c8291ffa></span><a href="#VPContent" class="VPSkipLink visually-hidden" data-v-c8291ffa> Skip to content </a><!--]--><!----><header class="VPNav" data-v-d8b57b2d data-v-7ad780c2><div class="VPNavBar" data-v-7ad780c2 data-v-9fd4d1dd><div class="wrapper" data-v-9fd4d1dd><div class="container" data-v-9fd4d1dd><div class="title" data-v-9fd4d1dd><div class="VPNavBarTitle has-sidebar" data-v-9fd4d1dd data-v-0ad69264><a class="title" href="/" data-v-0ad69264><!--[--><!--]--><!--[--><img class="VPImage logo" src="/logo.svg" alt data-v-ab19afbb><!--]--><span data-v-0ad69264>小蚂蚁云</span><!--[--><!--]--></a></div></div><div class="content" data-v-9fd4d1dd><div class="content-body" data-v-9fd4d1dd><!--[--><!--]--><div class="VPNavBarSearch search" data-v-9fd4d1dd><!--[--><!----><div id="local-search"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><span class="vp-icon DocSearch-Search-Icon"></span><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"><kbd class="DocSearch-Button-Key"></kbd><kbd class="DocSearch-Button-Key">K</kbd></span></button></div><!--]--></div><nav aria-labelledby="main-nav-aria-label" class="VPNavBarMenu menu" data-v-9fd4d1dd data-v-afb2845e><span id="main-nav-aria-label" class="visually-hidden" data-v-afb2845e> Main Navigation </span><!--[--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://www.rxthink.cn" target="_blank" rel="noreferrer" tabindex="0" data-v-afb2845e data-v-08fbf4b6><!--[--><span data-v-08fbf4b6>官网</span><!--]--></a><!--]--><!--[--><a class="VPLink link vp-external-link-icon VPNavBarMenuLink" href="https://www.rxthink.cn/goods/detail/2" target="_blank" rel="noreferrer" tabindex="0" data-v-afb2845e data-v-08fbf4b6><!--[--><span data-v-08fbf4b6>授权</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-afb2845e data-v-af5898d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-af5898d3><span class="text" data-v-af5898d3><!----><span data-v-af5898d3>部署文档</span><span class="vpi-chevron-down text-icon" data-v-af5898d3></span></span></button><div class="menu" data-v-af5898d3><div class="VPMenu" data-v-af5898d3 data-v-20ed86d6><div class="items" data-v-20ed86d6><!--[--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp6.layui.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF混编版ThinkPHP6+Layui版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp6.elevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP6+ElementPlus版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp6.antdvue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP6+AntDesign版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp6.naivevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP6+NaiveUI版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp8.layui.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF混编版ThinkPHP8+Layui版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp8.elevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP8+ElementPlus版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp8.antdvue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP8+AntDesign版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.thinkphp8.naivevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP8+NaiveUI版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.laravel13.layui.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF混编版Laravel13+Layui版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.laravel13.elevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离Laravel13+ElementPlus版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.laravel13.antdvue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离Laravel13+AntDesign版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://docs.laravel13.naivevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离Laravel13+NaiveUI版本<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-afb2845e data-v-af5898d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-af5898d3><span class="text" data-v-af5898d3><!----><span data-v-af5898d3>在线演示</span><span class="vpi-chevron-down text-icon" data-v-af5898d3></span></span></button><div class="menu" data-v-af5898d3><div class="VPMenu" data-v-af5898d3 data-v-20ed86d6><div class="items" data-v-20ed86d6><!--[--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp6.layui.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF混编版ThinkPHP6+Layui版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp6.elevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP6+ElementPlus版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp6.antdvue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP6+AntDesign版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp6.naivevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP6+NaiveUI版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp8.layui.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF混编版ThinkPHP8+Layui版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp8.elevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP8+ElementPlus版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp8.antdvue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP8+AntDesign版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.thinkphp8.naivevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离ThinkPHP8+NaiveUI版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.laravel13.layui.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF混编版Laravel13+Layui版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.laravel13.elevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离Laravel13+ElementPlus版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.laravel13.antdvue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离Laravel13+AntDesign版本<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="http://manage.laravel13.naivevue.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->RXThinkCMF前后端分离Laravel13+NaiveUI版本<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--[--><a class="VPLink link VPNavBarMenuLink" href="/zh/other/sponsor.html" tabindex="0" data-v-afb2845e data-v-08fbf4b6><!--[--><span data-v-08fbf4b6>广告赞助</span><!--]--></a><!--]--><!--[--><div class="VPFlyout VPNavBarMenuGroup" data-v-afb2845e data-v-af5898d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" data-v-af5898d3><span class="text" data-v-af5898d3><!----><span data-v-af5898d3>相关链接</span><span class="vpi-chevron-down text-icon" data-v-af5898d3></span></span></button><div class="menu" data-v-af5898d3><div class="VPMenu" data-v-af5898d3 data-v-20ed86d6><div class="items" data-v-20ed86d6><!--[--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="https://www.rxthink.cn" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->官方网站<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->Gitee 仓库<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="https://laravel.com/" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->Laravel 官网<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="https://cn.vuejs.org/" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->Vue3 文档<!--]--></a></div><!--]--><!--[--><div class="VPMenuLink" data-v-20ed86d6 data-v-f51f088d><a class="VPLink link vp-external-link-icon" href="https://www.naiveui.com/" target="_blank" rel="noreferrer" data-v-f51f088d><!--[-->NaiveUI<!--]--></a></div><!--]--><!--]--></div><!--[--><!--]--></div></div></div><!--]--><!--]--></nav><!----><div class="VPNavBarAppearance appearance" data-v-9fd4d1dd data-v-3f90c1a5><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-3f90c1a5 data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div><div class="VPSocialLinks VPNavBarSocialLinks social-links" data-v-9fd4d1dd data-v-ef6192dc data-v-e71e869c><!--[--><a class="VPSocialLink no-icon" href="https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue" aria-label="github" target="_blank" rel="noopener" data-v-e71e869c data-v-358b6670><span class="vpi-social-github" /></a><!--]--></div><div class="VPFlyout VPNavBarExtra extra" data-v-9fd4d1dd data-v-f953d92f data-v-af5898d3><button type="button" class="button" aria-haspopup="true" aria-expanded="false" aria-label="extra navigation" data-v-af5898d3><span class="vpi-more-horizontal icon" data-v-af5898d3></span></button><div class="menu" data-v-af5898d3><div class="VPMenu" data-v-af5898d3 data-v-20ed86d6><!----><!--[--><!--[--><!----><div class="group" data-v-f953d92f><div class="item appearance" data-v-f953d92f><p class="label" data-v-f953d92f>Appearance</p><div class="appearance-action" data-v-f953d92f><button class="VPSwitch VPSwitchAppearance" type="button" role="switch" title aria-checked="false" data-v-f953d92f data-v-be9742d9 data-v-b4ccac88><span class="check" data-v-b4ccac88><span class="icon" data-v-b4ccac88><!--[--><span class="vpi-sun sun" data-v-be9742d9></span><span class="vpi-moon moon" data-v-be9742d9></span><!--]--></span></span></button></div></div></div><div class="group" data-v-f953d92f><div class="item social-links" data-v-f953d92f><div class="VPSocialLinks social-links-list" data-v-f953d92f data-v-e71e869c><!--[--><a class="VPSocialLink no-icon" href="https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue" aria-label="github" target="_blank" rel="noopener" data-v-e71e869c data-v-358b6670><span class="vpi-social-github" /></a><!--]--></div></div></div><!--]--><!--]--></div></div></div><!--[--><!--]--><button type="button" class="VPNavBarHamburger hamburger" aria-label="mobile navigation" aria-expanded="false" aria-controls="VPNavScreen" data-v-9fd4d1dd data-v-6bee1efd><span class="container" data-v-6bee1efd><span class="top" data-v-6bee1efd></span><span class="middle" data-v-6bee1efd></span><span class="bottom" data-v-6bee1efd></span></span></button></div></div></div></div><div class="divider" data-v-9fd4d1dd><div class="divider-line" data-v-9fd4d1dd></div></div></div><!----></header><div class="VPLocalNav has-sidebar empty" data-v-d8b57b2d data-v-2488c25a><div class="container" data-v-2488c25a><button class="menu" aria-expanded="false" aria-controls="VPSidebarNav" data-v-2488c25a><span class="vpi-align-left menu-icon" data-v-2488c25a></span><span class="menu-text" data-v-2488c25a>Menu</span></button><div class="VPLocalNavOutlineDropdown" style="--vp-vh:0px;" data-v-2488c25a data-v-883964e0><button data-v-883964e0>Return to top</button><!----></div></div></div><aside class="VPSidebar" data-v-d8b57b2d data-v-42c4c606><div class="curtain" data-v-42c4c606></div><nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1" data-v-42c4c606><span class="visually-hidden" id="sidebar-aria-label" data-v-42c4c606> Sidebar Navigation </span><!--[--><!--]--><!--[--><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>📖 1. 了解项目</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/introduction.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>1.1 项目介绍</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/why.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>1.2 为什么选择我们</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/directory.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>1.3 项目目录结构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/course.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>1.4 新手入门指南</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tech-stack.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>1.5 技术栈说明</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/changelog.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>1.6 更新日志</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🚀 2. 快速入门</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/environment.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.1 开发环境准备</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/laragon.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.2 Laragon 环境搭建</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/backend-start.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.3 后端服务启动</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/frontend-start.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.4 前端服务启动</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/database-init.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.5 数据库初始化</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/env-vars.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.6 环境变量配置</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/first-api.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.7 第一个接口调试</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/docker.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.8 Docker 快速体验</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/quickstart/faq.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>2.9 常见问题 FAQ</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🧪 3. 模块开发实战</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/overview.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.1 概述与目标</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/database.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.2 数据库建表</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/model.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.3 模型层开发</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/validator.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.4 FormRequest 验证器</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/logic.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.5 Service 层开发</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/controller.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.6 控制器开发</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/route.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.7 路由注册</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/permission.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.8 权限节点配置</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/frontend-integration.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.9 前端联调指引</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/code-list.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.10 完整代码清单</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/guide/faq.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>3.11 常见问题与排错</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🏛️ 4. 架构设计</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/overview.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.1 整体架构概览</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/request-flow.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.2 请求处理链路</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/backend-layer.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.3 后端分层架构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/frontend-layer.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.4 前端分层架构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/directory-design.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.5 目录结构设计</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/base-classes.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.6 核心基类体系</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/cross-cutting.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.7 横切机制</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/cache.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.8 缓存架构设计</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/database-design.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.9 数据库设计</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/security.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.10 安全架构设计</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/architecture/extensibility.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>4.11 扩展性设计</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🔐 5. 核心功能</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>认证与安全</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/jwt.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.1 用户认证(JWT)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/auth-flow.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.2 认证流程实战</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/captcha.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.3 验证码机制</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/rbac.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.4 权限管理(RBAC)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/cors.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.5 跨域资源共享</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/password.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.6 密码加密服务</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/demo-mode.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.7 演示模式</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>数据与配置</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/tenant.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.8 多租户隔离</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/data-scope.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.9 数据权限</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/dict.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.10 字典模块</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/dict-guide.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.11 字典配置与使用</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/config.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.12 系统配置管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/param.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.13 系统参数管理</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>日志与监控</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/operation-log.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.14 操作日志</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/login-log.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.15 登录日志</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>响应与异常</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/exception.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.16 统一响应与异常抛出</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>注解系统</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/core/attributes.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>5.17 注解系统总览</p><!--]--></a><!----></div><!----></div><!--]--></div></section><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible has-active" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>📦 6. 业务模块</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/user.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.1 用户管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/role.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.2 角色管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/menu.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.3 菜单管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/dept.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.4 部门管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/level.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.5 职级管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/position.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.6 岗位管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/article.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.7 文章管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/content.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.8 公告与链接管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/city.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.9 行政区划管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/category.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.10 分类管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/job.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.11 定时任务</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/param.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.12 参数管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/tenant.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.13 租户管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/filetemplate.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.14 文件模板管理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/modules/index.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>6.15 首页与个人中心</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🧰 7. 文件处理</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tools/upload.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>7.1 文件上传全流程</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tools/upload-config.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>7.2 上传配置详解</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tools/rich-text.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>7.3 富文本处理</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tools/excel.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>7.4 数据导入导出</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tools/file-components.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>7.5 前端文件组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/tools/db-migrate.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>7.6 数据库迁移工具</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🔗 8. 接口规范与对接</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/response.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.1 统一响应格式</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/error-code.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.2 错误码对照表</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/pagination.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.3 分页查询规范</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/upload.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.4 文件上传接口</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/dict-api.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.5 字典数据接口</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/token.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.6 Token 使用说明</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/api-spec/overview.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>8.7 API 接口总览</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🖥️ 9. 前端开发</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>工程基础</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/overview.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.1 前端工程概述</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/directory.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.2 目录结构详解</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/env-config.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.3 环境与构建配置</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>核心机制</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/http.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.4 HTTP 请求封装</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/router.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.5 路由与动态菜单</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/store.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.6 状态管理(Pinia)</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/permission.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.7 权限控制</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/login.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.8 登录流程</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>公共组件</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/display-components.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.9 数据展示组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/form-components.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.10 数据录入组件</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/excel-components.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.11 Excel 导入导出组件</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>开发实践</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/new-page.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.12 新增页面开发步骤</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/api-module.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.13 API 模块编写规范</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/style.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.14 样式与主题定制</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/layout.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.15 布局系统</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/frontend/utils.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>9.16 工具函数</p><!--]--></a><!----></div><!----></div><!--]--></div></section><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>🔧 10. 代码生成器</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/overview.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.1 概述与架构</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/cli.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.2 CLI 命令行使用</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/web-ui.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.3 Web 管理界面</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/parser.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.4 表结构解析引擎</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/code-engine.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.5 代码生成引擎</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/templates.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.6 自定义模板开发</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/config.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.7 配置文件详解</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/demo.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.8 实战案例</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/generator/faq.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>10.9 常见问题</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>⚙️ 11. 运维部署</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/checklist.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.1 部署 Checklist</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/env-plan.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.2 环境规划</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/db-migrate.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.3 数据库迁移</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/backend.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.4 后端部署</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/frontend.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.5 前端部署</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/docker.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.6 Docker 生产部署</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/performance.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.7 性能调优</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/security.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.8 安全加固清单</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/backup.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.9 备份与恢复</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/troubleshooting.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.10 故障排查手册</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/deploy/ci-cd.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>11.11 CI/CD 流水线</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>📋 12. 规范标准</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>⭐ 必须遵守</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/api-response.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.1 API 响应规范</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/pagination.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.2 分页查询规范</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/git.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.3 Git 提交规范</p><!--]--></a><!----></div><!----></div><!--]--></div></section><section class="VPSidebarItem level-1 collapsible" data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h3 class="text" data-v-edd2eed8>📌 建议遵守</h3><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/deletion.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.4 数据删除规范</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/code-review.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.5 代码审查清单</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/backend-code.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.6 后端编码规范</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-2 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/standards/frontend-code.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>12.7 前端编码规范</p><!--]--></a><!----></div><!----></div><!--]--></div></section><!--]--></div></section></div><div class="no-transition group" data-v-51288d80><section class="VPSidebarItem level-0 collapsible" data-v-51288d80 data-v-edd2eed8><div class="item" role="button" tabindex="0" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><h2 class="text" data-v-edd2eed8>📄 附录</h2><div class="caret" role="button" aria-label="toggle section" tabindex="0" data-v-edd2eed8><span class="vpi-chevron-right caret-icon" data-v-edd2eed8></span></div></div><div class="items" data-v-edd2eed8><!--[--><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/faq.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>A. 常见问题汇总</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/database-tables.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>B. 数据库表结构速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/config-reference.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>C. 配置项速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/functions.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>D. 公共函数速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/api-cheatsheet.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>E. API 接口速查表</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/middleware.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>F. 中间件执行顺序</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/components.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>G. 前端组件速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/stores.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>H. 前端 Store 速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/enums.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>I. 前端 Enums 速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/glossary.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>J. 术语表</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/appendix/commands.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>K. Artisan 命令速查</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/other/contributing.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>L. 贡献指南</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/other/declare.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>M. 免责声明</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link link" href="/zh/other/sponsor.html" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>N. 广告赞助</p><!--]--></a><!----></div><!----></div><div class="VPSidebarItem level-1 is-link" data-v-edd2eed8><div class="item" data-v-edd2eed8><div class="indicator" data-v-edd2eed8></div><a class="VPLink link vp-external-link-icon link" href="https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue" target="_blank" rel="noreferrer" data-v-edd2eed8><!--[--><p class="text" data-v-edd2eed8>O. 开源协议</p><!--]--></a><!----></div><!----></div><!--]--></div></section></div><!--]--><!--[--><!--]--></nav></aside><div class="VPContent has-sidebar" id="VPContent" data-v-d8b57b2d data-v-9a6c75ad><div class="VPDoc has-sidebar has-aside" data-v-9a6c75ad data-v-e6f2a212><!--[--><!--]--><div class="container" data-v-e6f2a212><div class="aside" data-v-e6f2a212><div class="aside-curtain" data-v-e6f2a212></div><div class="aside-container" data-v-e6f2a212><div class="aside-content" data-v-e6f2a212><div class="VPDocAside" data-v-e6f2a212 data-v-cb998dce><!--[--><!--]--><!--[--><!--]--><nav aria-labelledby="doc-outline-aria-label" class="VPDocAsideOutline" data-v-cb998dce data-v-f610f197><div class="content" data-v-f610f197><div class="outline-marker" data-v-f610f197></div><div aria-level="2" class="outline-title" id="doc-outline-aria-label" role="heading" data-v-f610f197>本页内容</div><ul class="VPDocOutlineItem root" data-v-f610f197 data-v-53c99d69><!--[--><!--]--></ul></div></nav><!--[--><!--]--><div class="spacer" data-v-cb998dce></div><!--[--><!--[--><!--[--><!--[--><!--[--><div class="VPDocAsideSponsors" data-v-46d2db61><div class="VPSponsors vp-sponsor aside"><!--[--><section class="vp-sponsor-section"><!----><div class="VPSponsorsGrid vp-sponsor-grid mini"><!--[--><div class="vp-sponsor-grid-item"><a class="vp-sponsor-grid-link" href="https://www.rxthink.cn" target="_blank" rel="sponsored noopener"><article class="vp-sponsor-grid-box"><h4 class="visually-hidden">Become a sponsor</h4><img class="vp-sponsor-grid-image" src="/sponsor/rxthinkcmf.png" alt="Become a sponsor"></article></a></div><!--]--></div></section><section class="vp-sponsor-section"><!----><div class="VPSponsorsGrid vp-sponsor-grid xmini"><!--[--><div class="vp-sponsor-grid-item"><a class="vp-sponsor-grid-link" href="https://www.rxthink.cn" target="_blank" rel="sponsored noopener"><article class="vp-sponsor-grid-box"><h4 class="visually-hidden">企业级中台解决方案</h4><img class="vp-sponsor-grid-image" src="/sponsor/rxthinkcmf.png" alt="企业级中台解决方案"></article></a></div><div class="vp-sponsor-grid-item"><a class="vp-sponsor-grid-link" href="https://www.rxthink.cn" target="_blank" rel="sponsored noopener"><article class="vp-sponsor-grid-box"><h4 class="visually-hidden">企业级中台解决方案</h4><img class="vp-sponsor-grid-image" src="/sponsor/rxthinkcmf.png" alt="企业级中台解决方案"></article></a></div><!--]--></div></section><!--]--></div></div><a class="banner mp" href="https://www.rxthink.cn" target="_blank" data-v-46d2db61><img width="22" height="22" src="/sponsor/rxthinkcmf.png" data-v-46d2db61><span data-v-46d2db61><p class="extra-info" data-v-46d2db61>赋能开发者</p><p class="heading" data-v-46d2db61>企业级中台解决方案</p><p class="extra-info" data-v-46d2db61>助力企业发展</p></span></a><a class="banner cert" href="https://www.rxthink.cn" target="_blank" data-v-46d2db61><img width="22" height="22" src="/sponsor/rxthinkcmf.png" data-v-46d2db61><span data-v-46d2db61><p class="extra-info" data-v-46d2db61>赋能开发者</p><p class="heading" data-v-46d2db61>企业级中台解决方案</p><p class="extra-info" data-v-46d2db61>助力企业发展</p></span></a><!--]--><!--]--><!--]--><!--]--><!--]--><!----><!--[--><!--]--><!--[--><!--]--></div></div></div></div><div class="content" data-v-e6f2a212><div class="content-container" data-v-e6f2a212><!--[--><!--]--><main class="main" data-v-e6f2a212><div style="position:relative;" class="vp-doc _zh_modules_job" data-v-e6f2a212><div><h1 id="_6-11-定时任务" tabindex="-1">6.11 定时任务 <a class="header-anchor" href="#_6-11-定时任务" aria-label="Permalink to "6.11 定时任务""></a></h1><div class="tip custom-block"><p class="custom-block-title">概述</p><p>定时任务系统由三部分组成:<code>JobService</code>(调度逻辑)+ <code>BaseTask</code>(任务处理器)+ Artisan 命令(<code>job:run</code> / <code>job:daemon</code> 命令行入口)。支持三种触发方式:Linux Crontab、Windows 计划任务、Daemon 守护进程。</p></div><h2 id="系统架构" tabindex="-1">系统架构 <a class="header-anchor" href="#系统架构" aria-label="Permalink to "系统架构""></a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>┌─────────────────────────────────────────────────────────────────┐</span></span>
|
||
<span class="line"><span>│ 触发层(三选一) │</span></span>
|
||
<span class="line"><span>│ │</span></span>
|
||
<span class="line"><span>│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │</span></span>
|
||
<span class="line"><span>│ │ Linux Crontab│ │Windows 计划 │ │ Daemon 守护 │ │</span></span>
|
||
<span class="line"><span>│ │ │ │任务 │ │ 进程 │ │</span></span>
|
||
<span class="line"><span>│ │ * * * * * │ │ schtasks │ │ php artisan │ │</span></span>
|
||
<span class="line"><span>│ │ php artisan │ │ │ │ job:daemon │ │</span></span>
|
||
<span class="line"><span>│ │ job:run │ │ │ │ │ │</span></span>
|
||
<span class="line"><span>│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │</span></span>
|
||
<span class="line"><span>│ │ │ │ │</span></span>
|
||
<span class="line"><span>│ └─────────────────┼─────────────────┘ │</span></span>
|
||
<span class="line"><span>│ │ │</span></span>
|
||
<span class="line"><span>│ ▼ │</span></span>
|
||
<span class="line"><span>│ ┌─────────────────────────────┐ │</span></span>
|
||
<span class="line"><span>│ │ JobRunCommand / JobDaemon │ │</span></span>
|
||
<span class="line"><span>│ │ php artisan job:run │ │</span></span>
|
||
<span class="line"><span>│ │ php artisan job:daemon │ │</span></span>
|
||
<span class="line"><span>│ └────────────┬────────────────┘ │</span></span>
|
||
<span class="line"><span>└───────────────────────────┼─────────────────────────────────────┘</span></span>
|
||
<span class="line"><span> │</span></span>
|
||
<span class="line"><span> ▼</span></span>
|
||
<span class="line"><span>┌─────────────────────────────────────────────────────────────────┐</span></span>
|
||
<span class="line"><span>│ 调度层(JobService) │</span></span>
|
||
<span class="line"><span>│ │</span></span>
|
||
<span class="line"><span>│ runPending() shouldRun() │</span></span>
|
||
<span class="line"><span>│ ├─ 查询 status=1 的任务 ├─ 解析 cron 表达式 │</span></span>
|
||
<span class="line"><span>│ ├─ 逐个判断是否到执行时间 ├─ 分 时 日 月 周 逐段匹配 │</span></span>
|
||
<span class="line"><span>│ └─ 到期则执行 └─ 全部匹配返回 true │</span></span>
|
||
<span class="line"><span>│ │</span></span>
|
||
<span class="line"><span>│ executeJob($job) │</span></span>
|
||
<span class="line"><span>│ ├─ 检查执行策略(立即/排队/放弃) │</span></span>
|
||
<span class="line"><span>│ ├─ 调用 doExecute() 实际执行 │</span></span>
|
||
<span class="line"><span>│ ├─ 记录 JobLog 执行日志 │</span></span>
|
||
<span class="line"><span>│ └─ 返回执行结果 │</span></span>
|
||
<span class="line"><span>└───────────────────────────┼─────────────────────────────────────┘</span></span>
|
||
<span class="line"><span> │</span></span>
|
||
<span class="line"><span> ▼</span></span>
|
||
<span class="line"><span>┌─────────────────────────────────────────────────────────────────┐</span></span>
|
||
<span class="line"><span>│ 执行层 │</span></span>
|
||
<span class="line"><span>│ │</span></span>
|
||
<span class="line"><span>│ doExecute($job) │</span></span>
|
||
<span class="line"><span>│ ├─ 判断任务类型 │</span></span>
|
||
<span class="line"><span>│ │ │</span></span>
|
||
<span class="line"><span>│ ├─ http:// / https:// → executeHttp() │</span></span>
|
||
<span class="line"><span>│ │ └─ curl 发起 HTTP 请求 │</span></span>
|
||
<span class="line"><span>│ │ │</span></span>
|
||
<span class="line"><span>│ └─ 其它 → executeInternal() │</span></span>
|
||
<span class="line"><span>│ └─ 映射到 App\Task\{Name}Task::run() │</span></span>
|
||
<span class="line"><span>│ │</span></span>
|
||
<span class="line"><span>│ 示例: │</span></span>
|
||
<span class="line"><span>│ url = "SendSms" → App\Task\SendSmsTask::run() │</span></span>
|
||
<span class="line"><span>│ url = "Order/Close" → App\Task\Order\CloseTask::run() │</span></span>
|
||
<span class="line"><span>│ url = "https://..." → HTTP 请求 │</span></span>
|
||
<span class="line"><span>└─────────────────────────────────────────────────────────────────┘</span></span></code></pre></div><h2 id="任务数据结构" tabindex="-1">任务数据结构 <a class="header-anchor" href="#任务数据结构" aria-label="Permalink to "任务数据结构""></a></h2><h3 id="job-表字段" tabindex="-1">job 表字段 <a class="header-anchor" href="#job-表字段" aria-label="Permalink to "job 表字段""></a></h3><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>说明</th></tr></thead><tbody><tr><td><code>job_name</code></td><td>varchar</td><td>任务名称</td></tr><tr><td><code>job_alias</code></td><td>varchar</td><td>任务别名(唯一)</td></tr><tr><td><code>job_group</code></td><td>varchar</td><td>任务分组</td></tr><tr><td><code>status</code></td><td>tinyint</td><td>状态:0=未发布 1=运行中 2=暂停</td></tr><tr><td><code>cron_expression</code></td><td>varchar</td><td>Cron 表达式(5段:分 时 日 月 周)</td></tr><tr><td><code>execute_policy</code></td><td>tinyint</td><td>执行策略:1=立即 2=执行一次 3=放弃</td></tr><tr><td><code>is_sync</code></td><td>tinyint</td><td>是否同步:0=否 1=是</td></tr><tr><td><code>url</code></td><td>varchar</td><td>任务地址(内部类名或外部URL)</td></tr><tr><td><code>params</code></td><td>text</td><td>任务参数(JSON)</td></tr><tr><td><code>note</code></td><td>text</td><td>备注</td></tr></tbody></table><h3 id="job-log-表字段" tabindex="-1">job_log 表字段 <a class="header-anchor" href="#job-log-表字段" aria-label="Permalink to "job_log 表字段""></a></h3><table tabindex="0"><thead><tr><th>字段</th><th>类型</th><th>说明</th></tr></thead><tbody><tr><td><code>job_id</code></td><td>int</td><td>关联任务ID</td></tr><tr><td><code>job_name</code></td><td>varchar</td><td>任务名称</td></tr><tr><td><code>job_group</code></td><td>varchar</td><td>任务分组</td></tr><tr><td><code>job_message</code></td><td>text</td><td>执行结果消息(截取前500字符)</td></tr><tr><td><code>cron_expression</code></td><td>varchar</td><td>Cron 表达式</td></tr><tr><td><code>status</code></td><td>tinyint</td><td>状态:0=正常 1=失败</td></tr><tr><td><code>start_time</code></td><td>datetime</td><td>开始时间</td></tr><tr><td><code>end_time</code></td><td>datetime</td><td>结束时间</td></tr><tr><td><code>consume_time</code></td><td>int</td><td>耗时(毫秒)</td></tr><tr><td><code>exception_info</code></td><td>text</td><td>异常信息(截取前2000字符)</td></tr></tbody></table><h2 id="状态说明" tabindex="-1">状态说明 <a class="header-anchor" href="#状态说明" aria-label="Permalink to "状态说明""></a></h2><table tabindex="0"><thead><tr><th>状态值</th><th>说明</th><th>可执行</th><th>可暂停</th><th>可启动</th></tr></thead><tbody><tr><td>0</td><td>未发布</td><td>✗</td><td>✗</td><td>✓</td></tr><tr><td>1</td><td>运行中</td><td>✓</td><td>✓</td><td>✗</td></tr><tr><td>2</td><td>暂停</td><td>✗</td><td>✗</td><td>✓</td></tr><tr><td>3</td><td>已删除</td><td>✗</td><td>✗</td><td>✗</td></tr></tbody></table><h2 id="执行策略" tabindex="-1">执行策略 <a class="header-anchor" href="#执行策略" aria-label="Permalink to "执行策略""></a></h2><table tabindex="0"><thead><tr><th>策略值</th><th>说明</th><th>行为</th></tr></thead><tbody><tr><td>1</td><td>立即执行</td><td>丢弃之前的执行,立即运行</td></tr><tr><td>2</td><td>执行一次</td><td>等待上一次完成后执行</td></tr><tr><td>3</td><td>放弃执行</td><td>如果上一次还在运行则跳过</td></tr></tbody></table><h2 id="Cron-表达式语法" tabindex="-1">Cron 表达式语法 <a class="header-anchor" href="#Cron-表达式语法" aria-label="Permalink to "Cron 表达式语法""></a></h2><p>标准 5 段格式:<code>分 时 日 月 周</code></p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>┌────────── 分钟(0-59)</span></span>
|
||
<span class="line"><span>│ ┌──────── 小时(0-23)</span></span>
|
||
<span class="line"><span>│ │ ┌────── 日(1-31)</span></span>
|
||
<span class="line"><span>│ │ │ ┌──── 月(1-12)</span></span>
|
||
<span class="line"><span>│ │ │ │ ┌── 周(0-6,0=周日)</span></span>
|
||
<span class="line"><span>│ │ │ │ │</span></span>
|
||
<span class="line"><span>* * * * *</span></span></code></pre></div><table tabindex="0"><thead><tr><th>表达式</th><th>说明</th></tr></thead><tbody><tr><td><code>* * * * *</code></td><td>每分钟</td></tr><tr><td><code>0 * * * *</code></td><td>每小时整点</td></tr><tr><td><code>0 0 * * *</code></td><td>每天 0 点</td></tr><tr><td><code>0 2 * * *</code></td><td>每天凌晨 2 点</td></tr><tr><td><code>0 0 * * 1</code></td><td>每周一 0 点</td></tr><tr><td><code>0 0 1 * *</code></td><td>每月 1 号 0 点</td></tr><tr><td><code>*/5 * * * *</code></td><td>每 5 分钟</td></tr><tr><td><code>0 */2 * * *</code></td><td>每 2 小时</td></tr><tr><td><code>0 9-18 * * 1-5</code></td><td>工作日 9-18 点每小时</td></tr><tr><td><code>0 2 1,15 * *</code></td><td>每月 1 号和 15 号凌晨 2 点</td></tr></tbody></table><h2 id="方式一-Linux-Crontab-推荐-" tabindex="-1">方式一:Linux Crontab(推荐) <a class="header-anchor" href="#方式一-Linux-Crontab-推荐-" aria-label="Permalink to "方式一:Linux Crontab(推荐)""></a></h2><div class="tip custom-block"><p class="custom-block-title">适用场景</p><p>Linux / macOS 服务器,最常用的定时任务触发方式。系统级 cron 每分钟触发一次 Artisan 命令。</p></div><h3 id="配置步骤" tabindex="-1">配置步骤 <a class="header-anchor" href="#配置步骤" aria-label="Permalink to "配置步骤""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 1. 编辑 crontab</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 2. 添加定时任务(每分钟执行一次,推荐)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">*</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> cd /www/RXThinkCMF_Laravel13_NaiveVue </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">&&</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> /usr/bin/php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:run</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> >></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /dev/null</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> 2>&1</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 调试时改为写入日志文件</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">*</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> cd /www/RXThinkCMF_Laravel13_NaiveVue </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">&&</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> /usr/bin/php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:run</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> >></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /var/log/job.log</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> 2>&1</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 3. 保存后验证</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -l</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 查看已配置的 cron</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">tail</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /var/log/syslog</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> |</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> grep</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> CRON</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 查看 cron 日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">cd</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /www/RXThinkCMF_Laravel13_NaiveVue</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> &&</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:run</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 手动执行一次</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">路径注意</p><ul><li><code>cd</code> 必须切换到<strong>项目根目录</strong>,否则 Laravel 无法找到 <code>.env</code> 与配置</li><li><code>php</code> 建议使用绝对路径(如 <code>/usr/bin/php</code>),避免 cron 环境变量不同导致找不到 PHP</li><li><code>>> /dev/null 2>&1</code> 表示丢弃输出,调试时改为写入日志文件</li></ul></div><h3 id="Crontab-常用命令" tabindex="-1">Crontab 常用命令 <a class="header-anchor" href="#Crontab-常用命令" aria-label="Permalink to "Crontab 常用命令""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 编辑当前用户的 cron</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -l</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 列出当前用户的 cron</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -r</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 删除当前用户的所有 cron(慎用)</span></span></code></pre></div><h2 id="方式二-Windows-计划任务" tabindex="-1">方式二:Windows 计划任务 <a class="header-anchor" href="#方式二-Windows-计划任务" aria-label="Permalink to "方式二:Windows 计划任务""></a></h2><div class="tip custom-block"><p class="custom-block-title">适用场景</p><p>Windows Server 或本地开发环境(Laragon),通过任务计划程序定时触发。</p></div><h3 id="方式-A-图形界面配置" tabindex="-1">方式 A:图形界面配置 <a class="header-anchor" href="#方式-A-图形界面配置" aria-label="Permalink to "方式 A:图形界面配置""></a></h3><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>1. Win + R → taskschd.msc → 回车(打开任务计划程序)</span></span>
|
||
<span class="line"><span>2. 右侧点击"创建基本任务"</span></span>
|
||
<span class="line"><span>3. 名称:定时任务</span></span>
|
||
<span class="line"><span>4. 触发器:每天,重复间隔 1 分钟,持续时间无限期</span></span>
|
||
<span class="line"><span>5. 操作:启动程序</span></span>
|
||
<span class="line"><span> 程序或脚本:D:\laragon\bin\php\php-8.3.x-Win32-vs16-x64\php.exe</span></span>
|
||
<span class="line"><span> 添加参数:artisan job:run</span></span>
|
||
<span class="line"><span> 起始于:D:\laragon\www\RXThinkCMF_Laravel13_NaiveVue</span></span>
|
||
<span class="line"><span>6. 勾选"不管用户是否登录都要运行" → 完成</span></span></code></pre></div><h3 id="方式-B-命令行配置-schtasks-" tabindex="-1">方式 B:命令行配置(schtasks) <a class="header-anchor" href="#方式-B-命令行配置-schtasks-" aria-label="Permalink to "方式 B:命令行配置(schtasks)""></a></h3><div class="language-powershell vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">powershell</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 创建每分钟执行的任务(含工作目录与日志重定向)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">schtasks </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">create </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">tn </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">RXThinkCMF_Job</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> /</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">tr </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">cmd /c cd /d D:\laragon\www\RXThinkCMF_Laravel13_NaiveVue && D:\laragon\bin\php\php-8.3.x-Win32-vs16-x64\php.exe artisan job:run >> storage\job.log 2>&1</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> /</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">sc minute </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">mo </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">1</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> /</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">f</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 查询 / 手动运行 / 删除</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">schtasks </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">query </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">tn </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">RXThinkCMF_Job</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">schtasks </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">run </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">tn </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">RXThinkCMF_Job</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">schtasks </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">delete </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">/</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">tn </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">RXThinkCMF_Job</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> /</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">f</span></span></code></pre></div><div class="warning custom-block"><p class="custom-block-title">Windows 常见问题</p><ol><li><strong>路径空格</strong>:路径含空格时必须用引号包裹</li><li><strong>PHP 路径</strong>:使用 <code>php.exe</code> 的完整路径(Laragon 多版本共存时尤其注意 8.3 的路径)</li><li><strong>工作目录</strong>:必须设置为项目根目录</li><li><strong>输出重定向</strong>:<code>>></code> 在 <code>cmd /c</code> 内生效,注意相对路径基于工作目录</li></ol></div><h2 id="方式三-Daemon-守护进程" tabindex="-1">方式三:Daemon 守护进程 <a class="header-anchor" href="#方式三-Daemon-守护进程" aria-label="Permalink to "方式三:Daemon 守护进程""></a></h2><div class="tip custom-block"><p class="custom-block-title">适用场景</p><p>需要更精确的执行时机,或不想依赖系统 cron 的场景。进程常驻内存,自行调度。</p></div><h3 id="原理" tabindex="-1">原理 <a class="header-anchor" href="#原理" aria-label="Permalink to "原理""></a></h3><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>Daemon 进程启动</span></span>
|
||
<span class="line"><span> │</span></span>
|
||
<span class="line"><span> ▼</span></span>
|
||
<span class="line"><span>┌─────────────────────┐</span></span>
|
||
<span class="line"><span>│ while (true) │ 无限循环</span></span>
|
||
<span class="line"><span>│ │ │</span></span>
|
||
<span class="line"><span>│ ├─ runPending() │ 扫描并执行到期任务</span></span>
|
||
<span class="line"><span>│ ├─ sleep(60) │ 休眠 60 秒</span></span>
|
||
<span class="line"><span>│ └─ 继续循环 │</span></span>
|
||
<span class="line"><span>└─────────────────────┘</span></span></code></pre></div><ul><li>锁文件:<code>storage/app/job_daemon.lock</code>(内容为当前进程 PID,防止重复启动)</li><li>防重复:同一任务在同一分钟内只执行一次(<code>hasRunThisMinute</code> 查 JobLog)</li></ul><h3 id="运行方式" tabindex="-1">运行方式 <a class="header-anchor" href="#运行方式" aria-label="Permalink to "运行方式""></a></h3><p><strong>常用命令:</strong></p><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 前台常驻(开发观察)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> --stop</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 停止</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:run</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 一次性执行(交给系统 cron 每分钟触发)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">nohup</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> storage/logs/job_daemon.log</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> 2>&1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> &</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> # 后台</span></span></code></pre></div><h4 id="方式-A-前台运行-本地调试-" tabindex="-1">方式 A:前台运行(本地调试) <a class="header-anchor" href="#方式-A-前台运行-本地调试-" aria-label="Permalink to "方式 A:前台运行(本地调试)""></a></h4><div class="language-cmd vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">cmd</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">:: 项目根目录打开 CMD —— 启动</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">php artisan job:daemon</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">:: 停止(另开一个 CMD 窗口)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">php artisan job:</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">daemon</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> --</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">stop</span></span></code></pre></div><p><strong>启动成功输出:</strong></p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>[2026-10-07 22:10:06] Daemon 已启动 (PID: 32116)</span></span>
|
||
<span class="line"><span>[2026-10-07 22:10:06] 每分钟检查一次到期任务,按 Ctrl+C 优雅退出</span></span></code></pre></div><p><strong>运行日志:</strong></p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>[2026-10-07 22:10:06] [执行] 定时任务演示 (cron: */5 * * * *)</span></span>
|
||
<span class="line"><span>[2026-10-07 22:10:06] [执行] 定时任务案例 (cron: */5 * * * *)</span></span>
|
||
<span class="line"><span>[2026-10-07 22:10:06] 本轮执行完成,共执行 2 个任务</span></span></code></pre></div><table tabindex="0"><thead><tr><th>标记</th><th>含义</th></tr></thead><tbody><tr><td><code>[执行]</code></td><td>任务已触发执行,括号内显示 cron 表达式</td></tr><tr><td><code>[跳过]</code></td><td>同一分钟内该任务已执行过,自动跳过(防重复)</td></tr><tr><td><code>[失败]</code></td><td>任务执行异常,后跟错误信息(单个任务失败不影响其他任务)</td></tr><tr><td><code>本轮执行完成</code></td><td>当前分钟扫描完毕,显示执行数量</td></tr></tbody></table><div class="tip custom-block"><p class="custom-block-title">TIP</p><p>没有到期任务时 Daemon 静默等待(不输出日志),属正常行为。</p></div><p><strong>前端联动:</strong> Daemon 启动后,「定时任务」模块顶部显示绿色「守护进程运行中 (PID: xxx)」按钮;未启动时显示灰色。</p><div class="tip custom-block"><p class="custom-block-title">状态检测原理</p><p>前端通过 <code>GET /api/job/daemonStatus</code> 轮询,后端读取 <code>storage/app/job_daemon.lock</code> 中的 PID 并检查进程是否存活。若进程非正常退出但锁文件残留,前端可能仍显示「运行中」——执行 <code>php artisan job:daemon --stop</code> 或删除锁文件清理。</p></div><h4 id="方式-B-Supervisor-管理-Linux-生产推荐-" tabindex="-1">方式 B:Supervisor 管理(Linux 生产推荐) <a class="header-anchor" href="#方式-B-Supervisor-管理-Linux-生产推荐-" aria-label="Permalink to "方式 B:Supervisor 管理(Linux 生产推荐)""></a></h4><div class="language-ini vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ini</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">; /etc/supervisor/conf.d/rxthinkcmf-job.conf</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#59873A;">program:rxthinkcmf-job</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">command</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">php /www/RXThinkCMF_Laravel13_NaiveVue/artisan job:daemon</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">directory</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/www/RXThinkCMF_Laravel13_NaiveVue</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">autostart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">true</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">autorestart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">true</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">user</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">www-data</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">numprocs</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">1</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">redirect_stderr</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">true</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">stdout_logfile</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/var/log/rxthinkcmf-job.log</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">stdout_logfile_maxbytes</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">10MB</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">stdout_logfile_backups</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">5</span></span></code></pre></div><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> supervisorctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> reread</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> &&</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> supervisorctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> update</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> supervisorctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> start</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-job</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> supervisorctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> status</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-job</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">tail</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> /var/log/rxthinkcmf-job.log</span></span></code></pre></div><h4 id="方式-C-systemd-服务-Linux-生产推荐-" tabindex="-1">方式 C:systemd 服务(Linux 生产推荐) <a class="header-anchor" href="#方式-C-systemd-服务-Linux-生产推荐-" aria-label="Permalink to "方式 C:systemd 服务(Linux 生产推荐)""></a></h4><div class="language-ini vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ini</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">; /etc/systemd/system/rxthinkcmf-job.service</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#59873A;">Unit</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">Description</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">RXThinkCMF Job Daemon</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">After</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">network.target mysql.service</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#59873A;">Service</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">Type</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">simple</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">User</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">www-data</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">WorkingDirectory</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/www/RXThinkCMF_Laravel13_NaiveVue</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">ExecStart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">/usr/bin/php /www/RXThinkCMF_Laravel13_NaiveVue/artisan job:daemon</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">Restart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">always</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">RestartSec</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">10</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#59873A;">Install</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">WantedBy</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">multi-user.target</span></span></code></pre></div><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> systemctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> enable</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-job</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> systemctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> start</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-job</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> systemctl</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> status</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-job</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">sudo</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> journalctl</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -u</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> rxthinkcmf-job</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span></span></code></pre></div><h4 id="方式-D-nohup-后台运行-简单场景-" tabindex="-1">方式 D:nohup 后台运行(简单场景) <a class="header-anchor" href="#方式-D-nohup-后台运行-简单场景-" aria-label="Permalink to "方式 D:nohup 后台运行(简单场景)""></a></h4><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">nohup</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> storage/logs/job_daemon.log</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> 2>&1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> &</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">ps</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> aux</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> |</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> grep</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span></span>
|
||
<span class="line"><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">kill</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $(</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">pgrep</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -f</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">job:daemon</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span></span></code></pre></div><h4 id="Docker-环境" tabindex="-1">Docker 环境 <a class="header-anchor" href="#Docker-环境" aria-label="Permalink to "Docker 环境""></a></h4><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">docker</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> compose</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> exec</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> app</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 或以独立常驻容器运行 app 镜像的 artisan 命令</span></span></code></pre></div><h3 id="三种方式对比" tabindex="-1">三种方式对比 <a class="header-anchor" href="#三种方式对比" aria-label="Permalink to "三种方式对比""></a></h3><table tabindex="0"><thead><tr><th>特性</th><th>Crontab</th><th>Windows 计划任务</th><th>Daemon 守护进程</th></tr></thead><tbody><tr><td>适用系统</td><td>Linux / macOS</td><td>Windows</td><td>全平台</td></tr><tr><td>最小间隔</td><td>1 分钟</td><td>1 分钟</td><td>分钟级(每轮 sleep 60s)</td></tr><tr><td>资源占用</td><td>低(按需启动)</td><td>低(按需启动)</td><td>常驻内存</td></tr><tr><td>可靠性</td><td>高</td><td>高</td><td>高(配合 Supervisor/systemd)</td></tr><tr><td>日志追踪</td><td>需重定向</td><td>任务计划程序</td><td>自带输出</td></tr><tr><td>推荐场景</td><td>生产环境</td><td>Windows 生产</td><td>开发调试 / 不便配置 cron</td></tr></tbody></table><div class="tip custom-block"><p class="custom-block-title">推荐选择</p><ul><li><strong>Linux 生产环境</strong>:Crontab(简单可靠)</li><li><strong>Windows 生产环境</strong>:任务计划程序 或 Daemon + 计划任务守护</li><li><strong>Docker 环境</strong>:Daemon(容器内运行)</li><li><strong>本地开发调试</strong>:Daemon 前台运行(直接观察日志输出)</li></ul></div><h2 id="新建定时任务步骤" tabindex="-1">新建定时任务步骤 <a class="header-anchor" href="#新建定时任务步骤" aria-label="Permalink to "新建定时任务步骤""></a></h2><h3 id="_1-创建任务处理器" tabindex="-1">1. 创建任务处理器 <a class="header-anchor" href="#_1-创建任务处理器" aria-label="Permalink to "1. 创建任务处理器""></a></h3><div class="language-php vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">php</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"><?</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">php</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// app/Task/CleanLogTask.php(本步骤新建的处理器)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">namespace</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> App</span><span style="--shiki-dark:#F286C4;--shiki-dark-font-style:italic;--shiki-light:#999999;--shiki-light-font-style:inherit;">\</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;">Task</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">/**</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 清理过期日志任务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> *</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 数据库 url 字段:CleanLog</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 参数格式:{"days": 30}</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> */</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">class</span><span style="--shiki-dark:#97E1F1;--shiki-light:#2E8F82;"> CleanLogTask</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> extends</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#59873A;--shiki-light-font-style:inherit;"> BaseTask</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> /**</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 执行任务</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> *</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">@param</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> array</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> $params 任务参数</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">@return</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> string</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> 执行结果消息</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">@throws</span><span style="--shiki-dark:#F286C4;--shiki-dark-font-style:italic;--shiki-light:#999999;--shiki-light-font-style:inherit;"> \</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;">Exception</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> 执行失败时抛出</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> */</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> public</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> function</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> run</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">array</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">params</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> [])</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">:</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> string</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">days</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">params</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">days</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ??</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 30</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cutoffDate</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> date</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">Y-m-d H:i:s</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> strtotime</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">-</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">{$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B56959;">days</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> days</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">));</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 清理登录日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">loginCount</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> LoginLog</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">::</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">where</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">create_time</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"><</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cutoffDate</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">-></span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">delete</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 清理操作日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">operCount</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> OperationLog</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">::</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">where</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">create_time</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"><</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cutoffDate</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">-></span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">delete</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 清理任务日志</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">jobCount</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> JobLog</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">::</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">where</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">start_time</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"><</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cutoffDate</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">-></span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">delete</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> "</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">已清理 </span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">{</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B56959;">days</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">}</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 天前的日志:登录日志 </span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">{</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B56959;">loginCount</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">}</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 条,操作日志 </span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">{</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B56959;">operCount</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">}</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 条,任务日志 </span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">{</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">$</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B56959;">jobCount</span><span style="--shiki-dark:#E7EE98;--shiki-light:#999999;">}</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> 条</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">"</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span></code></pre></div><p>内置示例处理器:<code>app/Task/HelloWorldTask.php</code>(验证 daemon 调度)、<code>app/Task/SendSmsTask.php</code>(示例任务)。</p><h3 id="_2-在数据库-job-表中配置" tabindex="-1">2. 在数据库 job 表中配置 <a class="header-anchor" href="#_2-在数据库-job-表中配置" aria-label="Permalink to "2. 在数据库 job 表中配置""></a></h3><div class="language-sql vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">sql</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">INSERT INTO</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> laravel_job (</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> job_name, job_alias, job_group, job_trigger,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> url</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, params, cron_expression,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> execute_policy, </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">status</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, is_sync,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> is_delete, create_user, create_time</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">) </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">VALUES</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;"> (</span></span>
|
||
<span class="line"><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">清理过期日志</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">CleanLog</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">系统维护</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">cron</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">CleanLog</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">{"days":30}</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">0 2 * * *</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 2</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">0</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 0</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">admin</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">, </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">NOW</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">()</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">);</span></span></code></pre></div><p>(也可在「定时任务」管理界面新增。)</p><h3 id="_3-配置触发方式-三选一-" tabindex="-1">3. 配置触发方式(三选一) <a class="header-anchor" href="#_3-配置触发方式-三选一-" aria-label="Permalink to "3. 配置触发方式(三选一)""></a></h3><div class="language-bash vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">bash</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 方式一:Linux Crontab</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">crontab</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> -e</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 添加:* * * * * cd /项目路径 && /usr/bin/php artisan job:run >> /dev/null 2>&1</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 方式二:Windows 计划任务(见上文 schtasks 示例)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 方式三:Daemon 守护进程</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">php</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> artisan</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"> job:daemon</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"># 停止:php artisan job:daemon --stop</span></span></code></pre></div><h2 id="Service-配置-摘自-app-Services-JobService-php-实际代码-" tabindex="-1">Service 配置(摘自 <code>app/Services/JobService.php</code> 实际代码) <a class="header-anchor" href="#Service-配置-摘自-app-Services-JobService-php-实际代码-" aria-label="Permalink to "Service 配置(摘自 `app/Services/JobService.php` 实际代码)""></a></h2><div class="language-php vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">php</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">class</span><span style="--shiki-dark:#97E1F1;--shiki-light:#2E8F82;"> JobService</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> extends</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#59873A;--shiki-light-font-style:inherit;"> BaseService</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> use</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> HasCrudOperations</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> HasQueryScopes</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> HasUniqueCheck</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> protected</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">modelClass</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> Job</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">::</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">class</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 任务名 / 任务别名模糊匹配</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> protected</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> array</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">pageLikeFields</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> [</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">job_name</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">job_alias</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">];</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 状态 / 任务分组精确匹配</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> protected</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> array</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">pageEqFields</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> [</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">status</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">job_group</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">];</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 任务别名全局唯一</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> protected</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> array</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">uniqueFields</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> [</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">job_alias</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">];</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span></code></pre></div><div class="info custom-block"><p class="custom-block-title">未配置字典翻译与文件字段</p><p>任务表的 <code>status</code>、<code>execute_policy</code> 等枚举直接以数值存储,前端按 <a href="/zh/modules/job.html">6.11 定时任务</a> 状态说明渲染,<code>JobService</code> 未声明 <code>serializeMaps</code> / <code>fileFields</code>。</p></div><h2 id="API-接口" tabindex="-1">API 接口 <a class="header-anchor" href="#API-接口" aria-label="Permalink to "API 接口""></a></h2><h3 id="任务管理" tabindex="-1">任务管理 <a class="header-anchor" href="#任务管理" aria-label="Permalink to "任务管理""></a></h3><table tabindex="0"><thead><tr><th>方法</th><th>路径</th><th>权限码</th><th>说明</th></tr></thead><tbody><tr><td>GET</td><td><code>/api/job/page</code></td><td>sys:job:page</td><td>分页列表</td></tr><tr><td>GET</td><td><code>/api/job/list</code></td><td>sys:job:list</td><td>全量列表</td></tr><tr><td>GET</td><td><code>/api/job/detail/{id}</code></td><td>sys:job:detail</td><td>详情</td></tr><tr><td>GET</td><td><code>/api/job/runOnce/{id}</code></td><td>sys:job:execute</td><td>手动执行一次</td></tr><tr><td>GET</td><td><code>/api/job/pause/{id}</code></td><td>sys:job:pause</td><td>暂停任务</td></tr><tr><td>GET</td><td><code>/api/job/resume/{id}</code></td><td>sys:job:resume</td><td>恢复任务</td></tr><tr><td>GET</td><td><code>/api/job/daemonStatus</code></td><td>—</td><td>守护进程状态</td></tr><tr><td>POST</td><td><code>/api/job/add</code></td><td>sys:job:add</td><td>新增任务</td></tr><tr><td>POST</td><td><code>/api/job/status</code></td><td>sys:job:update</td><td>设置状态</td></tr><tr><td>PUT</td><td><code>/api/job/update</code></td><td>sys:job:update</td><td>修改任务</td></tr><tr><td>DELETE</td><td><code>/api/job/delete/{id}</code></td><td>sys:job:delete</td><td>删除任务</td></tr><tr><td>DELETE</td><td><code>/api/job/batchDelete</code></td><td>sys:job:batchDelete</td><td>批量删除</td></tr></tbody></table><h3 id="任务日志" tabindex="-1">任务日志 <a class="header-anchor" href="#任务日志" aria-label="Permalink to "任务日志""></a></h3><table tabindex="0"><thead><tr><th>方法</th><th>路径</th><th>权限码</th><th>说明</th></tr></thead><tbody><tr><td>GET</td><td><code>/api/job/log/page</code></td><td>sys:job:page</td><td>日志分页</td></tr><tr><td>GET</td><td><code>/api/job/log/detail/{id}</code></td><td>sys:job:detail</td><td>日志详情</td></tr><tr><td>DELETE</td><td><code>/api/job/log/delete/{id}</code></td><td>sys:job:delete</td><td>删除日志</td></tr><tr><td>DELETE</td><td><code>/api/job/log/batchDelete</code></td><td>sys:job:batchDelete</td><td>批量删除</td></tr></tbody></table><h2 id="核心代码解析" tabindex="-1">核心代码解析 <a class="header-anchor" href="#核心代码解析" aria-label="Permalink to "核心代码解析""></a></h2><h3 id="Cron-表达式匹配-JobService-matchCronField-" tabindex="-1">Cron 表达式匹配(JobService::matchCronField) <a class="header-anchor" href="#Cron-表达式匹配-JobService-matchCronField-" aria-label="Permalink to "Cron 表达式匹配(JobService::matchCronField)""></a></h3><div class="language-php vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">php</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// app/Services/JobService.php(来自项目实际代码)</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">/**</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 匹配 cron 字段</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> *</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 支持以下语法:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * - *:匹配所有</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * - */</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">n:每隔</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> n</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> 个单位</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> n</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">-</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">m:范围匹配</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> n</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">m</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">...</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;">:逗号分隔的多值</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> *</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#A65E2B;"> n:单个值精确匹配</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> */</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">protected</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> function</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> matchCronField</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> int</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">current</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">:</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> bool</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> ($</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">*</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;"> true</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 处理 */n(每隔 n 分钟/小时等)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">preg_match</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#EE6666;--shiki-light:#B5695977;">'/</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">^</span><span style="--shiki-dark:#F286C4;--shiki-light:#BDA437;">\*\/</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;">(</span><span style="--shiki-dark:#F286C4;--shiki-light:#BDA437;">\d</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">+</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">$</span><span style="--shiki-dark:#EE6666;--shiki-light:#B5695977;">/'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">m</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">))</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">current</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> %</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#AB5959;--shiki-light-font-style:inherit;">int</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">m</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 0</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 处理 n-m(范围)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">preg_match</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#EE6666;--shiki-light:#B5695977;">'/</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">^</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;">(</span><span style="--shiki-dark:#F286C4;--shiki-light:#BDA437;">\d</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">+</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;">)-(</span><span style="--shiki-dark:#F286C4;--shiki-light:#BDA437;">\d</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">+</span><span style="--shiki-dark:#E7EE98;--shiki-light:#AB5E3F;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">$</span><span style="--shiki-dark:#EE6666;--shiki-light:#B5695977;">/'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">m</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">))</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">current</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> >=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#AB5959;--shiki-light-font-style:inherit;">int</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">m</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> &&</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">current</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> <=</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#AB5959;--shiki-light-font-style:inherit;">int</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">m</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;">2</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">];</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 处理逗号分隔的多个值</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;">strpos</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">($</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> !==</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;"> false</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">values</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> array_map</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">intval</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> explode</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">));</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> in_array</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">($</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">current</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">values</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 单个值</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#AB5959;--shiki-light-font-style:inherit;">int</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">cronField</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">current</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span></code></pre></div><h3 id="防重复执行-JobService-hasRunThisMinute-" tabindex="-1">防重复执行(JobService::hasRunThisMinute) <a class="header-anchor" href="#防重复执行-JobService-hasRunThisMinute-" aria-label="Permalink to "防重复执行(JobService::hasRunThisMinute)""></a></h3><div class="language-php vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">php</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">/**</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * 检查任务在当前分钟是否已执行过</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> *</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> * Daemon 模式下,防止同一分钟内重复执行。</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> */</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">public</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> function</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> hasRunThisMinute</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">int</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">jobId</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">:</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> bool</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">{</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">minuteStart</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> date</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">Y-m-d H:i</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> .</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">:00</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">minuteEnd</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#97E1F1;--shiki-light:#998418;"> date</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">Y-m-d H:i</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> .</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">:59</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#998418;--shiki-light-font-style:inherit;"> JobLog</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">::</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">where</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">job_id</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">jobId</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -></span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">where</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">start_time</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">>=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">minuteStart</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -></span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">where</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">start_time</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;"><=</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> $</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">minuteEnd</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> -></span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">count</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">()</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ></span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 0</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span></code></pre></div><h3 id="JobService-能力清单" tabindex="-1">JobService 能力清单 <a class="header-anchor" href="#JobService-能力清单" aria-label="Permalink to "JobService 能力清单""></a></h3><table tabindex="0"><thead><tr><th>方法</th><th>说明</th></tr></thead><tbody><tr><td><code>runPending()</code></td><td>扫描并执行全部到期任务,返回执行数</td></tr><tr><td><code>shouldRun($job)</code></td><td>解析 cron 判断任务是否到期</td></tr><tr><td><code>executeJob($job)</code></td><td>执行入口(策略检查 + 执行 + 记录 JobLog)</td></tr><tr><td><code>runOnce($id)</code></td><td>手动执行一次(忽略 cron)</td></tr><tr><td><code>setStatus($id, $status)</code> / <code>pause($id)</code> / <code>resume($id)</code></td><td>状态流转</td></tr><tr><td><code>executeHttp($url, $params)</code></td><td>HTTP 类任务执行</td></tr><tr><td><code>executeInternal($url, $params)</code></td><td>内部 Task 类执行(映射 <code>App\Task\{Name}Task</code>)</td></tr></tbody></table><h2 id="注意事项" tabindex="-1">注意事项 <a class="header-anchor" href="#注意事项" aria-label="Permalink to "注意事项""></a></h2><ol><li><strong>互斥运行</strong>:Cron 模式和 Daemon 模式不要同时使用,否则会导致任务重复执行</li><li><strong>防重复执行</strong>:Daemon 模式内置防重复机制,同一任务在同一分钟内不会重复执行</li><li><strong>错误隔离</strong>:单个任务执行失败不影响其他任务和主循环</li><li><strong>优雅退出</strong>:Daemon 支持 <code>SIGTERM</code>/<code>SIGINT</code> 信号,<code>Ctrl+C</code> 或 <code>kill</code> 均可优雅停止</li><li><strong>锁文件</strong>:Daemon 的锁文件位于 <code>storage/app/job_daemon.lock</code>,异常退出后残留锁会自动检测并清理</li><li><strong>Windows 兼容</strong>:Daemon 在 Windows 下可正常运行,但信号处理(pcntl)不可用,需通过 <code>--stop</code> 参数或 <code>taskkill</code> 停止</li><li><strong>日志截断</strong>:执行结果消息截取前 500 字符,异常信息截取前 2000 字符写入 job_log</li><li><strong>create_user</strong>:命令行执行的任务日志中 <code>create_user</code> 由 HasAuditColumns trait 自动处理(无登录用户时为空)</li></ol><h2 id="常见问题" tabindex="-1">常见问题 <a class="header-anchor" href="#常见问题" aria-label="Permalink to "常见问题""></a></h2><h3 id="Q-任务不执行-" tabindex="-1">Q: 任务不执行? <a class="header-anchor" href="#Q-任务不执行-" aria-label="Permalink to "Q: 任务不执行?""></a></h3><p>A: 检查以下几点:</p><ol><li>任务状态是否为 <code>1</code>(运行中)</li><li>Cron 表达式格式是否正确(5 段)</li><li>Crontab 是否已配置且 cron 服务已启动</li><li>PHP 路径是否正确(建议使用绝对路径)</li><li>手动执行 <code>php artisan job:run</code> 是否正常</li></ol><h3 id="Q-任务重复执行-" tabindex="-1">Q: 任务重复执行? <a class="header-anchor" href="#Q-任务重复执行-" aria-label="Permalink to "Q: 任务重复执行?""></a></h3><p>A: Daemon 模式下检查 <code>hasRunThisMinute</code> 是否生效;Crontab 模式下确保只有一个 cron 在触发(<code>crontab -l</code> 检查重复项)。</p><h3 id="Q-任务执行超时-" tabindex="-1">Q: 任务执行超时? <a class="header-anchor" href="#Q-任务执行超时-" aria-label="Permalink to "Q: 任务执行超时?""></a></h3><p>A: 检查 PHP 的 <code>max_execution_time</code> 配置,长时间任务建议拆分或在处理器内调大 <code>set_time_limit(0)</code>。</p><h3 id="Q-如何查看任务执行日志-" tabindex="-1">Q: 如何查看任务执行日志? <a class="header-anchor" href="#Q-如何查看任务执行日志-" aria-label="Permalink to "Q: 如何查看任务执行日志?""></a></h3><p>A: 两种方式:</p><ol><li><strong>控制台实时日志</strong>:Daemon 前台运行时,<code>[执行]</code>、<code>[跳过]</code>、<code>[失败]</code> 直接输出到终端</li><li><strong>数据库持久化日志</strong>:通过 <code>GET /api/job/log/page</code> 查询,或直接查 <code>laravel_job_log</code> 表</li></ol><h3 id="Q-Daemon-控制台没有新日志输出-是卡住了吗-" tabindex="-1">Q: Daemon 控制台没有新日志输出,是卡住了吗? <a class="header-anchor" href="#Q-Daemon-控制台没有新日志输出-是卡住了吗-" aria-label="Permalink to "Q: Daemon 控制台没有新日志输出,是卡住了吗?""></a></h3><p>A: 不是。Daemon 每分钟检查一次,没有到期任务时静默等待,不输出任何日志。</p><h3 id="Q-Windows-下-Daemon-如何启动和停止-" tabindex="-1">Q: Windows 下 Daemon 如何启动和停止? <a class="header-anchor" href="#Q-Windows-下-Daemon-如何启动和停止-" aria-label="Permalink to "Q: Windows 下 Daemon 如何启动和停止?""></a></h3><p>A: 项目根目录打开 CMD:</p><div class="language-cmd vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">cmd</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">:: 启动</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">php artisan job:daemon</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">:: 停止(另开一个 CMD 窗口)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">php artisan job:</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">daemon</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> --</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">stop</span></span></code></pre></div><p>如提示 <code>Daemon 已在运行中 (PID: xxx)</code>,先执行 <code>php artisan job:daemon --stop</code> 停止旧进程,或手动删除 <code>storage/app/job_daemon.lock</code>。</p><h3 id="Q-提示找不到-Task-类-" tabindex="-1">Q: 提示找不到 Task 类? <a class="header-anchor" href="#Q-提示找不到-Task-类-" aria-label="Permalink to "Q: 提示找不到 Task 类?""></a></h3><p>A: 确认 <code>url</code> 字段的类名与 <code>app/Task/</code> 下的类文件一致(命名空间 <code>App\Task</code>),且类名采用大驼峰(<code>SendSms</code> → <code>SendSmsTask</code>)。</p></div></div></main><footer class="VPDocFooter" data-v-e6f2a212 data-v-1bcd8184><!--[--><!--]--><div class="edit-info" data-v-1bcd8184><div class="edit-link" data-v-1bcd8184><a class="VPLink link vp-external-link-icon no-icon edit-link-button" href="https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue" target="_blank" rel="noreferrer" data-v-1bcd8184><!--[--><span class="vpi-square-pen edit-link-icon" data-v-1bcd8184></span> 对本页提出修改建议<!--]--></a></div><!----></div><nav class="prev-next" aria-labelledby="doc-footer-aria-label" data-v-1bcd8184><span class="visually-hidden" id="doc-footer-aria-label" data-v-1bcd8184>Pager</span><div class="pager" data-v-1bcd8184><a class="VPLink link pager-link prev" href="/zh/modules/category.html" data-v-1bcd8184><!--[--><span class="desc" data-v-1bcd8184>上一页</span><span class="title" data-v-1bcd8184>6.10 分类管理</span><!--]--></a></div><div class="pager" data-v-1bcd8184><a class="VPLink link pager-link next" href="/zh/modules/param.html" data-v-1bcd8184><!--[--><span class="desc" data-v-1bcd8184>下一页</span><span class="title" data-v-1bcd8184>6.12 参数管理</span><!--]--></a></div></nav></footer><!--[--><!--]--></div></div></div><!--[--><!--]--></div></div><footer class="VPFooter has-sidebar" data-v-d8b57b2d data-v-566314d4><div class="container" data-v-566314d4><p class="message" data-v-566314d4>小蚂蚁云团队 · 提供技术支持</p><p class="copyright" data-v-566314d4>Copyright © 2018~2026 www.rxthink.cn. All rights reserved.</p></div></footer><!--[--><!--]--></div></div>
|
||
<script>window.__VP_HASH_MAP__=JSON.parse("{\"404.md\":\"DnXdkDqR\",\"index.md\":\"D3bZE_H9\",\"readme.md\":\"Dc96kdRW\",\"zh_api-spec_dict-api.md\":\"MfTlf-Rq\",\"zh_api-spec_error-code.md\":\"DdKE6Yjo\",\"zh_api-spec_overview.md\":\"Bd3_vI6O\",\"zh_api-spec_pagination.md\":\"B4LdMyoJ\",\"zh_api-spec_response.md\":\"Dx5cj9ua\",\"zh_api-spec_token.md\":\"2GDZM1pl\",\"zh_api-spec_upload.md\":\"ZW8K5EtN\",\"zh_appendix_api-cheatsheet.md\":\"gUidzOVw\",\"zh_appendix_commands.md\":\"Bvu5iDkw\",\"zh_appendix_components.md\":\"Bq2_a_sa\",\"zh_appendix_config-reference.md\":\"Dw4OaGfC\",\"zh_appendix_database-tables.md\":\"b7Dnw6YD\",\"zh_appendix_enums.md\":\"Bu6UKDK_\",\"zh_appendix_faq.md\":\"BLDPFBJw\",\"zh_appendix_functions.md\":\"C2SJVa13\",\"zh_appendix_glossary.md\":\"D8XQrdlz\",\"zh_appendix_middleware.md\":\"B9ZAk2ta\",\"zh_appendix_stores.md\":\"D1IiBcxM\",\"zh_architecture_backend-layer.md\":\"BZLK6j4N\",\"zh_architecture_base-classes.md\":\"Byq0OFjk\",\"zh_architecture_cache.md\":\"BcDBCO52\",\"zh_architecture_cross-cutting.md\":\"DUqtvvRR\",\"zh_architecture_database-design.md\":\"Ffr7_1E7\",\"zh_architecture_directory-design.md\":\"BlzSL-HM\",\"zh_architecture_extensibility.md\":\"DKG_sM5U\",\"zh_architecture_frontend-layer.md\":\"BAMcetWV\",\"zh_architecture_overview.md\":\"vEGZ1jMd\",\"zh_architecture_request-flow.md\":\"3RRedLuR\",\"zh_architecture_security.md\":\"TpAF1lOu\",\"zh_changelog.md\":\"DiySWD5D\",\"zh_core_attributes.md\":\"Dzfb9y1p\",\"zh_core_auth-flow.md\":\"B7yZ5Gpg\",\"zh_core_captcha.md\":\"iib8dTgy\",\"zh_core_config.md\":\"BPnTJJCo\",\"zh_core_cors.md\":\"Cs05vvXq\",\"zh_core_data-scope.md\":\"DLlLbAzb\",\"zh_core_demo-mode.md\":\"BKZB_gLO\",\"zh_core_dict-guide.md\":\"CKPAOxg8\",\"zh_core_dict.md\":\"CLvH0VmA\",\"zh_core_exception.md\":\"B7pHA59D\",\"zh_core_jwt.md\":\"DBhoQoGB\",\"zh_core_login-log.md\":\"CPHrxVGq\",\"zh_core_operation-log.md\":\"1EkrIiz9\",\"zh_core_param.md\":\"Cj9xUksT\",\"zh_core_password.md\":\"BB-pZGqh\",\"zh_core_rbac.md\":\"C7MAblAp\",\"zh_core_tenant.md\":\"DE-Ie1tJ\",\"zh_course.md\":\"DNsQCF_c\",\"zh_deploy_backend.md\":\"CuaqEWkv\",\"zh_deploy_backup.md\":\"rlmjryBF\",\"zh_deploy_checklist.md\":\"CeB-bMRe\",\"zh_deploy_ci-cd.md\":\"3J-fYqMO\",\"zh_deploy_db-migrate.md\":\"WfdLTVlT\",\"zh_deploy_docker.md\":\"CzBCpm9P\",\"zh_deploy_env-plan.md\":\"Cae93qIt\",\"zh_deploy_frontend.md\":\"C56IAqk1\",\"zh_deploy_performance.md\":\"Y7MSfya6\",\"zh_deploy_security.md\":\"B4d0UMPr\",\"zh_deploy_troubleshooting.md\":\"CeKbcq-N\",\"zh_directory.md\":\"BLYS-05A\",\"zh_frontend_api-module.md\":\"C230o9H9\",\"zh_frontend_directory.md\":\"DUolTlPN\",\"zh_frontend_display-components.md\":\"DSMhO7Op\",\"zh_frontend_env-config.md\":\"DrNbnag5\",\"zh_frontend_excel-components.md\":\"k_GUj_8y\",\"zh_frontend_form-components.md\":\"CzyBz1_G\",\"zh_frontend_http.md\":\"Bo4xVylL\",\"zh_frontend_layout.md\":\"BCznM-nU\",\"zh_frontend_login.md\":\"B0QR3I0r\",\"zh_frontend_new-page.md\":\"IgvnZMeV\",\"zh_frontend_overview.md\":\"EFvWGsmj\",\"zh_frontend_permission.md\":\"kckFUkzq\",\"zh_frontend_router.md\":\"CeOqjdkk\",\"zh_frontend_store.md\":\"Cx0VAmCT\",\"zh_frontend_style.md\":\"CxbsmuiD\",\"zh_frontend_utils.md\":\"DeKxhZot\",\"zh_generator_cli.md\":\"DTYhQP9g\",\"zh_generator_code-engine.md\":\"CkEnudWF\",\"zh_generator_config.md\":\"BWL7vDRz\",\"zh_generator_demo.md\":\"3VkiVrSN\",\"zh_generator_faq.md\":\"D3lNgtMV\",\"zh_generator_overview.md\":\"WbcMl4TZ\",\"zh_generator_parser.md\":\"CJCjOevX\",\"zh_generator_templates.md\":\"BqjfbiHt\",\"zh_generator_web-ui.md\":\"fUnU3aW6\",\"zh_guide_code-list.md\":\"BiDZT8m8\",\"zh_guide_controller.md\":\"o8N6W8UL\",\"zh_guide_database.md\":\"B2wsfmMF\",\"zh_guide_faq.md\":\"J1yRuoN7\",\"zh_guide_frontend-integration.md\":\"C0fSqH56\",\"zh_guide_logic.md\":\"DLMhUdwu\",\"zh_guide_model.md\":\"CvHPBNia\",\"zh_guide_overview.md\":\"DREbPZg0\",\"zh_guide_permission.md\":\"BJLsWl4l\",\"zh_guide_route.md\":\"CSnkVEip\",\"zh_guide_validator.md\":\"BXqdYRI0\",\"zh_introduction.md\":\"C9_-08eb\",\"zh_modules_article.md\":\"CxtP_Ohh\",\"zh_modules_category.md\":\"ChUkWDbt\",\"zh_modules_city.md\":\"BTRogsf9\",\"zh_modules_content.md\":\"CnaYI4Jj\",\"zh_modules_dept.md\":\"CSUwJEDw\",\"zh_modules_filetemplate.md\":\"BppDQtLJ\",\"zh_modules_index.md\":\"BvSZQSdA\",\"zh_modules_job.md\":\"2y2grIvc\",\"zh_modules_level.md\":\"CzxdosLj\",\"zh_modules_menu.md\":\"BRCydi8h\",\"zh_modules_param.md\":\"quKBjTEc\",\"zh_modules_position.md\":\"--IG6IrC\",\"zh_modules_role.md\":\"lz5Yd6fi\",\"zh_modules_tenant.md\":\"DtULuhMo\",\"zh_modules_user.md\":\"CWs1L1oP\",\"zh_other_contributing.md\":\"ieB_l0KJ\",\"zh_other_declare.md\":\"DcbcZmrU\",\"zh_other_sponsor.md\":\"ATS7Udz-\",\"zh_quickstart_backend-start.md\":\"D7RSgWvQ\",\"zh_quickstart_database-init.md\":\"BEufKVXY\",\"zh_quickstart_docker.md\":\"CzbPPEyb\",\"zh_quickstart_env-vars.md\":\"BQyx45xF\",\"zh_quickstart_environment.md\":\"CtRB6UiH\",\"zh_quickstart_faq.md\":\"CFcCRkQ8\",\"zh_quickstart_first-api.md\":\"D2e-a5iI\",\"zh_quickstart_frontend-start.md\":\"V-MlYwni\",\"zh_quickstart_laragon.md\":\"yfAgBues\",\"zh_standards_api-response.md\":\"CIhpSjY-\",\"zh_standards_backend-code.md\":\"bhPc81GA\",\"zh_standards_code-review.md\":\"DJ0LImTE\",\"zh_standards_deletion.md\":\"DB-w5P5J\",\"zh_standards_frontend-code.md\":\"BaSDfPRq\",\"zh_standards_git.md\":\"QpX2hwm-\",\"zh_standards_pagination.md\":\"DzWxZRNC\",\"zh_tech-stack.md\":\"DRd2TU8E\",\"zh_tools_db-migrate.md\":\"Dzr84YsD\",\"zh_tools_excel.md\":\"C4S1jxPR\",\"zh_tools_file-components.md\":\"DODbleUF\",\"zh_tools_rich-text.md\":\"DyBRDKc5\",\"zh_tools_upload-config.md\":\"7tLUywUj\",\"zh_tools_upload.md\":\"j1AQEVy9\",\"zh_why.md\":\"WG0cnOZz\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"小蚂蚁云\",\"titleTemplate\":\"RXThinkCMF 开发文档\",\"description\":\"A VitePress site\",\"base\":\"/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":\"light\",\"themeConfig\":{\"logo\":\"/logo.svg\",\"outline\":[2,3],\"socialLinks\":[{\"icon\":\"github\",\"link\":\"https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue\"}],\"footer\":{\"copyright\":\"Copyright © 2018~2026 www.rxthink.cn. All rights reserved.\",\"message\":\"小蚂蚁云团队 · 提供技术支持\"},\"editLink\":{\"pattern\":\"https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue\",\"text\":\"对本页提出修改建议\"},\"search\":{\"provider\":\"local\"}},\"locales\":{\"root\":{\"label\":\"简体中文\",\"lang\":\"zh-CN\",\"link\":\"/\",\"description\":\"RXThinkCMF 企业级前后端分离后台管理系统 - Laravel 13 + Vue3 + NaiveUI\",\"head\":[[\"meta\",{\"property\":\"og:url\",\"content\":\"http://docs.laravel13.naivevue.rxthink.cn\"}],[\"meta\",{\"property\":\"og:description\",\"content\":\"RXThinkCMF 企业级前后端分离后台管理系统 - Laravel 13 + Vue3 + NaiveUI\"}],[\"meta\",{\"property\":\"twitter:url\",\"content\":\"http://docs.laravel13.naivevue.rxthink.cn\"}],[\"meta\",{\"property\":\"twitter:title\",\"content\":\"RXThinkCMF Laravel13+NaiveUI 开发文档\"}],[\"meta\",{\"property\":\"twitter:description\",\"content\":\"RXThinkCMF 企业级前后端分离后台管理系统 - Laravel 13 + Vue3 + NaiveUI\"}],[\"script\",{},\"\\n var _hmt = _hmt || [];\\n (function() {\\n var hm = document.createElement(\\\"script\\\");\\n hm.src = \\\"https://hm.baidu.com/hm.js?8c4ed7e2f1d12bafe9e22e93e30237d4\\\";\\n var s = document.getElementsByTagName(\\\"script\\\")[0];\\n s.parentNode.insertBefore(hm, s);\\n })();\\n \"]],\"themeConfig\":{\"editLink\":{\"pattern\":\"https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue\",\"text\":\"对本页提出修改建议\"},\"outline\":{\"label\":\"本页内容\"},\"docFooter\":{\"prev\":\"上一页\",\"next\":\"下一页\"},\"nav\":[{\"text\":\"官网\",\"link\":\"https://www.rxthink.cn\"},{\"text\":\"授权\",\"link\":\"https://www.rxthink.cn/goods/detail/2\"},{\"text\":\"部署文档\",\"items\":[{\"text\":\"RXThinkCMF混编版ThinkPHP6+Layui版本\",\"link\":\"http://docs.thinkphp6.layui.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP6+ElementPlus版本\",\"link\":\"http://docs.thinkphp6.elevue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP6+AntDesign版本\",\"link\":\"http://docs.thinkphp6.antdvue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP6+NaiveUI版本\",\"link\":\"http://docs.thinkphp6.naivevue.rxthink.cn\"},{\"text\":\"RXThinkCMF混编版ThinkPHP8+Layui版本\",\"link\":\"http://docs.thinkphp8.layui.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP8+ElementPlus版本\",\"link\":\"http://docs.thinkphp8.elevue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP8+AntDesign版本\",\"link\":\"http://docs.thinkphp8.antdvue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP8+NaiveUI版本\",\"link\":\"http://docs.thinkphp8.naivevue.rxthink.cn\"},{\"text\":\"RXThinkCMF混编版Laravel13+Layui版本\",\"link\":\"http://docs.laravel13.layui.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离Laravel13+ElementPlus版本\",\"link\":\"http://docs.laravel13.elevue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离Laravel13+AntDesign版本\",\"link\":\"http://docs.laravel13.antdvue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离Laravel13+NaiveUI版本\",\"link\":\"http://docs.laravel13.naivevue.rxthink.cn\"}]},{\"text\":\"在线演示\",\"items\":[{\"text\":\"RXThinkCMF混编版ThinkPHP6+Layui版本\",\"link\":\"http://manage.thinkphp6.layui.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP6+ElementPlus版本\",\"link\":\"http://manage.thinkphp6.elevue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP6+AntDesign版本\",\"link\":\"http://manage.thinkphp6.antdvue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP6+NaiveUI版本\",\"link\":\"http://manage.thinkphp6.naivevue.rxthink.cn\"},{\"text\":\"RXThinkCMF混编版ThinkPHP8+Layui版本\",\"link\":\"http://manage.thinkphp8.layui.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP8+ElementPlus版本\",\"link\":\"http://manage.thinkphp8.elevue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP8+AntDesign版本\",\"link\":\"http://manage.thinkphp8.antdvue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离ThinkPHP8+NaiveUI版本\",\"link\":\"http://manage.thinkphp8.naivevue.rxthink.cn\"},{\"text\":\"RXThinkCMF混编版Laravel13+Layui版本\",\"link\":\"http://manage.laravel13.layui.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离Laravel13+ElementPlus版本\",\"link\":\"http://manage.laravel13.elevue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离Laravel13+AntDesign版本\",\"link\":\"http://manage.laravel13.antdvue.rxthink.cn\"},{\"text\":\"RXThinkCMF前后端分离Laravel13+NaiveUI版本\",\"link\":\"http://manage.laravel13.naivevue.rxthink.cn\"}]},{\"text\":\"广告赞助\",\"link\":\"/zh/other/sponsor.html\"},{\"text\":\"相关链接\",\"items\":[{\"text\":\"官方网站\",\"link\":\"https://www.rxthink.cn\"},{\"text\":\"Gitee 仓库\",\"link\":\"https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue\"},{\"text\":\"Laravel 官网\",\"link\":\"https://laravel.com/\"},{\"text\":\"Vue3 文档\",\"link\":\"https://cn.vuejs.org/\"},{\"text\":\"NaiveUI\",\"link\":\"https://www.naiveui.com/\"}]}],\"sidebar\":{\"/zh/\":[{\"text\":\"📖 1. 了解项目\",\"collapsed\":false,\"items\":[{\"text\":\"1.1 项目介绍\",\"link\":\"/zh/introduction.html\"},{\"text\":\"1.2 为什么选择我们\",\"link\":\"/zh/why.html\"},{\"text\":\"1.3 项目目录结构\",\"link\":\"/zh/directory.html\"},{\"text\":\"1.4 新手入门指南\",\"link\":\"/zh/course.html\"},{\"text\":\"1.5 技术栈说明\",\"link\":\"/zh/tech-stack.html\"},{\"text\":\"1.6 更新日志\",\"link\":\"/zh/changelog.html\"}]},{\"text\":\"🚀 2. 快速入门\",\"collapsed\":false,\"items\":[{\"text\":\"2.1 开发环境准备\",\"link\":\"/zh/quickstart/environment.html\"},{\"text\":\"2.2 Laragon 环境搭建\",\"link\":\"/zh/quickstart/laragon.html\"},{\"text\":\"2.3 后端服务启动\",\"link\":\"/zh/quickstart/backend-start.html\"},{\"text\":\"2.4 前端服务启动\",\"link\":\"/zh/quickstart/frontend-start.html\"},{\"text\":\"2.5 数据库初始化\",\"link\":\"/zh/quickstart/database-init.html\"},{\"text\":\"2.6 环境变量配置\",\"link\":\"/zh/quickstart/env-vars.html\"},{\"text\":\"2.7 第一个接口调试\",\"link\":\"/zh/quickstart/first-api.html\"},{\"text\":\"2.8 Docker 快速体验\",\"link\":\"/zh/quickstart/docker.html\"},{\"text\":\"2.9 常见问题 FAQ\",\"link\":\"/zh/quickstart/faq.html\"}]},{\"text\":\"🧪 3. 模块开发实战\",\"collapsed\":false,\"items\":[{\"text\":\"3.1 概述与目标\",\"link\":\"/zh/guide/overview.html\"},{\"text\":\"3.2 数据库建表\",\"link\":\"/zh/guide/database.html\"},{\"text\":\"3.3 模型层开发\",\"link\":\"/zh/guide/model.html\"},{\"text\":\"3.4 FormRequest 验证器\",\"link\":\"/zh/guide/validator.html\"},{\"text\":\"3.5 Service 层开发\",\"link\":\"/zh/guide/logic.html\"},{\"text\":\"3.6 控制器开发\",\"link\":\"/zh/guide/controller.html\"},{\"text\":\"3.7 路由注册\",\"link\":\"/zh/guide/route.html\"},{\"text\":\"3.8 权限节点配置\",\"link\":\"/zh/guide/permission.html\"},{\"text\":\"3.9 前端联调指引\",\"link\":\"/zh/guide/frontend-integration.html\"},{\"text\":\"3.10 完整代码清单\",\"link\":\"/zh/guide/code-list.html\"},{\"text\":\"3.11 常见问题与排错\",\"link\":\"/zh/guide/faq.html\"}]},{\"text\":\"🏛️ 4. 架构设计\",\"collapsed\":false,\"items\":[{\"text\":\"4.1 整体架构概览\",\"link\":\"/zh/architecture/overview.html\"},{\"text\":\"4.2 请求处理链路\",\"link\":\"/zh/architecture/request-flow.html\"},{\"text\":\"4.3 后端分层架构\",\"link\":\"/zh/architecture/backend-layer.html\"},{\"text\":\"4.4 前端分层架构\",\"link\":\"/zh/architecture/frontend-layer.html\"},{\"text\":\"4.5 目录结构设计\",\"link\":\"/zh/architecture/directory-design.html\"},{\"text\":\"4.6 核心基类体系\",\"link\":\"/zh/architecture/base-classes.html\"},{\"text\":\"4.7 横切机制\",\"link\":\"/zh/architecture/cross-cutting.html\"},{\"text\":\"4.8 缓存架构设计\",\"link\":\"/zh/architecture/cache.html\"},{\"text\":\"4.9 数据库设计\",\"link\":\"/zh/architecture/database-design.html\"},{\"text\":\"4.10 安全架构设计\",\"link\":\"/zh/architecture/security.html\"},{\"text\":\"4.11 扩展性设计\",\"link\":\"/zh/architecture/extensibility.html\"}]},{\"text\":\"🔐 5. 核心功能\",\"collapsed\":false,\"items\":[{\"text\":\"认证与安全\",\"collapsed\":false,\"items\":[{\"text\":\"5.1 用户认证(JWT)\",\"link\":\"/zh/core/jwt.html\"},{\"text\":\"5.2 认证流程实战\",\"link\":\"/zh/core/auth-flow.html\"},{\"text\":\"5.3 验证码机制\",\"link\":\"/zh/core/captcha.html\"},{\"text\":\"5.4 权限管理(RBAC)\",\"link\":\"/zh/core/rbac.html\"},{\"text\":\"5.5 跨域资源共享\",\"link\":\"/zh/core/cors.html\"},{\"text\":\"5.6 密码加密服务\",\"link\":\"/zh/core/password.html\"},{\"text\":\"5.7 演示模式\",\"link\":\"/zh/core/demo-mode.html\"}]},{\"text\":\"数据与配置\",\"collapsed\":false,\"items\":[{\"text\":\"5.8 多租户隔离\",\"link\":\"/zh/core/tenant.html\"},{\"text\":\"5.9 数据权限\",\"link\":\"/zh/core/data-scope.html\"},{\"text\":\"5.10 字典模块\",\"link\":\"/zh/core/dict.html\"},{\"text\":\"5.11 字典配置与使用\",\"link\":\"/zh/core/dict-guide.html\"},{\"text\":\"5.12 系统配置管理\",\"link\":\"/zh/core/config.html\"},{\"text\":\"5.13 系统参数管理\",\"link\":\"/zh/core/param.html\"}]},{\"text\":\"日志与监控\",\"collapsed\":false,\"items\":[{\"text\":\"5.14 操作日志\",\"link\":\"/zh/core/operation-log.html\"},{\"text\":\"5.15 登录日志\",\"link\":\"/zh/core/login-log.html\"}]},{\"text\":\"响应与异常\",\"collapsed\":false,\"items\":[{\"text\":\"5.16 统一响应与异常抛出\",\"link\":\"/zh/core/exception.html\"}]},{\"text\":\"注解系统\",\"collapsed\":false,\"items\":[{\"text\":\"5.17 注解系统总览\",\"link\":\"/zh/core/attributes.html\"}]}]},{\"text\":\"📦 6. 业务模块\",\"collapsed\":false,\"items\":[{\"text\":\"6.1 用户管理\",\"link\":\"/zh/modules/user.html\"},{\"text\":\"6.2 角色管理\",\"link\":\"/zh/modules/role.html\"},{\"text\":\"6.3 菜单管理\",\"link\":\"/zh/modules/menu.html\"},{\"text\":\"6.4 部门管理\",\"link\":\"/zh/modules/dept.html\"},{\"text\":\"6.5 职级管理\",\"link\":\"/zh/modules/level.html\"},{\"text\":\"6.6 岗位管理\",\"link\":\"/zh/modules/position.html\"},{\"text\":\"6.7 文章管理\",\"link\":\"/zh/modules/article.html\"},{\"text\":\"6.8 公告与链接管理\",\"link\":\"/zh/modules/content.html\"},{\"text\":\"6.9 行政区划管理\",\"link\":\"/zh/modules/city.html\"},{\"text\":\"6.10 分类管理\",\"link\":\"/zh/modules/category.html\"},{\"text\":\"6.11 定时任务\",\"link\":\"/zh/modules/job.html\"},{\"text\":\"6.12 参数管理\",\"link\":\"/zh/modules/param.html\"},{\"text\":\"6.13 租户管理\",\"link\":\"/zh/modules/tenant.html\"},{\"text\":\"6.14 文件模板管理\",\"link\":\"/zh/modules/filetemplate.html\"},{\"text\":\"6.15 首页与个人中心\",\"link\":\"/zh/modules/index.html\"}]},{\"text\":\"🧰 7. 文件处理\",\"collapsed\":false,\"items\":[{\"text\":\"7.1 文件上传全流程\",\"link\":\"/zh/tools/upload.html\"},{\"text\":\"7.2 上传配置详解\",\"link\":\"/zh/tools/upload-config.html\"},{\"text\":\"7.3 富文本处理\",\"link\":\"/zh/tools/rich-text.html\"},{\"text\":\"7.4 数据导入导出\",\"link\":\"/zh/tools/excel.html\"},{\"text\":\"7.5 前端文件组件\",\"link\":\"/zh/tools/file-components.html\"},{\"text\":\"7.6 数据库迁移工具\",\"link\":\"/zh/tools/db-migrate.html\"}]},{\"text\":\"🔗 8. 接口规范与对接\",\"collapsed\":false,\"items\":[{\"text\":\"8.1 统一响应格式\",\"link\":\"/zh/api-spec/response.html\"},{\"text\":\"8.2 错误码对照表\",\"link\":\"/zh/api-spec/error-code.html\"},{\"text\":\"8.3 分页查询规范\",\"link\":\"/zh/api-spec/pagination.html\"},{\"text\":\"8.4 文件上传接口\",\"link\":\"/zh/api-spec/upload.html\"},{\"text\":\"8.5 字典数据接口\",\"link\":\"/zh/api-spec/dict-api.html\"},{\"text\":\"8.6 Token 使用说明\",\"link\":\"/zh/api-spec/token.html\"},{\"text\":\"8.7 API 接口总览\",\"link\":\"/zh/api-spec/overview.html\"}]},{\"text\":\"🖥️ 9. 前端开发\",\"collapsed\":false,\"items\":[{\"text\":\"工程基础\",\"collapsed\":false,\"items\":[{\"text\":\"9.1 前端工程概述\",\"link\":\"/zh/frontend/overview.html\"},{\"text\":\"9.2 目录结构详解\",\"link\":\"/zh/frontend/directory.html\"},{\"text\":\"9.3 环境与构建配置\",\"link\":\"/zh/frontend/env-config.html\"}]},{\"text\":\"核心机制\",\"collapsed\":false,\"items\":[{\"text\":\"9.4 HTTP 请求封装\",\"link\":\"/zh/frontend/http.html\"},{\"text\":\"9.5 路由与动态菜单\",\"link\":\"/zh/frontend/router.html\"},{\"text\":\"9.6 状态管理(Pinia)\",\"link\":\"/zh/frontend/store.html\"},{\"text\":\"9.7 权限控制\",\"link\":\"/zh/frontend/permission.html\"},{\"text\":\"9.8 登录流程\",\"link\":\"/zh/frontend/login.html\"}]},{\"text\":\"公共组件\",\"collapsed\":false,\"items\":[{\"text\":\"9.9 数据展示组件\",\"link\":\"/zh/frontend/display-components.html\"},{\"text\":\"9.10 数据录入组件\",\"link\":\"/zh/frontend/form-components.html\"},{\"text\":\"9.11 Excel 导入导出组件\",\"link\":\"/zh/frontend/excel-components.html\"}]},{\"text\":\"开发实践\",\"collapsed\":false,\"items\":[{\"text\":\"9.12 新增页面开发步骤\",\"link\":\"/zh/frontend/new-page.html\"},{\"text\":\"9.13 API 模块编写规范\",\"link\":\"/zh/frontend/api-module.html\"},{\"text\":\"9.14 样式与主题定制\",\"link\":\"/zh/frontend/style.html\"},{\"text\":\"9.15 布局系统\",\"link\":\"/zh/frontend/layout.html\"},{\"text\":\"9.16 工具函数\",\"link\":\"/zh/frontend/utils.html\"}]}]},{\"text\":\"🔧 10. 代码生成器\",\"collapsed\":false,\"items\":[{\"text\":\"10.1 概述与架构\",\"link\":\"/zh/generator/overview.html\"},{\"text\":\"10.2 CLI 命令行使用\",\"link\":\"/zh/generator/cli.html\"},{\"text\":\"10.3 Web 管理界面\",\"link\":\"/zh/generator/web-ui.html\"},{\"text\":\"10.4 表结构解析引擎\",\"link\":\"/zh/generator/parser.html\"},{\"text\":\"10.5 代码生成引擎\",\"link\":\"/zh/generator/code-engine.html\"},{\"text\":\"10.6 自定义模板开发\",\"link\":\"/zh/generator/templates.html\"},{\"text\":\"10.7 配置文件详解\",\"link\":\"/zh/generator/config.html\"},{\"text\":\"10.8 实战案例\",\"link\":\"/zh/generator/demo.html\"},{\"text\":\"10.9 常见问题\",\"link\":\"/zh/generator/faq.html\"}]},{\"text\":\"⚙️ 11. 运维部署\",\"collapsed\":false,\"items\":[{\"text\":\"11.1 部署 Checklist\",\"link\":\"/zh/deploy/checklist.html\"},{\"text\":\"11.2 环境规划\",\"link\":\"/zh/deploy/env-plan.html\"},{\"text\":\"11.3 数据库迁移\",\"link\":\"/zh/deploy/db-migrate.html\"},{\"text\":\"11.4 后端部署\",\"link\":\"/zh/deploy/backend.html\"},{\"text\":\"11.5 前端部署\",\"link\":\"/zh/deploy/frontend.html\"},{\"text\":\"11.6 Docker 生产部署\",\"link\":\"/zh/deploy/docker.html\"},{\"text\":\"11.7 性能调优\",\"link\":\"/zh/deploy/performance.html\"},{\"text\":\"11.8 安全加固清单\",\"link\":\"/zh/deploy/security.html\"},{\"text\":\"11.9 备份与恢复\",\"link\":\"/zh/deploy/backup.html\"},{\"text\":\"11.10 故障排查手册\",\"link\":\"/zh/deploy/troubleshooting.html\"},{\"text\":\"11.11 CI/CD 流水线\",\"link\":\"/zh/deploy/ci-cd.html\"}]},{\"text\":\"📋 12. 规范标准\",\"collapsed\":false,\"items\":[{\"text\":\"⭐ 必须遵守\",\"collapsed\":false,\"items\":[{\"text\":\"12.1 API 响应规范\",\"link\":\"/zh/standards/api-response.html\"},{\"text\":\"12.2 分页查询规范\",\"link\":\"/zh/standards/pagination.html\"},{\"text\":\"12.3 Git 提交规范\",\"link\":\"/zh/standards/git.html\"}]},{\"text\":\"📌 建议遵守\",\"collapsed\":false,\"items\":[{\"text\":\"12.4 数据删除规范\",\"link\":\"/zh/standards/deletion.html\"},{\"text\":\"12.5 代码审查清单\",\"link\":\"/zh/standards/code-review.html\"},{\"text\":\"12.6 后端编码规范\",\"link\":\"/zh/standards/backend-code.html\"},{\"text\":\"12.7 前端编码规范\",\"link\":\"/zh/standards/frontend-code.html\"}]}]},{\"text\":\"📄 附录\",\"collapsed\":false,\"items\":[{\"text\":\"A. 常见问题汇总\",\"link\":\"/zh/appendix/faq.html\"},{\"text\":\"B. 数据库表结构速查\",\"link\":\"/zh/appendix/database-tables.html\"},{\"text\":\"C. 配置项速查\",\"link\":\"/zh/appendix/config-reference.html\"},{\"text\":\"D. 公共函数速查\",\"link\":\"/zh/appendix/functions.html\"},{\"text\":\"E. API 接口速查表\",\"link\":\"/zh/appendix/api-cheatsheet.html\"},{\"text\":\"F. 中间件执行顺序\",\"link\":\"/zh/appendix/middleware.html\"},{\"text\":\"G. 前端组件速查\",\"link\":\"/zh/appendix/components.html\"},{\"text\":\"H. 前端 Store 速查\",\"link\":\"/zh/appendix/stores.html\"},{\"text\":\"I. 前端 Enums 速查\",\"link\":\"/zh/appendix/enums.html\"},{\"text\":\"J. 术语表\",\"link\":\"/zh/appendix/glossary.html\"},{\"text\":\"K. Artisan 命令速查\",\"link\":\"/zh/appendix/commands.html\"},{\"text\":\"L. 贡献指南\",\"link\":\"/zh/other/contributing.html\"},{\"text\":\"M. 免责声明\",\"link\":\"/zh/other/declare.html\"},{\"text\":\"N. 广告赞助\",\"link\":\"/zh/other/sponsor.html\"},{\"text\":\"O. 开源协议\",\"link\":\"https://gitee.com/rxthinkcmf/RXThinkCMF_Laravel13_NaiveVue\"}]}]}}}},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
|
||
|
||
</body>
|
||
</html> |