签入版本

This commit is contained in:
2026-10-11 19:06:33 +08:00
parent 17d28de8b7
commit 4084c6bd17
674 changed files with 58855 additions and 1892 deletions
@@ -368,17 +368,24 @@ Content-Type: application/json
`ui/` 管理后台当前**未内置自动续签**:access_token 过期(code=401)时直接提示重新登录(摘自 `ui/src/utils/http/axios/index.ts` 实际代码):
```typescript
import { useDialog } from '@/hooks/web/useDialog';
const $dialog = useDialog();
// code === 401(ResultEnum.TIMEOUT)
case ResultEnum.TIMEOUT:
if (router.currentRoute.value?.name === PageEnum.BASE_LOGIN_NAME) return;
ElMessageBox.confirm('登录身份已失效,请重新登录!', '提示', {
type: 'warning',
})
.then(() => {
$dialog.warning({
title: '提示',
content: '登录身份已失效,请重新登录!',
positiveText: '确定',
closable: false,
maskClosable: false,
onPositiveClick: () => {
storage.clear(); // 清除本地登录态
window.location.href = PageEnum.BASE_LOGIN; // '/login'
})
.catch(() => {});
},
});
break;
```
@@ -288,10 +288,10 @@ class CaptchaService
```vue
<template>
<el-form-item>
<el-input v-model="form.code" placeholder="验证码" />
<n-form-item>
<n-input v-model:value="form.code" placeholder="验证码" />
<img :src="captchaImage" @click="refreshCaptcha" style="cursor: pointer;" />
</el-form-item>
</n-form-item>
</template>
<script setup>
@@ -257,7 +257,7 @@ data.forEach((group) => {
# -----------------------------------------------------------------------------
# 批量保存网站配置(key 为配置项编码)
# -----------------------------------------------------------------------------
curl -X POST http://localhost:8000/api/config/web/save \
curl -X POST http://admin.laravel13.naivevue/api/config/web/save \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <token>" \
-d '{
@@ -353,7 +353,7 @@ php artisan config:cache
## 环境配置建议
```ini
# 开发环境:允许所有来源(前端 localhost:8001,后端 localhost:8000)
# 开发环境:允许所有来源(前端 localhost:8001,后端 admin.laravel13.naivevue)
CORS_ALLOW_ORIGIN=*
# 测试环境:指定测试域名,提前验证跨域配置
@@ -64,7 +64,7 @@ php artisan route:list --path=user/add --json
# → "middleware": ["api", "auth.jwt", "tenant", "demo", "log.operation"]
# ③ 拦截生效(携带有效 token 发起写操作,期望 HTTP 403)
curl -X POST http://localhost:8000/api/user/add \
curl -X POST http://admin.laravel13.naivevue/api/user/add \
-H "Authorization: Bearer {access_token}" \
-H "Accept: application/json" \
-d '{"username":"demo"}'
@@ -266,12 +266,16 @@ class GeneratorController extends Controller
```typescript
// HTTP 响应拦截器
import { useMessage } from '@/hooks/web/useMessage';
const $message = useMessage();
axios.interceptors.response.use(response => {
const { code, msg } = response.data;
// 演示模式拦截
if (code === 403 && msg === '演示模式下禁止操作') {
ElMessage.warning('当前为演示环境,不允许执行此操作');
$message.warning('当前为演示环境,不允许执行此操作');
return Promise.reject(response.data);
}
@@ -284,13 +288,13 @@ axios.interceptors.response.use(response => {
```vue
<template>
<!-- 演示模式下禁用删除按钮 -->
<el-button
type="danger"
<n-button
type="error"
:disabled="isDemoMode"
@click="handleDelete"
>
删除
</el-button>
</n-button>
</template>
<script setup>
@@ -210,14 +210,13 @@ export function getDictItemByCode(code) {
```vue
<template>
<el-select v-model="formData.status" placeholder="请选择状态">
<el-option
v-for="item in statusOptions"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
<n-select
v-model:value="formData.status"
:options="statusOptions"
label-field="name"
value-field="value"
placeholder="请选择状态"
/>
</template>
<script setup>
@@ -246,9 +245,9 @@ const [genderOptions, statusOptions] = await Promise.all([
```vue
<template>
<el-tag :type="row.status === 1 ? 'success' : 'danger'">
<n-tag :type="row.status === 1 ? 'success' : 'error'" bordered>
{{ row.statusText }}
</el-tag>
</n-tag>
</template>
```
@@ -252,14 +252,13 @@ onMounted(async () => {
```vue
<template>
<el-select v-model="form.gender" placeholder="请选择性别">
<el-option
v-for="item in genderOptions"
:key="item.value"
:label="item.name"
:value="item.value"
/>
</el-select>
<n-select
v-model:value="form.gender"
:options="genderOptions"
label-field="name"
value-field="value"
placeholder="请选择性别"
/>
</template>
```
+13 -4
View File
@@ -278,15 +278,24 @@ if (token) {
:::
```typescript
import { useDialog } from '@/hooks/web/useDialog';
const $dialog = useDialog();
// code === 401(ResultEnum.TIMEOUT)
case ResultEnum.TIMEOUT:
if (router.currentRoute.value?.name === PageEnum.BASE_LOGIN_NAME) return;
ElMessageBox.confirm('登录身份已失效,请重新登录!', '提示', { type: 'warning' })
.then(() => {
$dialog.warning({
title: '提示',
content: '登录身份已失效,请重新登录!',
positiveText: '确定',
closable: false,
maskClosable: false,
onPositiveClick: () => {
storage.clear();
window.location.href = PageEnum.BASE_LOGIN; // '/login'
})
.catch(() => {});
},
});
break;
```
@@ -336,10 +336,10 @@ class UserController extends Controller
```vue
<template>
<!-- 单权限:拥有 sys:user:add 才显示 -->
<el-button v-perm="'sys:user:add'" type="primary">新增</el-button>
<n-button v-perm="'sys:user:add'" type="primary">新增</n-button>
<!-- 多权限:拥有任一权限即显示 -->
<el-button v-perms="['sys:user:add', 'sys:user:update']">操作</el-button>
<n-button v-perms="['sys:user:add', 'sys:user:update']">操作</n-button>
<!-- 无权限的按钮直接从 DOM 移除,而非仅隐藏 -->
</template>