1
This commit is contained in:
126
_doc/完整使用文档.md
126
_doc/完整使用文档.md
@@ -719,10 +719,136 @@ const params = await paramSetupServer.getOne('sys_title')
|
||||
<Editor v-model="content" />
|
||||
<UploadSingle v-model="fileUrl" />
|
||||
<TreeGrid :data="treeData" />
|
||||
<FloatPanel ref="floatPanel" title="详情面板" position="right" />
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### FloatPanel - 浮动面板组件
|
||||
|
||||
`FloatPanel` 是一个浮动在父窗体上的面板组件,类似于抽屉效果,调用方式和 `AsyncModal` 类似。
|
||||
|
||||
**基本使用:**
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<Button @click="showPanel">打开浮动面板</Button>
|
||||
|
||||
<FloatPanel
|
||||
ref="floatPanel"
|
||||
title="详情面板"
|
||||
position="right"
|
||||
:width="800"
|
||||
:show-back="true"
|
||||
back-text="返回"
|
||||
@back="handleBack"
|
||||
>
|
||||
<div>这里是面板内容</div>
|
||||
|
||||
<template slot="footer">
|
||||
<Button @click="hidePanel">取消</Button>
|
||||
<Button type="primary" @click="handleSave">保存</Button>
|
||||
</template>
|
||||
</FloatPanel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
showPanel() {
|
||||
this.$refs.floatPanel.show()
|
||||
},
|
||||
hidePanel() {
|
||||
this.$refs.floatPanel.hide()
|
||||
},
|
||||
handleBack() {
|
||||
console.log('返回按钮被点击')
|
||||
this.hidePanel()
|
||||
},
|
||||
handleSave() {
|
||||
console.log('保存')
|
||||
this.hidePanel()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
**调用方式(类似 AsyncModal):**
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<Button @click="openPanel">打开面板</Button>
|
||||
|
||||
<FloatPanel ref="floatPanel" title="详情" position="right">
|
||||
<div>内容</div>
|
||||
</FloatPanel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
openPanel() {
|
||||
// 通过 ref 调用 show 方法
|
||||
this.$refs.floatPanel.show()
|
||||
},
|
||||
closePanel() {
|
||||
// 通过 ref 调用 hide 方法
|
||||
this.$refs.floatPanel.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
**属性说明:**
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `title` | String | `''` | 面板标题 |
|
||||
| `width` | String/Number | `'80%'` | 面板宽度(字符串或数字) |
|
||||
| `height` | String/Number | `'80%'` | 面板高度(字符串或数字) |
|
||||
| `position` | String | `'right'` | 面板位置:`left`、`right`、`top`、`bottom`、`center` |
|
||||
| `showBack` | Boolean | `true` | 是否显示返回按钮 |
|
||||
| `showClose` | Boolean | `false` | 是否显示关闭按钮 |
|
||||
| `backText` | String | `'返回'` | 返回按钮文字 |
|
||||
| `closeOnClickBackdrop` | Boolean | `false` | 点击遮罩是否关闭 |
|
||||
| `mask` | Boolean | `true` | 是否显示遮罩 |
|
||||
| `zIndex` | Number | `1000` | 层级 |
|
||||
|
||||
**方法:**
|
||||
|
||||
| 方法 | 说明 | 参数 |
|
||||
|------|------|------|
|
||||
| `show(callback)` | 显示面板 | `callback`: 可选的回调函数 |
|
||||
| `hide()` | 隐藏面板 | - |
|
||||
|
||||
**事件:**
|
||||
|
||||
| 事件 | 说明 | 参数 |
|
||||
|------|------|------|
|
||||
| `back` | 点击返回按钮时触发 | - |
|
||||
|
||||
**插槽:**
|
||||
|
||||
| 插槽 | 说明 |
|
||||
|------|------|
|
||||
| `default` | 面板主体内容 |
|
||||
| `header-right` | 头部右侧内容 |
|
||||
| `footer` | 底部内容 |
|
||||
|
||||
**位置说明:**
|
||||
|
||||
- `left`: 从左侧滑入
|
||||
- `right`: 从右侧滑入(默认)
|
||||
- `top`: 从顶部滑入
|
||||
- `bottom`: 从底部滑入
|
||||
- `center`: 居中显示,带缩放动画
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 开发指南
|
||||
|
||||
203
demo/package-lock.json
generated
203
demo/package-lock.json
generated
@@ -21,6 +21,8 @@
|
||||
"css-loader": "^5.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"less": "^4.1.0",
|
||||
"less-loader": "^10.0.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"vue-loader": "^15.9.0",
|
||||
"vue-style-loader": "^4.1.0",
|
||||
@@ -2904,6 +2906,19 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/copy-anything": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
|
||||
"integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-what": "^3.14.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mesqueeb"
|
||||
}
|
||||
},
|
||||
"node_modules/core-js-compat": {
|
||||
"version": "3.45.1",
|
||||
"resolved": "https://registry.npmmirror.com/core-js-compat/-/core-js-compat-3.45.1.tgz",
|
||||
@@ -3331,6 +3346,20 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/errno": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
|
||||
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"prr": "~1.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"errno": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
@@ -4290,6 +4319,20 @@
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/image-size": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
|
||||
"integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"image-size": "bin/image-size.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/import-local": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/import-local/-/import-local-3.2.0.tgz",
|
||||
@@ -4466,6 +4509,13 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-what": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
|
||||
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-wsl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||
@@ -4581,6 +4631,16 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/klona": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",
|
||||
"integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/launch-editor": {
|
||||
"version": "2.11.1",
|
||||
"resolved": "https://registry.npmmirror.com/launch-editor/-/launch-editor-2.11.1.tgz",
|
||||
@@ -4592,6 +4652,80 @@
|
||||
"shell-quote": "^1.8.3"
|
||||
}
|
||||
},
|
||||
"node_modules/less": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmmirror.com/less/-/less-4.4.2.tgz",
|
||||
"integrity": "sha512-j1n1IuTX1VQjIy3tT7cyGbX7nvQOsFLoIqobZv4ttI5axP923gA44zUj6miiA6R5Aoms4sEGVIIcucXUbRI14g==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"copy-anything": "^2.0.1",
|
||||
"parse-node-version": "^1.0.1",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
"lessc": "bin/lessc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"errno": "^0.1.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"image-size": "~0.5.0",
|
||||
"make-dir": "^2.1.0",
|
||||
"mime": "^1.4.1",
|
||||
"needle": "^3.1.0",
|
||||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/less-loader": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-10.2.0.tgz",
|
||||
"integrity": "sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"klona": "^2.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"less": "^3.5.0 || ^4.0.0",
|
||||
"webpack": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/less/node_modules/make-dir": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
|
||||
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"pify": "^4.0.1",
|
||||
"semver": "^5.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/less/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/loader-runner": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/loader-runner/-/loader-runner-4.3.1.tgz",
|
||||
@@ -4886,6 +5020,38 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/needle": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
|
||||
"integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.3",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"bin": {
|
||||
"needle": "bin/needle"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/needle/node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz",
|
||||
@@ -5118,6 +5284,16 @@
|
||||
"tslib": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/parse-node-version": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
|
||||
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
|
||||
@@ -5202,6 +5378,17 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
|
||||
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-dir": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||
@@ -5396,6 +5583,14 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/prr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
|
||||
"integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/pseudomap": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/pseudomap/-/pseudomap-1.0.2.tgz",
|
||||
@@ -5704,6 +5899,14 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.3.tgz",
|
||||
"integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/schema-utils": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
"css-loader": "^5.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"less": "^4.1.0",
|
||||
"less-loader": "^10.0.0",
|
||||
"style-loader": "^2.0.0",
|
||||
"vue-loader": "^15.9.0",
|
||||
"vue-style-loader": "^4.1.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// 开发环境直接引用源码以支持热更新
|
||||
import AdminFramework from '../../src/index.js'
|
||||
import AdminFramework from '../../dist/admin-framework.js'
|
||||
|
||||
// 引入组件映射表
|
||||
import componentMap from './router/component-map.js'
|
||||
|
||||
@@ -21,6 +21,51 @@
|
||||
@changePage="query"></tables>
|
||||
</div>
|
||||
<editModal ref="editModal" :columns="editColumns" :rules="gridOption.rules"> </editModal>
|
||||
|
||||
<FloatPanel ref="floatPanel" title="城市详情" position="right">
|
||||
<div v-if="currentRow" class="detail-content">
|
||||
<div class="detail-item">
|
||||
<label>ID:</label>
|
||||
<span>{{ currentRow.id }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>城市名称(中文):</label>
|
||||
<span>{{ currentRow.cn_city }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>城市代码:</label>
|
||||
<span>{{ currentRow.city_code }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>省份(中文):</label>
|
||||
<span>{{ currentRow.cn_state || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>国家(中文):</label>
|
||||
<span>{{ currentRow.cn_country || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>城市名称(英文):</label>
|
||||
<span>{{ currentRow.city || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>省份(英文):</label>
|
||||
<span>{{ currentRow.state || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>国家(英文):</label>
|
||||
<span>{{ currentRow.country || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>省份代码:</label>
|
||||
<span>{{ currentRow.state_code || '-' }}</span>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>国家代码:</label>
|
||||
<span>{{ currentRow.country_code || '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</FloatPanel>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
@@ -36,6 +81,7 @@ export default {
|
||||
rules["cn_country"] = [{ required: false, message: '请填写国家' }];
|
||||
|
||||
return {
|
||||
currentRow: null,
|
||||
seachTypes: [
|
||||
{ key: 'cn_city', value: '城市名称' },
|
||||
{ key: 'city_code', value: '城市代码' },
|
||||
@@ -69,10 +115,17 @@ export default {
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
width: 200,
|
||||
width: 250,
|
||||
type: 'template',
|
||||
render: (h, params) => {
|
||||
let btns = [
|
||||
{
|
||||
title: '详情',
|
||||
type: 'info',
|
||||
click: () => {
|
||||
this.showDetail(params.row)
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '编辑',
|
||||
type: 'primary',
|
||||
@@ -138,7 +191,43 @@ export default {
|
||||
wch_citiesServer.exportCsv(this.gridOption.param).then(res => {
|
||||
tools.downloadFile(res, '城市管理.csv');
|
||||
});
|
||||
},
|
||||
showDetail(row) {
|
||||
this.currentRow = row
|
||||
this.$refs.floatPanel.show()
|
||||
},
|
||||
hideDetail() {
|
||||
this.$refs.floatPanel.hide()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.detail-content {
|
||||
padding: 10px 0;
|
||||
|
||||
.detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
label {
|
||||
min-width: 120px;
|
||||
font-weight: 500;
|
||||
color: #515a6e;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
color: #17233d;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,8 @@ module.exports = {
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'app.js',
|
||||
clean: true
|
||||
clean: true,
|
||||
publicPath: '/'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@@ -24,6 +25,10 @@ module.exports = {
|
||||
test: /\.css$/,
|
||||
use: ['vue-style-loader', 'css-loader']
|
||||
},
|
||||
{
|
||||
test: /\.less$/,
|
||||
use: ['vue-style-loader', 'css-loader', 'less-loader']
|
||||
},
|
||||
{
|
||||
test: /\.(png|jpe?g|gif|svg|woff2?|eot|ttf|otf)$/,
|
||||
type: 'asset/resource'
|
||||
@@ -45,7 +50,7 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
devServer: {
|
||||
hot: true,
|
||||
hot: true, // 启用热更新
|
||||
open: true,
|
||||
port: 8080,
|
||||
historyApiFallback: true
|
||||
|
||||
277
src/components/FloatPanel/index.vue
Normal file
277
src/components/FloatPanel/index.vue
Normal file
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<transition name="float-panel">
|
||||
<div v-if="showPanel" class="float-panel-wrapper" @click.self="handleBackdropClick">
|
||||
<div class="float-panel" :class="panelClass" :style="panelStyle">
|
||||
<div class="float-panel-header">
|
||||
<div class="header-left">
|
||||
<Button v-if="showBack" type="text" icon="ios-arrow-back" @click="handleBack">
|
||||
{{ backText }}
|
||||
</Button>
|
||||
<span v-if="title" class="panel-title">{{ title }}</span>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<slot name="header-right"></slot>
|
||||
<Button v-if="showClose" type="text" icon="ios-close" @click="hide"></Button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="float-panel-body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FloatPanel',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
width: {
|
||||
type: [String, Number],
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: '100%'
|
||||
},
|
||||
position: {
|
||||
type: String,
|
||||
default: 'right', // left, right, top, bottom, center
|
||||
validator: (value) => ['left', 'right', 'top', 'bottom', 'center'].includes(value)
|
||||
},
|
||||
showBack: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
backText: {
|
||||
type: String,
|
||||
default: '返回'
|
||||
},
|
||||
closeOnClickBackdrop: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
mask: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
default: 1000
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showPanel: false,
|
||||
callback: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
panelClass() {
|
||||
return {
|
||||
[`float-panel-${this.position}`]: true
|
||||
}
|
||||
},
|
||||
panelStyle() {
|
||||
const style = {
|
||||
zIndex: this.zIndex,
|
||||
width: typeof this.width === 'number' ? `${this.width}px` : this.width,
|
||||
height: typeof this.height === 'number' ? `${this.height}px` : this.height
|
||||
}
|
||||
return style
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show(callback) {
|
||||
this.showPanel = true
|
||||
this.callback = callback
|
||||
},
|
||||
hide() {
|
||||
this.showPanel = false
|
||||
this.callback = null
|
||||
},
|
||||
handleBack() {
|
||||
this.$emit('back')
|
||||
this.hide()
|
||||
},
|
||||
handleBackdropClick() {
|
||||
if (this.closeOnClickBackdrop) {
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
showPanel(newVal) {
|
||||
if (newVal) {
|
||||
document.body.style.overflow = 'hidden'
|
||||
} else {
|
||||
document.body.style.overflow = ''
|
||||
}
|
||||
},
|
||||
// 监听路由变化
|
||||
'$route'(to, from) {
|
||||
if (this.showPanel) {
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 组件销毁时关闭面板并清理
|
||||
if (this.showPanel) {
|
||||
this.hide()
|
||||
}
|
||||
document.body.style.overflow = ''
|
||||
},
|
||||
destroyed() {
|
||||
// 确保清理
|
||||
document.body.style.overflow = ''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.float-panel-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.float-panel {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
|
||||
&.float-panel-right {
|
||||
animation: slideInRight 0.3s ease-out;
|
||||
}
|
||||
|
||||
&.float-panel-left {
|
||||
animation: slideInLeft 0.3s ease-out;
|
||||
}
|
||||
|
||||
&.float-panel-top {
|
||||
animation: slideInTop 0.3s ease-out;
|
||||
}
|
||||
|
||||
&.float-panel-bottom {
|
||||
animation: slideInBottom 0.3s ease-out;
|
||||
}
|
||||
|
||||
&.float-panel-center {
|
||||
animation: fadeInScale 0.3s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.float-panel-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 16px 20px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
|
||||
.panel-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #17233d;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.header-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.float-panel-body {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
|
||||
// 动画效果
|
||||
.float-panel-enter-active,
|
||||
.float-panel-leave-active {
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.float-panel-enter,
|
||||
.float-panel-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@keyframes slideInRight {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInLeft {
|
||||
from {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInTop {
|
||||
from {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideInBottom {
|
||||
from {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeInScale {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,6 +19,7 @@ import Editor from './editor/index.vue'
|
||||
import editModal from './tables/editModal.vue'
|
||||
import fieldItem from './tables/fieldItem.vue'
|
||||
import FieldRenderer from './tables/fieldRenderer.vue'
|
||||
import FloatPanel from './FloatPanel/index.vue'
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +49,7 @@ const registerGlobalComponents = (Vue) => {
|
||||
Vue.component('editModal', editModal)
|
||||
Vue.component('fieldItem', fieldItem)
|
||||
Vue.component('FieldRenderer', FieldRenderer)
|
||||
Vue.component('FloatPanel', FloatPanel)
|
||||
}
|
||||
|
||||
// 注册自定义组件的方法
|
||||
@@ -80,7 +82,7 @@ export default {
|
||||
editModal,
|
||||
fieldItem,
|
||||
FieldRenderer,
|
||||
|
||||
FloatPanel
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export default {
|
||||
|
||||
.table-scroll-container {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
overflow: auto;
|
||||
overflow-y: visible;
|
||||
/* 横向滚动条始终可见,不需要滚动到底 */
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export default class uiTool {
|
||||
*/
|
||||
static downloadFile(res, fileName) {
|
||||
// 开头和结尾去掉 中间不去掉
|
||||
let tempFileName = fileName || `${new Date().getTime()}.csv`
|
||||
let tempFileName = fileName || `${new Date().getTime()}.csv`
|
||||
|
||||
const blob = new Blob([res.data || res])
|
||||
const downloadElement = document.createElement('a')
|
||||
@@ -130,20 +130,20 @@ export default class uiTool {
|
||||
}
|
||||
|
||||
static delConfirm(callback) {
|
||||
const Modal = (window.framework && window.framework.ViewUI && window.framework.ViewUI.Modal) || window.$Modal
|
||||
if (Modal) {
|
||||
Modal.confirm({
|
||||
title: '温馨提示',
|
||||
content: '<p>你确定删除吗?</p>',
|
||||
onOk: () => {
|
||||
callback && callback()
|
||||
}
|
||||
})
|
||||
}
|
||||
const Modal = window.rootVue.$Modal
|
||||
|
||||
Modal.confirm({
|
||||
title: '温馨提示',
|
||||
content: '<p>你确定删除吗?</p>',
|
||||
onOk: () => {
|
||||
callback && callback()
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
static showConfirm({ title = '温馨提示', content = '内容' }, callback) {
|
||||
const Modal = (window.framework && window.framework.ViewUI && window.framework.ViewUI.Modal) || window.$Modal
|
||||
const Modal = window.rootVue.$Modal
|
||||
if (Modal) {
|
||||
Modal.confirm({
|
||||
title,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="content-view ">
|
||||
<div class="tree-box">
|
||||
<div class="btn-top-box pa10">
|
||||
<Button type="warning" size="small" @click="delAll">全部删除</Button>
|
||||
<Button type="warning" size="small" @click="delAll">全部删除2</Button>
|
||||
</div>
|
||||
<Tree class="mt10" :data="treeData" :render="renderContent" @on-select-change="selectChange"></Tree>
|
||||
</div>
|
||||
@@ -83,25 +83,33 @@ export default {
|
||||
}
|
||||
}),
|
||||
h('span', data.title),
|
||||
h('Icon', {
|
||||
props: {
|
||||
type: 'ios-trash',
|
||||
size: '18'
|
||||
},
|
||||
h('span', {
|
||||
on: {
|
||||
click: () => {
|
||||
click: (e) => {
|
||||
e.stopPropagation() // 阻止事件冒泡
|
||||
e.preventDefault() // 阻止默认行为
|
||||
this.deleteLog(data)
|
||||
}
|
||||
},
|
||||
style: {
|
||||
'margin-left': '8px'
|
||||
'margin-left': '8px',
|
||||
cursor: 'pointer',
|
||||
display: 'inline-block'
|
||||
}
|
||||
})
|
||||
}, [
|
||||
h('Icon', {
|
||||
props: {
|
||||
type: 'ios-trash',
|
||||
size: '18'
|
||||
}
|
||||
})
|
||||
])
|
||||
])
|
||||
]
|
||||
)
|
||||
},
|
||||
async selectChange(row) {
|
||||
|
||||
row[0].selected = true
|
||||
this.selectRow = row[0].title
|
||||
let res = await sys_log_serve.detail({ title: this.selectRow })
|
||||
@@ -135,7 +143,7 @@ export default {
|
||||
.content-view {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
.tree-box {
|
||||
.log-box {
|
||||
height: 90vh;
|
||||
width: 300px;
|
||||
border-right: solid 1px #ccc;
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
<Button type="primary" @click="addWarp()">新增</Button>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<card class="tree-box">
|
||||
<TreeGrid :columns="gridOption.columns" :data="gridOption.data"></TreeGrid>
|
||||
</card>
|
||||
</div>
|
||||
<editModal ref="editModal" :columns="gridOption.editColumns" :rules="gridOption.rules">
|
||||
<div slot="bottom">
|
||||
@@ -394,9 +392,5 @@ export default {
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tree-box {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
max-height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user