优化更新
This commit is contained in:
@@ -146,7 +146,7 @@ class ConfigWeb(BaseModel):
|
||||
| 用途 | 枚举值(下拉选项) | 系统参数(配置值) |
|
||||
| 值类型 | 简单值(字符串) | 可存储较长的配置内容 |
|
||||
| 典型场景 | 状态、性别、类型 | SMTP配置、站点信息 |
|
||||
| 前端用法 | el-select 选项 | 配置表单 |
|
||||
| 前端用法 | a-select 选项 | 配置表单 |
|
||||
| 缓存策略 | Redis 缓存 | 按需查询 |
|
||||
| 数据量 | 通常每个字典 < 50 项 | 每个分组 < 20 项 |
|
||||
|
||||
@@ -158,18 +158,18 @@ class ConfigWeb(BaseModel):
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<el-form-item :label="item.name">
|
||||
<a-form-item :label="item.name">
|
||||
<!-- 文本输入 -->
|
||||
<el-input v-if="item.type === 'text'" v-model="item.value" />
|
||||
<a-input v-if="item.type === 'text'" v-model:value="item.value" />
|
||||
<!-- 数字输入 -->
|
||||
<el-input-number v-else-if="item.type === 'number'" v-model="item.value" />
|
||||
<a-input-number v-else-if="item.type === 'number'" v-model:value="item.value" />
|
||||
<!-- 下拉选择 -->
|
||||
<el-select v-else-if="item.type === 'select'" v-model="item.value">
|
||||
<el-option v-for="opt in parseOptions(item.options)" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||||
</el-select>
|
||||
<a-select v-else-if="item.type === 'select'" v-model:value="item.value">
|
||||
<a-select-option v-for="opt in parseOptions(item.options)" :key="opt.value" :value="opt.value">{{ opt.label }}</a-select-option>
|
||||
</a-select>
|
||||
<!-- 开关 -->
|
||||
<el-switch v-else-if="item.type === 'switch'" v-model="item.value" />
|
||||
</el-form-item>
|
||||
<a-switch v-else-if="item.type === 'switch'" v-model:checked="item.value" />
|
||||
</a-form-item>
|
||||
</template>
|
||||
```
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ if DJANGO_DEMO:
|
||||
前端可通过响应中的 `msg` 字段识别演示模式拦截,并展示相应提示:
|
||||
|
||||
```typescript
|
||||
// 前端拦截器已统一处理 code=1 的响应,自动弹出 ElMessage.error(msg)
|
||||
// 前端拦截器已统一处理 code=1 的响应,自动弹出 message.error(msg)
|
||||
// 无需额外处理,演示模式的提示会自动显示
|
||||
```
|
||||
|
||||
|
||||
@@ -87,14 +87,15 @@ def _enrich_records(records):
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<el-select v-model="form.trainingMethod" placeholder="请选择培训方式">
|
||||
<el-option
|
||||
<a-select v-model:value="form.trainingMethod" placeholder="请选择培训方式">
|
||||
<a-select-option
|
||||
v-for="item in dictOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
>
|
||||
{{ item.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -116,7 +117,7 @@ onMounted(async () => {
|
||||
|
||||
```typescript
|
||||
import { h } from 'vue';
|
||||
import { ElTag } from 'element-plus';
|
||||
import { Tag } from 'ant-design-vue';
|
||||
|
||||
export const columns = [
|
||||
{
|
||||
@@ -125,8 +126,8 @@ export const columns = [
|
||||
render(record) {
|
||||
const map = { 1: '线上', 2: '线下', 3: '混合' };
|
||||
const typeMap = { 1: 'success', 2: 'warning', 3: 'info' };
|
||||
return h(ElTag, { type: typeMap[record.row.trainingMethod] }, {
|
||||
default: () => map[record.row.trainingMethod] || '-'
|
||||
return h(Tag, { color: typeMap[record.trainingMethod] }, {
|
||||
default: () => map[record.trainingMethod] || '-'
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
@@ -105,19 +105,20 @@ const statusOptions = dictStore.getDict('sys_status')
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- el-select 下拉选择 -->
|
||||
<el-select v-model="form.status" placeholder="请选择状态">
|
||||
<el-option
|
||||
<!-- a-select 下拉选择 -->
|
||||
<a-select v-model:value="form.status" placeholder="请选择状态">
|
||||
<a-select-option
|
||||
v-for="item in statusOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
>
|
||||
{{ item.label }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
|
||||
<!-- el-tag 标签展示 -->
|
||||
<el-tag v-if="form.status === '1'">正常</el-tag>
|
||||
<el-tag v-else type="danger">停用</el-tag>
|
||||
<!-- Tag 标签展示 -->
|
||||
<Tag v-if="form.status === '1'" color="success">正常</Tag>
|
||||
<Tag v-else color="error">停用</Tag>
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -174,7 +175,7 @@ export const useDictStore = defineStore('dict', {
|
||||
|
||||
```
|
||||
1. 两级结构:字典类型(分组)+ 字典项(具体值),清晰管理
|
||||
2. 前端集成:useDictStore 统一管理,el-select 直接绑定
|
||||
2. 前端集成:useDictStore 统一管理,a-select 直接绑定
|
||||
3. 值为字符串:字典项 value 统一为字符串类型
|
||||
4. 避免硬编码:枚举值统一走字典,修改无需改代码
|
||||
5. Redis 缓存:减少数据库查询,提升性能
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useLockFn } from '@/utils/lock'
|
||||
// 包装提交函数,防止重复点击
|
||||
const handleSubmit = useLockFn(async () => {
|
||||
await axios.post('/level/add', formData)
|
||||
ElMessage.success('添加成功')
|
||||
message.success('添加成功')
|
||||
})
|
||||
```
|
||||
|
||||
@@ -37,25 +37,26 @@ function useLockFn(fn) {
|
||||
|
||||
### 按钮 loading
|
||||
|
||||
ElementPlus 的按钮组件支持 `loading` 属性,请求期间禁用按钮:
|
||||
Ant Design Vue 的按钮组件支持 `loading` 属性,请求期间禁用按钮:
|
||||
|
||||
```vue
|
||||
<el-button
|
||||
<a-button
|
||||
type="primary"
|
||||
:loading="submitting"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
</el-button>
|
||||
</a-button>
|
||||
|
||||
<script setup>
|
||||
import { message } from 'ant-design-vue';
|
||||
const submitting = ref(false)
|
||||
|
||||
async function handleSubmit() {
|
||||
submitting.value = true
|
||||
try {
|
||||
await axios.post('/level/add', formData)
|
||||
ElMessage.success('添加成功')
|
||||
message.success('添加成功')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ def check_captcha_rate_limit(ip):
|
||||
// 响应拦截器
|
||||
responseInterceptorsCatch: (error: any) => {
|
||||
if (error.response?.status === 429) {
|
||||
ElMessage.warning('请求过于频繁,请稍后再试');
|
||||
message.warning('请求过于频繁,请稍后再试');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// ... 其他错误处理
|
||||
|
||||
@@ -119,10 +119,10 @@ def get_user_permissions(user_id):
|
||||
|
||||
```html
|
||||
<!-- 只有拥有 sys:user:add 权限的用户才能看到此按钮 -->
|
||||
<el-button v-perm="'sys:user:add'" type="primary">新增</el-button>
|
||||
<a-button v-perm="'sys:user:add'" type="primary">新增</a-button>
|
||||
|
||||
<!-- 多个权限,满足其一即可 -->
|
||||
<el-button v-perm="['sys:user:update', 'sys:user:delete']">操作</el-button>
|
||||
<a-button v-perm="['sys:user:update', 'sys:user:delete']">操作</a-button>
|
||||
```
|
||||
|
||||
### 路由守卫
|
||||
|
||||
Reference in New Issue
Block a user