优化更新

This commit is contained in:
2026-09-13 17:33:13 +08:00
parent 8be23a62a3
commit 7f758cc6e9
97 changed files with 2333 additions and 3595 deletions
@@ -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>
```
### 路由守卫