81 lines
34 KiB
JavaScript
81 lines
34 KiB
JavaScript
import{_ as i,o as a,c as n,a2 as h}from"./chunks/framework.BbmSSMjL.js";const g=JSON.parse('{"title":"9.4 HTTP 请求封装","description":"","frontmatter":{},"headers":[],"relativePath":"zh/frontend/http.md","filePath":"zh/frontend/http.md"}'),t={name:"zh/frontend/http.md"};function k(l,s,p,e,F,d){return a(),n("div",null,[...s[0]||(s[0]=[h(`<h1 id="_9-4-HTTP-请求封装" tabindex="-1">9.4 HTTP 请求封装 <a class="header-anchor" href="#_9-4-HTTP-请求封装" aria-label="Permalink to "9.4 HTTP 请求封装""></a></h1><div class="tip custom-block"><p class="custom-block-title">概述</p><p>前端使用 Axios 封装 HTTP 请求,自动处理 Token 携带、响应码判断与错误提示(401 时提示重新登录)。</p></div><h2 id="封装结构" tabindex="-1">封装结构 <a class="header-anchor" href="#封装结构" aria-label="Permalink to "封装结构""></a></h2><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span>ui/src/utils/http/axios/</span></span>
|
||
<span class="line"><span>├── index.ts # Axios 实例配置和拦截器</span></span>
|
||
<span class="line"><span>├── Axios.ts # VAxios 类封装</span></span>
|
||
<span class="line"><span>├── axiosCancel.ts # 请求取消</span></span>
|
||
<span class="line"><span>├── axiosTransform.ts # 数据转换接口</span></span>
|
||
<span class="line"><span>├── checkStatus.ts # HTTP 状态码处理</span></span>
|
||
<span class="line"><span>├── helper.ts # 辅助函数</span></span>
|
||
<span class="line"><span>└── types.ts # 类型定义</span></span></code></pre></div><h2 id="核心拦截器" tabindex="-1">核心拦截器 <a class="header-anchor" href="#核心拦截器" aria-label="Permalink to "核心拦截器""></a></h2><h3 id="请求拦截器-自动携带-Token-" tabindex="-1">请求拦截器(自动携带 Token) <a class="header-anchor" href="#请求拦截器-自动携带-Token-" aria-label="Permalink to "请求拦截器(自动携带 Token)""></a></h3><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// ui/src/utils/http/axios/index.ts</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 请求前自动添加 Token(storage 键名 'ACCESS-TOKEN')</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> token</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> storage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">get</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">ACCESS-TOKEN</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> ''</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">config</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">headers</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">[</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">Authorization</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">]</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B5695977;"> \`</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">Bearer </span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">\${</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B56959;">token</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">}</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B5695977;">\`</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span></code></pre></div><h3 id="响应拦截器-统一错误处理-" tabindex="-1">响应拦截器(统一错误处理) <a class="header-anchor" href="#响应拦截器-统一错误处理-" aria-label="Permalink to "响应拦截器(统一错误处理)""></a></h3><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 响应处理逻辑(错误提示使用 NaiveUI 的离散式消息 API)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">import</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> useMessage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> from</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">@/hooks/web/useMessage</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> $message</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> useMessage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> code</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> data</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> msg</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> res</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">data</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">code</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 0</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> data</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 成功,返回 data(拦截器已解包)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">code</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 401</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ||</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> res</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">status</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 401</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // Token 过期 → 弹窗提示 → storage.clear() → 跳转登录(见下方 401 处理)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">code</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 403</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ||</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> res</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">status</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 403</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // 权限不足 / 租户异常 / 演示模式拦截</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> $message</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">error</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">msg</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ||</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">无访问权限</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 其他业务错误,显示提示</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">$message</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">error</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">msg</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ||</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">操作失败</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">);</span></span></code></pre></div><div class="tip custom-block"><p class="custom-block-title">响应处理规则</p><ul><li><code>code === 0</code>:成功,返回 <code>data</code></li><li><code>code/status === 401</code>:Token 过期,弹窗提示重新登录 → 清除本地存储 → 跳转登录页</li><li><code>code/status === 403</code>:权限不足,显示错误提示(<code>msg</code> 含权限码或拦截原因)</li><li>其它 <code>code</code>:业务失败,显示 <code>msg</code>(<code>1</code>=业务/FormRequest 错误、<code>404</code>=数据不存在、<code>422</code>=手动校验、<code>500</code>=服务器异常)</li><li>HTTP 状态码约定见 <a href="/zh/api-spec/response.html">8.1 统一响应格式</a></li></ul></div><h3 id="_401-处理-实际实现-摘自-ui-src-utils-http-axios-index-ts-" tabindex="-1">401 处理(实际实现,摘自 <code>ui/src/utils/http/axios/index.ts</code>) <a class="header-anchor" href="#_401-处理-实际实现-摘自-ui-src-utils-http-axios-index-ts-" aria-label="Permalink to "401 处理(实际实现,摘自 \`ui/src/utils/http/axios/index.ts\`)""></a></h3><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// code === 401(ResultEnum.TIMEOUT)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">case</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> ResultEnum</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">TIMEOUT</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#393A34;">:</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> if</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> (</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">router</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">currentRoute</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">value</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">?.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">name</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> ===</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> PageEnum</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">BASE_LOGIN_NAME</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> $dialog</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">warning</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">({</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> title</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">提示</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> content</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">登录身份已失效,请重新登录!</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> positiveText</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">确定</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> closable</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;"> false</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> maskClosable</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#1E754F;"> false</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> onPositiveClick</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> () </span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">=></span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> storage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">clear</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">();</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> window</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">location</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">href</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> PageEnum</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#B07D48;">BASE_LOGIN</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">; </span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// '/login'</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> },</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> });</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> break</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span></code></pre></div><div class="info custom-block"><p class="custom-block-title">自动续签能力在后端</p><p><code>ui/</code> 当前未内置自动续签(401 直接重新登录)。后端 <code>POST /api/refresh</code> 刷新能力完整保留,详见 <a href="/zh/core/auth-flow.html">5.2 认证流程实战</a> 与 <a href="/zh/api-spec/token.html">8.6 Token 使用说明</a>。</p></div><h2 id="API-模块编写" tabindex="-1">API 模块编写 <a class="header-anchor" href="#API-模块编写" aria-label="Permalink to "API 模块编写""></a></h2><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// ui/src/api/tool/example.ts</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">import</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> http</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> from</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">@/utils/http/axios</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">export</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> function</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> getExamplePage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#FFB86C;--shiki-dark-font-style:italic;--shiki-light:#B07D48;--shiki-light-font-style:inherit;">params</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">?</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> Record</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"><</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;">string</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">, </span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;">any</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">>)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> http</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">request</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">({</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> url</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/example/page</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> method</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">GET</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> params</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> });</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">export</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> function</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> exampleAdd</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#FFB86C;--shiki-dark-font-style:italic;--shiki-light:#B07D48;--shiki-light-font-style:inherit;">data</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> any</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> http</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">request</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">({</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> url</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/example/add</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> method</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">POST</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> data</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> });</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 注意:批量删除为 DELETE(请求体 { ids: [] })</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">export</span><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;"> function</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> exampleBatchDelete</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">(</span><span style="--shiki-dark:#FFB86C;--shiki-dark-font-style:italic;--shiki-light:#B07D48;--shiki-light-font-style:inherit;">data</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#97E1F1;--shiki-dark-font-style:italic;--shiki-light:#2E8F82;--shiki-light-font-style:inherit;"> any</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">)</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> return</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> http</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;">request</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">({</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> url</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">/example/batchDelete</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;"> method</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">DELETE</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> data</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> });</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">}</span></span></code></pre></div><p>(完整规范见 <a href="/zh/frontend/api-module.html">9.13 API 模块编写规范</a>。)</p><h2 id="在组件中使用" tabindex="-1">在组件中使用 <a class="header-anchor" href="#在组件中使用" aria-label="Permalink to "在组件中使用""></a></h2><div class="language-typescript vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">typescript</span><pre class="shiki shiki-themes dracula-soft vitesse-light vp-code" tabindex="0"><code><span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">import</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> {</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> getExamplePage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">,</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> exampleAdd</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> }</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> from</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">@/api/tool/example</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 获取列表(res 已是 data 部分)</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#AB5959;">const</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> res</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;"> await</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> getExamplePage</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">({ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;">pageNo</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">, </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;">pageSize</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 10</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> });</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">tableData</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">value</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> res</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">records</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;"> // { records, total, current, size }</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">total</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">value</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;"> =</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;"> res</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">.</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#B07D48;">total</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">;</span></span>
|
||
<span class="line"></span>
|
||
<span class="line"><span style="--shiki-dark:#7B7F8B;--shiki-light:#A0ADA0;">// 新增</span></span>
|
||
<span class="line"><span style="--shiki-dark:#F286C4;--shiki-light:#1E754F;">await</span><span style="--shiki-dark:#62E884;--shiki-light:#59873A;"> exampleAdd</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">({ </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;">name</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;"> '</span><span style="--shiki-dark:#E7EE98;--shiki-light:#B56959;">测试</span><span style="--shiki-dark:#DEE492;--shiki-light:#B5695977;">'</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;">, </span><span style="--shiki-dark:#F6F6F4;--shiki-light:#998418;">status</span><span style="--shiki-dark:#F286C4;--shiki-light:#999999;">:</span><span style="--shiki-dark:#BF9EEE;--shiki-light:#2F798A;"> 1</span><span style="--shiki-dark:#F6F6F4;--shiki-light:#999999;"> });</span></span></code></pre></div><h2 id="常见问题" tabindex="-1">常见问题 <a class="header-anchor" href="#常见问题" aria-label="Permalink to "常见问题""></a></h2><table tabindex="0"><thead><tr><th>现象</th><th>原因</th><th>处理</th></tr></thead><tbody><tr><td>所有请求 401</td><td>Token 未携带 / 已过期</td><td>检查拦截器与登录态;401 弹窗确认后清存储并跳登录页</td></tr><tr><td>请求 404</td><td>URL 与后端路由不一致</td><td>核对 <code>routes/api.php</code>(注意 <code>batchDelete</code> 为 DELETE)</td></tr><tr><td>请求跨域</td><td>直连后端且未配代理/CORS</td><td>用 Vite <code>VITE_PROXY</code> 代理或后端配 <code>CORS_ALLOW_ORIGIN</code></td></tr><tr><td>响应取不到 data</td><td>拦截器未解包</td><td>统一约定拦截器返回 <code>data</code>;排查是否绕过了 <code>http.request</code></td></tr></tbody></table>`,20)])])}const y=i(t,[["render",k]]);export{g as __pageData,y as default};
|