技师排班的解决方案.html 211 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. <!DOCTYPE html><html><head>
  2. <title>技师排班的解决方案</title>
  3. <meta charset="utf-8">
  4. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  5. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css">
  6. <style>
  7. pre{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;padding:1em;margin:.5em 0;overflow:auto;line-height:1.5;tab-size:4;hyphens:none;color:#555;background-color:#f0f0f0!important;border:#d6d6d6;border-radius:3px}pre[class*=language-]{padding:1em}code[class*=language-] .token.cdata,code[class*=language-] .token.comment,code[class*=language-] .token.doctype,code[class*=language-] .token.prolog,pre[class*=language-] .token.cdata,pre[class*=language-] .token.comment,pre[class*=language-] .token.doctype,pre[class*=language-] .token.prolog{color:#998;font-style:italic}code[class*=language-] .token.punctuation,pre[class*=language-] .token.punctuation{color:#920b2d}code[class*=language-] .namespace,pre[class*=language-] .namespace{opacity:.7}code[class*=language-] .token.property,pre[class*=language-] .token.property{font-weight:700;color:#333}code[class*=language-] .token.boolean,code[class*=language-] .token.function-name,code[class*=language-] .token.number,pre[class*=language-] .token.boolean,pre[class*=language-] .token.function-name,pre[class*=language-] .token.number{color:#d14}code[class*=language-] .token.tag,pre[class*=language-] .token.tag{color:#d14}code[class*=language-] .token.symbol,pre[class*=language-] .token.symbol{color:#990073}code[class*=language-] .token.selector,pre[class*=language-] .token.selector{color:teal}code[class*=language-] .token.attr-name,pre[class*=language-] .token.attr-name{color:#458;font-weight:700}code[class*=language-] .token.string,pre[class*=language-] .token.string{color:#d14}code[class*=language-] .token.char,pre[class*=language-] .token.char{color:#606aa1}code[class*=language-] .token.url,pre[class*=language-] .token.url{color:#888}code[class*=language-] .token.atrule,code[class*=language-] .token.attr-value,code[class*=language-] .token.keyword,pre[class*=language-] .token.atrule,pre[class*=language-] .token.attr-value,pre[class*=language-] .token.keyword{color:#222;font-weight:700}code[class*=language-] .token.function,pre[class*=language-] .token.function{color:#900}code[class*=language-] .token.class-name,pre[class*=language-] .token.class-name{text-decoration:underline;color:#606aa1}code[class*=language-] .token.variable,pre[class*=language-] .token.variable{color:teal}code[class*=language-] .token.bold,code[class*=language-] .token.important,pre[class*=language-] .token.bold,pre[class*=language-] .token.important{font-weight:700}code[class*=language-] .token.italic,pre[class*=language-] .token.italic{font-style:italic}code[class*=language-] .token.entity,pre[class*=language-] .token.entity{cursor:help}pre[data-line]{position:relative;padding:1em 0 1em 3em}pre[data-line] .line-highlight-wrapper{position:absolute;top:0;left:0;background-color:transparent;display:block;width:100%}pre[data-line] .line-highlight{position:absolute;left:0;right:0;padding:inherit 0;margin-top:1em;background:hsla(24,20%,50%,.08);background:linear-gradient(to right,hsla(24,20%,50%,.1) 70%,hsla(24,20%,50%,0));pointer-events:none;line-height:inherit;white-space:pre}pre[data-line] .line-highlight:before,pre[data-line] .line-highlight[data-end]:after{content:attr(data-start);position:absolute;top:.4em;left:.6em;min-width:1em;padding:0 .5em;background-color:hsla(24,20%,50%,.4);color:#f4f1ef;font:bold 65%/1.5 sans-serif;text-align:center;vertical-align:.3em;border-radius:999px;text-shadow:none;box-shadow:0 1px #fff}pre[data-line] .line-highlight[data-end]:after{content:attr(data-end);top:auto;bottom:.4em}html body{font-family:'Helvetica Neue',Helvetica,'Segoe UI',Arial,freesans,sans-serif;font-size:16px;line-height:1.6;color:#555;background-color:#fff;overflow:initial;box-sizing:border-box;word-wrap:break-word}html body>:first-child{margin-top:0}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{line-height:1.2;margin-top:1em;margin-bottom:16px;color:#030303}html body h1{font-size:2.25em;font-weight:300;padding-bottom:.3em}html body h2{font-size:1.75em;font-weight:400;padding-bottom:.3em}html body h3{font-size:1.5em;font-weight:500}html body h4{font-size:1.25em;font-weight:600}html body h5{font-size:1.1em;font-weight:600}html body h6{font-size:1em;font-weight:600}html body h1,html body h2,html body h3,html body h4,html body h5{font-weight:600}html body h5{font-size:1em}html body h6{color:#7e7e7e}html body strong{color:#030303}html body del{color:#7e7e7e}html body a:not([href]){color:inherit;text-decoration:none}html body a{color:#08c;text-decoration:none}html body a:hover{color:#00a3f5;text-decoration:none}html body img{max-width:100%}html body>p{margin-top:0;margin-bottom:16px;word-wrap:break-word}html body>ol,html body>ul{margin-bottom:16px}html body ol,html body ul{padding-left:2em}html body ol.no-list,html body ul.no-list{padding:0;list-style-type:none}html body ol ol,html body ol ul,html body ul ol,html body ul ul{margin-top:0;margin-bottom:0}html body li{margin-bottom:0}html body li.task-list-item{list-style:none}html body li>p{margin-top:0;margin-bottom:0}html body .task-list-item-checkbox{margin:0 .2em .25em -1.8em;vertical-align:middle}html body .task-list-item-checkbox:hover{cursor:pointer}html body blockquote{margin:16px 0;font-size:inherit;padding:0 15px;color:#7e7e7e;background-color:#f0f0f0;border-left:4px solid #d6d6d6}html body blockquote>:first-child{margin-top:0}html body blockquote>:last-child{margin-bottom:0}html body hr{height:4px;margin:32px 0;background-color:#d6d6d6;border:0 none}html body table{margin:10px 0 15px 0;border-collapse:collapse;border-spacing:0;display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all}html body table th{font-weight:700;color:#030303}html body table td,html body table th{border:1px solid #d6d6d6;padding:6px 13px}html body dl{padding:0}html body dl dt{padding:0;margin-top:16px;font-size:1em;font-style:italic;font-weight:700}html body dl dd{padding:0 16px;margin-bottom:16px}html body code{font-family:Menlo,Monaco,Consolas,'Courier New',monospace;font-size:.85em;color:#030303;background-color:#f0f0f0;border-radius:3px;padding:.2em 0}html body code::after,html body code::before{letter-spacing:-.2em;content:'\00a0'}html body pre>code{padding:0;margin:0;word-break:normal;white-space:pre;background:0 0;border:0}html body .highlight{margin-bottom:16px}html body .highlight pre,html body pre{padding:1em;overflow:auto;line-height:1.45;border:#d6d6d6;border-radius:3px}html body .highlight pre{margin-bottom:0;word-break:normal}html body pre code,html body pre tt{display:inline;max-width:initial;padding:0;margin:0;overflow:initial;line-height:inherit;word-wrap:normal;background-color:transparent;border:0}html body pre code:after,html body pre code:before,html body pre tt:after,html body pre tt:before{content:normal}html body blockquote,html body dl,html body ol,html body p,html body pre,html body ul{margin-top:0;margin-bottom:16px}html body kbd{color:#030303;border:1px solid #d6d6d6;border-bottom:2px solid #c7c7c7;padding:2px 4px;background-color:#f0f0f0;border-radius:3px}@media print{html body{background-color:#fff}html body h1,html body h2,html body h3,html body h4,html body h5,html body h6{color:#030303;page-break-after:avoid}html body blockquote{color:#7e7e7e}html body pre{page-break-inside:avoid}html body table{display:table}html body img{display:block;max-width:100%;max-height:100%}html body code,html body pre{word-wrap:break-word;white-space:pre}}.markdown-preview{width:100%;height:100%;box-sizing:border-box}.markdown-preview ul{list-style:disc}.markdown-preview ul ul{list-style:circle}.markdown-preview ul ul ul{list-style:square}.markdown-preview ol{list-style:decimal}.markdown-preview ol ol,.markdown-preview ul ol{list-style-type:lower-roman}.markdown-preview ol ol ol,.markdown-preview ol ul ol,.markdown-preview ul ol ol,.markdown-preview ul ul ol{list-style-type:lower-alpha}.markdown-preview .newpage,.markdown-preview .pagebreak{page-break-before:always}.markdown-preview pre.line-numbers{position:relative;padding-left:3.8em;counter-reset:linenumber}.markdown-preview pre.line-numbers>code{position:relative}.markdown-preview pre.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:1em;font-size:100%;left:0;width:3em;letter-spacing:-1px;border-right:1px solid #999;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.markdown-preview pre.line-numbers .line-numbers-rows>span{pointer-events:none;display:block;counter-increment:linenumber}.markdown-preview pre.line-numbers .line-numbers-rows>span:before{content:counter(linenumber);color:#999;display:block;padding-right:.8em;text-align:right}.markdown-preview .mathjax-exps .MathJax_Display{text-align:center!important}.markdown-preview:not([data-for=preview]) .code-chunk .code-chunk-btn-group{display:none}.markdown-preview:not([data-for=preview]) .code-chunk .status{display:none}.markdown-preview:not([data-for=preview]) .code-chunk .output-div{margin-bottom:16px}.markdown-preview .md-toc{padding:0}.markdown-preview .md-toc .md-toc-link-wrapper .md-toc-link{display:inline;padding:.25rem 0}.markdown-preview .md-toc .md-toc-link-wrapper .md-toc-link div,.markdown-preview .md-toc .md-toc-link-wrapper .md-toc-link p{display:inline}.markdown-preview .md-toc .md-toc-link-wrapper.highlighted .md-toc-link{font-weight:800}.scrollbar-style::-webkit-scrollbar{width:8px}.scrollbar-style::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}.scrollbar-style::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,.66);border:4px solid rgba(150,150,150,.66);background-clip:content-box}html body[for=html-export]:not([data-presentation-mode]){position:relative;width:100%;height:100%;top:0;left:0;margin:0;padding:0;overflow:auto}html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{position:relative;top:0;min-height:100vh}@media screen and (min-width:914px){html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{padding:2em calc(50% - 457px + 2em)}}@media screen and (max-width:914px){html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for=html-export]:not([data-presentation-mode]) .markdown-preview{font-size:14px!important;padding:1em}}@media print{html body[for=html-export]:not([data-presentation-mode]) #sidebar-toc-btn{display:none}}html body[for=html-export]:not([data-presentation-mode]) #sidebar-toc-btn{position:fixed;bottom:8px;left:8px;font-size:28px;cursor:pointer;color:inherit;z-index:99;width:32px;text-align:center;opacity:.4}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] #sidebar-toc-btn{opacity:1}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc{position:fixed;top:0;left:0;width:300px;height:100%;padding:32px 0 48px 0;font-size:14px;box-shadow:0 0 4px rgba(150,150,150,.33);box-sizing:border-box;overflow:auto;background-color:inherit}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar{width:8px}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-track{border-radius:10px;background-color:transparent}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc::-webkit-scrollbar-thumb{border-radius:5px;background-color:rgba(150,150,150,.66);border:4px solid rgba(150,150,150,.66);background-clip:content-box}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc a{text-decoration:none}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc{padding:0 16px}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper .md-toc-link{display:inline;padding:.25rem 0}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper .md-toc-link div,html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper .md-toc-link p{display:inline}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .md-sidebar-toc .md-toc .md-toc-link-wrapper.highlighted .md-toc-link{font-weight:800}html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{left:300px;width:calc(100% - 300px);padding:2em calc(50% - 457px - 300px / 2);margin:0;box-sizing:border-box}@media screen and (max-width:1274px){html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{padding:2em}}@media screen and (max-width:450px){html body[for=html-export]:not([data-presentation-mode])[html-show-sidebar-toc] .markdown-preview{width:100%}}html body[for=html-export]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .markdown-preview{left:50%;transform:translateX(-50%)}html body[for=html-export]:not([data-presentation-mode]):not([html-show-sidebar-toc]) .md-sidebar-toc{display:none}
  8. /* Please visit the URL below for more information: */
  9. /* https://shd101wyy.github.io/markdown-preview-enhanced/#/customize-css */
  10. </style>
  11. <!-- The content below will be included at the end of the <head> element. --><script type="text/javascript">
  12. document.addEventListener("DOMContentLoaded", function () {
  13. // your code here
  14. });
  15. </script></head><body for="html-export">
  16. <div class="crossnote markdown-preview ">
  17. <h1 id="技师排班解决方案">技师排班解决方案 </h1>
  18. <h2 id="目录">目录 </h2>
  19. <ol>
  20. <li><a href="#%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BE%E8%AE%A1">数据库设计</a></li>
  21. <li><a href="#%E5%90%8E%E7%AB%AF%E5%AE%9E%E7%8E%B0">后端实现</a>
  22. <ul>
  23. <li><a href="#model-%E5%AE%9A%E4%B9%89">Model 定义</a></li>
  24. <li><a href="#service-%E5%B1%82">Service 层</a></li>
  25. <li><a href="#controller-%E5%B1%82">Controller 层</a></li>
  26. </ul>
  27. </li>
  28. <li><a href="#%E5%89%8D%E7%AB%AF%E5%AE%9E%E7%8E%B0">前端实现</a>
  29. <ul>
  30. <li><a href="#%E5%B7%A5%E4%BD%9C%E8%A7%84%E5%88%99%E8%AE%BE%E7%BD%AE%E9%A1%B5%E9%9D%A2">工作规则设置页面</a></li>
  31. <li><a href="#%E7%89%B9%E6%AE%8A%E6%97%A5%E6%9C%9F%E8%AE%BE%E7%BD%AE%E9%A1%B5%E9%9D%A2">特殊日期设置页面</a></li>
  32. <li><a href="#api-%E5%B0%81%E8%A3%85">API 封装</a></li>
  33. </ul>
  34. </li>
  35. </ol>
  36. <h2 id="设计指标">设计指标 </h2>
  37. <h3 id="功能特点">功能特点 </h3>
  38. <ol>
  39. <li>技师可以设置默认工作规则</li>
  40. <li>支持设置特殊日期(休假或特殊工作日)</li>
  41. <li>自动生成30分钟时间槽</li>
  42. <li>预约后自动预留间隔时间</li>
  43. <li>完整的事务处理和并发控制</li>
  44. </ol>
  45. <h3 id="可扩展功能">可扩展功能 </h3>
  46. <ol>
  47. <li>节假日自动识别</li>
  48. <li>批量设置特殊日期</li>
  49. <li>工作规则模板</li>
  50. <li>临时调整工作时间</li>
  51. <li>规则生效时间设置</li>
  52. <li>规则复制功能</li>
  53. </ol>
  54. <h3 id="技术特点">技术特点 </h3>
  55. <ol>
  56. <li>使用 Laravel + UniApp (Vue3) 技术栈</li>
  57. <li>TypeScript 类型支持</li>
  58. <li>完整的错误处理</li>
  59. <li>统一的请求封装</li>
  60. <li>模块化的 API 管理</li>
  61. <li>响应式界面设计</li>
  62. </ol>
  63. <h3 id="性能优化">性能优化 </h3>
  64. <ol>
  65. <li>数据库索引优化</li>
  66. <li>事务处理</li>
  67. <li>并发控制</li>
  68. <li>缓存支持</li>
  69. <li>批量操作优化</li>
  70. </ol>
  71. <h2 id="数据库设计">数据库设计 </h2>
  72. <h3 id="1-数据表结构">1. 数据表结构 </h3>
  73. <pre data-role="codeBlock" data-info="sql" class="language-sql sql"><code><span class="token comment">-- 技师表</span>
  74. <span class="token keyword keyword-CREATE">CREATE</span> <span class="token keyword keyword-TABLE">TABLE</span> technicians <span class="token punctuation">(</span>
  75. id <span class="token keyword keyword-INT">INT</span> <span class="token keyword keyword-PRIMARY">PRIMARY</span> <span class="token keyword keyword-KEY">KEY</span> <span class="token keyword keyword-AUTO_INCREMENT">AUTO_INCREMENT</span><span class="token punctuation">,</span>
  76. name <span class="token keyword keyword-VARCHAR">VARCHAR</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  77. <span class="token keyword keyword-status">status</span> <span class="token keyword keyword-TINYINT">TINYINT</span> <span class="token keyword keyword-DEFAULT">DEFAULT</span> <span class="token number">1</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'1:正常,0:停用'</span><span class="token punctuation">,</span>
  78. created_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  79. updated_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span>
  80. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  81. <span class="token comment">-- 技师工作规则表</span>
  82. <span class="token keyword keyword-CREATE">CREATE</span> <span class="token keyword keyword-TABLE">TABLE</span> technician_work_rules <span class="token punctuation">(</span>
  83. id <span class="token keyword keyword-INT">INT</span> <span class="token keyword keyword-PRIMARY">PRIMARY</span> <span class="token keyword keyword-KEY">KEY</span> <span class="token keyword keyword-AUTO_INCREMENT">AUTO_INCREMENT</span><span class="token punctuation">,</span>
  84. technician_id <span class="token keyword keyword-INT">INT</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  85. work_days <span class="token keyword keyword-VARCHAR">VARCHAR</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">)</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'工作日 例如:1,2,3,4,5 表示周一到周五'</span><span class="token punctuation">,</span>
  86. start_time <span class="token keyword keyword-TIME">TIME</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword keyword-DEFAULT">DEFAULT</span> <span class="token string">'08:00'</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'默认上班时间'</span><span class="token punctuation">,</span>
  87. end_time <span class="token keyword keyword-TIME">TIME</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span> <span class="token keyword keyword-DEFAULT">DEFAULT</span> <span class="token string">'18:00'</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'默认下班时间'</span><span class="token punctuation">,</span>
  88. is_active <span class="token keyword keyword-TINYINT">TINYINT</span> <span class="token keyword keyword-DEFAULT">DEFAULT</span> <span class="token number">1</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'是否启用'</span><span class="token punctuation">,</span>
  89. created_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  90. updated_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  91. <span class="token keyword keyword-UNIQUE">UNIQUE</span> <span class="token keyword keyword-KEY">KEY</span> idx_technician <span class="token punctuation">(</span>technician_id<span class="token punctuation">)</span>
  92. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  93. <span class="token comment">-- 技师特殊日期表(休假或特殊工作日)</span>
  94. <span class="token keyword keyword-CREATE">CREATE</span> <span class="token keyword keyword-TABLE">TABLE</span> technician_special_dates <span class="token punctuation">(</span>
  95. id <span class="token keyword keyword-INT">INT</span> <span class="token keyword keyword-PRIMARY">PRIMARY</span> <span class="token keyword keyword-KEY">KEY</span> <span class="token keyword keyword-AUTO_INCREMENT">AUTO_INCREMENT</span><span class="token punctuation">,</span>
  96. technician_id <span class="token keyword keyword-INT">INT</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  97. <span class="token keyword keyword-date">date</span> <span class="token keyword keyword-DATE">DATE</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  98. is_working <span class="token keyword keyword-TINYINT">TINYINT</span> <span class="token keyword keyword-DEFAULT">DEFAULT</span> <span class="token number">0</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'1:特殊工作日,0:休息日'</span><span class="token punctuation">,</span>
  99. start_time <span class="token keyword keyword-TIME">TIME</span> <span class="token boolean">NULL</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'特殊工作日的上班时间'</span><span class="token punctuation">,</span>
  100. end_time <span class="token keyword keyword-TIME">TIME</span> <span class="token boolean">NULL</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'特殊工作日的下班时间'</span><span class="token punctuation">,</span>
  101. created_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  102. updated_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  103. <span class="token keyword keyword-UNIQUE">UNIQUE</span> <span class="token keyword keyword-KEY">KEY</span> idx_technician_date <span class="token punctuation">(</span>technician_id<span class="token punctuation">,</span> <span class="token keyword keyword-date">date</span><span class="token punctuation">)</span>
  104. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  105. <span class="token comment">-- 技师时间槽表</span>
  106. <span class="token keyword keyword-CREATE">CREATE</span> <span class="token keyword keyword-TABLE">TABLE</span> technician_time_slots <span class="token punctuation">(</span>
  107. id <span class="token keyword keyword-INT">INT</span> <span class="token keyword keyword-PRIMARY">PRIMARY</span> <span class="token keyword keyword-KEY">KEY</span> <span class="token keyword keyword-AUTO_INCREMENT">AUTO_INCREMENT</span><span class="token punctuation">,</span>
  108. technician_id <span class="token keyword keyword-INT">INT</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  109. <span class="token keyword keyword-date">date</span> <span class="token keyword keyword-DATE">DATE</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  110. start_time <span class="token keyword keyword-TIME">TIME</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  111. end_time <span class="token keyword keyword-TIME">TIME</span> <span class="token operator">NOT</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  112. <span class="token keyword keyword-status">status</span> <span class="token keyword keyword-TINYINT">TINYINT</span> <span class="token keyword keyword-DEFAULT">DEFAULT</span> <span class="token number">1</span> <span class="token keyword keyword-COMMENT">COMMENT</span> <span class="token string">'1:可预约,0:已预约,2:预留间隔'</span><span class="token punctuation">,</span>
  113. created_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  114. updated_at <span class="token keyword keyword-TIMESTAMP">TIMESTAMP</span> <span class="token boolean">NULL</span><span class="token punctuation">,</span>
  115. <span class="token keyword keyword-INDEX">INDEX</span> idx_technician_date <span class="token punctuation">(</span>technician_id<span class="token punctuation">,</span> <span class="token keyword keyword-date">date</span><span class="token punctuation">,</span> <span class="token keyword keyword-status">status</span><span class="token punctuation">)</span>
  116. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  117. </code></pre><h3 id="2-laravel-migration-文件">2. Laravel Migration 文件 </h3>
  118. <pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  119. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Migrations<span class="token punctuation">\</span>Migration</span><span class="token punctuation">;</span>
  120. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Schema<span class="token punctuation">\</span>Blueprint</span><span class="token punctuation">;</span>
  121. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Schema</span><span class="token punctuation">;</span>
  122. <span class="token keyword keyword-return">return</span> <span class="token keyword keyword-new">new</span> <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">extends</span> <span class="token class-name">Migration</span>
  123. <span class="token punctuation">{</span>
  124. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">up</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type keyword-void">void</span>
  125. <span class="token punctuation">{</span>
  126. <span class="token scope">Schema<span class="token punctuation">::</span></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technicians'</span><span class="token punctuation">,</span> <span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Blueprint</span> <span class="token variable">$table</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  127. <span class="token variable">$table</span><span class="token operator">-&gt;</span><span class="token function">id</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  128. <span class="token variable">$table</span><span class="token operator">-&gt;</span><span class="token keyword type-declaration keyword-string">string</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">,</span> <span class="token number">50</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  129. <span class="token variable">$table</span><span class="token operator">-&gt;</span><span class="token function">tinyInteger</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'status'</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">default</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  130. <span class="token variable">$table</span><span class="token operator">-&gt;</span><span class="token function">timestamps</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  131. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  132. <span class="token punctuation">}</span>
  133. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">down</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type keyword-void">void</span>
  134. <span class="token punctuation">{</span>
  135. <span class="token scope">Schema<span class="token punctuation">::</span></span><span class="token function">dropIfExists</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technicians'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  136. <span class="token punctuation">}</span>
  137. <span class="token punctuation">}</span><span class="token punctuation">;</span>
  138. </span></code></pre><h3 id="3-model-定义">3. Model 定义 </h3>
  139. <pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  140. <span class="token comment">// app/Models/Technician.php</span>
  141. <span class="token keyword keyword-namespace">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Models</span><span class="token punctuation">;</span>
  142. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
  143. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>HasMany</span><span class="token punctuation">;</span>
  144. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>HasOne</span><span class="token punctuation">;</span>
  145. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">Technician</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">Model</span>
  146. <span class="token punctuation">{</span>
  147. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$fillable</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'name'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'status'</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  148. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">workRule</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">HasOne</span>
  149. <span class="token punctuation">{</span>
  150. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">hasOne</span><span class="token punctuation">(</span><span class="token scope">TechnicianWorkRule<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  151. <span class="token punctuation">}</span>
  152. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">specialDates</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">HasMany</span>
  153. <span class="token punctuation">{</span>
  154. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">hasMany</span><span class="token punctuation">(</span><span class="token scope">TechnicianSpecialDate<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  155. <span class="token punctuation">}</span>
  156. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">timeSlots</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">HasMany</span>
  157. <span class="token punctuation">{</span>
  158. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">hasMany</span><span class="token punctuation">(</span><span class="token scope">TechnicianTimeSlot<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  159. <span class="token punctuation">}</span>
  160. <span class="token punctuation">}</span>
  161. </span></code></pre><pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  162. <span class="token comment">// app/Models/TechnicianWorkRule.php</span>
  163. <span class="token keyword keyword-namespace">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Models</span><span class="token punctuation">;</span>
  164. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
  165. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>BelongsTo</span><span class="token punctuation">;</span>
  166. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">TechnicianWorkRule</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">Model</span>
  167. <span class="token punctuation">{</span>
  168. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$fillable</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  169. <span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span>
  170. <span class="token string single-quoted-string">'work_days'</span><span class="token punctuation">,</span>
  171. <span class="token string single-quoted-string">'start_time'</span><span class="token punctuation">,</span>
  172. <span class="token string single-quoted-string">'end_time'</span><span class="token punctuation">,</span>
  173. <span class="token string single-quoted-string">'is_active'</span>
  174. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  175. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$casts</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  176. <span class="token string single-quoted-string">'is_active'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'boolean'</span><span class="token punctuation">,</span>
  177. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'datetime'</span><span class="token punctuation">,</span>
  178. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'datetime'</span>
  179. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  180. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">technician</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">BelongsTo</span>
  181. <span class="token punctuation">{</span>
  182. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">belongsTo</span><span class="token punctuation">(</span><span class="token scope">Technician<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  183. <span class="token punctuation">}</span>
  184. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">getWorkDaysArrayAttribute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type keyword-array">array</span>
  185. <span class="token punctuation">{</span>
  186. <span class="token keyword keyword-return">return</span> <span class="token function">array_map</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'intval'</span><span class="token punctuation">,</span> <span class="token function">explode</span><span class="token punctuation">(</span><span class="token string single-quoted-string">','</span><span class="token punctuation">,</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token property">work_days</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  187. <span class="token punctuation">}</span>
  188. <span class="token punctuation">}</span>
  189. </span></code></pre><pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  190. <span class="token comment">// app/Models/TechnicianSpecialDate.php</span>
  191. <span class="token keyword keyword-namespace">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Models</span><span class="token punctuation">;</span>
  192. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
  193. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>BelongsTo</span><span class="token punctuation">;</span>
  194. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">TechnicianSpecialDate</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">Model</span>
  195. <span class="token punctuation">{</span>
  196. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$fillable</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  197. <span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span>
  198. <span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span>
  199. <span class="token string single-quoted-string">'is_working'</span><span class="token punctuation">,</span>
  200. <span class="token string single-quoted-string">'start_time'</span><span class="token punctuation">,</span>
  201. <span class="token string single-quoted-string">'end_time'</span>
  202. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  203. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$casts</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  204. <span class="token string single-quoted-string">'date'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span>
  205. <span class="token string single-quoted-string">'is_working'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'boolean'</span><span class="token punctuation">,</span>
  206. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'datetime'</span><span class="token punctuation">,</span>
  207. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'datetime'</span>
  208. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  209. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">technician</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">BelongsTo</span>
  210. <span class="token punctuation">{</span>
  211. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">belongsTo</span><span class="token punctuation">(</span><span class="token scope">Technician<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  212. <span class="token punctuation">}</span>
  213. <span class="token punctuation">}</span>
  214. </span></code></pre><pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  215. <span class="token comment">// app/Models/TechnicianTimeSlot.php</span>
  216. <span class="token keyword keyword-namespace">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Models</span><span class="token punctuation">;</span>
  217. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Model</span><span class="token punctuation">;</span>
  218. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Eloquent<span class="token punctuation">\</span>Relations<span class="token punctuation">\</span>BelongsTo</span><span class="token punctuation">;</span>
  219. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">TechnicianTimeSlot</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">Model</span>
  220. <span class="token punctuation">{</span>
  221. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$fillable</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  222. <span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span>
  223. <span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span>
  224. <span class="token string single-quoted-string">'start_time'</span><span class="token punctuation">,</span>
  225. <span class="token string single-quoted-string">'end_time'</span><span class="token punctuation">,</span>
  226. <span class="token string single-quoted-string">'status'</span>
  227. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  228. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$casts</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  229. <span class="token string single-quoted-string">'date'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span>
  230. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'datetime'</span><span class="token punctuation">,</span>
  231. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'datetime'</span>
  232. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  233. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">technician</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">BelongsTo</span>
  234. <span class="token punctuation">{</span>
  235. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">belongsTo</span><span class="token punctuation">(</span><span class="token scope">Technician<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  236. <span class="token punctuation">}</span>
  237. <span class="token punctuation">}</span>
  238. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">TechnicianSchedule</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">Model</span>
  239. <span class="token punctuation">{</span>
  240. <span class="token keyword keyword-protected">protected</span> <span class="token variable">$casts</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  241. <span class="token string single-quoted-string">'work_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'array'</span><span class="token punctuation">,</span>
  242. <span class="token string single-quoted-string">'work_date'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span>
  243. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  244. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">technician</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  245. <span class="token punctuation">{</span>
  246. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">belongsTo</span><span class="token punctuation">(</span><span class="token scope">Technician<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  247. <span class="token punctuation">}</span>
  248. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">workPlans</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  249. <span class="token punctuation">{</span>
  250. <span class="token keyword keyword-return">return</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">hasMany</span><span class="token punctuation">(</span><span class="token scope">TechnicianWorkPlan<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">)</span>
  251. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'work_date'</span><span class="token punctuation">,</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token property">work_date</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  252. <span class="token punctuation">}</span>
  253. <span class="token punctuation">}</span>
  254. </span></code></pre><h2 id="后端实现">后端实现 </h2>
  255. <h3 id="1-service-层实现">1. Service 层实现 </h3>
  256. <pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  257. <span class="token comment">// app/Services/TechnicianScheduleService.php</span>
  258. <span class="token keyword keyword-namespace">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Services</span><span class="token punctuation">;</span>
  259. <span class="token keyword keyword-use">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>TechnicianWorkRule</span><span class="token punctuation">;</span>
  260. <span class="token keyword keyword-use">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>TechnicianSpecialDate</span><span class="token punctuation">;</span>
  261. <span class="token keyword keyword-use">use</span> <span class="token package">App<span class="token punctuation">\</span>Models<span class="token punctuation">\</span>TechnicianTimeSlot</span><span class="token punctuation">;</span>
  262. <span class="token keyword keyword-use">use</span> <span class="token package">Carbon<span class="token punctuation">\</span>Carbon</span><span class="token punctuation">;</span>
  263. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Collection</span><span class="token punctuation">;</span>
  264. <span class="token keyword keyword-use">use</span> <span class="token package">DB</span><span class="token punctuation">;</span>
  265. <span class="token keyword keyword-use">use</span> <span class="token package">Exception</span><span class="token punctuation">;</span>
  266. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">TechnicianScheduleService</span>
  267. <span class="token punctuation">{</span>
  268. <span class="token doc-comment comment">/**
  269. * 设置技师工作规则
  270. */</span>
  271. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">setWorkRule</span><span class="token punctuation">(</span>
  272. <span class="token keyword type-hint keyword-int">int</span> <span class="token variable">$technicianId</span><span class="token punctuation">,</span>
  273. <span class="token keyword type-hint keyword-array">array</span> <span class="token variable">$workDays</span><span class="token punctuation">,</span>
  274. <span class="token keyword type-hint keyword-string">string</span> <span class="token variable">$startTime</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'08:00'</span><span class="token punctuation">,</span>
  275. <span class="token keyword type-hint keyword-string">string</span> <span class="token variable">$endTime</span> <span class="token operator">=</span> <span class="token string single-quoted-string">'18:00'</span>
  276. <span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type keyword-void">void</span> <span class="token punctuation">{</span>
  277. <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
  278. <span class="token scope">DB<span class="token punctuation">::</span></span><span class="token function">beginTransaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  279. <span class="token scope">TechnicianWorkRule<span class="token punctuation">::</span></span><span class="token function">updateOrCreate</span><span class="token punctuation">(</span>
  280. <span class="token punctuation">[</span><span class="token string single-quoted-string">'technician_id'</span> <span class="token operator">=&gt;</span> <span class="token variable">$technicianId</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
  281. <span class="token punctuation">[</span>
  282. <span class="token string single-quoted-string">'work_days'</span> <span class="token operator">=&gt;</span> <span class="token function">implode</span><span class="token punctuation">(</span><span class="token string single-quoted-string">','</span><span class="token punctuation">,</span> <span class="token variable">$workDays</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  283. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token variable">$startTime</span><span class="token punctuation">,</span>
  284. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token variable">$endTime</span><span class="token punctuation">,</span>
  285. <span class="token string single-quoted-string">'is_active'</span> <span class="token operator">=&gt;</span> <span class="token constant boolean">true</span>
  286. <span class="token punctuation">]</span>
  287. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  288. <span class="token comment">// 生成未来30天的时间槽</span>
  289. <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">generateFutureTimeSlots</span><span class="token punctuation">(</span><span class="token variable">$technicianId</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  290. <span class="token scope">DB<span class="token punctuation">::</span></span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  291. <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  292. <span class="token scope">DB<span class="token punctuation">::</span></span><span class="token function">rollBack</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  293. <span class="token keyword keyword-throw">throw</span> <span class="token variable">$e</span><span class="token punctuation">;</span>
  294. <span class="token punctuation">}</span>
  295. <span class="token punctuation">}</span>
  296. <span class="token doc-comment comment">/**
  297. * 生成时间槽
  298. */</span>
  299. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">generateTimeSlots</span><span class="token punctuation">(</span><span class="token keyword type-hint keyword-int">int</span> <span class="token variable">$technicianId</span><span class="token punctuation">,</span> <span class="token keyword type-hint keyword-string">string</span> <span class="token variable">$date</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type keyword-void">void</span>
  300. <span class="token punctuation">{</span>
  301. <span class="token variable">$dateObj</span> <span class="token operator">=</span> <span class="token scope">Carbon<span class="token punctuation">::</span></span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token variable">$date</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  302. <span class="token variable">$dayOfWeek</span> <span class="token operator">=</span> <span class="token variable">$dateObj</span><span class="token operator">-&gt;</span><span class="token property">dayOfWeek</span><span class="token punctuation">;</span>
  303. <span class="token comment">// 获取工作规则</span>
  304. <span class="token variable">$workRule</span> <span class="token operator">=</span> <span class="token scope">TechnicianWorkRule<span class="token punctuation">::</span></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span> <span class="token variable">$technicianId</span><span class="token punctuation">)</span>
  305. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'is_active'</span><span class="token punctuation">,</span> <span class="token constant boolean">true</span><span class="token punctuation">)</span>
  306. <span class="token operator">-&gt;</span><span class="token function">first</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  307. <span class="token comment">// 获取特殊日期设置</span>
  308. <span class="token variable">$specialDate</span> <span class="token operator">=</span> <span class="token scope">TechnicianSpecialDate<span class="token punctuation">::</span></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span> <span class="token variable">$technicianId</span><span class="token punctuation">)</span>
  309. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span> <span class="token variable">$date</span><span class="token punctuation">)</span>
  310. <span class="token operator">-&gt;</span><span class="token function">first</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  311. <span class="token comment">// 判断是否工作日</span>
  312. <span class="token variable">$isWorkDay</span> <span class="token operator">=</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span>
  313. <span class="token variable">$startTime</span> <span class="token operator">=</span> <span class="token constant">null</span><span class="token punctuation">;</span>
  314. <span class="token variable">$endTime</span> <span class="token operator">=</span> <span class="token constant">null</span><span class="token punctuation">;</span>
  315. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token variable">$specialDate</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  316. <span class="token comment">// 特殊日期优先</span>
  317. <span class="token variable">$isWorkDay</span> <span class="token operator">=</span> <span class="token variable">$specialDate</span><span class="token operator">-&gt;</span><span class="token property">is_working</span><span class="token punctuation">;</span>
  318. <span class="token variable">$startTime</span> <span class="token operator">=</span> <span class="token variable">$specialDate</span><span class="token operator">-&gt;</span><span class="token property">start_time</span><span class="token punctuation">;</span>
  319. <span class="token variable">$endTime</span> <span class="token operator">=</span> <span class="token variable">$specialDate</span><span class="token operator">-&gt;</span><span class="token property">end_time</span><span class="token punctuation">;</span>
  320. <span class="token punctuation">}</span> <span class="token keyword keyword-elseif">elseif</span> <span class="token punctuation">(</span><span class="token variable">$workRule</span> <span class="token operator">&amp;&amp;</span> <span class="token function">in_array</span><span class="token punctuation">(</span><span class="token variable">$dayOfWeek</span><span class="token punctuation">,</span> <span class="token variable">$workRule</span><span class="token operator">-&gt;</span><span class="token property">work_days_array</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  321. <span class="token comment">// 普通工作日</span>
  322. <span class="token variable">$isWorkDay</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span>
  323. <span class="token variable">$startTime</span> <span class="token operator">=</span> <span class="token variable">$workRule</span><span class="token operator">-&gt;</span><span class="token property">start_time</span><span class="token punctuation">;</span>
  324. <span class="token variable">$endTime</span> <span class="token operator">=</span> <span class="token variable">$workRule</span><span class="token operator">-&gt;</span><span class="token property">end_time</span><span class="token punctuation">;</span>
  325. <span class="token punctuation">}</span>
  326. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$isWorkDay</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  327. <span class="token keyword keyword-return">return</span><span class="token punctuation">;</span>
  328. <span class="token punctuation">}</span>
  329. <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
  330. <span class="token scope">DB<span class="token punctuation">::</span></span><span class="token function">beginTransaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  331. <span class="token comment">// 删除原有时间槽</span>
  332. <span class="token scope">TechnicianTimeSlot<span class="token punctuation">::</span></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span> <span class="token variable">$technicianId</span><span class="token punctuation">)</span>
  333. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span> <span class="token variable">$date</span><span class="token punctuation">)</span>
  334. <span class="token operator">-&gt;</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  335. <span class="token comment">// 生成30分钟时间槽</span>
  336. <span class="token variable">$currentTime</span> <span class="token operator">=</span> <span class="token scope">Carbon<span class="token punctuation">::</span></span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token variable">$startTime</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  337. <span class="token variable">$endDateTime</span> <span class="token operator">=</span> <span class="token scope">Carbon<span class="token punctuation">::</span></span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token variable">$endTime</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  338. <span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span><span class="token variable">$currentTime</span><span class="token operator">-&gt;</span><span class="token function">copy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">addMinutes</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span> <span class="token operator">&lt;=</span> <span class="token variable">$endDateTime</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  339. <span class="token scope">TechnicianTimeSlot<span class="token punctuation">::</span></span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  340. <span class="token string single-quoted-string">'technician_id'</span> <span class="token operator">=&gt;</span> <span class="token variable">$technicianId</span><span class="token punctuation">,</span>
  341. <span class="token string single-quoted-string">'date'</span> <span class="token operator">=&gt;</span> <span class="token variable">$date</span><span class="token punctuation">,</span>
  342. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token variable">$currentTime</span><span class="token operator">-&gt;</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'H:i:s'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  343. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token variable">$currentTime</span><span class="token operator">-&gt;</span><span class="token function">copy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">addMinutes</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">format</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'H:i:s'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  344. <span class="token string single-quoted-string">'status'</span> <span class="token operator">=&gt;</span> <span class="token number">1</span>
  345. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  346. <span class="token variable">$currentTime</span><span class="token operator">-&gt;</span><span class="token function">addMinutes</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  347. <span class="token punctuation">}</span>
  348. <span class="token scope">DB<span class="token punctuation">::</span></span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  349. <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  350. <span class="token scope">DB<span class="token punctuation">::</span></span><span class="token function">rollBack</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  351. <span class="token keyword keyword-throw">throw</span> <span class="token variable">$e</span><span class="token punctuation">;</span>
  352. <span class="token punctuation">}</span>
  353. <span class="token punctuation">}</span>
  354. <span class="token punctuation">}</span>
  355. </span></code></pre><h3 id="2-controller-层实现">2. Controller 层实现 </h3>
  356. <pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token php language-php"><span class="token delimiter important">&lt;?php</span>
  357. <span class="token comment">// app/Http/Controllers/Api/TechnicianScheduleController.php</span>
  358. <span class="token keyword keyword-namespace">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Api</span><span class="token punctuation">;</span>
  359. <span class="token keyword keyword-use">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span>
  360. <span class="token keyword keyword-use">use</span> <span class="token package">App<span class="token punctuation">\</span>Services<span class="token punctuation">\</span>TechnicianScheduleService</span><span class="token punctuation">;</span>
  361. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>JsonResponse</span><span class="token punctuation">;</span>
  362. <span class="token keyword keyword-use">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Request</span><span class="token punctuation">;</span>
  363. <span class="token keyword keyword-use">use</span> <span class="token package">Exception</span><span class="token punctuation">;</span>
  364. <span class="token keyword keyword-class">class</span> <span class="token class-name-definition class-name">TechnicianScheduleController</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">Controller</span>
  365. <span class="token punctuation">{</span>
  366. <span class="token keyword keyword-private">private</span> <span class="token class-name type-declaration">TechnicianScheduleService</span> <span class="token variable">$scheduleService</span><span class="token punctuation">;</span>
  367. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">__construct</span><span class="token punctuation">(</span><span class="token class-name type-declaration">TechnicianScheduleService</span> <span class="token variable">$scheduleService</span><span class="token punctuation">)</span>
  368. <span class="token punctuation">{</span>
  369. <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token property">scheduleService</span> <span class="token operator">=</span> <span class="token variable">$scheduleService</span><span class="token punctuation">;</span>
  370. <span class="token punctuation">}</span>
  371. <span class="token doc-comment comment">/**
  372. * 设置工作规则
  373. */</span>
  374. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">setWorkRule</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">JsonResponse</span>
  375. <span class="token punctuation">{</span>
  376. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  377. <span class="token string single-quoted-string">'technician_id'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|exists:technicians,id'</span><span class="token punctuation">,</span>
  378. <span class="token string single-quoted-string">'work_days'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|array'</span><span class="token punctuation">,</span>
  379. <span class="token string single-quoted-string">'work_days.*'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'integer|between:0,6'</span><span class="token punctuation">,</span>
  380. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|date_format:H:i'</span><span class="token punctuation">,</span>
  381. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|date_format:H:i|after:start_time'</span>
  382. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  383. <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
  384. <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token property">scheduleService</span><span class="token operator">-&gt;</span><span class="token function">setWorkRule</span><span class="token punctuation">(</span>
  385. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">technician_id</span><span class="token punctuation">,</span>
  386. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">work_days</span><span class="token punctuation">,</span>
  387. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">start_time</span><span class="token punctuation">,</span>
  388. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">end_time</span>
  389. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  390. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  391. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'工作规则设置成功'</span>
  392. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  393. <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  394. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  395. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'工作规则设置失败:'</span> <span class="token operator">.</span> <span class="token variable">$e</span><span class="token operator">-&gt;</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  396. <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  397. <span class="token punctuation">}</span>
  398. <span class="token punctuation">}</span>
  399. <span class="token doc-comment comment">/**
  400. * 设置特殊日期
  401. */</span>
  402. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">setSpecialDate</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">JsonResponse</span>
  403. <span class="token punctuation">{</span>
  404. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  405. <span class="token string single-quoted-string">'technician_id'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|exists:technicians,id'</span><span class="token punctuation">,</span>
  406. <span class="token string single-quoted-string">'date'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|date|after:today'</span><span class="token punctuation">,</span>
  407. <span class="token string single-quoted-string">'is_working'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|boolean'</span><span class="token punctuation">,</span>
  408. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required_if:is_working,true|date_format:H:i|nullable'</span><span class="token punctuation">,</span>
  409. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required_if:is_working,true|date_format:H:i|after:start_time|nullable'</span>
  410. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  411. <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
  412. <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token property">scheduleService</span><span class="token operator">-&gt;</span><span class="token function">setSpecialDate</span><span class="token punctuation">(</span>
  413. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">technician_id</span><span class="token punctuation">,</span>
  414. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">date</span><span class="token punctuation">,</span>
  415. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">is_working</span><span class="token punctuation">,</span>
  416. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">start_time</span><span class="token punctuation">,</span>
  417. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">end_time</span>
  418. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  419. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  420. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'特殊日期设置成功'</span>
  421. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  422. <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  423. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  424. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'特殊日期设置失败:'</span> <span class="token operator">.</span> <span class="token variable">$e</span><span class="token operator">-&gt;</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  425. <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  426. <span class="token punctuation">}</span>
  427. <span class="token punctuation">}</span>
  428. <span class="token doc-comment comment">/**
  429. * 获取技师可预约时间段
  430. * <span class="token keyword keyword-@param">@param</span> <span class="token class-name">Request</span> <span class="token parameter">$request</span>
  431. * <span class="token keyword keyword-@return">@return</span> <span class="token class-name">JsonResponse</span>
  432. */</span>
  433. <span class="token keyword keyword-public">public</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">getAvailableTimeSlots</span><span class="token punctuation">(</span><span class="token class-name type-declaration">Request</span> <span class="token variable">$request</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">JsonResponse</span>
  434. <span class="token punctuation">{</span>
  435. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token function">validate</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  436. <span class="token string single-quoted-string">'technician_id'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|exists:technicians,id'</span><span class="token punctuation">,</span>
  437. <span class="token string single-quoted-string">'date'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|date|after_or_equal:today'</span><span class="token punctuation">,</span>
  438. <span class="token string single-quoted-string">'service_duration'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'required|integer|min:30'</span><span class="token punctuation">,</span> <span class="token comment">// 服务时长(分钟)</span>
  439. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  440. <span class="token keyword keyword-try">try</span> <span class="token punctuation">{</span>
  441. <span class="token comment">// 获取技师当天排班</span>
  442. <span class="token variable">$schedule</span> <span class="token operator">=</span> <span class="token scope">TechnicianSchedule<span class="token punctuation">::</span></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span> <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">technician_id</span><span class="token punctuation">)</span>
  443. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'work_date'</span><span class="token punctuation">,</span> <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">date</span><span class="token punctuation">)</span>
  444. <span class="token operator">-&gt;</span><span class="token function">first</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  445. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token variable">$schedule</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  446. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  447. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'技师当天未排班'</span><span class="token punctuation">,</span>
  448. <span class="token string single-quoted-string">'data'</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  449. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  450. <span class="token punctuation">}</span>
  451. <span class="token comment">// 获取已预约的时间段</span>
  452. <span class="token variable">$bookedTimeSlots</span> <span class="token operator">=</span> <span class="token scope">TechnicianWorkPlan<span class="token punctuation">::</span></span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technician_id'</span><span class="token punctuation">,</span> <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">technician_id</span><span class="token punctuation">)</span>
  453. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'date'</span><span class="token punctuation">,</span> <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">date</span><span class="token punctuation">)</span>
  454. <span class="token operator">-&gt;</span><span class="token function">where</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'status'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'!='</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'cancelled'</span><span class="token punctuation">)</span>
  455. <span class="token operator">-&gt;</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'plan_start_time'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'plan_end_time'</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  456. <span class="token operator">-&gt;</span><span class="token function">toArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  457. <span class="token comment">// 计算可用时间段</span>
  458. <span class="token variable">$availableTimeSlots</span> <span class="token operator">=</span> <span class="token this keyword">$this</span><span class="token operator">-&gt;</span><span class="token function">calculateAvailableTimeSlots</span><span class="token punctuation">(</span>
  459. <span class="token variable">$schedule</span><span class="token operator">-&gt;</span><span class="token property">work_time</span><span class="token punctuation">,</span>
  460. <span class="token variable">$bookedTimeSlots</span><span class="token punctuation">,</span>
  461. <span class="token variable">$request</span><span class="token operator">-&gt;</span><span class="token property">service_duration</span>
  462. <span class="token punctuation">)</span><span class="token punctuation">;</span>
  463. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  464. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token string single-quoted-string">'success'</span><span class="token punctuation">,</span>
  465. <span class="token string single-quoted-string">'data'</span> <span class="token operator">=&gt;</span> <span class="token variable">$availableTimeSlots</span>
  466. <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  467. <span class="token punctuation">}</span> <span class="token keyword keyword-catch">catch</span> <span class="token punctuation">(</span><span class="token class-name class-name-fully-qualified"><span class="token punctuation">\</span>Exception</span> <span class="token variable">$e</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  468. <span class="token keyword keyword-return">return</span> <span class="token function">response</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">json</span><span class="token punctuation">(</span><span class="token punctuation">[</span>
  469. <span class="token string single-quoted-string">'message'</span> <span class="token operator">=&gt;</span> <span class="token variable">$e</span><span class="token operator">-&gt;</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  470. <span class="token string single-quoted-string">'data'</span> <span class="token operator">=&gt;</span> <span class="token punctuation">[</span><span class="token punctuation">]</span>
  471. <span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token number">500</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  472. <span class="token punctuation">}</span>
  473. <span class="token punctuation">}</span>
  474. <span class="token doc-comment comment">/**
  475. * 计算可用时间段
  476. * <span class="token keyword keyword-@param">@param</span> <span class="token class-name"><span class="token keyword keyword-array">array</span></span> <span class="token parameter">$workTime</span> 工作时间 [<span class="token punctuation">{</span>"start":"09:00","end":"18:00"<span class="token punctuation">}</span>]
  477. * <span class="token keyword keyword-@param">@param</span> <span class="token class-name"><span class="token keyword keyword-array">array</span></span> <span class="token parameter">$bookedTimeSlots</span> 已预约时间段
  478. * <span class="token keyword keyword-@param">@param</span> <span class="token class-name"><span class="token keyword keyword-int">int</span></span> <span class="token parameter">$serviceDuration</span> 服务时长(分钟)
  479. * <span class="token keyword keyword-@return">@return</span> <span class="token class-name"><span class="token keyword keyword-array">array</span></span>
  480. */</span>
  481. <span class="token keyword keyword-private">private</span> <span class="token keyword keyword-function">function</span> <span class="token function-definition function">calculateAvailableTimeSlots</span><span class="token punctuation">(</span><span class="token keyword type-hint keyword-array">array</span> <span class="token variable">$workTime</span><span class="token punctuation">,</span> <span class="token keyword type-hint keyword-array">array</span> <span class="token variable">$bookedTimeSlots</span><span class="token punctuation">,</span> <span class="token keyword type-hint keyword-int">int</span> <span class="token variable">$serviceDuration</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type keyword-array">array</span>
  482. <span class="token punctuation">{</span>
  483. <span class="token variable">$availableSlots</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  484. <span class="token keyword keyword-foreach">foreach</span> <span class="token punctuation">(</span><span class="token variable">$workTime</span> <span class="token keyword keyword-as">as</span> <span class="token variable">$period</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  485. <span class="token variable">$startTime</span> <span class="token operator">=</span> <span class="token function">strtotime</span><span class="token punctuation">(</span><span class="token variable">$period</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'start'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  486. <span class="token variable">$endTime</span> <span class="token operator">=</span> <span class="token function">strtotime</span><span class="token punctuation">(</span><span class="token variable">$period</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'end'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  487. <span class="token comment">// 按30分钟间隔切分时间段</span>
  488. <span class="token variable">$currentSlot</span> <span class="token operator">=</span> <span class="token variable">$startTime</span><span class="token punctuation">;</span>
  489. <span class="token keyword keyword-while">while</span> <span class="token punctuation">(</span><span class="token variable">$currentSlot</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token variable">$serviceDuration</span> <span class="token operator">*</span> <span class="token number">60</span><span class="token punctuation">)</span> <span class="token operator">&lt;=</span> <span class="token variable">$endTime</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  490. <span class="token variable">$slotEnd</span> <span class="token operator">=</span> <span class="token variable">$currentSlot</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token variable">$serviceDuration</span> <span class="token operator">*</span> <span class="token number">60</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  491. <span class="token comment">// 检查是否与已预约时间段冲突</span>
  492. <span class="token variable">$isAvailable</span> <span class="token operator">=</span> <span class="token constant boolean">true</span><span class="token punctuation">;</span>
  493. <span class="token keyword keyword-foreach">foreach</span> <span class="token punctuation">(</span><span class="token variable">$bookedTimeSlots</span> <span class="token keyword keyword-as">as</span> <span class="token variable">$bookedSlot</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  494. <span class="token variable">$bookedStart</span> <span class="token operator">=</span> <span class="token function">strtotime</span><span class="token punctuation">(</span><span class="token variable">$bookedSlot</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'plan_start_time'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  495. <span class="token variable">$bookedEnd</span> <span class="token operator">=</span> <span class="token function">strtotime</span><span class="token punctuation">(</span><span class="token variable">$bookedSlot</span><span class="token punctuation">[</span><span class="token string single-quoted-string">'plan_end_time'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  496. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token variable">$currentSlot</span> <span class="token operator">&lt;</span> <span class="token variable">$bookedEnd</span> <span class="token operator">&amp;&amp;</span> <span class="token variable">$slotEnd</span> <span class="token operator">&gt;</span> <span class="token variable">$bookedStart</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  497. <span class="token variable">$isAvailable</span> <span class="token operator">=</span> <span class="token constant boolean">false</span><span class="token punctuation">;</span>
  498. <span class="token keyword keyword-break">break</span><span class="token punctuation">;</span>
  499. <span class="token punctuation">}</span>
  500. <span class="token punctuation">}</span>
  501. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span><span class="token variable">$isAvailable</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  502. <span class="token variable">$availableSlots</span><span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span>
  503. <span class="token string single-quoted-string">'start_time'</span> <span class="token operator">=&gt;</span> <span class="token function">date</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'H:i'</span><span class="token punctuation">,</span> <span class="token variable">$currentSlot</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
  504. <span class="token string single-quoted-string">'end_time'</span> <span class="token operator">=&gt;</span> <span class="token function">date</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'H:i'</span><span class="token punctuation">,</span> <span class="token variable">$slotEnd</span><span class="token punctuation">)</span>
  505. <span class="token punctuation">]</span><span class="token punctuation">;</span>
  506. <span class="token punctuation">}</span>
  507. <span class="token variable">$currentSlot</span> <span class="token operator">+=</span> <span class="token number">1800</span><span class="token punctuation">;</span> <span class="token comment">// 30分钟</span>
  508. <span class="token punctuation">}</span>
  509. <span class="token punctuation">}</span>
  510. <span class="token keyword keyword-return">return</span> <span class="token variable">$availableSlots</span><span class="token punctuation">;</span>
  511. <span class="token punctuation">}</span>
  512. <span class="token punctuation">}</span>
  513. </span></code></pre><h3 id="3-路由定义">3. 路由定义 </h3>
  514. <pre data-role="codeBlock" data-info="php" class="language-php php"><code><span class="token comment">// routes/api.php</span>
  515. <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">prefix</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'technician'</span><span class="token punctuation">)</span><span class="token operator">-&gt;</span><span class="token function">group</span><span class="token punctuation">(</span><span class="token keyword keyword-function">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  516. <span class="token comment">// 技师工作规则设置</span>
  517. <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'work-rule'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token scope">TechnicianScheduleController<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'setWorkRule'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  518. <span class="token comment">// 特殊日期设置</span>
  519. <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'special-date'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token scope">TechnicianScheduleController<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'setSpecialDate'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  520. <span class="token comment">// 获取可用时间槽</span>
  521. <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">get</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'time-slots'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token scope">TechnicianScheduleController<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'getAvailableTimeSlots'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  522. <span class="token comment">// 预约时间槽</span>
  523. <span class="token scope">Route<span class="token punctuation">::</span></span><span class="token function">post</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'book'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token scope">TechnicianScheduleController<span class="token punctuation">::</span></span><span class="token keyword keyword-class">class</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'bookTimeSlot'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  524. <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
  525. </code></pre><h2 id="前端实现-uniapp-vue3">前端实现 (UniApp Vue3) </h2>
  526. <h3 id="1-工作规则设置页面">1. 工作规则设置页面 </h3>
  527. <pre data-role="codeBlock" data-info="html" class="language-html html"><code><span class="token comment">&lt;!-- pages/technician/schedule/index.vue --&gt;</span>
  528. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  529. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>view</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>schedule-setting<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  530. <span class="token comment">&lt;!-- 工作日设置 --&gt;</span>
  531. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-section</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>工作日设置<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>line<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  532. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-list</span><span class="token punctuation">&gt;</span></span>
  533. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-list-item</span> <span class="token attr-name">v-for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>day in weekDays<span class="token punctuation">"</span></span> <span class="token attr-name">:key</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>day.value<span class="token punctuation">"</span></span>
  534. <span class="token attr-name">:title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>day.label<span class="token punctuation">"</span></span>
  535. <span class="token attr-name">:switchChecked</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>workDays.includes(day.value)<span class="token punctuation">"</span></span>
  536. <span class="token attr-name">@switch-change</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>(e) =&gt; toggleWorkDay(day.value, e.value)<span class="token punctuation">"</span></span>
  537. <span class="token attr-name">showSwitch</span>
  538. <span class="token punctuation">/&gt;</span></span>
  539. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-list</span><span class="token punctuation">&gt;</span></span>
  540. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-section</span><span class="token punctuation">&gt;</span></span>
  541. <span class="token comment">&lt;!-- 工作时间设置 --&gt;</span>
  542. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-section</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>工作时间设置<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>line<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  543. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-list</span><span class="token punctuation">&gt;</span></span>
  544. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-list-item</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>上班时间<span class="token punctuation">"</span></span> <span class="token attr-name">showArrow</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showStartTimePicker = true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  545. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name"><span class="token namespace">v-slot:</span>footer</span><span class="token punctuation">&gt;</span></span>
  546. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>text</span><span class="token punctuation">&gt;</span></span>{{ startTime }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>text</span><span class="token punctuation">&gt;</span></span>
  547. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
  548. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-list-item</span><span class="token punctuation">&gt;</span></span>
  549. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-list-item</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>下班时间<span class="token punctuation">"</span></span> <span class="token attr-name">showArrow</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showEndTimePicker = true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  550. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name"><span class="token namespace">v-slot:</span>footer</span><span class="token punctuation">&gt;</span></span>
  551. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>text</span><span class="token punctuation">&gt;</span></span>{{ endTime }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>text</span><span class="token punctuation">&gt;</span></span>
  552. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
  553. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-list-item</span><span class="token punctuation">&gt;</span></span>
  554. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-list</span><span class="token punctuation">&gt;</span></span>
  555. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-section</span><span class="token punctuation">&gt;</span></span>
  556. <span class="token comment">&lt;!-- 保存按钮 --&gt;</span>
  557. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>view</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>button-group<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  558. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>primary-button<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>saveWorkRule<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>保存设置<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  559. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>view</span><span class="token punctuation">&gt;</span></span>
  560. <span class="token comment">&lt;!-- 特殊日期设置 --&gt;</span>
  561. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-section</span> <span class="token attr-name">title</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>特殊日期设置<span class="token punctuation">"</span></span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>line<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  562. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>secondary-button<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showCalendar = true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  563. 设置休息日/特殊工作日
  564. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  565. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-section</span><span class="token punctuation">&gt;</span></span>
  566. <span class="token comment">&lt;!-- 时间选择器 --&gt;</span>
  567. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-datetime-picker</span>
  568. <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showStartTimePicker<span class="token punctuation">"</span></span>
  569. <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>time<span class="token punctuation">"</span></span>
  570. <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>startTime<span class="token punctuation">"</span></span>
  571. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onStartTimeChange<span class="token punctuation">"</span></span>
  572. <span class="token punctuation">/&gt;</span></span>
  573. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-datetime-picker</span>
  574. <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showEndTimePicker<span class="token punctuation">"</span></span>
  575. <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>time<span class="token punctuation">"</span></span>
  576. <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>endTime<span class="token punctuation">"</span></span>
  577. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onEndTimeChange<span class="token punctuation">"</span></span>
  578. <span class="token punctuation">/&gt;</span></span>
  579. <span class="token comment">&lt;!-- 日历选择器 --&gt;</span>
  580. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-calendar</span>
  581. <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showCalendar<span class="token punctuation">"</span></span>
  582. <span class="token attr-name">:insert</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>false<span class="token punctuation">"</span></span>
  583. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onSelectSpecialDate<span class="token punctuation">"</span></span>
  584. <span class="token attr-name">:start-date</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>startDate<span class="token punctuation">"</span></span>
  585. <span class="token attr-name">:end-date</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>endDate<span class="token punctuation">"</span></span>
  586. <span class="token punctuation">/&gt;</span></span>
  587. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>view</span><span class="token punctuation">&gt;</span></span>
  588. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
  589. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
  590. <span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> ref<span class="token punctuation">,</span> onMounted <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">'vue'</span>
  591. <span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> onLoad <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">'@dcloudio/uni-app'</span>
  592. <span class="token comment">// 工作日配置</span>
  593. <span class="token keyword keyword-const">const</span> weekDays <span class="token operator">=</span> <span class="token punctuation">[</span>
  594. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周一'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">1</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  595. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周二'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  596. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周三'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  597. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周四'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">4</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  598. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周五'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">5</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  599. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周六'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">6</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>
  600. <span class="token punctuation">{</span> <span class="token literal-property property">label</span><span class="token operator">:</span> <span class="token string">'周日'</span><span class="token punctuation">,</span> <span class="token literal-property property">value</span><span class="token operator">:</span> <span class="token number">0</span> <span class="token punctuation">}</span>
  601. <span class="token punctuation">]</span>
  602. <span class="token comment">// 响应式数据</span>
  603. <span class="token keyword keyword-const">const</span> workDays <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  604. <span class="token keyword keyword-const">const</span> startTime <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">'08:00'</span><span class="token punctuation">)</span>
  605. <span class="token keyword keyword-const">const</span> endTime <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">'18:00'</span><span class="token punctuation">)</span>
  606. <span class="token keyword keyword-const">const</span> showStartTimePicker <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
  607. <span class="token keyword keyword-const">const</span> showEndTimePicker <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
  608. <span class="token keyword keyword-const">const</span> showCalendar <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
  609. <span class="token comment">// 日期范围</span>
  610. <span class="token keyword keyword-const">const</span> startDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  611. <span class="token keyword keyword-const">const</span> endDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token known-class-name class-name">Date</span><span class="token punctuation">.</span><span class="token method function property-access">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">90</span> <span class="token operator">*</span> <span class="token number">24</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span>
  612. <span class="token comment">// 获取技师当前设置</span>
  613. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">getCurrentSettings</span> <span class="token operator">=</span> <span class="token keyword keyword-async">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  614. <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
  615. <span class="token keyword keyword-const">const</span> res <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> uni<span class="token punctuation">.</span><span class="token method function property-access">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  616. <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">'/api/technician/work-rule'</span><span class="token punctuation">,</span>
  617. <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span>
  618. <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  619. <span class="token literal-property property">technician_id</span><span class="token operator">:</span> <span class="token function">getApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">globalData</span><span class="token punctuation">.</span><span class="token property-access">technicianId</span>
  620. <span class="token punctuation">}</span>
  621. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  622. <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span><span class="token property-access">statusCode</span> <span class="token operator">===</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  623. <span class="token keyword keyword-const">const</span> <span class="token punctuation">{</span> work_days<span class="token punctuation">,</span> start_time<span class="token punctuation">,</span> end_time <span class="token punctuation">}</span> <span class="token operator">=</span> res<span class="token punctuation">.</span><span class="token property-access">data</span><span class="token punctuation">.</span><span class="token property-access">data</span>
  624. workDays<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> work_days<span class="token punctuation">.</span><span class="token method function property-access">split</span><span class="token punctuation">(</span><span class="token string">','</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">map</span><span class="token punctuation">(</span><span class="token known-class-name class-name">Number</span><span class="token punctuation">)</span>
  625. startTime<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> start_time
  626. endTime<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> end_time
  627. <span class="token punctuation">}</span>
  628. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  629. uni<span class="token punctuation">.</span><span class="token method function property-access">showToast</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  630. <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'获取设置失败'</span><span class="token punctuation">,</span>
  631. <span class="token literal-property property">icon</span><span class="token operator">:</span> <span class="token string">'none'</span>
  632. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  633. <span class="token punctuation">}</span>
  634. <span class="token punctuation">}</span>
  635. <span class="token comment">// 切换工作日</span>
  636. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">toggleWorkDay</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">day<span class="token punctuation">,</span> checked</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  637. <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>checked<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  638. workDays<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">.</span><span class="token method function property-access">push</span><span class="token punctuation">(</span>day<span class="token punctuation">)</span>
  639. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
  640. <span class="token keyword keyword-const">const</span> index <span class="token operator">=</span> workDays<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">.</span><span class="token method function property-access">indexOf</span><span class="token punctuation">(</span>day<span class="token punctuation">)</span>
  641. <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>index <span class="token operator">&gt;</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  642. workDays<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">.</span><span class="token method function property-access">splice</span><span class="token punctuation">(</span>index<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span>
  643. <span class="token punctuation">}</span>
  644. <span class="token punctuation">}</span>
  645. <span class="token punctuation">}</span>
  646. <span class="token comment">// 时间选择回调</span>
  647. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onStartTimeChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  648. startTime<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> time
  649. <span class="token punctuation">}</span>
  650. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onEndTimeChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  651. endTime<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> time
  652. <span class="token punctuation">}</span>
  653. <span class="token comment">// 保存工作规则</span>
  654. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">saveWorkRule</span> <span class="token operator">=</span> <span class="token keyword keyword-async">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  655. <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
  656. <span class="token keyword keyword-const">const</span> res <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> uni<span class="token punctuation">.</span><span class="token method function property-access">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  657. <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">'/api/technician/work-rule'</span><span class="token punctuation">,</span>
  658. <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">'POST'</span><span class="token punctuation">,</span>
  659. <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  660. <span class="token literal-property property">technician_id</span><span class="token operator">:</span> <span class="token function">getApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">globalData</span><span class="token punctuation">.</span><span class="token property-access">technicianId</span><span class="token punctuation">,</span>
  661. <span class="token literal-property property">work_days</span><span class="token operator">:</span> workDays<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">,</span>
  662. <span class="token literal-property property">start_time</span><span class="token operator">:</span> startTime<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">,</span>
  663. <span class="token literal-property property">end_time</span><span class="token operator">:</span> endTime<span class="token punctuation">.</span><span class="token property-access">value</span>
  664. <span class="token punctuation">}</span>
  665. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  666. <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span><span class="token property-access">statusCode</span> <span class="token operator">===</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  667. uni<span class="token punctuation">.</span><span class="token method function property-access">showToast</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  668. <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'设置成功'</span><span class="token punctuation">,</span>
  669. <span class="token literal-property property">icon</span><span class="token operator">:</span> <span class="token string">'success'</span>
  670. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  671. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
  672. <span class="token keyword control-flow keyword-throw">throw</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span><span class="token property-access">data</span><span class="token punctuation">.</span><span class="token property-access">message</span><span class="token punctuation">)</span>
  673. <span class="token punctuation">}</span>
  674. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  675. uni<span class="token punctuation">.</span><span class="token method function property-access">showToast</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  676. <span class="token literal-property property">title</span><span class="token operator">:</span> error<span class="token punctuation">.</span><span class="token property-access">message</span> <span class="token operator">||</span> <span class="token string">'设置失败'</span><span class="token punctuation">,</span>
  677. <span class="token literal-property property">icon</span><span class="token operator">:</span> <span class="token string">'none'</span>
  678. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  679. <span class="token punctuation">}</span>
  680. <span class="token punctuation">}</span>
  681. <span class="token comment">// 页面加载时获取当前设置</span>
  682. <span class="token function">onLoad</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  683. <span class="token function">getCurrentSettings</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  684. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  685. </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
  686. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>scss<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
  687. <span class="token selector"><span class="token class">.schedule-setting</span></span> <span class="token punctuation">{</span>
  688. <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  689. <span class="token selector"><span class="token class">.button-group</span></span> <span class="token punctuation">{</span>
  690. <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">30</span><span class="token unit">rpx</span> <span class="token number">0</span><span class="token punctuation">;</span>
  691. <span class="token punctuation">}</span>
  692. <span class="token selector"><span class="token class">.primary-button</span></span> <span class="token punctuation">{</span>
  693. <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode color">#007AFF</span><span class="token punctuation">;</span>
  694. <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode color">#fff</span><span class="token punctuation">;</span>
  695. <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  696. <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  697. <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
  698. <span class="token punctuation">}</span>
  699. <span class="token selector"><span class="token class">.secondary-button</span></span> <span class="token punctuation">{</span>
  700. <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode color">#F8F8F8</span><span class="token punctuation">;</span>
  701. <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode color">#333</span><span class="token punctuation">;</span>
  702. <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token hexcode color">#DDDDDD</span><span class="token punctuation">;</span>
  703. <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  704. <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  705. <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
  706. <span class="token property">margin-top</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  707. <span class="token punctuation">}</span>
  708. <span class="token punctuation">}</span>
  709. </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
  710. </code></pre><h3 id="2-特殊日期设置页面">2. 特殊日期设置页面 </h3>
  711. <pre data-role="codeBlock" data-info="html" class="language-html html"><code><span class="token comment">&lt;!-- pages/technician/schedule/special-date.vue --&gt;</span>
  712. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  713. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>view</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>special-date<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  714. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-forms</span> <span class="token attr-name">ref</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>form<span class="token punctuation">"</span></span> <span class="token attr-name">:modelValue</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>formData<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  715. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-forms-item</span> <span class="token attr-name">label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>日期<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  716. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>text</span><span class="token punctuation">&gt;</span></span>{{ date }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>text</span><span class="token punctuation">&gt;</span></span>
  717. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-forms-item</span><span class="token punctuation">&gt;</span></span>
  718. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-forms-item</span> <span class="token attr-name">label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>是否工作<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  719. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>switch</span> <span class="token attr-name">:checked</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>formData.is_working<span class="token punctuation">"</span></span> <span class="token attr-name">@change</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onWorkingChange<span class="token punctuation">"</span></span> <span class="token punctuation">/&gt;</span></span>
  720. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-forms-item</span><span class="token punctuation">&gt;</span></span>
  721. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span> <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>formData.is_working<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  722. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-forms-item</span> <span class="token attr-name">label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>上班时间<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  723. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>view</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>time-picker<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showStartTimePicker = true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  724. {{ formData.start_time || '请选择' }}
  725. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>view</span><span class="token punctuation">&gt;</span></span>
  726. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-forms-item</span><span class="token punctuation">&gt;</span></span>
  727. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-forms-item</span> <span class="token attr-name">label</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>下班时间<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  728. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>view</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>time-picker<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showEndTimePicker = true<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  729. {{ formData.end_time || '请选择' }}
  730. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>view</span><span class="token punctuation">&gt;</span></span>
  731. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-forms-item</span><span class="token punctuation">&gt;</span></span>
  732. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
  733. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>uni-forms</span><span class="token punctuation">&gt;</span></span>
  734. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>view</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>button-group<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>
  735. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>primary-button<span class="token punctuation">"</span></span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>saveSpecialDate<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span>保存设置<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  736. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>view</span><span class="token punctuation">&gt;</span></span>
  737. <span class="token comment">&lt;!-- 时间选择器 --&gt;</span>
  738. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-datetime-picker</span>
  739. <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showStartTimePicker<span class="token punctuation">"</span></span>
  740. <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>time<span class="token punctuation">"</span></span>
  741. <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>formData.start_time<span class="token punctuation">"</span></span>
  742. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onStartTimeChange<span class="token punctuation">"</span></span>
  743. <span class="token punctuation">/&gt;</span></span>
  744. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>uni-datetime-picker</span>
  745. <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>showEndTimePicker<span class="token punctuation">"</span></span>
  746. <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>time<span class="token punctuation">"</span></span>
  747. <span class="token attr-name">:value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>formData.end_time<span class="token punctuation">"</span></span>
  748. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onEndTimeChange<span class="token punctuation">"</span></span>
  749. <span class="token punctuation">/&gt;</span></span>
  750. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>view</span><span class="token punctuation">&gt;</span></span>
  751. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
  752. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
  753. <span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> ref <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">'vue'</span>
  754. <span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> onLoad <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">'@dcloudio/uni-app'</span>
  755. <span class="token keyword keyword-const">const</span> date <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token string">''</span><span class="token punctuation">)</span>
  756. <span class="token keyword keyword-const">const</span> formData <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  757. <span class="token literal-property property">is_working</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  758. <span class="token literal-property property">start_time</span><span class="token operator">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
  759. <span class="token literal-property property">end_time</span><span class="token operator">:</span> <span class="token string">''</span>
  760. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  761. <span class="token keyword keyword-const">const</span> showStartTimePicker <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
  762. <span class="token keyword keyword-const">const</span> showEndTimePicker <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span>
  763. <span class="token comment">// 获取特殊日期设置</span>
  764. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">getSpecialDateSettings</span> <span class="token operator">=</span> <span class="token keyword keyword-async">async</span> <span class="token punctuation">(</span><span class="token parameter">date</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  765. <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
  766. <span class="token keyword keyword-const">const</span> res <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> uni<span class="token punctuation">.</span><span class="token method function property-access">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  767. <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">'/api/technician/special-date'</span><span class="token punctuation">,</span>
  768. <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span>
  769. <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  770. <span class="token literal-property property">technician_id</span><span class="token operator">:</span> <span class="token function">getApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">globalData</span><span class="token punctuation">.</span><span class="token property-access">technicianId</span><span class="token punctuation">,</span>
  771. <span class="token literal-property property">date</span><span class="token operator">:</span> date
  772. <span class="token punctuation">}</span>
  773. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  774. <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span><span class="token property-access">statusCode</span> <span class="token operator">===</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  775. formData<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> res<span class="token punctuation">.</span><span class="token property-access">data</span><span class="token punctuation">.</span><span class="token property-access">data</span> <span class="token operator">||</span> <span class="token punctuation">{</span>
  776. <span class="token literal-property property">is_working</span><span class="token operator">:</span> <span class="token boolean">false</span><span class="token punctuation">,</span>
  777. <span class="token literal-property property">start_time</span><span class="token operator">:</span> <span class="token string">''</span><span class="token punctuation">,</span>
  778. <span class="token literal-property property">end_time</span><span class="token operator">:</span> <span class="token string">''</span>
  779. <span class="token punctuation">}</span>
  780. <span class="token punctuation">}</span>
  781. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  782. uni<span class="token punctuation">.</span><span class="token method function property-access">showToast</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  783. <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'获取设置失败'</span><span class="token punctuation">,</span>
  784. <span class="token literal-property property">icon</span><span class="token operator">:</span> <span class="token string">'none'</span>
  785. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  786. <span class="token punctuation">}</span>
  787. <span class="token punctuation">}</span>
  788. <span class="token comment">// 工作状态切换</span>
  789. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onWorkingChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">e</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  790. formData<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">.</span><span class="token property-access">is_working</span> <span class="token operator">=</span> e<span class="token punctuation">.</span><span class="token property-access">detail</span><span class="token punctuation">.</span><span class="token property-access">value</span>
  791. <span class="token punctuation">}</span>
  792. <span class="token comment">// 时间选择回调</span>
  793. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onStartTimeChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  794. formData<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">.</span><span class="token property-access">start_time</span> <span class="token operator">=</span> time
  795. <span class="token punctuation">}</span>
  796. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onEndTimeChange</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">time</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  797. formData<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">.</span><span class="token property-access">end_time</span> <span class="token operator">=</span> time
  798. <span class="token punctuation">}</span>
  799. <span class="token comment">// 保存特殊日期设置</span>
  800. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">saveSpecialDate</span> <span class="token operator">=</span> <span class="token keyword keyword-async">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  801. <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
  802. <span class="token keyword keyword-const">const</span> res <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> uni<span class="token punctuation">.</span><span class="token method function property-access">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  803. <span class="token literal-property property">url</span><span class="token operator">:</span> <span class="token string">'/api/technician/special-date'</span><span class="token punctuation">,</span>
  804. <span class="token literal-property property">method</span><span class="token operator">:</span> <span class="token string">'POST'</span><span class="token punctuation">,</span>
  805. <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  806. <span class="token literal-property property">technician_id</span><span class="token operator">:</span> <span class="token function">getApp</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token property-access">globalData</span><span class="token punctuation">.</span><span class="token property-access">technicianId</span><span class="token punctuation">,</span>
  807. <span class="token literal-property property">date</span><span class="token operator">:</span> date<span class="token punctuation">.</span><span class="token property-access">value</span><span class="token punctuation">,</span>
  808. <span class="token spread operator">...</span>formData<span class="token punctuation">.</span><span class="token property-access">value</span>
  809. <span class="token punctuation">}</span>
  810. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  811. <span class="token keyword control-flow keyword-if">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span><span class="token property-access">statusCode</span> <span class="token operator">===</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  812. uni<span class="token punctuation">.</span><span class="token method function property-access">showToast</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  813. <span class="token literal-property property">title</span><span class="token operator">:</span> <span class="token string">'设置成功'</span><span class="token punctuation">,</span>
  814. <span class="token literal-property property">icon</span><span class="token operator">:</span> <span class="token string">'success'</span>
  815. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  816. <span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  817. uni<span class="token punctuation">.</span><span class="token method function property-access">navigateBack</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  818. <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">1500</span><span class="token punctuation">)</span>
  819. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-else">else</span> <span class="token punctuation">{</span>
  820. <span class="token keyword control-flow keyword-throw">throw</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Error</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span><span class="token property-access">data</span><span class="token punctuation">.</span><span class="token property-access">message</span><span class="token punctuation">)</span>
  821. <span class="token punctuation">}</span>
  822. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  823. uni<span class="token punctuation">.</span><span class="token method function property-access">showToast</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  824. <span class="token literal-property property">title</span><span class="token operator">:</span> error<span class="token punctuation">.</span><span class="token property-access">message</span> <span class="token operator">||</span> <span class="token string">'设置失败'</span><span class="token punctuation">,</span>
  825. <span class="token literal-property property">icon</span><span class="token operator">:</span> <span class="token string">'none'</span>
  826. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  827. <span class="token punctuation">}</span>
  828. <span class="token punctuation">}</span>
  829. <span class="token comment">// 页面加载</span>
  830. <span class="token function">onLoad</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">options</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  831. date<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> options<span class="token punctuation">.</span><span class="token property-access">date</span>
  832. <span class="token function">getSpecialDateSettings</span><span class="token punctuation">(</span>options<span class="token punctuation">.</span><span class="token property-access">date</span><span class="token punctuation">)</span>
  833. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  834. </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
  835. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>style</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>scss<span class="token punctuation">"</span></span><span class="token punctuation">&gt;</span></span><span class="token style"><span class="token language-css">
  836. <span class="token selector"><span class="token class">.special-date</span></span> <span class="token punctuation">{</span>
  837. <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  838. <span class="token selector"><span class="token class">.time-picker</span></span> <span class="token punctuation">{</span>
  839. <span class="token property">border</span><span class="token punctuation">:</span> <span class="token number">1</span><span class="token unit">px</span> solid <span class="token hexcode color">#DDDDDD</span><span class="token punctuation">;</span>
  840. <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  841. <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  842. <span class="token punctuation">}</span>
  843. <span class="token selector"><span class="token class">.button-group</span></span> <span class="token punctuation">{</span>
  844. <span class="token property">margin</span><span class="token punctuation">:</span> <span class="token number">30</span><span class="token unit">rpx</span> <span class="token number">0</span><span class="token punctuation">;</span>
  845. <span class="token punctuation">}</span>
  846. <span class="token selector"><span class="token class">.primary-button</span></span> <span class="token punctuation">{</span>
  847. <span class="token property">background-color</span><span class="token punctuation">:</span> <span class="token hexcode color">#007AFF</span><span class="token punctuation">;</span>
  848. <span class="token property">color</span><span class="token punctuation">:</span> <span class="token hexcode color">#fff</span><span class="token punctuation">;</span>
  849. <span class="token property">border-radius</span><span class="token punctuation">:</span> <span class="token number">10</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  850. <span class="token property">padding</span><span class="token punctuation">:</span> <span class="token number">20</span><span class="token unit">rpx</span><span class="token punctuation">;</span>
  851. <span class="token property">text-align</span><span class="token punctuation">:</span> center<span class="token punctuation">;</span>
  852. <span class="token punctuation">}</span>
  853. <span class="token punctuation">}</span>
  854. </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>style</span><span class="token punctuation">&gt;</span></span>
  855. </code></pre><h3 id="3-获取技师可用时间例子">3. 获取技师可用时间例子 </h3>
  856. <pre data-role="codeBlock" data-info="html" class="language-html html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  857. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
  858. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-datetime-picker</span>
  859. <span class="token attr-name">v-model</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>selectedDate<span class="token punctuation">"</span></span>
  860. <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>date<span class="token punctuation">"</span></span>
  861. <span class="token attr-name">:min-date</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>minDate<span class="token punctuation">"</span></span>
  862. <span class="token attr-name">:max-date</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>maxDate<span class="token punctuation">"</span></span>
  863. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onDateSelected<span class="token punctuation">"</span></span>
  864. <span class="token punctuation">/&gt;</span></span>
  865. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>van-picker</span>
  866. <span class="token attr-name">v-if</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>timeSlots.length<span class="token punctuation">"</span></span>
  867. <span class="token attr-name">:columns</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>timeSlots<span class="token punctuation">"</span></span>
  868. <span class="token attr-name">@confirm</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>onTimeSelected<span class="token punctuation">"</span></span>
  869. <span class="token punctuation">/&gt;</span></span>
  870. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
  871. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
  872. <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span> <span class="token attr-name">setup</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
  873. <span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> ref <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">'vue'</span>
  874. <span class="token keyword module keyword-import">import</span> <span class="token imports">axios</span> <span class="token keyword module keyword-from">from</span> <span class="token string">'axios'</span>
  875. <span class="token keyword module keyword-import">import</span> <span class="token imports"><span class="token punctuation">{</span> showToast <span class="token punctuation">}</span></span> <span class="token keyword module keyword-from">from</span> <span class="token string">'vant'</span>
  876. <span class="token keyword keyword-const">const</span> selectedDate <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
  877. <span class="token keyword keyword-const">const</span> minDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  878. <span class="token keyword keyword-const">const</span> maxDate <span class="token operator">=</span> <span class="token keyword keyword-new">new</span> <span class="token class-name">Date</span><span class="token punctuation">(</span><span class="token known-class-name class-name">Date</span><span class="token punctuation">.</span><span class="token method function property-access">now</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">30</span> <span class="token operator">*</span> <span class="token number">24</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">60</span> <span class="token operator">*</span> <span class="token number">1000</span><span class="token punctuation">)</span>
  879. <span class="token keyword keyword-const">const</span> timeSlots <span class="token operator">=</span> <span class="token function">ref</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">)</span>
  880. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">getAvailableTimeSlots</span> <span class="token operator">=</span> <span class="token keyword keyword-async">async</span> <span class="token punctuation">(</span><span class="token parameter">date</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  881. <span class="token keyword control-flow keyword-try">try</span> <span class="token punctuation">{</span>
  882. <span class="token keyword keyword-const">const</span> response <span class="token operator">=</span> <span class="token keyword control-flow keyword-await">await</span> axios<span class="token punctuation">.</span><span class="token method function property-access">get</span><span class="token punctuation">(</span><span class="token string">'/api/technician/available-time-slots'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
  883. <span class="token literal-property property">params</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  884. <span class="token literal-property property">technician_id</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token comment">// 技师ID</span>
  885. <span class="token literal-property property">date</span><span class="token operator">:</span> date<span class="token punctuation">,</span>
  886. <span class="token literal-property property">service_duration</span><span class="token operator">:</span> <span class="token number">60</span> <span class="token comment">// 服务时长(分钟)</span>
  887. <span class="token punctuation">}</span>
  888. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  889. timeSlots<span class="token punctuation">.</span><span class="token property-access">value</span> <span class="token operator">=</span> response<span class="token punctuation">.</span><span class="token property-access">data</span><span class="token punctuation">.</span><span class="token property-access">data</span><span class="token punctuation">.</span><span class="token method function property-access">map</span><span class="token punctuation">(</span><span class="token parameter">slot</span> <span class="token arrow operator">=&gt;</span>
  890. <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>slot<span class="token punctuation">.</span><span class="token property-access">start_time</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">-</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>slot<span class="token punctuation">.</span><span class="token property-access">end_time</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
  891. <span class="token punctuation">)</span>
  892. <span class="token punctuation">}</span> <span class="token keyword control-flow keyword-catch">catch</span> <span class="token punctuation">(</span>error<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  893. <span class="token function">showToast</span><span class="token punctuation">(</span>error<span class="token punctuation">.</span><span class="token property-access">response</span><span class="token operator">?.</span>data<span class="token operator">?.</span>message <span class="token operator">||</span> <span class="token string">'获取可用时间失败'</span><span class="token punctuation">)</span>
  894. <span class="token punctuation">}</span>
  895. <span class="token punctuation">}</span>
  896. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onDateSelected</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  897. <span class="token keyword keyword-const">const</span> formatDate <span class="token operator">=</span> value<span class="token punctuation">.</span><span class="token method function property-access">toISOString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token method function property-access">split</span><span class="token punctuation">(</span><span class="token string">'T'</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span>
  898. <span class="token function">getAvailableTimeSlots</span><span class="token punctuation">(</span>formatDate<span class="token punctuation">)</span>
  899. <span class="token punctuation">}</span>
  900. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">onTimeSelected</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token parameter">value</span><span class="token punctuation">)</span> <span class="token arrow operator">=&gt;</span> <span class="token punctuation">{</span>
  901. <span class="token comment">// 处理时间段选择</span>
  902. <span class="token console class-name">console</span><span class="token punctuation">.</span><span class="token method function property-access">log</span><span class="token punctuation">(</span><span class="token string">'Selected time slot:'</span><span class="token punctuation">,</span> value<span class="token punctuation">)</span>
  903. <span class="token punctuation">}</span>
  904. </span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
  905. </code></pre><h3 id="4-api-请求封装">4. API 请求封装 </h3>
  906. <pre data-role="codeBlock" data-info="typescript" class="language-typescript typescript"><code><span class="token comment">// utils/request.ts</span>
  907. <span class="token keyword keyword-import">import</span> <span class="token punctuation">{</span> baseURL <span class="token punctuation">}</span> <span class="token keyword keyword-from">from</span> <span class="token string">'@/config'</span>
  908. <span class="token keyword keyword-interface">interface</span> <span class="token class-name">RequestOptions</span> <span class="token keyword keyword-extends">extends</span> <span class="token class-name">UniApp</span><span class="token punctuation">.</span>RequestOptions <span class="token punctuation">{</span>
  909. loading<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span>
  910. <span class="token punctuation">}</span>
  911. <span class="token keyword keyword-const">const</span> <span class="token function-variable function">request</span> <span class="token operator">=</span> <span class="token punctuation">(</span>options<span class="token operator">:</span> RequestOptions<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  912. <span class="token keyword keyword-const">const</span> <span class="token punctuation">{</span> loading <span class="token operator">=</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token operator">=</span> options
  913. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>loading<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  914. uni<span class="token punctuation">.</span><span class="token function">showLoading</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  915. title<span class="token operator">:</span> <span class="token string">'加载中'</span>
  916. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  917. <span class="token punctuation">}</span>
  918. <span class="token keyword keyword-return">return</span> <span class="token keyword keyword-new">new</span> <span class="token class-name"><span class="token builtin">Promise</span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>resolve<span class="token punctuation">,</span> reject<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  919. uni<span class="token punctuation">.</span><span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  920. <span class="token operator">...</span>options<span class="token punctuation">,</span>
  921. url<span class="token operator">:</span> baseURL <span class="token operator">+</span> options<span class="token punctuation">.</span>url<span class="token punctuation">,</span>
  922. header<span class="token operator">:</span> <span class="token punctuation">{</span>
  923. <span class="token operator">...</span>options<span class="token punctuation">.</span>header<span class="token punctuation">,</span>
  924. <span class="token string-property property">'Authorization'</span><span class="token operator">:</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">Bearer </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>uni<span class="token punctuation">.</span><span class="token function">getStorageSync</span><span class="token punctuation">(</span><span class="token string">'token'</span><span class="token punctuation">)</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span>
  925. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  926. <span class="token function-variable function">success</span><span class="token operator">:</span> <span class="token punctuation">(</span>res<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  927. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>res<span class="token punctuation">.</span>statusCode <span class="token operator">===</span> <span class="token number">200</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  928. <span class="token function">resolve</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
  929. <span class="token punctuation">}</span> <span class="token keyword keyword-else">else</span> <span class="token punctuation">{</span>
  930. <span class="token function">reject</span><span class="token punctuation">(</span>res<span class="token punctuation">.</span>data<span class="token punctuation">)</span>
  931. <span class="token punctuation">}</span>
  932. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  933. <span class="token function-variable function">fail</span><span class="token operator">:</span> <span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  934. <span class="token function">reject</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span>
  935. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  936. <span class="token function-variable function">complete</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  937. <span class="token keyword keyword-if">if</span> <span class="token punctuation">(</span>loading<span class="token punctuation">)</span> <span class="token punctuation">{</span>
  938. uni<span class="token punctuation">.</span><span class="token function">hideLoading</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
  939. <span class="token punctuation">}</span>
  940. <span class="token punctuation">}</span>
  941. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  942. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  943. <span class="token punctuation">}</span>
  944. <span class="token keyword keyword-export">export</span> <span class="token keyword keyword-default">default</span> request
  945. </code></pre><h3 id="5-api-接口定义">5. API 接口定义 </h3>
  946. <pre data-role="codeBlock" data-info="typescript" class="language-typescript typescript"><code><span class="token comment">// api/technician.ts</span>
  947. <span class="token keyword keyword-import">import</span> request <span class="token keyword keyword-from">from</span> <span class="token string">'@/utils/request'</span>
  948. <span class="token comment">// 获取工作规则</span>
  949. <span class="token keyword keyword-export">export</span> <span class="token keyword keyword-const">const</span> <span class="token function-variable function">getWorkRule</span> <span class="token operator">=</span> <span class="token punctuation">(</span>technicianId<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  950. <span class="token keyword keyword-return">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  951. url<span class="token operator">:</span> <span class="token string">'/technician/work-rule'</span><span class="token punctuation">,</span>
  952. method<span class="token operator">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span>
  953. data<span class="token operator">:</span> <span class="token punctuation">{</span> technician_id<span class="token operator">:</span> technicianId <span class="token punctuation">}</span>
  954. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  955. <span class="token punctuation">}</span>
  956. <span class="token comment">// 设置工作规则</span>
  957. <span class="token keyword keyword-export">export</span> <span class="token keyword keyword-const">const</span> <span class="token function-variable function">setWorkRule</span> <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token operator">:</span> <span class="token punctuation">{</span>
  958. technician_id<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span>
  959. work_days<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
  960. start_time<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
  961. end_time<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
  962. <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  963. <span class="token keyword keyword-return">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  964. url<span class="token operator">:</span> <span class="token string">'/technician/work-rule'</span><span class="token punctuation">,</span>
  965. method<span class="token operator">:</span> <span class="token string">'POST'</span><span class="token punctuation">,</span>
  966. data
  967. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  968. <span class="token punctuation">}</span>
  969. <span class="token comment">// 获取特殊日期设置</span>
  970. <span class="token keyword keyword-export">export</span> <span class="token keyword keyword-const">const</span> <span class="token function-variable function">getSpecialDate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>technicianId<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">,</span> date<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  971. <span class="token keyword keyword-return">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  972. url<span class="token operator">:</span> <span class="token string">'/technician/special-date'</span><span class="token punctuation">,</span>
  973. method<span class="token operator">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span>
  974. data<span class="token operator">:</span> <span class="token punctuation">{</span>
  975. technician_id<span class="token operator">:</span> technicianId<span class="token punctuation">,</span>
  976. date
  977. <span class="token punctuation">}</span>
  978. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  979. <span class="token punctuation">}</span>
  980. <span class="token comment">// 设置特殊日期</span>
  981. <span class="token keyword keyword-export">export</span> <span class="token keyword keyword-const">const</span> <span class="token function-variable function">setSpecialDate</span> <span class="token operator">=</span> <span class="token punctuation">(</span>data<span class="token operator">:</span> <span class="token punctuation">{</span>
  982. technician_id<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">;</span>
  983. date<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
  984. is_working<span class="token operator">:</span> <span class="token builtin">boolean</span><span class="token punctuation">;</span>
  985. start_time<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
  986. end_time<span class="token operator">?</span><span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">;</span>
  987. <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  988. <span class="token keyword keyword-return">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  989. url<span class="token operator">:</span> <span class="token string">'/technician/special-date'</span><span class="token punctuation">,</span>
  990. method<span class="token operator">:</span> <span class="token string">'POST'</span><span class="token punctuation">,</span>
  991. data
  992. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  993. <span class="token punctuation">}</span>
  994. <span class="token comment">// 获取可用时间槽</span>
  995. <span class="token keyword keyword-export">export</span> <span class="token keyword keyword-const">const</span> <span class="token function-variable function">getTimeSlots</span> <span class="token operator">=</span> <span class="token punctuation">(</span>technicianId<span class="token operator">:</span> <span class="token builtin">number</span><span class="token punctuation">,</span> date<span class="token operator">:</span> <span class="token builtin">string</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  996. <span class="token keyword keyword-return">return</span> <span class="token function">request</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
  997. url<span class="token operator">:</span> <span class="token string">'/technician/time-slots'</span><span class="token punctuation">,</span>
  998. method<span class="token operator">:</span> <span class="token string">'GET'</span><span class="token punctuation">,</span>
  999. data<span class="token operator">:</span> <span class="token punctuation">{</span>
  1000. technician_id<span class="token operator">:</span> technicianId<span class="token punctuation">,</span>
  1001. date
  1002. <span class="token punctuation">}</span>
  1003. <span class="token punctuation">}</span><span class="token punctuation">)</span>
  1004. <span class="token punctuation">}</span>
  1005. </code></pre><h3 id="6-页面配置">6. 页面配置 </h3>
  1006. <pre data-role="codeBlock" data-info="json" class="language-json json"><code><span class="token comment">// pages.json</span>
  1007. <span class="token punctuation">{</span>
  1008. <span class="token property">"pages"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
  1009. <span class="token punctuation">{</span>
  1010. <span class="token property">"path"</span><span class="token operator">:</span> <span class="token string">"pages/technician/schedule/index"</span><span class="token punctuation">,</span>
  1011. <span class="token property">"style"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  1012. <span class="token property">"navigationBarTitleText"</span><span class="token operator">:</span> <span class="token string">"排班设置"</span>
  1013. <span class="token punctuation">}</span>
  1014. <span class="token punctuation">}</span><span class="token punctuation">,</span>
  1015. <span class="token punctuation">{</span>
  1016. <span class="token property">"path"</span><span class="token operator">:</span> <span class="token string">"pages/technician/schedule/special-date"</span><span class="token punctuation">,</span>
  1017. <span class="token property">"style"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
  1018. <span class="token property">"navigationBarTitleText"</span><span class="token operator">:</span> <span class="token string">"特殊日期设置"</span>
  1019. <span class="token punctuation">}</span>
  1020. <span class="token punctuation">}</span>
  1021. <span class="token punctuation">]</span>
  1022. <span class="token punctuation">}</span>
  1023. </code></pre>
  1024. </div>
  1025. <div class="md-sidebar-toc">
  1026. <div class="md-toc">
  1027. <details style="padding:0;;padding-left:0px;" open="">
  1028. <summary class="md-toc-link-wrapper">
  1029. <a href="#技师排班解决方案" class="md-toc-link"><p>技师排班解决方案</p>
  1030. </a>
  1031. </summary>
  1032. <div>
  1033. <div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1034. <a href="#目录" class="md-toc-link">
  1035. <p>目录</p>
  1036. </a></div><details style="padding:0;;padding-left:24px;" open="">
  1037. <summary class="md-toc-link-wrapper">
  1038. <a href="#设计指标" class="md-toc-link"><p>设计指标</p>
  1039. </a>
  1040. </summary>
  1041. <div>
  1042. <div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1043. <a href="#功能特点" class="md-toc-link">
  1044. <p>功能特点</p>
  1045. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1046. <a href="#可扩展功能" class="md-toc-link">
  1047. <p>可扩展功能</p>
  1048. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1049. <a href="#技术特点" class="md-toc-link">
  1050. <p>技术特点</p>
  1051. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1052. <a href="#性能优化" class="md-toc-link">
  1053. <p>性能优化</p>
  1054. </a></div>
  1055. </div>
  1056. </details>
  1057. <details style="padding:0;;padding-left:24px;" open="">
  1058. <summary class="md-toc-link-wrapper">
  1059. <a href="#数据库设计" class="md-toc-link"><p>数据库设计</p>
  1060. </a>
  1061. </summary>
  1062. <div>
  1063. <div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1064. <a href="#1-数据表结构" class="md-toc-link">
  1065. <ol>
  1066. <li>数据表结构</li>
  1067. </ol>
  1068. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1069. <a href="#2-laravel-migration-文件" class="md-toc-link">
  1070. <ol start="2">
  1071. <li>Laravel Migration 文件</li>
  1072. </ol>
  1073. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1074. <a href="#3-model-定义" class="md-toc-link">
  1075. <ol start="3">
  1076. <li>Model 定义</li>
  1077. </ol>
  1078. </a></div>
  1079. </div>
  1080. </details>
  1081. <details style="padding:0;;padding-left:24px;" open="">
  1082. <summary class="md-toc-link-wrapper">
  1083. <a href="#后端实现" class="md-toc-link"><p>后端实现</p>
  1084. </a>
  1085. </summary>
  1086. <div>
  1087. <div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1088. <a href="#1-service-层实现" class="md-toc-link">
  1089. <ol>
  1090. <li>Service 层实现</li>
  1091. </ol>
  1092. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1093. <a href="#2-controller-层实现" class="md-toc-link">
  1094. <ol start="2">
  1095. <li>Controller 层实现</li>
  1096. </ol>
  1097. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1098. <a href="#3-路由定义" class="md-toc-link">
  1099. <ol start="3">
  1100. <li>路由定义</li>
  1101. </ol>
  1102. </a></div>
  1103. </div>
  1104. </details>
  1105. <details style="padding:0;;padding-left:24px;" open="">
  1106. <summary class="md-toc-link-wrapper">
  1107. <a href="#前端实现-uniapp-vue3" class="md-toc-link"><p>前端实现 (UniApp Vue3)</p>
  1108. </a>
  1109. </summary>
  1110. <div>
  1111. <div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1112. <a href="#1-工作规则设置页面" class="md-toc-link">
  1113. <ol>
  1114. <li>工作规则设置页面</li>
  1115. </ol>
  1116. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1117. <a href="#2-特殊日期设置页面" class="md-toc-link">
  1118. <ol start="2">
  1119. <li>特殊日期设置页面</li>
  1120. </ol>
  1121. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1122. <a href="#3-获取技师可用时间例子" class="md-toc-link">
  1123. <ol start="3">
  1124. <li>获取技师可用时间例子</li>
  1125. </ol>
  1126. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1127. <a href="#4-api-请求封装" class="md-toc-link">
  1128. <ol start="4">
  1129. <li>API 请求封装</li>
  1130. </ol>
  1131. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1132. <a href="#5-api-接口定义" class="md-toc-link">
  1133. <ol start="5">
  1134. <li>API 接口定义</li>
  1135. </ol>
  1136. </a></div><div class="md-toc-link-wrapper" style="padding:0;;display:list-item;list-style:square;margin-left:42px">
  1137. <a href="#6-页面配置" class="md-toc-link">
  1138. <ol start="6">
  1139. <li>页面配置</li>
  1140. </ol>
  1141. </a></div>
  1142. </div>
  1143. </details>
  1144. </div>
  1145. </details>
  1146. </div>
  1147. </div>
  1148. <a id="sidebar-toc-btn">≡</a>
  1149. <script>
  1150. document.body.setAttribute('html-show-sidebar-toc', true)
  1151. var sidebarTOCBtn = document.getElementById('sidebar-toc-btn')
  1152. sidebarTOCBtn.addEventListener('click', function(event) {
  1153. event.stopPropagation()
  1154. if (document.body.hasAttribute('html-show-sidebar-toc')) {
  1155. document.body.removeAttribute('html-show-sidebar-toc')
  1156. } else {
  1157. document.body.setAttribute('html-show-sidebar-toc', true)
  1158. }
  1159. })
  1160. </script>
  1161. </body></html>