diff --git a/README.md b/README.md
index 6d61532..e5c7a84 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,112 @@
---
+## 快速导航(按角色)
+
+### 框架使用者(接入业务项目)
+
+- 目标:最快把框架跑起来并完成菜单页面映射。
+- 建议阅读顺序:`§1 依赖与环境` → `§2 引入方式` → `§3 核心 API` → `§7 组件映射与动态路由` → `§12 组件使用说明`。
+- 最小落地步骤:
+ 1. 安装 peer 依赖并引入 `admin-framework.js`。
+ 2. 调用 `AdminFramework.createApp({ title, apiUrl, componentMap })`。
+ 3. 在 `componentMap` 中注册业务页面路径并与后端菜单 `component` 字段对齐。
+
+### 业务开发者(写页面和接口联调)
+
+- 目标:在现有框架内开发业务页、调用接口、使用内置组件。
+- 建议阅读顺序:`§5 HTTP 模块` → `§6 uiTool/tools` → `§8 systemApi` → `§9 Vuex` → `§12 组件使用说明`。
+- 高频关注:
+ - 请求约定(`code === 0`、`401` 自动处理、参数预处理)。
+ - `this.$http` / `this.$uiTool` / `this.$tools` 的用法。
+ - 全局组件与按需组件边界(见 `§12.14` 索引)。
+
+### 二次封装维护者(改框架内核)
+
+- 目标:扩展框架能力(路由、Store、组件注册、系统 API 聚合等)。
+- 建议阅读顺序:`§3.2 createApp 执行流程` → `§4 框架实例` → `§7 动态路由` → `§8 systemApi` → `§9 createStore`。
+- 变更建议:
+ 1. 先改 `src/index.js` 的初始化路径(插件、原型、Store、Router)。
+ 2. 同步维护 `src/views/index.js` 的默认 `componentMap`。
+ 3. 变更 `src/api/system` 时同步更新 `src/api/system/index.js` 聚合导出与 README `§8`。
+
+### 常见任务直达
+
+| 任务 | 直达章节 |
+|------|----------|
+| 第一次接入并启动 | `§1` + `§2` + `§3` |
+| 菜单点击后页面不显示 | `§7`(重点看 `componentMap`) |
+| 请求报错或 token 失效 | `§5` + `§9.1 user` |
+| 顶部标题/Logo 不正确 | `§9.2 app`(`getSysTitle`) |
+| 想知道组件怎么用 | `§12`(先看 `§12.14` 索引) |
+
+### 5分钟上手清单
+
+> 目标:5 分钟内把框架跑起来并看到一个业务页面。
+
+#### 第 1 步:安装依赖(1 分钟)
+
+在业务项目安装 peer 依赖:
+
+```bash
+npm i vue vue-router vuex view-design axios
+```
+
+#### 第 2 步:准备框架包(1 分钟)
+
+- 已有 `dist/admin-framework.js`:直接拷贝到业务项目(例如 `src/vendor/`)。
+- 没有构建产物:在框架项目根目录执行:
+
+```bash
+npm run build
+```
+
+#### 第 3 步:准备页面映射(1 分钟)
+
+创建一个业务页面并准备 `componentMap`:
+
+```javascript
+// 例如 src/router/component-map.js
+import DemoPage from '@/views/demo/index.vue'
+
+export default {
+ 'demo/index': DemoPage,
+ 'demo/index.vue': DemoPage
+}
+```
+
+#### 第 4 步:入口创建应用(1 分钟)
+
+```javascript
+import Vue from 'vue'
+import AdminFramework from '@/vendor/admin-framework.js'
+import componentMap from '@/router/component-map'
+
+const app = AdminFramework.createApp({
+ title: '后台管理系统',
+ apiUrl: 'http://127.0.0.1:3000/admin_api/',
+ componentMap
+})
+
+app.$mount('#app')
+```
+
+#### 第 5 步:验证(1 分钟)
+
+- 能进入登录页(或已有 token 时进入主框架页)。
+- 左侧菜单点击后,页面能正常渲染(无“页面组件未加载”提示)。
+- 打开浏览器控制台,确认可访问:
+ - `window.framework`
+ - `window.rootVue`
+
+#### 常见 3 个坑(上手必看)
+
+1. 后端菜单里的 `component` 路径必须和 `componentMap` 键一致(推荐同时写带 `.vue` 和不带 `.vue` 两种)。
+2. `apiUrl` 建议以 `/admin_api/` 结尾,避免接口前缀不一致。
+3. 若登录后菜单空白,优先检查 `authorityMenus` 返回格式与 `user/setAuthorityMenus` 动态路由是否执行。
+
+---
+
## 1. 依赖与环境
### 1.1 Peer 依赖(由业务项目安装)
@@ -70,6 +176,19 @@ import AdminFramework from './vendor/admin-framework.js'
| `HomePage` | `Vue` 组件 | 可选,自定义首页;默认框架内置欢迎页 |
| `onReady` | `function` | 可选,根实例 `created` 末尾调用,`this` 为 Vue 根实例 |
+### 3.2 `createApp` 执行流程(源码行为)
+
+1. 自动补齐 `uploadUrl`(未传时按 `apiUrl` 拼接 `/upload`)。
+2. 注册 `ViewUI`、`VueRouter`、`Vuex`。
+3. 注入全局原型:`$config`、`$http`、`$tools`、`$uiTool`、`$framework`。
+4. 全局注册组件(`registerGlobalComponents`)。
+5. 建立 `componentMap`(内置系统页 + 业务传入映射)。
+6. 创建 Store 并初始化 HTTP。
+7. 创建 Router(基础路由 + 动态主路由),并挂守卫。
+8. 创建根 Vue;恢复菜单与系统标题;最后执行 `onReady`。
+
+> 注意:框架实例是单例,`store/router` 初始化后会复用;通常整个应用只调用一次 `createApp`。
+
**示例:**
```javascript
@@ -113,6 +232,13 @@ app.$mount('#app')
| `storeModules` | 默认 `user`、`app` 模块描述,扩展 Store 时可参考 |
| `createBaseRoutes` / `setupRouterGuards` / `registerComponents` | 高级自定义路由/组件时使用 |
+### 4.4 运行时全局对象
+
+浏览器环境下,框架会暴露:
+
+- `window.framework`:框架单例。
+- `window.rootVue`:`createApp` 创建的根实例(便于调试)。
+
### 4.2 `addComponentMap(customMap)`
在运行时追加组件映射(与 `createApp` 里的 `componentMap` 语义相同)。
@@ -151,6 +277,7 @@ AdminFramework.initHttp(
- 成功:后端 JSON 需 `code === 0`,否则走全局错误提示并 `reject`。
- `401`:清空 token,并跳转登录路由(依赖 `window.framework.router`)。
+- 请求参数会做预处理:递归移除对象中值为 `''` 的键,并自动格式化 `Date`。
### 5.3 方法说明
@@ -188,6 +315,12 @@ export default {
await this.$http.get('/xxx', { id: 1 }, { hideLoad: true })
```
+### 5.4 常见注意点
+
+- `post(url, body, config)` 当前实现固定会显示 loading(`showLoad`),`hideLoad` 只在 `get` 内部判断。
+- `postFormData` 使用 `application/x-www-form-urlencoded`。
+- `fileExport` 返回 `blob` 响应;`is_down=false` 时可自行处理文件流。
+
---
## 6. uiTool 模块
@@ -260,20 +393,47 @@ AdminFramework.createApp({
框架内置已注册一批系统页(如 `system/sys_menu` 等),见 `src/views/index.js` 中 `setupComponentMap`;业务模块在 `componentMap` 中追加即可。
+### 7.1 内置映射(默认可用)
+
+默认已注入以下路径(可直接在后端菜单配置里使用):
+
+- `home/index`
+- `system/sys_log`
+- `system/sys_log_operate`
+- `system/sys_param_setup`
+- `system/sys_role`
+- `system/sys_user`
+- `system/sys_tenant`
+- `system/sys_control`
+- `system/sys_menu`
+- `system/sys_title`
+
---
## 8. 系统 API(`systemApi`)
-`AdminFramework.systemApi` 聚合导出 `src/api/system` 下各 `*Server`,例如:
+`AdminFramework.systemApi` 聚合导出 `src/api/system/index.js` 中的服务(以下为当前版本完整导出):
| 导出名 | 模块文件 | 典型用途 |
|--------|----------|----------|
+| `fileServe` | `fileServe.js` | 文件上传下载 |
+| `plaAccountServer` | `pla_account_server.js` | 平台账号管理 |
+| `rolePermissionServer` | `rolePermissionServer.js` | 角色权限 |
+| `roleServer` | `roleServer.js` | 角色管理 |
+| `sysAddressServer` | `sysAddressServer.js` | 地址字典 |
+| `sysModuleServer` | `sysModuleServer.js` | 模块管理 |
+| `sysLogServe` | `sys_log_serve.js` | 系统日志 |
+| `systemTypeServer` | `systemType_server.js` | 系统类型配置 |
+| `tableServer` | `tableServer.js` | 表结构相关 |
| `userServer` | `userServer.js` | 登录、用户 CRUD、权限菜单 |
+| `formFieldServer` | `formFieldServer.js` | 表单字段 |
+| `formServer` | `formServer.js` | 表单模型 |
| `menuServer` | `menuServer.js` | 菜单管理 |
-| `roleServer` / `rolePermissionServer` | 角色与权限 |
-| `paramSetupServer` | 系统参数(如站点标题、Logo) |
-| `fileServe` | 文件上传下载 |
-| `modelServer` / `tableServer` / `formServer` 等 | 低代码/表单相关 |
+| `modelFieldServer` | `modelFieldServer.js` | 数据模型字段 |
+| `modelServer` | `modelServer.js` | 数据模型 |
+| `paramSetupServer` | `paramSetupServer.js` | 系统参数(标题、Logo) |
+| `sysControlTypeServer` | `sysControlTypeServer.js` | 控件类型 |
+| `sysTenantServer` | `sysTenantServer.js` | 租户管理 |
**调用示例:**
@@ -290,19 +450,36 @@ async function login() {
实际请求仍走全局配置的 `http`(`apiUrl`、token 头)。
+> 说明:`src/api/system` 中若存在未在 `index.js` 聚合导出的文件(例如实验性模块),不会出现在 `AdminFramework.systemApi`。
+
---
## 9. Vuex(`this.$store`)
默认模块:
+### 9.0 `createStore`(扩展自定义模块)
+
+框架导出 `createStore(Vuex, customModules, createPersistedState)`,可在默认 `user/app` 基础上合并业务模块:
+
+```javascript
+import Vuex from 'vuex'
+// 源码工程示例:按项目结构从 store 导入 createStore
+import { createStore } from '@/store'
+import foo from './store/foo'
+
+const store = createStore(Vuex, { foo }, null)
+```
+
+`createPersistedState` 传入后会启用本地持久化插件(`window.localStorage`)。
+
### 9.1 `user`(`namespaced: true`)
| 项 | 说明 |
|----|------|
-| `state` | `token`、`userName`、`authorityMenus`、`menuList` 等 |
-| `mutations` | `setToken`、`setUserName`、`setAuthorityMenus`、`setMenuList` |
-| `actions` | `setAuthorityMenus`:拉取或传入菜单 JSON,生成动态路由并写入 `localStorage` |
+| `state` | `token`、`userName`、`avatorImgPath`、`authorityMenus`、`menuList`、`currentTenant` |
+| `mutations` | `setToken`、`setUserName`、`setAuthorityMenus`、`setMenuList`、`setCurrentTenant` |
+| `actions` | `setAuthorityMenus`(生成动态路由)、`handleLogin`、`handleLogOut` |
**登录后刷新菜单示例:**
@@ -322,7 +499,8 @@ await this.$store.dispatch('user/setAuthorityMenus', {
| 项 | 说明 |
|----|------|
| `state` | `sysFormModel`(标题、Logo)、面包屑、首页路由 |
-| `actions` | `getSysTitle`:根据参数与接口更新站点标题与 Logo |
+| `mutations` | `setBreadCrumb`、`setHomeRoute`、`setSysTitle` |
+| `actions` | `getSysTitle`:根据登录状态和参数接口更新站点标题与 Logo |
```javascript
await this.$store.dispatch('app/getSysTitle', {
@@ -737,18 +915,178 @@ Main 中示例:`
+```
+
+#### 12.12.2 `date-picker/index.vue`(`DatePicker` 封装)
+
+- 用途:统一 `DatePicker` 的 `v-model` 语义。
+- Props:`value`
+- 事件:`input`、`change`
+- 说明:其余能力通过 `v-bind="$attrs"` 透传到 iView `DatePicker`。
+
+```vue
+
+```
+
+#### 12.12.3 `switch/index.vue`(`FrameworkSwitch`)
+
+- 用途:布尔/0/1 字段统一开关封装,避免 `` 名称冲突。
+- Props:`value`(支持 `true/false/1/0/'1'/'0'/'true'/'false'`)
+- 事件:`input`、`change`、`on-change`
+
+```vue
+
+```
+
+#### 12.12.4 `cron-input/index.vue`
+
+- 用途:可视化拼 Cron(`minute hour day month dayOfWeek`)字符串。
+- Props:`value`(Cron 字符串)
+- 事件:`input`
+- 说明:点击下拉后可选分钟/小时/日/月/周,点“确定”写回 Cron。
+
+```vue
+
+```
+
+#### 12.12.5 `main/pageHead.vue`
+
+- 用途:页面头部工具条;当 `this.$route.meta.type === '功能'` 时显示返回按钮。
+- 插槽:默认插槽(放新增/导出等按钮)
+- 内置方法:`goBack()`(`this.$router.go(-1)`)
+
+```vue
+
+
+
+```
+
+#### 12.12.6 `markdown/markdown.vue`(`MarkdownEditor`)
+
+- 用途:基于 `simplemde` 的 Markdown 编辑器。
+- Props:
+ - `value: String`
+ - `options: Object`(SimpleMDE 配置)
+ - `localCache: Boolean`(默认 `true`,写入 `localStorage.markdownContent`)
+- 事件:`input`、`on-change`、`on-focus`、`on-blur`
+
+```vue
+
+```
+
+#### 12.12.7 `cropper/index.vue`(`Cropper`)
+
+- 用途:图片裁剪(`cropperjs`),默认 1:1 比例。
+- Props:`src`、`preview`、`moveStep`、`cropButtonText`
+- 事件:`on-crop`(回传裁剪后的 `File`)
+- 说明:默认要求图片尺寸至少 `500x500`,否则提示错误。
+
+```vue
+
+```
+
+#### 12.12.8 `upload/Custom.vue`
+
+- 用途:通用文件上传(显示文件名与上传进度,上传至 OSS)。
+- Props:`value`、`accept`、`btnText`
+- 事件:`input`(上传成功后的 OSS 地址)
+- 方法:`clear()`
+
+```vue
+
+```
+
+#### 12.12.9 `md-icons/icons.vue`(`Icons`)
+
+- 用途:渲染项目内 iconfont 图标(`iconfont icon-${type}`)。
+- Props:`type`(必填)、`color`、`size`
+
+```vue
+
+```
+
+### 12.13 仅内部子组件(通常不单独直接使用)
+
+这些组件由父组件组合使用,业务页面一般不直接引用;如需复用,建议复制其父组件交互一起接入。
+
+| 组件路径 | 主要被谁使用 | 作用 |
+|----------|--------------|------|
+| `main/components/side-menu/side-menu-item.vue` | `SideMenu` | 递归渲染 `Submenu` 节点与子菜单。 |
+| `main/components/terminal/terminal.vue` | `main/components/terminal/index.vue` | 终端内容面板(当前为“终端功能暂未启用”占位)。 |
+| `split-pane/trigger.vue` | `split-pane/split.vue` | 分割条拖拽手柄视图。 |
+| `treeGrid/component/subThead.vue` | `treeGrid/index.vue` | 树表头部渲染。 |
+| `treeGrid/component/subColmns.vue` | `treeGrid/index.vue`/`subTreeGrid.vue` | `colgroup` 宽度控制。 |
+| `treeGrid/component/subTreeGrid.vue` | `treeGrid/index.vue` | 子树递归渲染、展开收起状态维护。 |
+| `treeGrid/component/renderCol.vue` | `treeGrid/index.vue`/`subTreeGrid.vue` | 安全执行列 `render(h, params)`。 |
+| `upload/mod/fileBtn.vue` | `upload/Custom.vue`/`upload/mod/fileListModal.vue` | 文件选择按钮。 |
+| `upload/mod/fileListModal.vue` | 上传业务页(按需) | 批量选文件 +(可选)批量上传 + 回调。 |
+
+### 12.14 `src/components` 全量组件索引(按路径)
+
+> 说明:下表覆盖 `src/components/**/*.vue`。`注册方式` 里“全局”表示由 `registerGlobalComponents` 自动注册;“按需”表示需手动引入;“内部”表示被父组件组合使用。
+
+| 组件路径 | 注册方式 | 入口章节 |
+|----------|----------|----------|
+| `asyncModal/index.vue` | 全局 | 12.6 |
+| `common-icon/common-icon.vue` | 全局 | 12.11 |
+| `cropper/index.vue` | 按需 | 12.12.7 |
+| `cron-input/index.vue` | 按需 | 12.12.4 |
+| `date-picker/index.vue` | 按需 | 12.12.2 |
+| `editor/index.vue` | 全局 | 12.5 |
+| `FloatPanel/index.vue` | 全局 | 12.10 |
+| `info-card/infor-card.vue` | 全局(`InfoCard`) | 12.8 |
+| `load-flower/index.vue` | 全局 | 12.11 |
+| `login-form/login-form.vue` | 按需 | 12.12.1 |
+| `main/main.vue` | 全局(`Main`) | 12.1 |
+| `main/pageHead.vue` | 按需 | 12.12.5 |
+| `main/components/a-back-top/index.vue` | 内部(可按需) | 12.1 / 12.11 |
+| `main/components/fullscreen/fullscreen.vue` | 内部(可按需) | 12.1 |
+| `main/components/header-bar/header-bar.vue` | 内部(可按需) | 12.1 |
+| `main/components/header-bar/custom-bread-crumb/custom-bread-crumb.vue` | 内部(可按需) | 12.1 |
+| `main/components/header-bar/sider-trigger/sider-trigger.vue` | 内部(可按需) | 12.1 |
+| `main/components/language/language.vue` | 内部(可按需) | 12.1 |
+| `main/components/side-menu/collapsed-menu.vue` | 内部 | 12.1 |
+| `main/components/side-menu/side-menu-item.vue` | 内部 | 12.13 |
+| `main/components/side-menu/side-menu.vue` | 内部(可按需) | 12.1 |
+| `main/components/terminal/index.vue` | 内部(可按需) | 12.1 |
+| `main/components/terminal/terminal.vue` | 内部 | 12.13 |
+| `main/components/user/user.vue` | 内部(可按需) | 12.1 |
+| `markdown/markdown.vue` | 按需 | 12.12.6 |
+| `md-icons/icons.vue` | 按需 | 12.12.9 |
+| `parent-view/parent-view.vue` | 全局(`ParentView`) | 12.1 |
+| `split-pane/split.vue` | 全局(`SplitPane`) | 12.9 |
+| `split-pane/trigger.vue` | 内部 | 12.13 |
+| `switch/index.vue` | 按需 | 12.12.3 |
+| `tables/editModal.vue` | 全局(`editModal`) | 12.6 |
+| `tables/fieldItem.vue` | 全局(`fieldItem`) | 12.7 |
+| `tables/fieldRenderer.vue` | 全局(`FieldRenderer`) | 12.7 |
+| `tables/index.vue` | 全局(`Tables`) | 12.2 |
+| `text-area/index.vue` | 全局(`TextArea`) | 12.11 |
+| `treeGrid/index.vue` | 全局(`TreeGrid`) | 12.3 |
+| `treeGrid/component/renderCol.vue` | 内部 | 12.13 |
+| `treeGrid/component/subColmns.vue` | 内部 | 12.13 |
+| `treeGrid/component/subThead.vue` | 内部 | 12.13 |
+| `treeGrid/component/subTreeGrid.vue` | 内部 | 12.13 |
+| `upload/Custom.vue` | 按需 | 12.12.8 |
+| `upload/Multiple.vue` | 全局(`UploadMultiple`) | 12.4 |
+| `upload/Single.vue` | 全局(`UploadSingle`) | 12.4 |
+| `upload/mod/fileBtn.vue` | 内部 | 12.13 |
+| `upload/mod/fileListModal.vue` | 内部(可按需) | 12.13 |
---
diff --git a/package-lock.json b/package-lock.json
index d568bc2..ee97be8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -28,7 +28,6 @@
"@babel/preset-env": "^7.12.0",
"autoprefixer": "^10.4.21",
"babel-loader": "^8.2.0",
- "cross-env": "^10.1.0",
"css-loader": "^5.0.0",
"file-loader": "^6.2.0",
"less": "^4.0.0",
@@ -1814,13 +1813,6 @@
"node": ">=10.0.0"
}
},
- "node_modules/@epic-web/invariant": {
- "version": "1.0.0",
- "resolved": "https://registry.npmmirror.com/@epic-web/invariant/-/invariant-1.0.0.tgz",
- "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -2849,24 +2841,6 @@
"@cropper/utils": "^2.0.1"
}
},
- "node_modules/cross-env": {
- "version": "10.1.0",
- "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-10.1.0.tgz",
- "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@epic-web/invariant": "^1.0.0",
- "cross-spawn": "^7.0.6"
- },
- "bin": {
- "cross-env": "dist/bin/cross-env.js",
- "cross-env-shell": "dist/bin/cross-env-shell.js"
- },
- "engines": {
- "node": ">=20"
- }
- },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
diff --git a/src/api/system/index.js b/src/api/system/index.js
index 69638dd..ea3bd94 100644
--- a/src/api/system/index.js
+++ b/src/api/system/index.js
@@ -18,6 +18,7 @@ export { default as modelFieldServer } from './modelFieldServer'
export { default as modelServer } from './modelServer'
export { default as paramSetupServer } from './paramSetupServer'
export { default as sysControlTypeServer } from './sysControlTypeServer'
+export { default as sysTenantServer } from './sysTenantServer'
diff --git a/src/api/system/sysTenantServer.js b/src/api/system/sysTenantServer.js
new file mode 100644
index 0000000..32d1ead
--- /dev/null
+++ b/src/api/system/sysTenantServer.js
@@ -0,0 +1,22 @@
+import http from '@/utils/http'
+
+class SysTenantServer {
+ async list() {
+ return http.get('/sys_tenant/index', {})
+ }
+
+ async add(row) {
+ return http.post('/sys_tenant/add', row)
+ }
+
+ async edit(row) {
+ return http.post('/sys_tenant/edit', row)
+ }
+
+ async del(row) {
+ return http.post('/sys_tenant/del', row)
+ }
+}
+
+const sysTenantServer = new SysTenantServer()
+export default sysTenantServer
diff --git a/src/assets/css/ivewExpand.less b/src/assets/css/ivewExpand.less
index 1f1a1f1..39b4a42 100644
--- a/src/assets/css/ivewExpand.less
+++ b/src/assets/css/ivewExpand.less
@@ -110,6 +110,9 @@
}
.table-warp {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
.ivu-card-body {
height: 100%;
display: flex;
@@ -186,20 +189,21 @@
text-overflow: ellipsis;
}
-/* 自适应表格宽度 */
+/* 与 View Design 一致:横向/纵向滚动由 .ivu-table-body 上的 overflow 类控制,避免 wrapper 与整表同高导致横向条在页面最底 */
.ivu-table-wrapper {
width: 100%;
height: 100%;
- overflow-x: auto;
- overflow-y: auto;
+ overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
+ min-height: 0;
}
.ivu-table {
width: 100% !important;
flex: 1;
+ min-height: 0;
}
/* 移除 table-layout: auto,使用 iView 默认的 fixed 布局以确保列对齐 */
@@ -208,8 +212,8 @@
} */
.ivu-table-body {
- overflow-y: auto;
flex: 1;
+ min-height: 0;
}
/* 按钮风格一致 */
diff --git a/src/components/main/components/header-bar/header-bar.less b/src/components/main/components/header-bar/header-bar.less
index 1594d65..281d1ab 100644
--- a/src/components/main/components/header-bar/header-bar.less
+++ b/src/components/main/components/header-bar/header-bar.less
@@ -5,14 +5,24 @@
height: 64px;
display: flex;
flex-direction: row;
+ align-items: center;
- .custom-content-con {
- height: 64px;
- padding-right: 120px;
- line-height: 64px;
- display: inline-block;
- vertical-align: top;
+ .header-breadcrumb {
+ margin-left: 30px;
flex: 1;
+ min-width: 0;
+ overflow: hidden;
+ line-height: 64px;
}
+ .header-right-slot {
+ flex-shrink: 0;
+ height: 64px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ flex-wrap: nowrap;
+ padding-right: 10px;
+ line-height: 64px;
+ }
}
diff --git a/src/components/main/components/header-bar/header-bar.vue b/src/components/main/components/header-bar/header-bar.vue
index 0774b8c..f7f59b3 100644
--- a/src/components/main/components/header-bar/header-bar.vue
+++ b/src/components/main/components/header-bar/header-bar.vue
@@ -1,8 +1,8 @@