优化更新

This commit is contained in:
2026-09-14 09:44:33 +08:00
parent b3a9e21254
commit 5b8e178970
60 changed files with 1243 additions and 1022 deletions
@@ -88,6 +88,8 @@ return R.failed("参数错误")
```typescript
// src/utils/http/axios/index.ts
import { message, Modal } from 'ant-design-vue';
transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
const { code, data, msg } = res.data;
@@ -98,19 +100,21 @@ transformRequestData: (res: AxiosResponse<Result>, options: RequestOptions) => {
// 业务失败(code === 1):弹出错误提示
if (code === ResultEnum.ERROR) {
ElMessage.error(msg);
message.error(msg);
throw new Error(msg);
}
// 登录超时(code === 401):弹出确认框,跳转登录页
if (code === ResultEnum.TIMEOUT) {
ElMessageBox.confirm('登录身份已失效,请重新登录!', '提示', {
confirmButtonText: '确定',
showCancelButton: false,
type: 'warning',
}).then(() => {
storage.clear();
window.location.href = '/login';
Modal.confirm({
title: '提示',
content: '登录身份已失效,请重新登录!',
okText: '确定',
cancelText: '取消',
onOk: () => {
storage.clear();
window.location.href = '/login';
},
});
throw new Error(msg);
}
@@ -144,22 +148,24 @@ const result = await getPositionList(params);
| code | 说明 | 前端行为 |
|------|------|----------|
| 0 | 成功 | 返回 `data` |
| 1 | 业务失败 | `ElMessage.error(msg)` + `throw` |
| 1 | 业务失败 | `message.error(msg)` + `throw` |
| 401 | 未登录或 Token 过期 | 弹出确认框 → 跳转登录页 |
HTTP 状态码始终为 200,业务成功/失败通过 `code` 字段区分。
## 前端错误展示
业务错误通过 `ElMessage.error` 弹出提示,无需组件手动处理:
业务错误通过 `message.error` 弹出提示,无需组件手动处理:
```typescript
import { message } from 'ant-design-vue';
// 组件中直接调用,错误由拦截器处理
try {
await positionAdd(formData);
message('操作成功');
message.success('操作成功');
} catch (e) {
// 拦截器已弹出 ElMessage.error,此处可选处理
// 拦截器已弹出 message.error,此处可选处理
}
```
@@ -145,25 +145,25 @@ class ParamService(BaseService[Param]):
```typescript
// src/views/system/param/columns.ts
{
label: '参数类型',
prop: 'type',
title: '参数类型',
dataIndex: 'type',
width: 100,
// 方式一:直接使用后端返回的 typeText 字段
render(record) {
return h(ElTag,
{ type: record.row.type == 0 ? 'primary' : 'warning' },
{ default: () => record.row.typeText });
customRender: ({ record }) => {
return h(Tag,
{ color: record.type == 0 ? 'processing' : 'warning' },
() => record.typeText);
},
},
{
label: '状态',
prop: 'status',
title: '状态',
dataIndex: 'status',
width: 100,
// 方式二:直接使用后端返回的 statusText 字段
render(record) {
return h(ElTag,
{ type: record.row.status == 1 ? 'success' : 'danger' },
{ default: () => record.row.statusText });
customRender: ({ record }) => {
return h(Tag,
{ color: record.status == 1 ? 'success' : 'error' },
() => record.statusText);
},
},
```
@@ -205,7 +205,7 @@ export const schemas: FormSchema[] = [
label: '参数类型',
componentProps: {
placeholder: '请选择参数类型',
clearable: true,
allowClear: true,
options: [
{ label: '系统', value: 0 },
{ label: '业务', value: 1 },
@@ -218,7 +218,7 @@ export const schemas: FormSchema[] = [
label: '状态',
componentProps: {
placeholder: '请选择状态',
clearable: true,
allowClear: true,
options: [
{ label: '正常', value: 1 },
{ label: '禁用', value: 2 },
@@ -309,8 +309,8 @@ const options = [
// 业务字段为数字
formData.type = 0;
// el-option 绑定时需要转换
<el-option :value="Number(item.value)" />
// a-select-option 绑定时需要转换
<a-select-option :value="Number(item.value)" />
```
搜索表单中的 `options` 的 `value` 为字符串 `'0'`/`'1'`,后端 `page_eq_fields` 中的 `type` 字段期望数字。前端 API 传参时自动转换。
@@ -353,7 +353,7 @@ biz_ —— 业务类字典
```
1. 后台「字典管理」中新增字典类型和字典项
2. 后端 service 设置 serialize_maps(字段名 → 字典编码)
3. 前端 columns.ts 使用 render 函数渲染状态标签(直接用 xxxText 字段)
3. 前端 columns.ts 使用 customRender 函数渲染状态标签(直接用 xxxText 字段)
4. 前端 querySchemas.ts 中配置搜索选项(硬编码或 API 获取)
5. 表单提交时 value 为字符串,后端存储时注意类型处理
```
@@ -362,4 +362,4 @@ biz_ —— 业务类字典
## 总结
字典数据联调通过后端字典 API + `serialize_maps` 映射显示名 + 前端 `render` 函数渲染标签实现。`serialize_maps` 的 value 为数据字典编码,BaseService 自动查询字典并以 `xxxText` 格式输出。字典值统一为字符串,前端使用时注意类型转换。简单场景硬编码选项,动态场景通过 API 获取。
字典数据联调通过后端字典 API + `serialize_maps` 映射显示名 + 前端 `customRender` 函数渲染标签实现。`serialize_maps` 的 value 为数据字典编码,BaseService 自动查询字典并以 `xxxText` 格式输出。字典值统一为字符串,前端使用时注意类型转换。简单场景硬编码选项,动态场景通过 API 获取。
@@ -51,13 +51,17 @@ def add(request: Request, data: PositionForm):
```vue
<!-- src/views/system/position/index.vue -->
<el-button type="primary" @click="handleAdd" v-perm="['sys:position:add']">
添加岗位
</el-button>
<el-button type="danger" @click="handleDelete()" :disabled="!selectionData.length"
v-perm="['sys:position:batchDelete']">
删除
</el-button>
<a-space>
<a-button type="primary" @click="handleAdd" v-perm="['sys:position:add']">
<template #icon><PlusOutlined /></template>
添加岗位
</a-button>
<a-button type="primary" danger @click="handleDelete()" :disabled="!selectionData.length"
v-perm="['sys:position:batchDelete']">
<template #icon><DeleteOutlined /></template>
删除
</a-button>
</a-space>
```
### TableAction auth 属性