refactor(更新前端): 🔀 更新前端项目版本
This commit is contained in:
435
web/CHANGELOG.md
435
web/CHANGELOG.md
@@ -1,435 +0,0 @@
|
|||||||
# <a href="https://gitee.com/lyt-top/vue-next-admin" target="_blank">vue-next-admin 更新日志</a>
|
|
||||||
|
|
||||||
🎉🎉🔥 `vue-next-admin` 基于 vue3.x 、Typescript、vite、Element plus 等,适配手机、平板、pc 的后台开源免费模板库(vue2.x 请切换 vue-prev-admin 分支)
|
|
||||||
|
|
||||||
## 2.4.21
|
|
||||||
|
|
||||||
`2022.12.12`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 菜单背景高亮颜色可自定义,通过 `布局配置 -> 菜单设置 -> 菜单高亮背景色` 进行设置
|
|
||||||
- 🐞 修复 `分栏布局` 二级导航菜单内容多时,无法滚动问题,感谢群友@静雨轩主人
|
|
||||||
- 🐞 修复 [!42 修复 工作流无法添加新节点问题](https://gitee.com/lyt-top/vue-next-admin/pulls/42),感谢[@beta](https://gitee.com/beta_dz)
|
|
||||||
- 🎯 优化 `/make/tableDemo` 表头很多时,无法滚动问题,感谢群友@糊涂涂涂
|
|
||||||
|
|
||||||
## 2.4.2
|
|
||||||
|
|
||||||
`2022.12.09`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 国际化自动导入文件功能,只需在 `/src/i18n/pages` 下新建文件夹定义即可
|
|
||||||
- 🎉 新增 `/make/tableDemo` 中 [搜索框展开,收缩功能,高级筛选组件 有计划做吗](https://gitee.com/lyt-top/vue-next-admin/issues/I6511L)
|
|
||||||
- 🐞 修复 [!40 开启 TagsView 缓存后,刷新后所有的路由都变成组件缓存了](https://gitee.com/lyt-top/vue-next-admin/pulls/40),感谢[@mrjimin](https://gitee.com/mrjimin)
|
|
||||||
- 🐞 修复 [!41 修复 get 请求传递嵌套对象或数组时无法正常编码问题](https://gitee.com/lyt-top/vue-next-admin/pulls/41),感谢[@随心](https://gitee.com/jiangqiang1996)
|
|
||||||
- 🐞 修复 组件 wangEditor 回显值的问题
|
|
||||||
- 🐞 修复 `/fun/echartsMap`(地理坐标/地图)、`visualizingDemo2`(数据可视化演示 2) 演示报错问题
|
|
||||||
- 🎯 优化 版本升级提示
|
|
||||||
- 🎯 优化 无权限登录时增加提示信息,[BUG:因前端加载路由(initFrontEndControlRoutes)中当前用户角色为一个陌生角色, 导致 router.beforeEach 会死循环 浏览器崩溃](https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO),感谢[@canroc](https://gitee.com/canroc)、[@随心](https://gitee.com/jiangqiang1996)
|
|
||||||
- 🌈 重构 `/views/system` 新增修改组件合并。[可以把新增修改组件合并成一个吧](https://gitee.com/lyt-top/vue-next-admin/issues/I64WES)
|
|
||||||
- 🌈 重构 图标选择器,[图标选择器没办法筛选,只能筛选 ali 的](https://gitee.com/lyt-top/vue-next-admin/issues/I64HZD),感谢[@随心](https://gitee.com/jiangqiang1996)
|
|
||||||
|
|
||||||
## 2.4.1
|
|
||||||
|
|
||||||
`2022.11.30`
|
|
||||||
|
|
||||||
- 🎉 新增 版本升级提示
|
|
||||||
- 🐞 修复 [先打开 F12 再登录进去,然后改变浏览器大小 js 报错](https://gitee.com/lyt-top/vue-next-admin/issues/I63ZZT),感谢[@Quber](https://gitee.com/quber)
|
|
||||||
|
|
||||||
## 2.4.0
|
|
||||||
|
|
||||||
`2022.11.29`
|
|
||||||
|
|
||||||
⚡⚡⚡ 此版为破坏性更新,应群友建议 `script lang="ts"` 改 `script lang="ts" setup 语法糖`。
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 表格封装演示,路径:`组件封装 -> 表格封装演示`
|
|
||||||
- 🎉 新增 master 分支 script lang="ts" 改成 script lang="ts" setup 语法糖,将同步基础分支
|
|
||||||
- 🐞 修复 [v2.3.0 版本报错问题处理](https://gitee.com/lyt-top/vue-next-admin/issues/I623RP)
|
|
||||||
- 🐞 修复 [el-backtop 滚动高度不触发(固定了 header)](https://gitee.com/lyt-top/vue-next-admin/issues/I63N0D),感谢[@dejavuuuuu](https://gitee.com/zc19951010)
|
|
||||||
- 🎯 优化 完善 ts 类型,删除根目录 `plugins.d.ts、shim.d.ts、source.d.ts`,移入到 `/src/types/global.d.ts`
|
|
||||||
- 🎯 优化 代码 `watch` 移动到 `生命周期钩子` 最后,文字注释等
|
|
||||||
|
|
||||||
## 2.3.0
|
|
||||||
|
|
||||||
`2022.11.16`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 新版登录页
|
|
||||||
- 🎉 新增 tagsview 鼠标中键 `关闭当前 tagsview`
|
|
||||||
- 🎉 新增 `分栏菜单鼠标悬停预加载`。[分栏模式如何去掉鼠标悬浮父级菜单,分栏菜单自动加载的功能啊](https://gitee.com/lyt-top/vue-next-admin/issues/I5RUY7)。操作路径:`布局配置 -> 分栏设置`
|
|
||||||
- 🐞 修复 [vue-i18n](https://vue-i18n.intlify.dev/api/general.html#createi18n) 报错,[!39 修复 i18n 兼容性问题](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/39/files),感谢[@随心](https://toscode.gitee.com/jiangqiang1996)
|
|
||||||
- 🐞 修复 顶栏搜索功能点击蒙蔽弹窗不关闭
|
|
||||||
- 🐞 修复 [!38 fix: bug refreshRouterViewKey 值为 null 导致路由缓存第一次无效](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/38/files),感谢[@P)](https://toscode.gitee.com/foxp8y)
|
|
||||||
- 🐞 修复 `路由参数 -> 普通路由/动态路由` 国际化演示时,`tagsView` 和 `浏览器标题` 显示异常。[演示中:路由参数界面 -> 动态路由,国际化显示时面包屑、浏览器标题有 bug](https://gitee.com/lyt-top/vue-next-admin/issues/I5JRJG)
|
|
||||||
- 🐞 修复 `路由参数 -> 普通路由/动态路由` 动态设置 `tagsViewName` 时,`tagsView 右键菜单刷新` 功能失效(也就是路由后面有参数时,query、params)。[普通或动态路由新建页面后点击 tagview 刷新无效](https://gitee.com/lyt-top/vue-next-admin/issues/I5K3YO),感谢[@dejavuuuuu](https://gitee.com/zc19951010)
|
|
||||||
- 🐞 修复 [表单(el-form)中,字体图标偏移问题](https://gitee.com/lyt-top/vue-next-admin/issues/I5K1PM)
|
|
||||||
- 🐞 修复 路由 `router.addRoute` 时,一直提示 `No match found for location with path 'xxx'`
|
|
||||||
- 🎯 优化 全局 `getCurrentInstance` 替换成 [`provide/inject`](https://cn.vuejs.org/api/application.html#app-provide) 或通过 `ref` 处理
|
|
||||||
- 🎯 优化 引入组件方式 `(import xxx from xxx)` 改成 `defineAsyncComponent(() => import(xxx))`
|
|
||||||
- 🎯 优化 页面高度 100% 问题,重写布局配置 `界面设置 -> 固定 Header` 多余的 `el-scrollbar` 逻辑、重写各界面需 `计算属性 computed` 设置动态高度问题(改为 css `flex` 设置自适应高度,具体查看文档:[设置可视区高度 100%](https://lyt-top.gitee.io/vue-next-admin-doc-preview/config/otherIssues/#%E8%AE%BE%E7%BD%AE%E5%8F%AF%E8%A7%86%E5%8C%BA%E9%AB%98%E5%BA%A6-100)。[!31 修复页面样式无法通过百分比设置的问题](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/31),感谢[@LostDeer](https://toscode.gitee.com/lyt-top/vue-next-admin/pulls/31/files)。`(改动较大,删除多余代码)`
|
|
||||||
- 🎯 优化 [wangeditor](https://www.wangeditor.com/) 组件,`@wangeditor/editor-for-vue`。可自行修改,组件位置:`/src/components/editor`。相关 Issues:[wangeditor 编辑器多个菜单不能回弹](https://gitee.com/lyt-top/vue-next-admin/issues/I5M5H7)
|
|
||||||
- 🌈 重构 外链、内嵌 iframe 逻辑 + 美化,iframe 支持缓存
|
|
||||||
|
|
||||||
## 2.2.0
|
|
||||||
|
|
||||||
`2022.07.10`
|
|
||||||
|
|
||||||
⚡⚡⚡ [/sec/stores/userInfo.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/stores/userInfo.ts) 下添加了 `getApiUserInfo` 接口模拟数据 `setTimeout` 为 3 秒
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🐞 修复 [主界面重新授权按钮点击卡死不跳转登录界面#I5C3JS](https://gitee.com/lyt-top/vue-next-admin/issues/I5C3JS),感谢[@Hero-Typ](https://gitee.com/tian_yu_peng)
|
|
||||||
- 🐞 修复 编译警告[#I5CVSB](https://gitee.com/lyt-top/vue-next-admin/issues/I5CVSB),全局替换成 `:deep(attr)`,感谢[@Linvas](https://gitee.com/linvas)。参考文档:[vue3 sfc-style](https://v3.cn.vuejs.org/api/sfc-style.html#style-scoped)。`node_modules\print-js\dist\print.js` 需 `print-js` 作者适配或去除 `package.json` 中的 `"print-js": "^1.6.0"`
|
|
||||||
- 🐞 修复 [vue-next-admin-template-js 版本前端控制路由:userInfo.js 请求用户信息接口报错,加载不到路由 可以写个定时器模拟一下接口 一样的报错#I5F1HP](https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP),感谢[@白开水](https://gitee.com/libin951223)
|
|
||||||
|
|
||||||
## 2.1.1
|
|
||||||
|
|
||||||
`2022.05.27`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 深色模式下,`<el-button text></el-button>` 时,`:active` 样式
|
|
||||||
- 🎯 优化 [页面缓存在刷新之后失效 #I58U75](https://gitee.com/lyt-top/vue-next-admin/issues/I58U75)),感谢[@ls0428](https://gitee.com/ls0428)
|
|
||||||
- 🎯 优化 [SvgIcon 对下载的 Svg 图像设置颜色无效 #I59ND0](https://gitee.com/lyt-top/vue-next-admin/issues/I59ND0)),感谢[@elus_z](https://gitee.com/elus_z)
|
|
||||||
- 🎯 优化 `/src/utils/toolsValidate.ts` 工具类
|
|
||||||
- 🐞 修复 [布局切换,TagsView 显示的 tab 会多一个出来 #I58WGM](https://gitee.com/lyt-top/vue-next-admin/issues/I58WGM),感谢[@lg_boy](https://gitee.com/lg_boy)
|
|
||||||
- 🐞 修复 [如果设置顶部面包屑导航开启图标 isBreadcrumbIcon=true 后,样式有点问题 如果不开启就是正常的 #I58VB8](https://gitee.com/lyt-top/vue-next-admin/issues/I58VB8)
|
|
||||||
- 🐞 修复 地址栏路由地址输入错误时,返回首页后,再次输入路由地址错误时,不跳转 404 问题
|
|
||||||
- 🐞 修复 [2.1.0 版本的图标选择组件多次点击后功能失效 #I590TH](https://gitee.com/lyt-top/vue-next-admin/issues/I590TH),感谢[@quber](https://gitee.com/quber)
|
|
||||||
|
|
||||||
## 2.1.0
|
|
||||||
|
|
||||||
`2022.04.18`
|
|
||||||
|
|
||||||
⚡⚡⚡ 此版本为破环性更新,优化内容如下:(谨慎更新!谨慎更新!!谨慎更新!!!)。因为 `vuex` 替换成 `pinia`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 部分界面图片不显示问题(更换 gitee 在线图片地址源)
|
|
||||||
- 🎯 优化 各界面方法引入与逻辑之间添加一行空行,方便区分内容
|
|
||||||
- 🎯 优化 图标选择器 [#I4YAHB](https://gitee.com/lyt-top/vue-next-admin/issues/I4YAHB),感谢[@真有你的](https://gitee.com/sunliusen)
|
|
||||||
- 🎯 优化 图标选择器 icon type 类型为 all 时,类型 ali、ele、awe 回显问题
|
|
||||||
- 🎯 优化 去掉开发环境 i18n 控制台警告,页面代码:[i18n/index.ts](https://gitee.com/lyt-top/vue-next-admin/blob/master/src/i18n/index.ts)
|
|
||||||
- 🎯 优化 `NextLoading.start()` 方法,防止第一次进入界面时出现短暂空白
|
|
||||||
- 🎯 优化 地址栏有参数退出登录,再次登录不跳之前界面问题 `src/layout/navBars/breadcrumb/user.vue`
|
|
||||||
- 🎯 优化 `SvgIcon` 组件,防止 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题,工作流不可连线、全屏时关闭按钮消失问题
|
|
||||||
- 🎯 优化 [如果 url 中有中文等特殊字符,第一次切换该 tab 时 keep-alive 失效#I55JS7](https://gitee.com/lyt-top/vue-next-admin/issues/I55JS7),感谢[yuyong1566](https://gitee.com/yuyong1566)
|
|
||||||
- 🎯 优化 [wangEditor](https://www.wangeditor.com/) 更新到 v5,[vue3 版本线上示例中 wangeditor 富文本编辑器 demo 实例,无法换行#I5565B](https://gitee.com/lyt-top/vue-next-admin/issues/I5565B),感谢@[jenchih](https://gitee.com/jenchih)
|
|
||||||
- 🎯 优化 [在关闭 tagview 时,高度刷新时会会变化,出现滚动条](https://gitee.com/lyt-top/vue-next-admin/issues/I55FHM),感谢[张松](https://gitee.com/zs310071113)
|
|
||||||
- 🎯 优化 [路由参数](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)演示
|
|
||||||
- 🎉 新增 [vuex](https://vuex.vuejs.org/) 替换成 [pinia](https://pinia.vuejs.org/getting-started.html)
|
|
||||||
- 🎉 新增 tagsView 支持自定义 tagsView 名称(文章详情时有用),前往体验:[路由参数/普通路由](https://lyt-top.gitee.io/vue-next-admin-preview/#/params/common)。新增 tagsView 支持自定义名称国际化,感谢[@q7but](https://gitee.com/q7but)、[!22 add 添加自定义 tagVIewName 拓展,支持国际化](https://gitee.com/lyt-top/vue-next-admin/pulls/22/files)、感谢[@tony_tong_xin](https://gitee.com/tony_tong_xin)
|
|
||||||
- 🐞 修复 适配 `"element-plus": "^2.1.9",2.2.0` 版本
|
|
||||||
- 🐞 修复 [导航栏横向布局后,一级菜单显示问题#I4Z3M3](https://gitee.com/lyt-top/vue-next-admin/issues/I4Z3M3)
|
|
||||||
- 🐞 修复 横向布局三级及以上导航菜单高亮、导航高度不统一问题
|
|
||||||
- 🐞 修复 分栏模式下,选中的菜单是 primary 样式,鼠标移入字也变成 primary 色了,感谢群友@孤夜-流殇
|
|
||||||
- 🐞 修复 [vuex 里面改了颜色 但是不生效 #I4WFMA](https://gitee.com/lyt-top/vue-next-admin/issues/I4WFMA)
|
|
||||||
- 🐞 修复 全局主题 primary 清空颜色后报错,[#I4X0LG](https://gitee.com/lyt-top/vue-next-admin/issues/I4X0LG),感谢[面向 BUG 编程](https://gitee.com/fhtfy)
|
|
||||||
- 🐞 修复 [.eslintrc.js 文件 rules 标签名错误 #I53IPK](https://gitee.com/lyt-top/vue-next-admin/issues/I53IPK),感谢[yuyong1566](https://gitee.com/yuyong1566)
|
|
||||||
- 🐞 修复 `开启 Tagsview 图标` 时,`tagsView 右键菜单关闭` 报错问题
|
|
||||||
- 🐞 修复 `router.push` 路径找不到时报错问题,`404、401 界面` 已移入到 `main` 主布局里(之前全屏)
|
|
||||||
- 🐞 修复 [全局修改组件大小失效了](https://gitee.com/lyt-top/vue-next-admin/issues/I551RP),感谢[lg_boy](https://gitee.com/lg_boy)
|
|
||||||
- 🐞 修复 [修改一下配置时,需要每次都清理 `window.localStorage` 浏览器永久缓存,配置才会生效,问题解决#I567R1](https://gitee.com/lyt-top/vue-next-admin/issues/I567R1),感谢[@lanbao123](https://gitee.com/lanbao123)
|
|
||||||
- 🐞 修复 [标记为需要缓存的 tab 页后,再次从左侧菜单打开,还是显示被缓存的页面内容#I4UY3G](https://gitee.com/lyt-top/vue-next-admin/issues/I4UY3G),感谢@axcc1234、特别感谢群友@华仔
|
|
||||||
- 🌈 重构 路由(`/src/router/index.ts`)解决 No match found for location with path "xxx"(前端控制,后端控制未解决) 问题
|
|
||||||
|
|
||||||
## 2.0.2
|
|
||||||
|
|
||||||
`2022.03.04`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 Alert 提示添加边框
|
|
||||||
- 🎯 优化 功能 / 数字滚动 演示界面
|
|
||||||
- 🐞 修复 全局主题按钮颜色 :active 问题
|
|
||||||
- 🐞 修复 Dropdown 下拉菜单样式问题
|
|
||||||
- 🐞 修复 SvgIcon 图标组件动态切换时报警告问题,[SvgIcon 改变 name 时可能导致图像不显示](https://gitee.com/lyt-top/vue-next-admin/issues/I4VGE0),感谢@axcc1234
|
|
||||||
|
|
||||||
## 2.0.1
|
|
||||||
|
|
||||||
`2022.02.25`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 svgIcon 图标组件
|
|
||||||
- 🎯 优化 vite.config.ts 打包,感谢群友@YourObjec
|
|
||||||
- 🐞 修复 tagViews 开启图标不显示问题(风格 5),感谢群友@坏人
|
|
||||||
- 🐞 修复 [Element Plus 1.2.0-beta.6 以后的版本 el-table 在移动端无法左右滑动](https://gitee.com/lyt-top/vue-next-admin/issues/I4UPTP),感谢@YGDada
|
|
||||||
|
|
||||||
## 2.0.0
|
|
||||||
|
|
||||||
`2022.02.21`
|
|
||||||
|
|
||||||
⚡⚡⚡ 此版本为破环性更新,优化内容如下:(谨慎更新!谨慎更新!!谨慎更新!!!)。演示界面建议直接覆盖文件。如需使用之前版本,请前往[gitee 发行版](https://gitee.com/lyt-top/vue-next-admin/releases) 进行对应版本下载。基础版会基于 `master` 分支进行修改
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🌟 更新 登录页、首页
|
|
||||||
- 💔 移除 vue-web-screen-shot
|
|
||||||
- 💔 移除 城市多级联动,完整 json 数据请去 [vue-next-admin-images/menu](https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu) 仓库查看
|
|
||||||
- 💔 移除 功能/echartsTree 树图
|
|
||||||
- 💔 移除 其它设置/Tagsview 风格 2、Tagsview 风格 3
|
|
||||||
- 💔 移除 功能/验证器
|
|
||||||
- 🚧 调整 src/api 编写方式
|
|
||||||
- 🚧 调整 自定义封装公用组件演示,更好的维护
|
|
||||||
- 🎉 新增 Volar 支持,vs code 配置参考 [Vue Language Features (Volar)](https://lyt-top.gitee.io/vue-next-admin-doc-preview/home/vscode/)
|
|
||||||
- 🎉 新增 `SvgIcon` 支持本地 svg 图标使用
|
|
||||||
- 🎉 新增 表单表格验证演示
|
|
||||||
- 🎯 优化 全局主题(移除 success、info、warning、danger)
|
|
||||||
- 🎯 优化 工作流(开源)
|
|
||||||
- 🎯 优化 element plus svg 图标,`elementXXX` 改成 `ele-XXX`
|
|
||||||
- 🌈 重构 深色模式
|
|
||||||
- 🌹 合并 [处理 parent 的 h100 由于外层有 min-height 导致失效的问题](https://gitee.com/lyt-top/vue-next-admin/pulls/20),感谢@MaxNull、@21030442-mao
|
|
||||||
- 🐞 修复 element plus 升级 `^1.3.0-beta.5` 后 组件 size 大小问题(大改:涉及布局、演示界面)
|
|
||||||
- 🐞 修复 vs code 使用 Vue Language Features (Volar) 插件 代码报红问题(可以把公用的 ts 类型定义封装起来公用)
|
|
||||||
|
|
||||||
## 1.2.2
|
|
||||||
|
|
||||||
`2021.12.21`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 iframes 滚动条问题
|
|
||||||
- 🎯 优化 部署后每次都要强制刷新清浏览器缓存问题
|
|
||||||
- 🎉 新增 工具类百分比验证演示
|
|
||||||
- 🐞 修复 [tag-view 标签右键会超出浏览器 #I4KN78](https://gitee.com/lyt-top/vue-next-admin/issues/I4KN78)
|
|
||||||
|
|
||||||
## 1.2.1
|
|
||||||
|
|
||||||
`2021.12.12`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 cropper 裁剪时卡顿问题 [#I4M2VQ](https://gitee.com/lyt-top/vue-next-admin/issues/I4M2VQ)
|
|
||||||
- 🎯 优化 Wangeditor 富文本编辑器的问题 [#I4LPC1](https://gitee.com/lyt-top/vue-next-admin/issues/I4LPC1)、[#I4LM7I](https://gitee.com/lyt-top/vue-next-admin/issues/I4LM7I)
|
|
||||||
- 🐞 修复 浏览器标题问题
|
|
||||||
- 🐞 修复 element plus svg 图标引入
|
|
||||||
- 🐞 修复 工作流不可以拖线连接问题
|
|
||||||
|
|
||||||
## 1.2.0
|
|
||||||
|
|
||||||
`2021.11.28`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 深色模式
|
|
||||||
- 🎯 优化 `/@/utils` 文件夹,合并删除单一内容
|
|
||||||
- 🎯 优化 系统设置:菜单管理(新增、修改)、角色管理(新增菜单权限)、用户管理、部门管理、字典管理
|
|
||||||
- 🎯 优化 登录界面逻辑、权限管理逻辑
|
|
||||||
- 🎯 优化 同步 [vue-next-admin-images](https://gitee.com/lyt-top/vue-next-admin-images/tree/master/menu) 后端控制菜单模拟数据
|
|
||||||
- 🎉 新增 适配 Font Icon 向 SVG Icon 迁移(改动大,"element-plus": "^1.2.0-beta.4" 谨慎更新)
|
|
||||||
- 🐞 修复 热更新问题,感谢@甜蜜蜜
|
|
||||||
- 🐞 修复 页面/element 字体图标演示
|
|
||||||
- 🐞 修复 功能/图标选择器演示,新增高级功能 [issues #I4GJXQ](https://gitee.com/lyt-top/vue-next-admin/issues/I4GJXQ)
|
|
||||||
|
|
||||||
## 1.1.2
|
|
||||||
|
|
||||||
`2021.10.17`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🐞 修复 开启全屏时,刷新界面被还原成未全屏的状态
|
|
||||||
- 🎯 优化 tagsView 右键菜单关闭逻辑
|
|
||||||
- 🎯 优化 wangeditor 富文本编辑器(增加双向绑定)
|
|
||||||
- 🎉 新增 工作流(暂不开源)
|
|
||||||
- 🎉 新增 基础版 ts(不带国际化),切换 `vue-next-admin-template` 分支
|
|
||||||
|
|
||||||
## 1.1.1
|
|
||||||
|
|
||||||
`2021.09.25`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本(`"element-plus": "^1.1.0-beta.13"` 版本运行错误,`^1.1.0-beta.16`修复横向菜单卡死问题)
|
|
||||||
- 🐞 修复 Dialog 弹窗位置错误、Drawer 抽屉内边距、el-menu 菜单收起时背景色问题
|
|
||||||
- 🎯 优化 锁屏界面自动锁屏(s/秒)必须设置至少 1 秒
|
|
||||||
- 🎉 新增 分栏布局,鼠标移入当前项时,显示当前项菜单内容
|
|
||||||
- 🎉 新增 工作流(未完成)
|
|
||||||
|
|
||||||
## 1.1.0
|
|
||||||
|
|
||||||
`2021.09.10`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 小屏模式下登录页二维码遮挡标题问题
|
|
||||||
- 🎉 新增 图片验证器
|
|
||||||
- 🎉 新增 动态复杂表单
|
|
||||||
- 🎉 新增 工作流(未完成)
|
|
||||||
- 🎉 新增 深色主题(伪深色,样式变动大,谨慎更新)
|
|
||||||
|
|
||||||
## 1.0.18
|
|
||||||
|
|
||||||
`2021.08.29`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 权限组件去掉顶级 div(`/src/components/auth`)
|
|
||||||
- 🎉 新增 布局配置添加恢复默认按钮
|
|
||||||
- 🐞 修复 升级 <a href="https://element-plus.gitee.io/#/zh-CN/component/changelog" target="_blank">element plus 1.1.0-beta.7</a>后项目无法启动、el-menu 菜单
|
|
||||||
- 🐞 修复 表格固定列时的层级、设置了相对定位时,遮挡左侧导航菜单问题
|
|
||||||
|
|
||||||
## 1.0.17
|
|
||||||
|
|
||||||
`2021.08.22`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 去除设置布局切换,重置主题样式(initSetLayoutChange),切换布局需手动设置样式,设置的样式自动同步各布局
|
|
||||||
- 🎯 优化 Dropdown 下拉菜单用户账号靠边时换行问题
|
|
||||||
- 🎯 优化 左侧导航菜单,共用菜单树,防止 `布局配置` 设置 `菜单 / 顶栏` 时,样式丢失等问题
|
|
||||||
- 🐞 修复 固定 header 后没有回到顶部的 bug,拉取项目后运行不起来的 bug。<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/14" target="_blank">!14</a>,感谢<a href="https://gitee.com/wjs0509" target="_blank">@wjs0509</a>
|
|
||||||
- 🐞 修复 tagView 右键全屏后,浏览器窗口大小发生任何变化都会导致左边菜单显示出来,并且可点击打开对应页面。<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I46E6T" target="_blank">I46E6T</a>
|
|
||||||
- 🐞 修复 默认设置 `菜单 / 顶栏` 样式不生效问题(/@/src/store/modules/themeConfig.ts)
|
|
||||||
|
|
||||||
## 1.0.16
|
|
||||||
|
|
||||||
`2021.08.14`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 菜单高亮(详情且详情设置了 meta.isHide 时,顶级菜单高亮),感谢群友@YourObject
|
|
||||||
- 🎯 优化 详情路径写法:如父级(/pages/filtering),那么详情为(/pages/filtering/details?id=1)。这样写可实现(详情时,父级菜单高亮),否则写成(/pages/filteringDetails?id=1)顶级菜单将不会高亮。可参考:`页面/过滤筛选组件`,点击当前图片进行测试
|
|
||||||
- 🎯 优化 tagsView 右键菜单全屏时,打开的界面高度问题
|
|
||||||
- 🎯 优化 图表批量 resize 问题
|
|
||||||
- 🐞 修复 菜单收起时(设置全局主题:primary 且有二级菜单时),文字高亮颜色不对
|
|
||||||
- 🐞 修复 国际化 <a href="https://gitee.com/lyt-top/vue-next-admin/issues/I43NPE" target="_blank">#I43NPE</a>。可参考:`页面/过滤筛选组件`,点击顶部语言切换,进行底部分页国际化查看
|
|
||||||
|
|
||||||
## 1.0.15
|
|
||||||
|
|
||||||
`2021.08.06`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 tagsView 右键菜单点击时的字段名(id 已修改成 contextMenuClickId)与路由中返回的 id 名冲突问题,感谢群友@伯牙已遇钟子期
|
|
||||||
- 🎉 新增 多个 form 表单验证界面演示
|
|
||||||
|
|
||||||
## 1.0.14
|
|
||||||
|
|
||||||
`2021.07.29`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本(vue、vuex、vue-router),出现问题,请手动降级。版本查看:<a href="https://www.npmjs.com/" target="_blank">vnpm</a>
|
|
||||||
- 🎯 优化 数据可视化图表演示加载卡顿问题、优化有图表的演示界面
|
|
||||||
- 🎯 优化 路由参数演示界面
|
|
||||||
- 🎯 优化 tagsView 操作演示界面,由于存在相同路由多标签,必须要传全部参数值(query 或者 params)
|
|
||||||
- 🎉 新增 开启 TagsView 共用,开启时:(多个路由菜单共用一个详情组件(参数为后点击的覆盖前面点击的),tagsView 中只会出现一个(不支持同时出现多个 tagsView 标签))。关闭时:(多个路由菜单共用一个详情组件,参数不同,会同时出现多个 tagsView 标签)
|
|
||||||
- 🐞 修复 tagsView 共用(单标签)时,右键菜单功能点击,参数不对的问题(第 2n+个参数未覆盖第一个参数值)
|
|
||||||
- 🐞 修复 多 tagsView 标签(参数不同)、单个 tagsView 标签公用(参数不同)所带来的刷新功能、横向自动滚动等问题
|
|
||||||
- 🐞 修复 处理全屏若干问题,<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/12" target="_blank">pr!12</a>,感谢群友@另一个前端
|
|
||||||
|
|
||||||
## 1.0.13
|
|
||||||
|
|
||||||
`2021.07.25`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 数据可视化演示界面(/visualizingDemo1、/visualizingDemo2)
|
|
||||||
- 🎉 新增 登录页扫码登录
|
|
||||||
|
|
||||||
## 1.0.12
|
|
||||||
|
|
||||||
`2021.07.16`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 数据可视化演示空界面(待完善)
|
|
||||||
- 🎯 优化 tagsView 动态路由(xxx/:id/:name)时的右键菜单刷新、关闭其它时参数丢失问题(2021.07.15 优化)
|
|
||||||
- 🐞 修复 路由带参数时,复制路径到登录页,跳转后参数消失的问题
|
|
||||||
- 🐞 修复 设置多个外链,点击后,页面内容停留在上一个内容(内容未改变)、国际化处理、打开新窗口 sessionStorage 共享等
|
|
||||||
|
|
||||||
## 1.0.11
|
|
||||||
|
|
||||||
`2021.07.14`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 路由参数、图片懒加载界面演示
|
|
||||||
- ⚠️ 警告 Form 表单 `binding value must be a string or number`,解决:加上 `label-position="top"` 不报警告(等待官方修复)
|
|
||||||
- 🎯 优化 锁屏界面动画效果、首页图表显示
|
|
||||||
- 🎯 优化 tagsView 右键菜单 `关闭` 功能逻辑
|
|
||||||
- 🐞 修复 开启 TagsView 拖拽报错及小于 `1000px` 时自动设置禁止拖拽(<a href="https://gitee.com/lyt-top/vue-next-admin/issues/I3ZRRI" target="_blank">#I3ZRRI</a>)
|
|
||||||
- 🐞 修复 `iframe 内嵌、外链` 高度问题,使用 computed 进行计算
|
|
||||||
- 🐞 修复 默认布局开启 `侧边栏 Logo` 与关闭 `菜单水平折叠`,切换到横向布局时,菜单看不见的问题
|
|
||||||
- 🐞 修复 切换不同布局时,再去开启 `经典布局分割菜单` 功能不生效问题
|
|
||||||
- 🐞 修复 浏览器窗口标题中/英文切换不实时生效的问题
|
|
||||||
- 🐞 修复 切换布局时,某些功能不可以使用。部分界面不需要取消事件监听(proxy.mittBus.off('xxx'))
|
|
||||||
- 🐞 修复 动态路由带参数,router-link 跳转问题(<a href="hhttps://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G" target="_blank">#I3YX6G</a>)
|
|
||||||
- 🐞 修复 横向菜单有二级菜单时,点击子级菜单不高亮问题
|
|
||||||
- 🐞 修复 功能 tagsView 操作演示不生效
|
|
||||||
|
|
||||||
## 1.0.10
|
|
||||||
|
|
||||||
`2021.07.07`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本(字体图标无问题)
|
|
||||||
- 🎯 优化 内嵌 iframe、外链,解决 tagsView 刷新问题
|
|
||||||
|
|
||||||
## 1.0.9
|
|
||||||
|
|
||||||
`2021.07.02`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎯 优化 图标选择器设置宽度、v-model 等问题
|
|
||||||
- 🎯 优化 滚动通知栏在手机上的体验
|
|
||||||
- 🎯 优化 系统管理/新增菜单(编辑菜单),使用 `图标选择器` 进行模拟
|
|
||||||
- 🎯 优化 字体图标(自动载入) 逻辑
|
|
||||||
- 🐞 修复 screenfull 全屏时,按键盘 esc 键图标不改变问题,感谢群友@伯牙已遇钟子期
|
|
||||||
|
|
||||||
## 1.0.8
|
|
||||||
|
|
||||||
`2021.06.29`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 表单中英文切换演示
|
|
||||||
- 🎯 优化 登录页查看密码 icon 图标
|
|
||||||
- 🎯 优化 图标选择器
|
|
||||||
- 🎯 优化 拖动指令
|
|
||||||
- 🐞 修复 form 表单在页面小于 576px 时的排版问题
|
|
||||||
|
|
||||||
## 1.0.7
|
|
||||||
|
|
||||||
`2021.06.24`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🎉 新增 拖动指令及其演示界面
|
|
||||||
- 🎯 优化 锁屏界面,解锁提示
|
|
||||||
- 🎯 优化 登录页在手机上显示的效果
|
|
||||||
|
|
||||||
## 1.0.6
|
|
||||||
|
|
||||||
`2021.06.23`
|
|
||||||
|
|
||||||
- 🎯 优化 去掉内嵌 iframe 内边距(padding)
|
|
||||||
- 🎯 优化 城市多级联动组件
|
|
||||||
- 🎯 优化 Tree 树形控件改成表格组件
|
|
||||||
- 🐞 修复 Cascader 级联选择器高度问题
|
|
||||||
|
|
||||||
## 1.0.5
|
|
||||||
|
|
||||||
`2021.06.22`
|
|
||||||
|
|
||||||
- 🌟 更新 vite 降级为@vite2.3.7,降级方法 `cnpm install vite@2.3.7`,防止 element plus 字体图标消失
|
|
||||||
- 🐞 修复 开启后端控制路由(isRequestRoutes = true)时,内嵌 iframe、外链不可使用的问题
|
|
||||||
|
|
||||||
## 1.0.4
|
|
||||||
|
|
||||||
`2021.06.19`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本("vite": "^2.3.7")热更新无问题
|
|
||||||
- 🎉 新增 深克隆工具,方便开发,感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/6" target="_blank">#6</a>)
|
|
||||||
- 🎯 优化 vuex 模块自动导入。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/4" target="_blank">#4</a>),感谢群友@web 小学生-第五君
|
|
||||||
- 🎯 优化 类型定义提高编码体验,修复不能将类型“string | undefined”分配给类型“string”的问题。感谢<a href="https://gitee.com/kangert" target="_blank">@kangert</a>(<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/5" target="_blank">#5</a>)
|
|
||||||
- 🎯 优化 `layout` 文件夹移动到与 `views` 文件夹同级(改动较大,`/@/views/layout` 变成 `/@/layout`)
|
|
||||||
- 🎯 优化 页面有 `console.log` 时 `eslint` 不生效问题
|
|
||||||
- 🎯 优化 页面、ts 中 `any` 类型问题(改动较大)
|
|
||||||
- 🎯 优化 登录页在手机上显示的效果
|
|
||||||
- 🎯 优化 多行注释信息,鼠标放到方法名即可查看,更加直观的知道方法参数等。引入方法时需去掉以 `.ts` 结尾的后缀(改动较大)
|
|
||||||
- 🎯 优化 移除 `utils/storage.ts` 下的旧写法(改动较大)
|
|
||||||
- 🎯 优化 拆分 `router` 下内容,路由、前端、后端控制分开写,方便理解
|
|
||||||
- 🐞 修复 鼠标移入顶部用户信息栏 `开/关全屏` 文字反向问题
|
|
||||||
- 🐞 修复 热更新时,NextLoading(界面 loading) 不消失问题 `window.nextLoading === undefined`
|
|
||||||
- 🐞 修复 vuex 中不可以使用 `/@/api/xxx` 下的接口调用问题
|
|
||||||
|
|
||||||
## 1.0.3
|
|
||||||
|
|
||||||
`2021.06.02`
|
|
||||||
|
|
||||||
- ❄️ 删除 G6 思维导图界面
|
|
||||||
- 🌟 更新 手动更新 vue、vue-router、vuex 到最近最多人使用的版本,出现不可预测的问题请降低版本。版本查看:<a href="https://www.npmjs.com/package/vue" target="_blank">vue 版本查看</a>
|
|
||||||
- 🐞 修复 开启后端控制路由 `isRequestRoutes` 在非首页刷新页面后,回到首页的问题,感谢群友@伯牙已遇钟子期
|
|
||||||
|
|
||||||
## 1.0.2
|
|
||||||
|
|
||||||
`2021.06.01`
|
|
||||||
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🐞 修复 菜单搜索中文不可以搜索的问题,感谢群友@逍遥天意
|
|
||||||
|
|
||||||
## 1.0.1
|
|
||||||
|
|
||||||
`2021.05.31`
|
|
||||||
|
|
||||||
- 🎉 新增 更新日志文件 `CHANGELOG.md`,以后每次更新都会在这里显示对应内容
|
|
||||||
- 🌟 更新 依赖更新最新版本
|
|
||||||
- 🐞 修复 分栏、经典布局路由设置 `meta.isHide` 为 `true` 时报错问题,感谢群友@29、@芭芭拉
|
|
||||||
- 🐞 修复 经典布局点击 `tagsView` 左侧菜单数据不变问题
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2021 lyt-Top
|
Copyright (c) 2023 dvadmin,hugedream
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<div align="center">django-vue-admin:web </div>
|
<div align="center">django-vue3-admin:web </div>
|
||||||
|
|
||||||
#### 🌈 介绍
|
#### 🌈 介绍
|
||||||
|
|
||||||
基于 vue3.x + CompositionAPI + typescript + vite + element plus + vue-router-next + next.vuex,适配手机、平板、pc 的后台开源免费模板,希望减少工作量,帮助大家实现快速开发。
|
django-vue3-admin,基于 vue3 + CompositionAPI + typescript + vite + element plus, 是一款全栈,快速,开源的后台管理系统!
|
||||||
|
|
||||||
#### 🏭 环境支持
|
#### 🏭 环境支持
|
||||||
|
|
||||||
|
|||||||
@@ -6,11 +6,11 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<meta
|
<meta
|
||||||
name="keywords"
|
name="keywords"
|
||||||
content="vue-next-admin,vue-prev-admin,vue-admin-wonderful,后台管理系统一站式平台模板,希望可以帮你完成快速开发。vue2.x,vue2.0,vue2,vue3,vue3.x,vue3.0,CompositionAPI,typescript,element plus,element,plus,admin,wonderful,wonderful-next,vue-next-admin,vite,vite-admin,快速,高效,后台模板,后台系统,管理系统"
|
content="django-vue3-admin"
|
||||||
/>
|
/>
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="vue-next-admin,基于 vue3 + CompositionAPI + typescript + vite + element plus,适配手机、平板、pc 的后台开源免费管理系统模板!vue-prev-admin,基于 vue2 + element ui,适配手机、平板、pc 的后台开源免费管理系统模板!"
|
content="django-vue3-admin,基于 vue3 + CompositionAPI + typescript + vite + element plus, 是一款全栈,快速,开源的后台管理系统!"
|
||||||
/>
|
/>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<title>vue-next-admin</title>
|
<title>vue-next-admin</title>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-next-admin",
|
"name": "django-vue3-admin",
|
||||||
"version": "2.4.21",
|
"version": "1.0.0",
|
||||||
"description": "vue3 vite next admin template",
|
"description": "django-vue3-admin,基于 vue3 + CompositionAPI + typescript + vite + element plus, 是一款全栈,快速,开源的后台管理系统!",
|
||||||
"author": "lyt_20201208",
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite --force",
|
"dev": "vite --force",
|
||||||
@@ -11,6 +10,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.0.10",
|
"@element-plus/icons-vue": "^2.0.10",
|
||||||
|
"@fast-crud/fast-crud": "^1.9.0",
|
||||||
|
"@fast-crud/ui-element": "^1.9.0",
|
||||||
|
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"axios": "^1.2.1",
|
"axios": "^1.2.1",
|
||||||
@@ -26,17 +28,20 @@
|
|||||||
"mitt": "^3.0.0",
|
"mitt": "^3.0.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.0.28",
|
"pinia": "^2.0.28",
|
||||||
|
"pinia-plugin-persist": "^1.0.0",
|
||||||
"print-js": "^1.6.0",
|
"print-js": "^1.6.0",
|
||||||
"qrcodejs2-fixes": "^0.0.2",
|
"qrcodejs2-fixes": "^0.0.2",
|
||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.0",
|
||||||
"splitpanes": "^3.1.5",
|
"splitpanes": "^3.1.5",
|
||||||
|
"ts-md5": "^1.3.1",
|
||||||
"vue": "^3.2.45",
|
"vue": "^3.2.45",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-grid-layout": "^3.0.0-beta1",
|
"vue-grid-layout": "^3.0.0-beta1",
|
||||||
"vue-i18n": "^9.2.2",
|
"vue-i18n": "^9.2.2",
|
||||||
"vue-router": "^4.1.6"
|
"vue-router": "^4.1.6",
|
||||||
|
"xe-utils": "^3.5.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.11.13",
|
"@types/node": "^18.11.13",
|
||||||
@@ -60,9 +65,6 @@
|
|||||||
"last 2 versions",
|
"last 2 versions",
|
||||||
"not dead"
|
"not dead"
|
||||||
],
|
],
|
||||||
"bugs": {
|
|
||||||
"url": "https://gitee.com/lyt-top/vue-next-admin/issues"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.0.0",
|
"node": ">=16.0.0",
|
||||||
"npm": ">= 7.0.0"
|
"npm": ">= 7.0.0"
|
||||||
@@ -70,14 +72,14 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"vue",
|
"vue",
|
||||||
"vue3",
|
"vue3",
|
||||||
"vuejs/vue-next",
|
|
||||||
"element-ui",
|
"element-ui",
|
||||||
"element-plus",
|
"element-plus",
|
||||||
"vue-next-admin",
|
"django-vue3-admin",
|
||||||
"next-admin"
|
"django",
|
||||||
|
"django-restframework"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitee.com/lyt-top/vue-next-admin.git"
|
"url": "https://gitee.com/huge-dream/django-vue3-admin.git"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,53 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 50" width="64" height="50">
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<defs>
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<image width="64" height="50" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAAyCAYAAADsg90UAAAAAXNSR0IB2cksfwAACI5JREFUeJy1WgtsW9UZdvNq0xU6WhZoCCVx7Gunbld1GSsMdYpGREhwr+2IMbQWqRoTk+iWPZi2wWhm1kwEmqV52feRJrbvvd6DiUnbQCAemzY2xh4tSB0wOqZIqAtLYzultIWEpt13btLq+sap/R8nRzpK4vh+5/++85///8851yEk1V+hX6B0tyE3OWwt0x789VR78AKlZ0KBz1oxBE3+BdUW9PNuQ7nJbk/BDQ/v4hi0x44z1R64jyrAVCjQ/fLNN8/ZoUWdgqGc57AFE6I86giH+QRw6XI9QE4RBz3iTAyVW3EyQdEDUmeIIhyeFNtMHO/o0B4e8qYASfVvLk2p4BKgdnioFCAvEQeddhnyFivOpOgvBaFXiAKcygQDrk927S/zjkae5xUA/X3YI/C5AFwHLrSPw+2+YYfCMugiCvDaCbGt0hc9uAXuP1OEAPACZQ+fAGguQ9nGgglx0OfsOAhq24lBcG/YYQa/kWLIz3XlCW4B6mKRCoCMEQdNu3VpnRVnMhBYA2L/LVCATCooXuNJSHXFzv58P+mMyyu5RQDAKNntdLnNjoN0+NMCM0D8901NDkGXuyBAseRZn3Ubagu3AFjTd1GXAdZdpCqurMgSIBS4BwRn8wgwje/d4pV6yz2adGQJyM/bo/ZyC+DSlWqApIiDHqtPyFdlCyBeD4Lv5xHgr5mAWO4ZjTRh9s8tlQDoryIbrOISoLYvvAIALxIHnIHn3GnFmfDfztLhH/IEv/vYd72xyKElJM/6Gdjj4fYCuNA3yYMa6ogdBwQfvIwAk+mguHZz3+MbMPsfLrEALD3v5RfAkH3UOID+Jqqwj2ULIDZeJvhF2He8I0NfX2ry8wI85VSy41LBzaUPsXT4L/Iy0OUbrTgpsXUlyI7lEOAsvGOboPRdKejK28shAPqpek1etxjHArxAiXCo/pAdB2QPLRQg8BLcv8ITi4h4bnaZBGD2+IsQQG0DCDUyv2LfjcHVQyB93iLAecz+bvY/T1x6YrnImwIkVakIAeSrAfIucdCz7qRcY8VJh8RrQDplWfvHxttaVvkGe6vg/h8tpwDoR926wpcOb9CkEhQ4Mbrqym4rTkrcydLhs5bU95Wwwwx+311m8qxPQ4CtvE6AdKjcLlCrQkNJXNXdnYUD0t+eF+AE1v76rV0/qvTEo/8kkkGJq/yFLIKhPsgtgEszl8E4cdAxPHdllgDBwGZW9k6Fguaa9A4PtMEwkrDe0chhCPAZ/E5dNn/kPiWqGe5mVSH1rJCdze2w4rDNDsi/gdn/FPtb0KTfUmeyQenvuE45WCLQd6unsc3fwKeAw0yHX+Zwu247DpbB3emQv3R7x7du8GgybdtrKGc39Ty23rQnqfKk5y9wCwD1XACZJg56xGUMZFVhx1taytjPBnWAfuihyT+3TEiAQwC1Mhzmqwrr9QhbBoeJg36A6Ou0Y/kGe2qQ+mhiGspHDcODTZfs0eRr8fkE0Z4xpyGt4RJgTnX1carq8Jw9dhzv6BB5k+VJyK9t6+y8dNK74bGHMSHK00Scc/CC7fwC6MotAjX6GuqTzsTBkosYW/f9YKUnIb1OFiAW/c4Ce5Lq18jLKKnu5xaApTWBHn0n8Nz6ixhw4zvJ5HXlvU2R3gWui02XizwhrEznbTW9vQ64nUEckBUut13EQOHzFFUA70jErBv+09xcYrXHqUXK8H9qIXXapSs1dm4FN1SF95DdzlD72LMNUt/15CMvXT65NfzIRtQOq5FCv7jAHkPppdqDZ3YvZFZgY8WEQN8dvvFxpB8hLvWT3T8uyWxckG9CEfX38fk0ahGgmboMMIk/2xg5UJKbYZ62sf9RbI7UPxGJzLgT0R2Y/RM0z1HO+QZ6Gl/3+dh2Wmdb6HQwUJc9IfI6fPc40Z5xCLeW2wvw8Pfoy0B5mfoMAuYLn+7oKE0FxZqp+YvWTHugw24PvvtLIjZLh83cAghzmxHqASb5qntz/4EvsfEy7UHroepvJoKtWdUcPPKrVGwsA6k2FuYTAPXAGoC8RfYCStflqRvv3VuB4Hc1SI9bBJjAZ1VWe+p1+TqBHpfG+M8Ksa0EgLacAnhiETNzIPjdbztLPIfPWrME0CSkQ+UfxDFmkQ5v5RPAYcYBckFTcDfUWc+hwZsw06tA+EiOi5RoDns66ctA/Qm3AE4tuhYgZ5Zl9uPR32165PtlINoMwjM5jtPfSvn9WTe/iEufw7PUW+U3a2NSKZ8CTU0s+DyzHAJgq9yuNDaywxNtkQuVWaTDBqs5SIdsQt4hjsXOCvmvzrDu6Fdnebo3Hj3u69xXngoFqkH09KL3ie2BB6y2XCsfZNt1apnOqsL7uY/KoB57k+SDJRUhIZlX2iD4UJ4b5ef+3dqabY9hlunUdPt0XXyIryqs1yKVAv3qbPFuKNNedaAR5FeD4NE8AqRTwZ1ZmxqnHv0EcI4Rxz3hNqSqxThevrEXqpJq31IJgOD3TN3+h0tYmmPpLt9bJex80W4SRBzmEF7kE8Bhbo5aONwutwCx6K4JUVyByu/JfOTn+6EFAiTNN1uoAgxyC1BvqFcAZLJo8pr8rlvuq8wExfpFUl+u/s7/dt6R9UKkS5ergHeaOP6Yc2SQLw7Mqa6SDznsHakvzLAyoeAPCyRvVoXpUGCb1ZZqRWFnhdQXPWcg3Jac5App7C2MImf/5Kb+nupJ0X8FSL1NEOACEyyHPQ9QbWA73CIEkBuEIqrCzUO9CsNB6esCqQ8pAqD/Oe33l9vs2SLQd6svuhJSWW6GeVptLFKGbMD9eltjZ2cjw5m4o60ChF4lCvBeJhjIuntAYF4N3KNEO9Lwgmo+F/D5mNt1cbr/2OeD916qx+HSB4gCsDdNdmXZM7dbjRJtYXeZd/EJ4DDX3Q4uARLSj604yO23UgVA2jRy2EO+OkNX/w+fZNm8pw5QbAAAAABJRU5ErkJggg=="/>
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"> <image id="image0" width="64" height="64" x="0" y="0"
|
||||||
</defs>
|
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
|
||||||
<style>
|
AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QA/wD/AP+gvaeTAAAJ
|
||||||
tspan { white-space:pre }
|
30lEQVR42u2ae3QU1R3HP3dmd1kSIAlCIJDwCMpDEXxU0MpDEY5wRK2CVhTFqhUrWBSh9VFaUXvq
|
||||||
</style>
|
oe1RSxWLYkFbqsJpFbFqUNE2gghKgaA5SokYjCRgIhDy3JnbP353ybDsZndDCO3pfs+ZMzuzd+69
|
||||||
<use id="Background" href="#img1" x="0" y="0" />
|
v+/93d9rBlJIIYUUUkghhRRSSOH/EupETyAW8p+oBrCAIJAJ+IH2QDvgEFAPHACqAWfnjA7/uwQY
|
||||||
|
YTHC9gYGA/2BQeY6xwgeMETUAY1ABfAZsAlYD2wF6pIh44QSYARvDwwBRpvjDCAb8CXZXSWwFlhs
|
||||||
|
zo2JENHmBHhWuytwMXA1MALIaqUh9gNLgAVAeTwSjjsBRmAfor4KZXUGfSWa60CfSfIrnQg08Aow
|
||||||
|
AyhrjoRWI8AjaFegD3AKosp9kD2M8gf+7NZUfePW152FUrbVLj2gAmndlbI6oFRfXLe31k4OWgdb
|
||||||
|
aVpLgDuA2lgktJgAjyp3Ak4HzgWGm989gXTEijdi2WtwGh/ddW+/Bufg3qlAP8AF9gHfYNl7fR2z
|
||||||
|
vw32H3mg08hb7GD+efnKFzhPu6Fz0Dr9GAioB24DlgJEIyFpAjzuaQAw0RxnGCIiuy9R/sAjZY+O
|
||||||
|
X1/76dtTgJsRrYgGjbi0EmCdP7vfxuwb/+gG84eP027oErTOaCEJ64DLgG+OiQCP4IOBacBVQF7M
|
||||||
|
B5T1lltTOe+LObk9gZ8jlj4ZNAAbrfYZL+XMePnb4MnfnaKdxrEkbzMagKnAihYR4FH1bsAPgelA
|
||||||
|
bjOPhLDsv1R/8NwjFcumTwFmAR2TnLQXDvCPQO7Qxbk/fa8Xtv9OtM5Jso+ngB/B0dvASlD484EX
|
||||||
|
gAfjCO8q27do79JpD1csm34/cN8xCg9gAxc27N7yxM4fZwUbK3bcgWVvTbKP02PNIyYBHuEvBZYD
|
||||||
|
FxBPYyx75b4XZi46uOGlBcC18QhOEp3Rel7pA0PHHdr88lwse0MSz+YCnRMmwCP8xcAioFfcIZRa
|
||||||
|
X1dc8OD+d5+ZDVzeioJ74QOmly+ecm3djsK5KGtzgs9lAd0TJsBgABJN9UxggAqcxl+UPX75ROAH
|
||||||
|
x0l4L64v++24S92afT8DVZFAez+SZ8QnwBPQzCJBy61s/9Mld3YBmIPs2eMNC5jxxdzeOcq2H0Nc
|
||||||
|
aIs7ioazETeXgPSqqHrjiyu1E5oNdGkD4cNIQ+s5FUtvKsSyC+O01bFIikXAmESFUXZgefmSG04F
|
||||||
|
LmpD4cMYePCD5VcQql+CpMexcBDYG5cAj/qfk9DwSu2q/ey9NcB1yD47EZhc/vTUUiz7o2baVJrj
|
||||||
|
KESLqgIkuvqWb+3XCy/NAkZ6bjtAObIiXrfZyRxh0l2kokPE/VpzhO/7kJi+BimKpEVMI+/Q1tUj
|
||||||
|
lFKrteQj0VACVEX7w4pxLxH/rVHWe7qhdhhHBhl7gElIjj8SGGXOY5DE5G0ghISo9wKXAEWH+4Rf
|
||||||
|
IzHHDUjFJ4SE0qORQMyJMpcL6ku3FqFUNdGx04yXEAGhWI2PhNpX/+XHxUZALzKRIkc18CWS+d2D
|
||||||
|
rObTwGTgD4hbykeSlTfNs+XACmAbstLdge3Ac+bei8hqRmJw1euP1KOsL2JMdhtEzwajEVAPxOrI
|
||||||
|
86RVUrX6l43AwIh/0oEraNKKAUgc/jyiCd8CDwMfIaufDRQiW2IT8LmZ1wRz/jtiwHzALuCtKLM5
|
||||||
|
qfaTNd2UZX8W5b9KM1Z0MbwXhiHd3ANhKGX9u7b4nU4k7vrygGvM7z1IxWYQMB7YgBQ3/2kWoB/i
|
||||||
|
VaqAvxniLjBzW02TjTgsh1t3sAfwVZRxi0zf8QnwYD0x3EYTA9Y+t766OzEirBgY6GlfgRjJy5A6
|
||||||
|
3grgXfPfKCT8LgS2IPlImLz3EU2JRI52na+j3H8fcYNJEbANKGieAAVHWu9EYNPkGcLnUcBpwO+R
|
||||||
|
srYf0QqQ1W+PGMAxQF9kC62MOiVUpKU/gLEvsUpiR03eNGwE/tQccy1EOU0Gtrc5dwW+h2hEHbIt
|
||||||
|
RgPFwOtIVDrQCB8m5k3EHnihNTqy2vQhcbZzc6u3Fng55r9ag1j6WHF45Eo3GIEc5KXHlZ62E5CC
|
||||||
|
C8A4Q0oBYitGIIYVxGgGkT39WsR4XynL7ua51sAqM8fkCDBaUA88TiyPoHWm8gfLONIglQKbEfc3
|
||||||
|
CbjJCFsIzEf2OUiaXWPabjak3IZUnM5B9r0CbgWGIltyK+Ia84xwb9CkTSG7Y/bXaPp45vJJeAGb
|
||||||
|
K4vHq699BPzKEHGEsdPaOaV9/1EHarYXVNIUnS0CnkX2cXi/rzEkhVciDdnDf40yF2UEc8215bkO
|
||||||
|
46Dpf7/pNwCUdxh2TaXWjtclv2AWpFnEJGDnjA7h3OB5swq3H9HAdftkTZxn1WwvKKapTHYjosLR
|
||||||
|
Kkfeey1OX00/GokfwpXoTZnj7srCdcNF2iIzb+K9GWpWAwwJtcBDRsjLPDJkB/OHD0DUe6y52d8c
|
||||||
|
bQmtfO3W+jJ7jNJOox/ZTos52khGRVwXZhjcA8xEjFjTs1pfqPztC2lKak4EtnSZ8rsd2nUmmOt3
|
||||||
|
EA8Wd/UTIsDTUakh4Y3wfe2Exva4+639ZtATgZCy/c92On/ahWg3F3nTtACoSvQVecJBjOlwJ2Kp
|
||||||
|
VxkKegX7DpsALEOselvjtZ73Fu7WrjPNXD9FkouRVNnakLAbeTmyGAjpUMO0vHmbdnO0VT/eKOow
|
||||||
|
7PtPBnoOuR2tuyDB0eOAm8wHEknX7T02YTbwE9AZgR6nzfR3P/kxxPe2BUr92f0e6HbTc5fjOmOR
|
||||||
|
lPkeYF+yn8q06MWFGeQQ8BhwnXadvF7zt58F3I/sw+OJz/1d+83Jm190rnYapwNlwFzgXy3prMVv
|
||||||
|
bjypcwFwvQ6FgvkLK8tQ6m7EVrQ2XODN9KETZ/d6cPtoXOcuJLeYhfFOLflQqlU+kDABkx9ldVM2
|
||||||
|
9p4nr+55aMvqS5AUtm8rjFOCZS/NmfnK5rRTx96undB4pDI0C3i1pcK3GgGHSVAWaJ2tfP4J2nXq
|
||||||
|
KpbeXFa9Yfm5SAB1Jk1JTSJoBD4FVmWMmbnhpMkLzgZuRbs9kETtPuCDYxG+VQk4TIIgA7gRyx6p
|
||||||
|
LHtTbfG7GyuW3ZIWqvzyTCT3H0BTKBueQy1SvioBttsZ3bd1ueo3lelnTxoCTMF1BiEp8zPAQmDP
|
||||||
|
sQh+XAiIIMICvgPMQKnhyvLtQql1zqGqHXWfF1bWfFLghPbuzHTrq0OqXXrA7tC1Lm3QRU6w/+gM
|
||||||
|
X+fc3kpZI7TrDEe7WYaYVxE//yFJuro2JyCCCD8wDKkUjwb6opSLsvYrpeqQIkhQax1E60y07gja
|
||||||
|
QrLHIqSMvgpJmxP69u+/hoAIIhTyjv50RDPygZOQL8gUUo4vRQqhxcDH5rwfjm2fn3ACmiHFRvJ5
|
||||||
|
EJfaQCuqdwoppJBCCimkkEJz+A8yuCszfDFdCAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMy0wMi0w
|
||||||
|
NFQwOToyODoxNyswMDowMFBCTAkAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjMtMDItMDRUMDk6Mjg6
|
||||||
|
MTcrMDA6MDAhH/S1AAAAAElFTkSuQmCC" />
|
||||||
</svg>
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 4.1 KiB |
@@ -69,9 +69,6 @@
|
|||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
|
<el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>
|
<el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>
|
||||||
<el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>
|
|
||||||
<el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
|
<el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
@@ -171,7 +168,7 @@ const onHandleCommandClick = (path: string) => {
|
|||||||
})
|
})
|
||||||
.catch(() => {});
|
.catch(() => {});
|
||||||
} else if (path === 'wareHouse') {
|
} else if (path === 'wareHouse') {
|
||||||
window.open('https://gitee.com/lyt-top/vue-next-admin');
|
window.open('https://gitee.com/huge-dream/django-vue3-admin');
|
||||||
} else {
|
} else {
|
||||||
router.push(path);
|
router.push(path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,10 +76,10 @@ const delayShow = () => {
|
|||||||
};
|
};
|
||||||
// 页面加载时
|
// 页面加载时
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
delayShow();
|
// delayShow();
|
||||||
setTimeout(() => {
|
// setTimeout(() => {
|
||||||
state.btnTxt = t('message.upgrade.btnTwo');
|
// state.btnTxt = t('message.upgrade.btnTwo');
|
||||||
}, 200);
|
// }, 200);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ export const useThemeConfig = defineStore('themeConfig', {
|
|||||||
* 界面显示
|
* 界面显示
|
||||||
*/
|
*/
|
||||||
// 是否开启侧边栏 Logo
|
// 是否开启侧边栏 Logo
|
||||||
isShowLogo: false,
|
isShowLogo: true,
|
||||||
// 初始化变量,用于 el-scrollbar 的高度更新,请勿删除
|
// 初始化变量,用于 el-scrollbar 的高度更新,请勿删除
|
||||||
isShowLogoChange: false,
|
isShowLogoChange: false,
|
||||||
// 是否开启 Breadcrumb,强制经典、横向布局不显示
|
// 是否开启 Breadcrumb,强制经典、横向布局不显示
|
||||||
@@ -86,11 +86,11 @@ export const useThemeConfig = defineStore('themeConfig', {
|
|||||||
// 是否开启 Tagsview
|
// 是否开启 Tagsview
|
||||||
isTagsview: true,
|
isTagsview: true,
|
||||||
// 是否开启 Breadcrumb 图标
|
// 是否开启 Breadcrumb 图标
|
||||||
isBreadcrumbIcon: false,
|
isBreadcrumbIcon: true,
|
||||||
// 是否开启 Tagsview 图标
|
// 是否开启 Tagsview 图标
|
||||||
isTagsviewIcon: false,
|
isTagsviewIcon: true,
|
||||||
// 是否开启 TagsView 缓存
|
// 是否开启 TagsView 缓存
|
||||||
isCacheTagsView: false,
|
isCacheTagsView: true,
|
||||||
// 是否开启 TagsView 拖拽
|
// 是否开启 TagsView 拖拽
|
||||||
isSortableTagsView: true,
|
isSortableTagsView: true,
|
||||||
// 是否开启 TagsView 共用
|
// 是否开启 TagsView 共用
|
||||||
@@ -102,9 +102,9 @@ export const useThemeConfig = defineStore('themeConfig', {
|
|||||||
// 是否开启色弱模式
|
// 是否开启色弱模式
|
||||||
isInvert: false,
|
isInvert: false,
|
||||||
// 是否开启水印
|
// 是否开启水印
|
||||||
isWartermark: true,
|
isWartermark: false,
|
||||||
// 水印文案
|
// 水印文案
|
||||||
wartermarkText: 'vue-next-admin',
|
wartermarkText: '',
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 其它设置
|
* 其它设置
|
||||||
@@ -131,21 +131,21 @@ export const useThemeConfig = defineStore('themeConfig', {
|
|||||||
* 后端控制路由
|
* 后端控制路由
|
||||||
*/
|
*/
|
||||||
// 是否开启后端控制路由
|
// 是否开启后端控制路由
|
||||||
isRequestRoutes: false,
|
isRequestRoutes: true,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 全局网站标题 / 副标题
|
* 全局网站标题 / 副标题
|
||||||
*/
|
*/
|
||||||
// 网站主标题(菜单导航、浏览器当前网页标题)
|
// 网站主标题(菜单导航、浏览器当前网页标题)
|
||||||
globalTitle: 'vue-next-admin',
|
globalTitle: 'dvadmin',
|
||||||
// 网站副标题(登录页顶部文字)
|
// 网站副标题(登录页顶部文字)
|
||||||
globalViceTitle: 'vueNextAdmin',
|
globalViceTitle: 'dvadmin',
|
||||||
// 网站副标题(登录页顶部文字)
|
// 网站副标题(登录页顶部文字)
|
||||||
globalViceTitleMsg: '专注、免费、开源、维护、解疑',
|
globalViceTitleMsg: '企业级后台管理系统',
|
||||||
// 默认初始语言,可选值"<zh-cn|en|zh-tw>",默认 zh-cn
|
// 默认初始语言,可选值"<zh-cn|en|zh-tw>",默认 zh-cn
|
||||||
globalI18n: 'zh-cn',
|
globalI18n: 'zh-cn',
|
||||||
// 默认全局组件大小,可选值"<large|'default'|small>",默认 'large'
|
// 默认全局组件大小,可选值"<large|'default'|small>",默认 'large'
|
||||||
globalComponentSize: 'large',
|
globalComponentSize: 'default',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
|
|||||||
@@ -1,434 +0,0 @@
|
|||||||
.chart-scrollbar {
|
|
||||||
.chart-warp {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
.chart-warp-bottom {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
.big-data-down-left,
|
|
||||||
.big-data-down-right {
|
|
||||||
width: 30%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 0 7.5px 15px 15px;
|
|
||||||
width: 100%;
|
|
||||||
height: 33.33%;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: var(--el-color-white);
|
|
||||||
border: 1px solid var(--el-border-color-lighter);
|
|
||||||
border-radius: 4px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 15px;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
.flex-title {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
.flex-title-small {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.flex-content {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
.flex-content-overflow {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.big-data-down-left {
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
.sky {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.sky-left {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
.sky-center {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0 10px;
|
|
||||||
font {
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.span {
|
|
||||||
background: #22bc76;
|
|
||||||
border-radius: 2px;
|
|
||||||
padding: 0 5px;
|
|
||||||
color: var(--el-color-white);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sky-right {
|
|
||||||
span {
|
|
||||||
font-size: 30px;
|
|
||||||
}
|
|
||||||
font {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sky-dd {
|
|
||||||
.sky-dl {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 28px;
|
|
||||||
overflow: hidden;
|
|
||||||
div {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
i {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tip {
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.sky-dl-first {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.d-states {
|
|
||||||
display: flex;
|
|
||||||
.d-states-item {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
overflow: hidden;
|
|
||||||
i {
|
|
||||||
font-size: 20px;
|
|
||||||
height: 33px;
|
|
||||||
width: 33px;
|
|
||||||
line-height: 33px;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 100%;
|
|
||||||
flex-shrink: 1;
|
|
||||||
color: var(--el-color-white);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.i-bg1 {
|
|
||||||
background: #22bc76;
|
|
||||||
}
|
|
||||||
.i-bg2 {
|
|
||||||
background: #e2356d;
|
|
||||||
}
|
|
||||||
.i-bg3 {
|
|
||||||
background: #43bbef;
|
|
||||||
}
|
|
||||||
.d-states-flex {
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 0 10px 0;
|
|
||||||
.d-states-item-label {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
overflow: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
.d-states-item-value {
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 3px;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.d-btn {
|
|
||||||
margin-top: 5px;
|
|
||||||
.d-btn-item {
|
|
||||||
border: 1px solid var(--el-color-primary);
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
border-radius: 35px;
|
|
||||||
align-items: center;
|
|
||||||
padding: 5px;
|
|
||||||
margin-top: 15px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
.d-btn-item-left {
|
|
||||||
font-size: 20px;
|
|
||||||
border: 1px solid var(--el-color-primary);
|
|
||||||
width: 25px;
|
|
||||||
height: 25px;
|
|
||||||
line-height: 25px;
|
|
||||||
border-radius: 100%;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
.d-btn-item-center {
|
|
||||||
padding: 0 10px;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.d-btn-item-eight {
|
|
||||||
text-align: right;
|
|
||||||
padding-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.big-data-down-center {
|
|
||||||
width: 40%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
.big-data-down-center-one {
|
|
||||||
height: 66.67%;
|
|
||||||
padding: 0 7.5px 15px;
|
|
||||||
.big-data-down-center-one-content {
|
|
||||||
height: 100%;
|
|
||||||
background: var(--el-color-white);
|
|
||||||
padding: 15px;
|
|
||||||
border: 1px solid var(--el-border-color-lighter);
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.big-data-down-center-two {
|
|
||||||
padding: 0 7.5px 15px;
|
|
||||||
height: 33.33%;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: var(--el-color-white);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 15px;
|
|
||||||
border: 1px solid var(--el-border-color-lighter);
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
.flex-title {
|
|
||||||
margin-bottom: 15px;
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
.flex-title-small {
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.flex-content {
|
|
||||||
flex: 1;
|
|
||||||
font-size: 12px;
|
|
||||||
display: flex;
|
|
||||||
height: calc(100% - 30px);
|
|
||||||
.flex-content-left {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
width: 120px;
|
|
||||||
height: 100%;
|
|
||||||
.monitor-item {
|
|
||||||
width: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.monitor-wave {
|
|
||||||
cursor: pointer;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
position: relative;
|
|
||||||
background-color: var(--el-color-primary);
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
background: #f4f4f4;
|
|
||||||
animation: roateOne 10s linear infinite;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
&::before {
|
|
||||||
bottom: 10px;
|
|
||||||
border-radius: 60%;
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
bottom: 8px;
|
|
||||||
opacity: 0.7;
|
|
||||||
border-radius: 37%;
|
|
||||||
}
|
|
||||||
.monitor-z-index {
|
|
||||||
position: relative;
|
|
||||||
z-index: 2;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 100%;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes roateOne {
|
|
||||||
0% {
|
|
||||||
transform: translate(-50%, 0) rotateZ(0deg);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: translate(-50%, -2%) rotateZ(180deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: translate(-50%, 0%) rotateZ(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.monitor-active {
|
|
||||||
background-color: #22bc76;
|
|
||||||
.monitor-z-index {
|
|
||||||
color: #22bc76;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.flex-content-right {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.big-data-down-right {
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 0 15px 15px 7.5px;
|
|
||||||
.flex-title {
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
}
|
|
||||||
.flex-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
.task {
|
|
||||||
display: flex;
|
|
||||||
height: 45px;
|
|
||||||
.task-item {
|
|
||||||
flex: 1;
|
|
||||||
color: var(--el-color-white);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
.task-item-box {
|
|
||||||
position: relative;
|
|
||||||
width: 45px;
|
|
||||||
height: 45px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 100%;
|
|
||||||
z-index: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
box-shadow: 0 10px 12px 0 rgba(0, 0, 0, 0.3);
|
|
||||||
&::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
z-index: -2;
|
|
||||||
left: -50%;
|
|
||||||
top: -50%;
|
|
||||||
width: 200%;
|
|
||||||
height: 200%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: 50% 50%, 50% 50%;
|
|
||||||
background-position: 0 0, 100% 0, 100% 100%, 0 100%;
|
|
||||||
background-image: linear-gradient(#19d4ae, #19d4ae), linear-gradient(#5ab1ef, #5ab1ef), linear-gradient(#fa6e86, #fa6e86),
|
|
||||||
linear-gradient(#ffb980, #ffb980);
|
|
||||||
animation: rotate 2s linear infinite;
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
z-index: -1;
|
|
||||||
left: 1px;
|
|
||||||
top: 1px;
|
|
||||||
width: calc(100% - 2px);
|
|
||||||
height: calc(100% - 2px);
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
.task-item-value {
|
|
||||||
text-align: center;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.task-item-label {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.task1 {
|
|
||||||
&::after {
|
|
||||||
background: #5492be;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.task2 {
|
|
||||||
&::after {
|
|
||||||
background: #43a177;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.task3 {
|
|
||||||
&::after {
|
|
||||||
background: #a76077;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.task-first-item {
|
|
||||||
flex-direction: column;
|
|
||||||
text-align: center;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
.task-first {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.progress {
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex: 1;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-top: 15px;
|
|
||||||
.progress-item {
|
|
||||||
height: 33.33%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.progress-box {
|
|
||||||
flex: 1;
|
|
||||||
width: 100%;
|
|
||||||
margin-left: 10px;
|
|
||||||
:deep(.el-progress__text) {
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
font-size: 12px !important;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
:deep(.el-progress-bar__outer) {
|
|
||||||
background-color: rgba(0, 0, 0, 0.1) !important;
|
|
||||||
}
|
|
||||||
:deep(.el-progress-bar) {
|
|
||||||
margin-right: -22px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/**
|
|
||||||
* sky 天气
|
|
||||||
* @returns 返回模拟数据
|
|
||||||
*/
|
|
||||||
export const skyList = [
|
|
||||||
{
|
|
||||||
v1: '时间',
|
|
||||||
v2: '天气',
|
|
||||||
v3: '温度',
|
|
||||||
v5: '降水',
|
|
||||||
v7: '风力',
|
|
||||||
type: 'title',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
v1: '今天',
|
|
||||||
v2: 'ele-Sunny',
|
|
||||||
v3: '20°/26°',
|
|
||||||
v5: '50%',
|
|
||||||
v7: '13m/s',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
v1: '明天',
|
|
||||||
v2: 'ele-Lightning',
|
|
||||||
v3: '20°/26°',
|
|
||||||
v5: '50%',
|
|
||||||
v7: '13m/s',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前设置状态
|
|
||||||
* @returns 返回模拟数据
|
|
||||||
*/
|
|
||||||
export const dBtnList = [
|
|
||||||
{
|
|
||||||
v2: '阳光玫瑰种植',
|
|
||||||
v3: '126天',
|
|
||||||
v4: '设备在线',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 当前设备监测
|
|
||||||
* @returns 返回模拟数据
|
|
||||||
*/
|
|
||||||
export const chartData4List = [
|
|
||||||
{
|
|
||||||
label: '温度',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '光照',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '湿度',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '风力',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="big-data-up mb15">
|
|
||||||
<div class="up-left">
|
|
||||||
<i class="el-icon-time mr5"></i>
|
|
||||||
<span>{{ state.time.txt }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="up-center">
|
|
||||||
<span>智慧农业系统平台</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="chartHead">
|
|
||||||
import { reactive, onBeforeMount, onUnmounted } from 'vue';
|
|
||||||
import { formatDate } from '/@/utils/formatTime';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
time: {
|
|
||||||
txt: '',
|
|
||||||
fun: 0,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化时间
|
|
||||||
const initTime = () => {
|
|
||||||
state.time.txt = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS WWW QQQQ');
|
|
||||||
state.time.fun = window.setInterval(() => {
|
|
||||||
state.time.txt = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS WWW QQQQ');
|
|
||||||
}, 1000);
|
|
||||||
};
|
|
||||||
// 页面加载前
|
|
||||||
onBeforeMount(() => {
|
|
||||||
initTime();
|
|
||||||
});
|
|
||||||
// 页面卸载时
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.clearInterval(state.time.fun);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.big-data-up {
|
|
||||||
height: 55px;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 15px;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
.up-left {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
.up-center {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
font-size: 18px;
|
|
||||||
letter-spacing: 5px;
|
|
||||||
background-image: -webkit-linear-gradient(
|
|
||||||
left,
|
|
||||||
var(--el-color-primary),
|
|
||||||
var(--el-color-primary-light-3) 25%,
|
|
||||||
var(--el-color-primary) 50%,
|
|
||||||
var(--el-color-primary-light-3) 75%,
|
|
||||||
var(--el-color-primary)
|
|
||||||
);
|
|
||||||
-webkit-text-fill-color: transparent;
|
|
||||||
-webkit-background-clip: text;
|
|
||||||
background-clip: text;
|
|
||||||
background-size: 200% 100%;
|
|
||||||
-webkit-animation: masked-animation-data-v-b02d8052 4s linear infinite;
|
|
||||||
animation: masked-animation-data-v-b02d8052 4s linear infinite;
|
|
||||||
-webkit-box-reflect: below -2px -webkit-gradient(linear, left top, left bottom, from(transparent), to(hsla(0, 0%, 100%, 0.1)));
|
|
||||||
position: relative;
|
|
||||||
@keyframes masked-animation {
|
|
||||||
0% {
|
|
||||||
background-position: 0 0;
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
background-position: -100% 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
position: relative;
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
width: 250px;
|
|
||||||
position: absolute;
|
|
||||||
bottom: -15px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
border: 1px transparent solid;
|
|
||||||
border-image: linear-gradient(to right, var(--el-color-primary-light-9), var(--el-color-primary)) 1 10;
|
|
||||||
}
|
|
||||||
span {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,477 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="chart-scrollbar layout-padding">
|
|
||||||
<div class="chart-warp layout-padding-auto layout-padding-view">
|
|
||||||
<div class="chart-warp-top">
|
|
||||||
<ChartHead />
|
|
||||||
</div>
|
|
||||||
<div class="chart-warp-bottom">
|
|
||||||
<!-- 左边 -->
|
|
||||||
<div class="big-data-down-left">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">天气预报</div>
|
|
||||||
<div class="flex-content">
|
|
||||||
<div class="sky">
|
|
||||||
<SvgIcon name="ele-Sunny" class="sky-left" />
|
|
||||||
<div class="sky-center">
|
|
||||||
<div class="mb2">
|
|
||||||
<span>多云转晴</span>
|
|
||||||
<span>东南风</span>
|
|
||||||
<span class="span ml5">良</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sky-right">
|
|
||||||
<span>25</span>
|
|
||||||
<span>°C</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="sky-dd">
|
|
||||||
<div class="sky-dl" v-for="(v, k) in state.skyList" :key="k" :class="{ 'sky-dl-first': k === 1 }">
|
|
||||||
<div>{{ v.v1 }}</div>
|
|
||||||
<div v-if="v.type === 'title'">{{ v.v2 }}</div>
|
|
||||||
<div v-else>
|
|
||||||
<SvgIcon :name="v.v2" />
|
|
||||||
</div>
|
|
||||||
<div>{{ v.v3 }}</div>
|
|
||||||
<div class="tip">{{ v.v5 }}</div>
|
|
||||||
<div>{{ v.v7 }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">当前设备状态</div>
|
|
||||||
<div class="flex-content flex-content-overflow">
|
|
||||||
<div class="d-states">
|
|
||||||
<div class="d-states-item">
|
|
||||||
<SvgIcon name="ele-Odometer" class="i-bg1" />
|
|
||||||
<div class="d-states-flex">
|
|
||||||
<div class="d-states-item-label">园区设备数</div>
|
|
||||||
<div class="d-states-item-value">99</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-states-item">
|
|
||||||
<SvgIcon name="ele-FirstAidKit" class="i-bg2" />
|
|
||||||
<div class="d-states-flex">
|
|
||||||
<div class="d-states-item-label">预警设备数</div>
|
|
||||||
<div class="d-states-item-value">10</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-states-item">
|
|
||||||
<SvgIcon name="ele-VideoPlay" class="i-bg3" />
|
|
||||||
<div class="d-states-flex">
|
|
||||||
<div class="d-states-item-label">运行设备数</div>
|
|
||||||
<div class="d-states-item-value">20</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-btn">
|
|
||||||
<div class="d-btn-item" v-for="(v, k) in state.dBtnList" :key="k">
|
|
||||||
<i class="d-btn-item-left el-icon-money"></i>
|
|
||||||
<div class="d-btn-item-center">
|
|
||||||
<div>{{ v.v2 }}|{{ v.v3 }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="d-btn-item-eight">{{ v.v4 }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">近30天预警总数</div>
|
|
||||||
<div class="flex-content">
|
|
||||||
<div style="height: 100%" ref="chartsWarningRef"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 中间 -->
|
|
||||||
<div class="big-data-down-center">
|
|
||||||
<div class="big-data-down-center-one">
|
|
||||||
<div class="big-data-down-center-one-content">
|
|
||||||
<div style="height: 100%" ref="chartsCenterOneRef"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="big-data-down-center-two">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">
|
|
||||||
<span>当前设备监测</span>
|
|
||||||
<span class="flex-title-small">单位:次</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex-content">
|
|
||||||
<div class="flex-content-left">
|
|
||||||
<div class="monitor-item" v-for="(v, k) in state.chartData4List" :key="k">
|
|
||||||
<div class="monitor-wave">
|
|
||||||
<div class="monitor-z-index">
|
|
||||||
<div class="monitor-item-label">{{ v.label }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-content-right">
|
|
||||||
<div style="height: 100%" ref="chartsMonitorRef"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右边 -->
|
|
||||||
<div class="big-data-down-right">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">
|
|
||||||
<span>近7天产品追溯扫码统计</span>
|
|
||||||
<span class="flex-title-small">单位:次</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex-content">
|
|
||||||
<div style="height: 100%" ref="chartsSevenDaysRef"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">当前任务统计</div>
|
|
||||||
<div class="flex-content">
|
|
||||||
<div class="task">
|
|
||||||
<div class="task-item task-first-item">
|
|
||||||
<div class="task-item-value task-first">25</div>
|
|
||||||
<div class="task-item-label">待办任务</div>
|
|
||||||
</div>
|
|
||||||
<div class="task-item">
|
|
||||||
<div class="task-item-box task1">
|
|
||||||
<div class="task-item-value">12</div>
|
|
||||||
<div class="task-item-label">施肥</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="task-item">
|
|
||||||
<div class="task-item-box task2">
|
|
||||||
<div class="task-item-value">3</div>
|
|
||||||
<div class="task-item-label">施药</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="task-item">
|
|
||||||
<div class="task-item-box task3">
|
|
||||||
<div class="task-item-value">5</div>
|
|
||||||
<div class="task-item-label">农事</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="progress">
|
|
||||||
<div class="progress-item">
|
|
||||||
<span>施肥率</span>
|
|
||||||
<div class="progress-box">
|
|
||||||
<el-progress :percentage="70" color="#43bdf0"></el-progress>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="progress-item">
|
|
||||||
<span>施药率</span>
|
|
||||||
<div class="progress-box">
|
|
||||||
<el-progress :percentage="36" color="#43bdf0"></el-progress>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="progress-item">
|
|
||||||
<span>农事率</span>
|
|
||||||
<div class="progress-box">
|
|
||||||
<el-progress :percentage="91" color="#43bdf0"></el-progress>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="flex-title">
|
|
||||||
<span>近7天投入品记录</span>
|
|
||||||
<span class="flex-title-small">单位:件</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex-content">
|
|
||||||
<div style="height: 100%" ref="chartsInvestmentRef"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="chartIndex">
|
|
||||||
import { defineAsyncComponent, reactive, onMounted, watch, nextTick, onActivated, ref } from 'vue';
|
|
||||||
import * as echarts from 'echarts';
|
|
||||||
import 'echarts-wordcloud';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
|
||||||
import { skyList, dBtnList, chartData4List } from '/@/views/chart/chart';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const ChartHead = defineAsyncComponent(() => import('/@/views/chart/head.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const chartsCenterOneRef = ref();
|
|
||||||
const chartsSevenDaysRef = ref();
|
|
||||||
const chartsWarningRef = ref();
|
|
||||||
const chartsMonitorRef = ref();
|
|
||||||
const chartsInvestmentRef = ref();
|
|
||||||
const storesTagsViewRoutes = useTagsViewRoutes();
|
|
||||||
const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
|
|
||||||
const state = reactive({
|
|
||||||
skyList,
|
|
||||||
dBtnList,
|
|
||||||
chartData4List,
|
|
||||||
myCharts: [] as EmptyArrayType,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化中间图表1
|
|
||||||
const initChartsCenterOne = () => {
|
|
||||||
const myChart = echarts.init(chartsCenterOneRef.value);
|
|
||||||
const option = {
|
|
||||||
grid: {
|
|
||||||
top: 15,
|
|
||||||
right: 15,
|
|
||||||
bottom: 20,
|
|
||||||
left: 30,
|
|
||||||
},
|
|
||||||
tooltip: {},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'wordCloud',
|
|
||||||
sizeRange: [12, 40],
|
|
||||||
rotationRange: [0, 0],
|
|
||||||
rotationStep: 45,
|
|
||||||
gridSize: Math.random() * 20 + 5,
|
|
||||||
shape: 'circle',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
textStyle: {
|
|
||||||
fontFamily: 'sans-serif',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
color: function () {
|
|
||||||
return `rgb(${[Math.round(Math.random() * 160), Math.round(Math.random() * 160), Math.round(Math.random() * 160)].join(',')})`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{ name: 'vue-next-admin', value: 520 },
|
|
||||||
{ name: 'lyt', value: 520 },
|
|
||||||
{ name: 'next-admin', value: 500 },
|
|
||||||
{ name: '更名', value: 420 },
|
|
||||||
{ name: '智慧农业', value: 520 },
|
|
||||||
{ name: '男神', value: 2.64 },
|
|
||||||
{ name: '好身材', value: 4.03 },
|
|
||||||
{ name: '校草', value: 24.95 },
|
|
||||||
{ name: '酷', value: 4.04 },
|
|
||||||
{ name: '时尚', value: 5.27 },
|
|
||||||
{ name: '阳光活力', value: 5.8 },
|
|
||||||
{ name: '初恋', value: 3.09 },
|
|
||||||
{ name: '英俊潇洒', value: 24.71 },
|
|
||||||
{ name: '霸气', value: 6.33 },
|
|
||||||
{ name: '腼腆', value: 2.55 },
|
|
||||||
{ name: '蠢萌', value: 3.88 },
|
|
||||||
{ name: '青春', value: 8.04 },
|
|
||||||
{ name: '网红', value: 5.87 },
|
|
||||||
{ name: '萌', value: 6.97 },
|
|
||||||
{ name: '认真', value: 2.53 },
|
|
||||||
{ name: '古典', value: 2.49 },
|
|
||||||
{ name: '温柔', value: 3.91 },
|
|
||||||
{ name: '有个性', value: 3.25 },
|
|
||||||
{ name: '可爱', value: 9.93 },
|
|
||||||
{ name: '幽默诙谐', value: 3.65 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
state.myCharts.push(myChart);
|
|
||||||
};
|
|
||||||
// 初始化近7天产品追溯扫码统计
|
|
||||||
const initChartsSevenDays = () => {
|
|
||||||
const myChart = echarts.init(chartsSevenDaysRef.value);
|
|
||||||
const option = {
|
|
||||||
grid: {
|
|
||||||
top: 15,
|
|
||||||
right: 15,
|
|
||||||
bottom: 20,
|
|
||||||
left: 30,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
data: ['1天', '2天', '3天', '4天', '5天', '6天', '7天'],
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '邮件营销',
|
|
||||||
type: 'line',
|
|
||||||
stack: '总量',
|
|
||||||
data: [12, 32, 11, 34, 90, 23, 21],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '联盟广告',
|
|
||||||
type: 'line',
|
|
||||||
stack: '总量',
|
|
||||||
data: [22, 82, 91, 24, 90, 30, 30],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: '视频广告',
|
|
||||||
type: 'line',
|
|
||||||
stack: '总量',
|
|
||||||
data: [50, 32, 18, 14, 90, 30, 50],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
state.myCharts.push(myChart);
|
|
||||||
};
|
|
||||||
// 初始化近30天预警总数
|
|
||||||
const initChartsWarning = () => {
|
|
||||||
const myChart = echarts.init(chartsWarningRef.value);
|
|
||||||
const option = {
|
|
||||||
grid: {
|
|
||||||
top: 50,
|
|
||||||
right: 20,
|
|
||||||
bottom: 30,
|
|
||||||
left: 30,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: '面积模式',
|
|
||||||
type: 'pie',
|
|
||||||
radius: [20, 50],
|
|
||||||
center: ['50%', '50%'],
|
|
||||||
roseType: 'area',
|
|
||||||
itemStyle: {
|
|
||||||
borderRadius: 8,
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{ value: 40, name: '监测设备预警' },
|
|
||||||
{ value: 38, name: '天气预警' },
|
|
||||||
{ value: 32, name: '任务预警' },
|
|
||||||
{ value: 30, name: '病虫害预警' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
state.myCharts.push(myChart);
|
|
||||||
};
|
|
||||||
// 初始化当前设备监测
|
|
||||||
const initChartsMonitor = () => {
|
|
||||||
const myChart = echarts.init(chartsMonitorRef.value);
|
|
||||||
const option = {
|
|
||||||
grid: {
|
|
||||||
top: 15,
|
|
||||||
right: 15,
|
|
||||||
bottom: 20,
|
|
||||||
left: 30,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
data: ['02:00', '04:00', '06:00', '08:00', '10:00', '12:00', '14:00'],
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
itemStyle: {
|
|
||||||
color: '#289df5',
|
|
||||||
borderColor: '#289df5',
|
|
||||||
areaStyle: {
|
|
||||||
type: 'default',
|
|
||||||
opacity: 0.1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: [20, 32, 31, 34, 12, 13, 20],
|
|
||||||
type: 'line',
|
|
||||||
areaStyle: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
state.myCharts.push(myChart);
|
|
||||||
};
|
|
||||||
// 初始化近7天投入品记录
|
|
||||||
const initChartsInvestment = () => {
|
|
||||||
const myChart = echarts.init(chartsInvestmentRef.value);
|
|
||||||
const option = {
|
|
||||||
grid: {
|
|
||||||
top: 15,
|
|
||||||
right: 15,
|
|
||||||
bottom: 20,
|
|
||||||
left: 30,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: ['1天', '2天', '3天', '4天', '5天', '6天', '7天'],
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
data: [10, 20, 15, 80, 70, 11, 30],
|
|
||||||
type: 'bar',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
state.myCharts.push(myChart);
|
|
||||||
};
|
|
||||||
// 批量设置 echarts resize
|
|
||||||
const initEchartsResizeFun = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
for (let i = 0; i < state.myCharts.length; i++) {
|
|
||||||
state.myCharts[i].resize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 批量设置 echarts resize
|
|
||||||
const initEchartsResize = () => {
|
|
||||||
window.addEventListener('resize', initEchartsResizeFun);
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initChartsCenterOne();
|
|
||||||
initChartsSevenDays();
|
|
||||||
initChartsWarning();
|
|
||||||
initChartsMonitor();
|
|
||||||
initChartsInvestment();
|
|
||||||
initEchartsResize();
|
|
||||||
});
|
|
||||||
// 由于页面缓存原因,keep-alive
|
|
||||||
onActivated(() => {
|
|
||||||
initEchartsResizeFun();
|
|
||||||
});
|
|
||||||
// 监听 pinia 中的 tagsview 开启全屏变化,重新 resize 图表,防止不出现/大小不变等
|
|
||||||
watch(
|
|
||||||
() => isTagsViewCurrenFull.value,
|
|
||||||
() => {
|
|
||||||
initEchartsResizeFun();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import './chart.scss';
|
|
||||||
</style>
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="error layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="error-flex">
|
|
||||||
<div class="left">
|
|
||||||
<div class="left-item">
|
|
||||||
<div class="left-item-animation left-item-num">401</div>
|
|
||||||
<div class="left-item-animation left-item-title">{{ $t('message.noAccess.accessTitle') }}</div>
|
|
||||||
<div class="left-item-animation left-item-msg">{{ $t('message.noAccess.accessMsg') }}</div>
|
|
||||||
<div class="left-item-animation left-item-btn">
|
|
||||||
<el-button type="primary" size="default" round @click="onSetAuth">{{ $t('message.noAccess.accessBtn') }}</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<img
|
|
||||||
src="https://img-blog.csdnimg.cn/3333f265772a4fa89287993500ecbf96.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_16,color_FFFFFF,t_70,g_se,x_16"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="noPower">
|
|
||||||
import { Session } from '/@/utils/storage';
|
|
||||||
|
|
||||||
const onSetAuth = () => {
|
|
||||||
// https://gitee.com/lyt-top/vue-next-admin/issues/I5C3JS
|
|
||||||
// 清除缓存/token等
|
|
||||||
Session.clear();
|
|
||||||
// 使用 reload 时,不需要调用 resetRoute() 重置路由
|
|
||||||
window.location.reload();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.error {
|
|
||||||
height: 100%;
|
|
||||||
.error-flex {
|
|
||||||
margin: auto;
|
|
||||||
display: flex;
|
|
||||||
height: 350px;
|
|
||||||
width: 900px;
|
|
||||||
.left {
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
.left-item {
|
|
||||||
.left-item-animation {
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-num;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
}
|
|
||||||
.left-item-num {
|
|
||||||
color: var(--el-color-info);
|
|
||||||
font-size: 55px;
|
|
||||||
}
|
|
||||||
.left-item-title {
|
|
||||||
font-size: 20px;
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
margin: 15px 0 5px 0;
|
|
||||||
animation-delay: 0.1s;
|
|
||||||
}
|
|
||||||
.left-item-msg {
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
font-size: 12px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
.left-item-btn {
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.right {
|
|
||||||
flex: 1;
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-img;
|
|
||||||
animation-duration: 2s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="error layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="error-flex">
|
|
||||||
<div class="left">
|
|
||||||
<div class="left-item">
|
|
||||||
<div class="left-item-animation left-item-num">404</div>
|
|
||||||
<div class="left-item-animation left-item-title">{{ $t('message.notFound.foundTitle') }}</div>
|
|
||||||
<div class="left-item-animation left-item-msg">{{ $t('message.notFound.foundMsg') }}</div>
|
|
||||||
<div class="left-item-animation left-item-btn">
|
|
||||||
<el-button type="primary" size="default" round @click="onGoHome">{{ $t('message.notFound.foundBtn') }}</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<img
|
|
||||||
src="https://img-blog.csdnimg.cn/9eb1d85a417f4ed1ba7107f149ce3da1.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAbHl0LXRvcA==,size_16,color_FFFFFF,t_70,g_se,x_16"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="notFound">
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
// 返回首页
|
|
||||||
const onGoHome = () => {
|
|
||||||
router.push('/');
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.error {
|
|
||||||
height: 100%;
|
|
||||||
.error-flex {
|
|
||||||
margin: auto;
|
|
||||||
display: flex;
|
|
||||||
height: 350px;
|
|
||||||
width: 900px;
|
|
||||||
.left {
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
.left-item {
|
|
||||||
.left-item-animation {
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-num;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
}
|
|
||||||
.left-item-num {
|
|
||||||
color: var(--el-color-info);
|
|
||||||
font-size: 55px;
|
|
||||||
}
|
|
||||||
.left-item-title {
|
|
||||||
font-size: 20px;
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
margin: 15px 0 5px 0;
|
|
||||||
animation-delay: 0.1s;
|
|
||||||
}
|
|
||||||
.left-item-msg {
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
font-size: 12px;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
.left-item-btn {
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.right {
|
|
||||||
flex: 1;
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-img;
|
|
||||||
animation-duration: 2s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-card shadow="hover" header="复制剪切演示">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `vue-clipboard3`,项目地址:https://github.com/JamieCurnow/vue-clipboard3`"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<el-input placeholder="请输入内容" v-model="state.copyVal">
|
|
||||||
<template #append>
|
|
||||||
<el-button @click="copyText(state.copyVal)">复制链接</el-button>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<el-input placeholder="先点击上方 `复制链接` 按钮,然后 `Ctrl + V` 进行粘贴! " v-model="state.shearVal" class="mt15"> </el-input>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funClipboard">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import commonFunction from '/@/utils/commonFunction';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const { copyText } = commonFunction();
|
|
||||||
const state = reactive({
|
|
||||||
copyVal: 'https://gitee.com/lyt-top/vue-next-admin',
|
|
||||||
shearVal: '',
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-card shadow="hover" header="数字滚动演示">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `countup.js`,项目地址:https://github.com/inorganik/countUp.js"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :sm="6" class="mb15" v-for="(v, k) in state.topCardItemList" :key="k">
|
|
||||||
<div class="countup-card-item countup-card-item-box" :style="{ background: `var(${v.color})` }">
|
|
||||||
<div class="countup-card-item-flex" ref="topCardItemRefs">
|
|
||||||
<div class="countup-card-item-title pb3">{{ v.title }}</div>
|
|
||||||
<div class="countup-card-item-title-num pb6"></div>
|
|
||||||
<div class="countup-card-item-tip pb3">{{ v.tip }}</div>
|
|
||||||
<div class="countup-card-item-tip-num"></div>
|
|
||||||
</div>
|
|
||||||
<i :class="v.icon" :style="{ color: v.iconColor }"></i>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default" @click="refreshCurrent">
|
|
||||||
<el-icon>
|
|
||||||
<ele-RefreshRight />
|
|
||||||
</el-icon>
|
|
||||||
重置/刷新数值
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funCountup">
|
|
||||||
import { reactive, onMounted, nextTick, ref } from 'vue';
|
|
||||||
import { CountUp } from 'countup.js';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const topCardItemRefs = ref<RefType[]>([]);
|
|
||||||
const state = reactive({
|
|
||||||
topCardItemList: [
|
|
||||||
{
|
|
||||||
title: '今日访问人数',
|
|
||||||
titleNum: '123',
|
|
||||||
tip: '在场人数',
|
|
||||||
tipNum: '911',
|
|
||||||
color: '--el-color-primary',
|
|
||||||
iconColor: '#ffcb47',
|
|
||||||
icon: 'iconfont icon-jinridaiban',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '实验室总数',
|
|
||||||
titleNum: '123',
|
|
||||||
tip: '使用中',
|
|
||||||
tipNum: '611',
|
|
||||||
color: '--el-color-success',
|
|
||||||
iconColor: '#70cf41',
|
|
||||||
icon: 'iconfont icon-AIshiyanshi',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '申请人数(月)',
|
|
||||||
titleNum: '123',
|
|
||||||
tip: '通过人数',
|
|
||||||
tipNum: '911',
|
|
||||||
color: '--el-color-warning',
|
|
||||||
iconColor: '#dfae64',
|
|
||||||
icon: 'iconfont icon-shenqingkaiban',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '销售情况',
|
|
||||||
titleNum: '123',
|
|
||||||
tip: '销售数',
|
|
||||||
tipNum: '911',
|
|
||||||
color: '--el-color-danger',
|
|
||||||
iconColor: '#e56565',
|
|
||||||
icon: 'iconfont icon-ditu',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化数字滚动
|
|
||||||
const initNumCountUp = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
topCardItemRefs.value.forEach((v: HTMLDivElement) => {
|
|
||||||
new CountUp(v.querySelector('.countup-card-item-title-num') as HTMLDivElement, Math.random() * 10000).start();
|
|
||||||
new CountUp(v.querySelector('.countup-card-item-tip-num') as HTMLDivElement, Math.random() * 1000).start();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 重置/刷新数值
|
|
||||||
const refreshCurrent = () => {
|
|
||||||
initNumCountUp();
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initNumCountUp();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.countup-card-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 103px;
|
|
||||||
background: var(--el-text-color-secondary);
|
|
||||||
border-radius: 4px;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.countup-card-item-box {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
&:hover {
|
|
||||||
i {
|
|
||||||
right: 0px !important;
|
|
||||||
bottom: 0px !important;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
position: absolute;
|
|
||||||
right: -10px;
|
|
||||||
bottom: -10px;
|
|
||||||
font-size: 70px;
|
|
||||||
transform: rotate(-30deg);
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
.countup-card-item-flex {
|
|
||||||
padding: 0 20px;
|
|
||||||
color: var(--el-color-white);
|
|
||||||
.countup-card-item-title,
|
|
||||||
.countup-card-item-tip {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.countup-card-item-title-num {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
.countup-card-item-tip-num {
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="croppers-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="cropper 图片裁剪">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `cropperjs`,项目地址:https://github.com/fengyuanchen/cropperjs"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<div class="cropper-img-warp">
|
|
||||||
<div class="mb15 mt15">
|
|
||||||
<img class="cropper-img" :src="state.cropperImg" />
|
|
||||||
</div>
|
|
||||||
<el-button type="primary" size="default" @click="onCropperDialogOpen">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Crop />
|
|
||||||
</el-icon>
|
|
||||||
更换头像
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
<CropperDialog ref="cropperDialogRef" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funCropper">
|
|
||||||
import { defineAsyncComponent, ref, reactive } from 'vue';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const CropperDialog = defineAsyncComponent(() => import('/@/components/cropper/index.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const cropperDialogRef = ref();
|
|
||||||
const state = reactive({
|
|
||||||
cropperImg: 'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 打开裁剪弹窗
|
|
||||||
const onCropperDialogOpen = () => {
|
|
||||||
cropperDialogRef.value.openDialog(state.cropperImg);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.croppers-container {
|
|
||||||
.cropper-img-warp {
|
|
||||||
text-align: center;
|
|
||||||
.cropper-img {
|
|
||||||
margin: auto;
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div ref="echartsMapRef" style="height: 100%"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funEchartsMap">
|
|
||||||
import { reactive, onMounted, ref } from 'vue';
|
|
||||||
import * as echarts from 'echarts';
|
|
||||||
import 'echarts/extension/bmap/bmap';
|
|
||||||
import { echartsMapList, echartsMapData } from './mock';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const echartsMapRef = ref<RefType>('');
|
|
||||||
const state = reactive({
|
|
||||||
echartsMap: '' as unknown,
|
|
||||||
echartsMapList,
|
|
||||||
echartsMapData,
|
|
||||||
});
|
|
||||||
|
|
||||||
// echartsMap 将坐标信息和对应物理量的值合在一起
|
|
||||||
const convertData = (data: EmptyObjectType[]) => {
|
|
||||||
let res = [];
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
|
||||||
let geoCoord = state.echartsMapData[data[i].name];
|
|
||||||
if (geoCoord) {
|
|
||||||
res.push({
|
|
||||||
name: data[i].name,
|
|
||||||
value: geoCoord.concat(data[i].value),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
// 初始化 echartsMap
|
|
||||||
const initEchartsMap = () => {
|
|
||||||
const myChart = echarts.init(echartsMapRef.value);
|
|
||||||
const option = {
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
},
|
|
||||||
color: ['#9a60b4', '#ea7ccc'],
|
|
||||||
bmap: {
|
|
||||||
center: [104.114129, 37.550339],
|
|
||||||
zoom: 5,
|
|
||||||
roam: true,
|
|
||||||
mapStyle: {},
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: 'pm2.5',
|
|
||||||
type: 'scatter',
|
|
||||||
coordinateSystem: 'bmap',
|
|
||||||
data: convertData(state.echartsMapList),
|
|
||||||
symbolSize: function (val: any) {
|
|
||||||
return val[2] / 10;
|
|
||||||
},
|
|
||||||
encode: {
|
|
||||||
value: 2,
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
formatter: '{b}',
|
|
||||||
position: 'right',
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
label: {
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Top 5',
|
|
||||||
type: 'effectScatter',
|
|
||||||
coordinateSystem: 'bmap',
|
|
||||||
data: convertData(
|
|
||||||
state.echartsMapList
|
|
||||||
.sort(function (a: any, b: any) {
|
|
||||||
return b.value - a.value;
|
|
||||||
})
|
|
||||||
.slice(0, 6)
|
|
||||||
),
|
|
||||||
symbolSize: function (val: any) {
|
|
||||||
return val[2] / 10;
|
|
||||||
},
|
|
||||||
encode: {
|
|
||||||
value: 2,
|
|
||||||
},
|
|
||||||
showEffectOn: 'render',
|
|
||||||
rippleEffect: {
|
|
||||||
brushType: 'stroke',
|
|
||||||
},
|
|
||||||
hoverAnimation: true,
|
|
||||||
label: {
|
|
||||||
formatter: '{b}',
|
|
||||||
position: 'right',
|
|
||||||
show: true,
|
|
||||||
},
|
|
||||||
itemStyle: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowColor: '#333',
|
|
||||||
},
|
|
||||||
zlevel: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
window.addEventListener('resize', () => {
|
|
||||||
myChart.resize();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initEchartsMap();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,387 +0,0 @@
|
|||||||
// 地图模拟数据
|
|
||||||
export const echartsMapList = [
|
|
||||||
{ name: '海门', value: 9 },
|
|
||||||
{ name: '鄂尔多斯', value: 12 },
|
|
||||||
{ name: '招远', value: 12 },
|
|
||||||
{ name: '舟山', value: 12 },
|
|
||||||
{ name: '齐齐哈尔', value: 14 },
|
|
||||||
{ name: '盐城', value: 15 },
|
|
||||||
{ name: '赤峰', value: 16 },
|
|
||||||
{ name: '青岛', value: 18 },
|
|
||||||
{ name: '乳山', value: 18 },
|
|
||||||
{ name: '金昌', value: 19 },
|
|
||||||
{ name: '泉州', value: 21 },
|
|
||||||
{ name: '莱西', value: 21 },
|
|
||||||
{ name: '日照', value: 21 },
|
|
||||||
{ name: '胶南', value: 22 },
|
|
||||||
{ name: '南通', value: 23 },
|
|
||||||
{ name: '拉萨', value: 24 },
|
|
||||||
{ name: '云浮', value: 24 },
|
|
||||||
{ name: '梅州', value: 25 },
|
|
||||||
{ name: '文登', value: 25 },
|
|
||||||
{ name: '上海', value: 25 },
|
|
||||||
{ name: '攀枝花', value: 25 },
|
|
||||||
{ name: '威海', value: 25 },
|
|
||||||
{ name: '承德', value: 25 },
|
|
||||||
{ name: '厦门', value: 26 },
|
|
||||||
{ name: '汕尾', value: 26 },
|
|
||||||
{ name: '潮州', value: 26 },
|
|
||||||
{ name: '丹东', value: 27 },
|
|
||||||
{ name: '太仓', value: 27 },
|
|
||||||
{ name: '曲靖', value: 27 },
|
|
||||||
{ name: '烟台', value: 28 },
|
|
||||||
{ name: '福州', value: 29 },
|
|
||||||
{ name: '瓦房店', value: 30 },
|
|
||||||
{ name: '即墨', value: 30 },
|
|
||||||
{ name: '抚顺', value: 31 },
|
|
||||||
{ name: '玉溪', value: 31 },
|
|
||||||
{ name: '张家口', value: 31 },
|
|
||||||
{ name: '阳泉', value: 31 },
|
|
||||||
{ name: '莱州', value: 32 },
|
|
||||||
{ name: '湖州', value: 32 },
|
|
||||||
{ name: '汕头', value: 32 },
|
|
||||||
{ name: '昆山', value: 33 },
|
|
||||||
{ name: '宁波', value: 33 },
|
|
||||||
{ name: '湛江', value: 33 },
|
|
||||||
{ name: '揭阳', value: 34 },
|
|
||||||
{ name: '荣成', value: 34 },
|
|
||||||
{ name: '连云港', value: 35 },
|
|
||||||
{ name: '葫芦岛', value: 35 },
|
|
||||||
{ name: '常熟', value: 36 },
|
|
||||||
{ name: '东莞', value: 36 },
|
|
||||||
{ name: '河源', value: 36 },
|
|
||||||
{ name: '淮安', value: 36 },
|
|
||||||
{ name: '泰州', value: 36 },
|
|
||||||
{ name: '南宁', value: 37 },
|
|
||||||
{ name: '营口', value: 37 },
|
|
||||||
{ name: '惠州', value: 37 },
|
|
||||||
{ name: '江阴', value: 37 },
|
|
||||||
{ name: '蓬莱', value: 37 },
|
|
||||||
{ name: '韶关', value: 38 },
|
|
||||||
{ name: '嘉峪关', value: 38 },
|
|
||||||
{ name: '广州', value: 38 },
|
|
||||||
{ name: '延安', value: 38 },
|
|
||||||
{ name: '太原', value: 39 },
|
|
||||||
{ name: '清远', value: 39 },
|
|
||||||
{ name: '中山', value: 39 },
|
|
||||||
{ name: '昆明', value: 39 },
|
|
||||||
{ name: '寿光', value: 40 },
|
|
||||||
{ name: '盘锦', value: 40 },
|
|
||||||
{ name: '长治', value: 41 },
|
|
||||||
{ name: '深圳', value: 360 },
|
|
||||||
{ name: '珠海', value: 42 },
|
|
||||||
{ name: '宿迁', value: 43 },
|
|
||||||
{ name: '咸阳', value: 43 },
|
|
||||||
{ name: '铜川', value: 44 },
|
|
||||||
{ name: '平度', value: 44 },
|
|
||||||
{ name: '佛山', value: 44 },
|
|
||||||
{ name: '海口', value: 44 },
|
|
||||||
{ name: '江门', value: 45 },
|
|
||||||
{ name: '章丘', value: 45 },
|
|
||||||
{ name: '肇庆', value: 46 },
|
|
||||||
{ name: '大连', value: 47 },
|
|
||||||
{ name: '临汾', value: 47 },
|
|
||||||
{ name: '吴江', value: 47 },
|
|
||||||
{ name: '石嘴山', value: 49 },
|
|
||||||
{ name: '沈阳', value: 50 },
|
|
||||||
{ name: '苏州', value: 50 },
|
|
||||||
{ name: '茂名', value: 50 },
|
|
||||||
{ name: '嘉兴', value: 51 },
|
|
||||||
{ name: '长春', value: 51 },
|
|
||||||
{ name: '胶州', value: 52 },
|
|
||||||
{ name: '银川', value: 52 },
|
|
||||||
{ name: '张家港', value: 52 },
|
|
||||||
{ name: '三门峡', value: 53 },
|
|
||||||
{ name: '锦州', value: 54 },
|
|
||||||
{ name: '南昌', value: 54 },
|
|
||||||
{ name: '柳州', value: 54 },
|
|
||||||
{ name: '三亚', value: 54 },
|
|
||||||
{ name: '自贡', value: 56 },
|
|
||||||
{ name: '吉林', value: 56 },
|
|
||||||
{ name: '阳江', value: 57 },
|
|
||||||
{ name: '泸州', value: 57 },
|
|
||||||
{ name: '西宁', value: 57 },
|
|
||||||
{ name: '宜宾', value: 58 },
|
|
||||||
{ name: '呼和浩特', value: 58 },
|
|
||||||
{ name: '成都', value: 58 },
|
|
||||||
{ name: '大同', value: 58 },
|
|
||||||
{ name: '镇江', value: 59 },
|
|
||||||
{ name: '桂林', value: 59 },
|
|
||||||
{ name: '张家界', value: 59 },
|
|
||||||
{ name: '宜兴', value: 59 },
|
|
||||||
{ name: '北海', value: 60 },
|
|
||||||
{ name: '西安', value: 61 },
|
|
||||||
{ name: '金坛', value: 62 },
|
|
||||||
{ name: '东营', value: 62 },
|
|
||||||
{ name: '牡丹江', value: 63 },
|
|
||||||
{ name: '遵义', value: 63 },
|
|
||||||
{ name: '绍兴', value: 63 },
|
|
||||||
{ name: '扬州', value: 64 },
|
|
||||||
{ name: '常州', value: 64 },
|
|
||||||
{ name: '潍坊', value: 65 },
|
|
||||||
{ name: '重庆', value: 66 },
|
|
||||||
{ name: '台州', value: 67 },
|
|
||||||
{ name: '南京', value: 67 },
|
|
||||||
{ name: '滨州', value: 70 },
|
|
||||||
{ name: '贵阳', value: 71 },
|
|
||||||
{ name: '无锡', value: 71 },
|
|
||||||
{ name: '本溪', value: 71 },
|
|
||||||
{ name: '克拉玛依', value: 72 },
|
|
||||||
{ name: '渭南', value: 72 },
|
|
||||||
{ name: '马鞍山', value: 72 },
|
|
||||||
{ name: '宝鸡', value: 72 },
|
|
||||||
{ name: '焦作', value: 75 },
|
|
||||||
{ name: '句容', value: 75 },
|
|
||||||
{ name: '北京', value: 79 },
|
|
||||||
{ name: '徐州', value: 79 },
|
|
||||||
{ name: '衡水', value: 80 },
|
|
||||||
{ name: '包头', value: 80 },
|
|
||||||
{ name: '绵阳', value: 80 },
|
|
||||||
{ name: '乌鲁木齐', value: 84 },
|
|
||||||
{ name: '枣庄', value: 84 },
|
|
||||||
{ name: '杭州', value: 84 },
|
|
||||||
{ name: '淄博', value: 85 },
|
|
||||||
{ name: '鞍山', value: 86 },
|
|
||||||
{ name: '溧阳', value: 86 },
|
|
||||||
{ name: '库尔勒', value: 86 },
|
|
||||||
{ name: '安阳', value: 90 },
|
|
||||||
{ name: '开封', value: 90 },
|
|
||||||
{ name: '济南', value: 92 },
|
|
||||||
{ name: '德阳', value: 93 },
|
|
||||||
{ name: '温州', value: 95 },
|
|
||||||
{ name: '九江', value: 96 },
|
|
||||||
{ name: '邯郸', value: 98 },
|
|
||||||
{ name: '临安', value: 99 },
|
|
||||||
{ name: '兰州', value: 99 },
|
|
||||||
{ name: '沧州', value: 100 },
|
|
||||||
{ name: '临沂', value: 103 },
|
|
||||||
{ name: '南充', value: 104 },
|
|
||||||
{ name: '天津', value: 105 },
|
|
||||||
{ name: '富阳', value: 106 },
|
|
||||||
{ name: '泰安', value: 112 },
|
|
||||||
{ name: '诸暨', value: 112 },
|
|
||||||
{ name: '郑州', value: 113 },
|
|
||||||
{ name: '哈尔滨', value: 114 },
|
|
||||||
{ name: '聊城', value: 116 },
|
|
||||||
{ name: '芜湖', value: 117 },
|
|
||||||
{ name: '唐山', value: 119 },
|
|
||||||
{ name: '平顶山', value: 119 },
|
|
||||||
{ name: '邢台', value: 119 },
|
|
||||||
{ name: '德州', value: 120 },
|
|
||||||
{ name: '济宁', value: 120 },
|
|
||||||
{ name: '荆州', value: 127 },
|
|
||||||
{ name: '宜昌', value: 130 },
|
|
||||||
{ name: '义乌', value: 132 },
|
|
||||||
{ name: '丽水', value: 133 },
|
|
||||||
{ name: '洛阳', value: 134 },
|
|
||||||
{ name: '秦皇岛', value: 136 },
|
|
||||||
{ name: '株洲', value: 143 },
|
|
||||||
{ name: '石家庄', value: 147 },
|
|
||||||
{ name: '莱芜', value: 148 },
|
|
||||||
{ name: '常德', value: 152 },
|
|
||||||
{ name: '保定', value: 153 },
|
|
||||||
{ name: '湘潭', value: 154 },
|
|
||||||
{ name: '金华', value: 157 },
|
|
||||||
{ name: '岳阳', value: 169 },
|
|
||||||
{ name: '长沙', value: 175 },
|
|
||||||
{ name: '衢州', value: 177 },
|
|
||||||
{ name: '廊坊', value: 93 },
|
|
||||||
{ name: '菏泽', value: 194 },
|
|
||||||
{ name: '合肥', value: 229 },
|
|
||||||
{ name: '武汉', value: 273 },
|
|
||||||
{ name: '大庆', value: 279 },
|
|
||||||
];
|
|
||||||
|
|
||||||
// 地图经纬度数据
|
|
||||||
export const echartsMapData = {
|
|
||||||
海门: [121.15, 31.89],
|
|
||||||
鄂尔多斯: [109.781327, 39.608266],
|
|
||||||
招远: [120.38, 37.35],
|
|
||||||
舟山: [122.207216, 29.985295],
|
|
||||||
齐齐哈尔: [123.97, 47.33],
|
|
||||||
盐城: [120.13, 33.38],
|
|
||||||
赤峰: [118.87, 42.28],
|
|
||||||
青岛: [120.33, 36.07],
|
|
||||||
乳山: [121.52, 36.89],
|
|
||||||
金昌: [102.188043, 38.520089],
|
|
||||||
泉州: [118.58, 24.93],
|
|
||||||
莱西: [120.53, 36.86],
|
|
||||||
日照: [119.46, 35.42],
|
|
||||||
胶南: [119.97, 35.88],
|
|
||||||
南通: [121.05, 32.08],
|
|
||||||
拉萨: [91.11, 29.97],
|
|
||||||
云浮: [112.02, 22.93],
|
|
||||||
梅州: [116.1, 24.55],
|
|
||||||
文登: [122.05, 37.2],
|
|
||||||
上海: [121.48, 31.22],
|
|
||||||
攀枝花: [101.718637, 26.582347],
|
|
||||||
威海: [122.1, 37.5],
|
|
||||||
承德: [117.93, 40.97],
|
|
||||||
厦门: [118.1, 24.46],
|
|
||||||
汕尾: [115.375279, 22.786211],
|
|
||||||
潮州: [116.63, 23.68],
|
|
||||||
丹东: [124.37, 40.13],
|
|
||||||
太仓: [121.1, 31.45],
|
|
||||||
曲靖: [103.79, 25.51],
|
|
||||||
烟台: [121.39, 37.52],
|
|
||||||
福州: [119.3, 26.08],
|
|
||||||
瓦房店: [121.979603, 39.627114],
|
|
||||||
即墨: [120.45, 36.38],
|
|
||||||
抚顺: [123.97, 41.97],
|
|
||||||
玉溪: [102.52, 24.35],
|
|
||||||
张家口: [114.87, 40.82],
|
|
||||||
阳泉: [113.57, 37.85],
|
|
||||||
莱州: [119.942327, 37.177017],
|
|
||||||
湖州: [120.1, 30.86],
|
|
||||||
汕头: [116.69, 23.39],
|
|
||||||
昆山: [120.95, 31.39],
|
|
||||||
宁波: [121.56, 29.86],
|
|
||||||
湛江: [110.359377, 21.270708],
|
|
||||||
揭阳: [116.35, 23.55],
|
|
||||||
荣成: [122.41, 37.16],
|
|
||||||
连云港: [119.16, 34.59],
|
|
||||||
葫芦岛: [120.836932, 40.711052],
|
|
||||||
常熟: [120.74, 31.64],
|
|
||||||
东莞: [113.75, 23.04],
|
|
||||||
河源: [114.68, 23.73],
|
|
||||||
淮安: [119.15, 33.5],
|
|
||||||
泰州: [119.9, 32.49],
|
|
||||||
南宁: [108.33, 22.84],
|
|
||||||
营口: [122.18, 40.65],
|
|
||||||
惠州: [114.4, 23.09],
|
|
||||||
江阴: [120.26, 31.91],
|
|
||||||
蓬莱: [120.75, 37.8],
|
|
||||||
韶关: [113.62, 24.84],
|
|
||||||
嘉峪关: [98.289152, 39.77313],
|
|
||||||
广州: [113.23, 23.16],
|
|
||||||
延安: [109.47, 36.6],
|
|
||||||
太原: [112.53, 37.87],
|
|
||||||
清远: [113.01, 23.7],
|
|
||||||
中山: [113.38, 22.52],
|
|
||||||
昆明: [102.73, 25.04],
|
|
||||||
寿光: [118.73, 36.86],
|
|
||||||
盘锦: [122.070714, 41.119997],
|
|
||||||
长治: [113.08, 36.18],
|
|
||||||
深圳: [114.07, 22.62],
|
|
||||||
珠海: [113.52, 22.3],
|
|
||||||
宿迁: [118.3, 33.96],
|
|
||||||
咸阳: [108.72, 34.36],
|
|
||||||
铜川: [109.11, 35.09],
|
|
||||||
平度: [119.97, 36.77],
|
|
||||||
佛山: [113.11, 23.05],
|
|
||||||
海口: [110.35, 20.02],
|
|
||||||
江门: [113.06, 22.61],
|
|
||||||
章丘: [117.53, 36.72],
|
|
||||||
肇庆: [112.44, 23.05],
|
|
||||||
大连: [121.62, 38.92],
|
|
||||||
临汾: [111.5, 36.08],
|
|
||||||
吴江: [120.63, 31.16],
|
|
||||||
石嘴山: [106.39, 39.04],
|
|
||||||
沈阳: [123.38, 41.8],
|
|
||||||
苏州: [120.62, 31.32],
|
|
||||||
茂名: [110.88, 21.68],
|
|
||||||
嘉兴: [120.76, 30.77],
|
|
||||||
长春: [125.35, 43.88],
|
|
||||||
胶州: [120.03336, 36.264622],
|
|
||||||
银川: [106.27, 38.47],
|
|
||||||
张家港: [120.555821, 31.875428],
|
|
||||||
三门峡: [111.19, 34.76],
|
|
||||||
锦州: [121.15, 41.13],
|
|
||||||
南昌: [115.89, 28.68],
|
|
||||||
柳州: [109.4, 24.33],
|
|
||||||
三亚: [109.511909, 18.252847],
|
|
||||||
自贡: [104.778442, 29.33903],
|
|
||||||
吉林: [126.57, 43.87],
|
|
||||||
阳江: [111.95, 21.85],
|
|
||||||
泸州: [105.39, 28.91],
|
|
||||||
西宁: [101.74, 36.56],
|
|
||||||
宜宾: [104.56, 29.77],
|
|
||||||
呼和浩特: [111.65, 40.82],
|
|
||||||
成都: [104.06, 30.67],
|
|
||||||
大同: [113.3, 40.12],
|
|
||||||
镇江: [119.44, 32.2],
|
|
||||||
桂林: [110.28, 25.29],
|
|
||||||
张家界: [110.479191, 29.117096],
|
|
||||||
宜兴: [119.82, 31.36],
|
|
||||||
北海: [109.12, 21.49],
|
|
||||||
西安: [108.95, 34.27],
|
|
||||||
金坛: [119.56, 31.74],
|
|
||||||
东营: [118.49, 37.46],
|
|
||||||
牡丹江: [129.58, 44.6],
|
|
||||||
遵义: [106.9, 27.7],
|
|
||||||
绍兴: [120.58, 30.01],
|
|
||||||
扬州: [119.42, 32.39],
|
|
||||||
常州: [119.95, 31.79],
|
|
||||||
潍坊: [119.1, 36.62],
|
|
||||||
重庆: [106.54, 29.59],
|
|
||||||
台州: [121.420757, 28.656386],
|
|
||||||
南京: [118.78, 32.04],
|
|
||||||
滨州: [118.03, 37.36],
|
|
||||||
贵阳: [106.71, 26.57],
|
|
||||||
无锡: [120.29, 31.59],
|
|
||||||
本溪: [123.73, 41.3],
|
|
||||||
克拉玛依: [84.77, 45.59],
|
|
||||||
渭南: [109.5, 34.52],
|
|
||||||
马鞍山: [118.48, 31.56],
|
|
||||||
宝鸡: [107.15, 34.38],
|
|
||||||
焦作: [113.21, 35.24],
|
|
||||||
句容: [119.16, 31.95],
|
|
||||||
北京: [116.46, 39.92],
|
|
||||||
徐州: [117.2, 34.26],
|
|
||||||
衡水: [115.72, 37.72],
|
|
||||||
包头: [110, 40.58],
|
|
||||||
绵阳: [104.73, 31.48],
|
|
||||||
乌鲁木齐: [87.68, 43.77],
|
|
||||||
枣庄: [117.57, 34.86],
|
|
||||||
杭州: [120.19, 30.26],
|
|
||||||
淄博: [118.05, 36.78],
|
|
||||||
鞍山: [122.85, 41.12],
|
|
||||||
溧阳: [119.48, 31.43],
|
|
||||||
库尔勒: [86.06, 41.68],
|
|
||||||
安阳: [114.35, 36.1],
|
|
||||||
开封: [114.35, 34.79],
|
|
||||||
济南: [117, 36.65],
|
|
||||||
德阳: [104.37, 31.13],
|
|
||||||
温州: [120.65, 28.01],
|
|
||||||
九江: [115.97, 29.71],
|
|
||||||
邯郸: [114.47, 36.6],
|
|
||||||
临安: [119.72, 30.23],
|
|
||||||
兰州: [103.73, 36.03],
|
|
||||||
沧州: [116.83, 38.33],
|
|
||||||
临沂: [118.35, 35.05],
|
|
||||||
南充: [106.110698, 30.837793],
|
|
||||||
天津: [117.2, 39.13],
|
|
||||||
富阳: [119.95, 30.07],
|
|
||||||
泰安: [117.13, 36.18],
|
|
||||||
诸暨: [120.23, 29.71],
|
|
||||||
郑州: [113.65, 34.76],
|
|
||||||
哈尔滨: [126.63, 45.75],
|
|
||||||
聊城: [115.97, 36.45],
|
|
||||||
芜湖: [118.38, 31.33],
|
|
||||||
唐山: [118.02, 39.63],
|
|
||||||
平顶山: [113.29, 33.75],
|
|
||||||
邢台: [114.48, 37.05],
|
|
||||||
德州: [116.29, 37.45],
|
|
||||||
济宁: [116.59, 35.38],
|
|
||||||
荆州: [112.239741, 30.335165],
|
|
||||||
宜昌: [111.3, 30.7],
|
|
||||||
义乌: [120.06, 29.32],
|
|
||||||
丽水: [119.92, 28.45],
|
|
||||||
洛阳: [112.44, 34.7],
|
|
||||||
秦皇岛: [119.57, 39.95],
|
|
||||||
株洲: [113.16, 27.83],
|
|
||||||
石家庄: [114.48, 38.03],
|
|
||||||
莱芜: [117.67, 36.19],
|
|
||||||
常德: [111.69, 29.05],
|
|
||||||
保定: [115.48, 38.85],
|
|
||||||
湘潭: [112.91, 27.87],
|
|
||||||
金华: [119.64, 29.12],
|
|
||||||
岳阳: [113.09, 29.37],
|
|
||||||
长沙: [113, 28.21],
|
|
||||||
衢州: [118.88, 28.97],
|
|
||||||
廊坊: [116.7, 39.53],
|
|
||||||
菏泽: [115.480656, 35.23375],
|
|
||||||
合肥: [117.27, 31.86],
|
|
||||||
武汉: [114.31, 30.52],
|
|
||||||
大庆: [125.03, 46.58],
|
|
||||||
};
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="grid-layout-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="vue-grid-layout 拖拽布局演示">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `vue-grid-layout`,项目地址:https://github.com/jbaysolutions/vue-grid-layout"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<grid-layout
|
|
||||||
v-model:layout="state.layouts"
|
|
||||||
:col-num="12"
|
|
||||||
:row-height="30"
|
|
||||||
:is-draggable="true"
|
|
||||||
:is-resizable="true"
|
|
||||||
:is-mirrored="false"
|
|
||||||
:vertical-compact="true"
|
|
||||||
:margin="[10, 10]"
|
|
||||||
:use-css-transforms="true"
|
|
||||||
>
|
|
||||||
<grid-item v-for="item in state.layouts" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i" :key="item.i">
|
|
||||||
<div class="w100 h100 flex">
|
|
||||||
<span class="flex-margin font14">{{ item.i }}</span>
|
|
||||||
</div>
|
|
||||||
</grid-item>
|
|
||||||
</grid-layout>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funGridLayout">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
layouts: [
|
|
||||||
{ x: 0, y: 0, w: 2, h: 2, i: '0' },
|
|
||||||
{ x: 2, y: 0, w: 2, h: 4, i: '1' },
|
|
||||||
{ x: 4, y: 0, w: 2, h: 5, i: '2' },
|
|
||||||
{ x: 6, y: 0, w: 2, h: 3, i: '3' },
|
|
||||||
{ x: 8, y: 0, w: 2, h: 3, i: '4' },
|
|
||||||
{ x: 10, y: 0, w: 2, h: 3, i: '5' },
|
|
||||||
{ x: 0, y: 5, w: 2, h: 5, i: '6' },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.grid-layout-container {
|
|
||||||
.vue-grid-item {
|
|
||||||
background: var(--el-color-primary);
|
|
||||||
color: var(--el-color-white);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div ref="printRef" class="layout-pd">
|
|
||||||
<el-card shadow="hover" header="打印演示">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `print-js`,项目地址:https://github.com/crabbly/Print.js。请在打印弹窗 `更多设置` 中开启 `背景图形。`"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<el-button @click="onPrintJs" size="default" type="primary">
|
|
||||||
<SvgIcon name="iconfont icon-dayin" />
|
|
||||||
点击打印演示
|
|
||||||
</el-button>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funPrintJs">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import printJs from 'print-js';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const printRef = ref();
|
|
||||||
|
|
||||||
// 打印点击
|
|
||||||
const onPrintJs = () => {
|
|
||||||
printJs({
|
|
||||||
printable: printRef.value,
|
|
||||||
type: 'html',
|
|
||||||
css: ['//at.alicdn.com/t/c/font_2298093_rnp72ifj3ba.css', '//unpkg.com/element-plus/dist/index.css'],
|
|
||||||
scanStyles: false,
|
|
||||||
style: `@media print{.mb15{margin-bottom:15px;}.el-button--small i.iconfont{font-size: 12px !important;margin-right: 5px;}}`,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="qrcode-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="qrcodejs2 二维码生成">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `qrcodejs2`,项目地址:https://github.com/davidshimjs/qrcodejs"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<div class="qrcode-img-warp">
|
|
||||||
<div class="mb30 mt30 qrcode-img">
|
|
||||||
<div class="qrcode" ref="qrcodeRef"></div>
|
|
||||||
</div>
|
|
||||||
<el-button type="primary" size="default" @click="onInitQrcode">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Refresh />
|
|
||||||
</el-icon>
|
|
||||||
重新生成
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funQrcode">
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
import QRCode from 'qrcodejs2-fixes';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const qrcodeRef = ref();
|
|
||||||
|
|
||||||
// 初始化生成二维码
|
|
||||||
const initQrcode = () => {
|
|
||||||
new QRCode(qrcodeRef.value, {
|
|
||||||
text: `https://lyt-top.gitee.io/vue-next-admin-preview/#/login?t=${new Date().getTime()}`,
|
|
||||||
width: 125,
|
|
||||||
height: 125,
|
|
||||||
colorDark: '#000000',
|
|
||||||
colorLight: '#ffffff',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 重新生成
|
|
||||||
const onInitQrcode = () => {
|
|
||||||
qrcodeRef.value.innerHTML = '';
|
|
||||||
initQrcode();
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initQrcode();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.qrcode-container {
|
|
||||||
.qrcode-img-warp {
|
|
||||||
text-align: center;
|
|
||||||
.qrcode-img {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 125px;
|
|
||||||
.qrcode {
|
|
||||||
margin: auto;
|
|
||||||
width: 125px;
|
|
||||||
height: 125px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="splitpanes-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="splitpanes 窗格拆分器">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `splitpanes`,项目地址:https://github.com/antoniandre/splitpanes"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<splitpanes class="default-theme" @resize="paneSize = $event[0].size" style="height: 500px">
|
|
||||||
<pane :size="32"> 1 </pane>
|
|
||||||
<pane :size="36">
|
|
||||||
<splitpanes class="default-theme" :horizontal="true">
|
|
||||||
<pane :size="100"> 2 </pane>
|
|
||||||
<pane :size="100"> 3 </pane>
|
|
||||||
</splitpanes>
|
|
||||||
</pane>
|
|
||||||
<pane :size="32"> 4 </pane>
|
|
||||||
</splitpanes>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funSplitpanes">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { Splitpanes, Pane } from 'splitpanes';
|
|
||||||
import 'splitpanes/dist/splitpanes.css';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const paneSize = ref(50);
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.splitpanes__pane {
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
position: relative;
|
|
||||||
font-size: 70px;
|
|
||||||
color: var(--el-color-primary-light-5);
|
|
||||||
border: 1px solid var(--el-border-color-lighter);
|
|
||||||
background-color: var(--el-color-primary) !important;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="fun-tagsview layout-pd">
|
|
||||||
<NoticeBar
|
|
||||||
text="已删除非当前页 tagsView 演示,后续有时间可以再加回来!,tagsview 支持多标签(参数不同)、单标签共用(参数不同)"
|
|
||||||
background="#ecf5ff"
|
|
||||||
color="#409eff"
|
|
||||||
/>
|
|
||||||
<el-card shadow="hover" header="tagsView 当前页演示" class="mt15">
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default" @click="refreshCurrentTagsView">
|
|
||||||
<el-icon>
|
|
||||||
<ele-RefreshRight />
|
|
||||||
</el-icon>
|
|
||||||
刷新当前页
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default" @click="closeCurrentTagsView">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Close />
|
|
||||||
</el-icon>
|
|
||||||
关闭当前页
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="warning" size="default" @click="closeOtherTagsView">
|
|
||||||
<el-icon>
|
|
||||||
<ele-CircleClose />
|
|
||||||
</el-icon>
|
|
||||||
关闭其它
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default" @click="closeAllTagsView">
|
|
||||||
<el-icon>
|
|
||||||
<ele-FolderDelete />
|
|
||||||
</el-icon>
|
|
||||||
全部关闭
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default" @click="openCurrenFullscreen">
|
|
||||||
<el-icon>
|
|
||||||
<ele-FullScreen />
|
|
||||||
</el-icon>
|
|
||||||
当前页全屏
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funTagsView">
|
|
||||||
import { defineAsyncComponent } from 'vue';
|
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import mittBus from '/@/utils/mitt';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const NoticeBar = defineAsyncComponent(() => import('/@/components/noticeBar/index.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
// 0 刷新当前,1 关闭当前,2 关闭其它,3 关闭全部 4 当前页全屏
|
|
||||||
// 1、刷新当前 tagsView
|
|
||||||
const refreshCurrentTagsView = () => {
|
|
||||||
mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 0, ...route }));
|
|
||||||
};
|
|
||||||
// 2、关闭当前 tagsView
|
|
||||||
const closeCurrentTagsView = () => {
|
|
||||||
mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 1, ...route }));
|
|
||||||
};
|
|
||||||
// 3、关闭其它 tagsView
|
|
||||||
const closeOtherTagsView = () => {
|
|
||||||
mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 2, ...route }));
|
|
||||||
};
|
|
||||||
// 4、关闭全部 tagsView
|
|
||||||
const closeAllTagsView = () => {
|
|
||||||
mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 3, ...route }));
|
|
||||||
};
|
|
||||||
// 5、开启当前页面全屏
|
|
||||||
const openCurrenFullscreen = () => {
|
|
||||||
mittBus.emit('onCurrentContextmenuClick', Object.assign({}, { contextMenuClickId: 4, ...route }));
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.fun-tagsview {
|
|
||||||
.fun-tagsview-from-item {
|
|
||||||
:deep(.el-form-item__content) {
|
|
||||||
margin-left: 0 !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="editor-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="wangeditor富文本编辑器">
|
|
||||||
<el-alert
|
|
||||||
title="感谢优秀的 `wangeditor`,项目地址:https://github.com/wangeditor-team/wangEditor"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mb15"
|
|
||||||
></el-alert>
|
|
||||||
<Editor v-model:get-html="state.editor.htmlVal" v-model:get-text="state.editor.textVal" :disable="state.editor.disable" />
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="funWangEditor">
|
|
||||||
import { defineAsyncComponent, reactive } from 'vue';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const Editor = defineAsyncComponent(() => import('/@/components/editor/index.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
editor: {
|
|
||||||
htmlVal:
|
|
||||||
'<p><span style="color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); font-size: 14px;">胡歌,1982年9月20日出生于上海市徐汇区,中国内地影视男演员、流行乐歌手,</span><a href="https://baike.baidu.com/item/%E6%B0%91%E7%9B%9F/1971441?fromModule=lemma_inlink" target="_blank" style="text-indent: 28px; text-align: start;">民盟</a><span style="color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); font-size: 14px;">盟员</span><span style="color: rgb(51, 102, 204); background-color: rgb(255, 255, 255); font-size: 12px;"><sup> [1]</sup></span><a href="" target="" style="text-indent: 28px; text-align: start;"> </a><span style="color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); font-size: 14px;"> ,毕业于</span><a href="https://baike.baidu.com/item/%E4%B8%8A%E6%B5%B7%E6%88%8F%E5%89%A7%E5%AD%A6%E9%99%A2/1736818?fromModule=lemma_inlink" target="_blank" style="text-indent: 28px; text-align: start;">上海戏剧学院</a><span style="color: rgb(51, 51, 51); background-color: rgb(255, 255, 255); font-size: 14px;">表演系。</span></p>',
|
|
||||||
textVal: '胡歌,1982年9月20日出生于上海市徐汇区,中国内地影视男演员、流行乐歌手,民盟盟员 [1] ,毕业于上海戏剧学院表演系。',
|
|
||||||
disable: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,30 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-alert
|
|
||||||
title="温馨提示:1、此页面无法模拟后端控制路由,因为 `gitee` 上所请求的 `json` 菜单数据线上会出现跨域的情况(json地址:
|
|
||||||
https://gitee.com/lyt-top/vue-next-admin-images/raw/master/menu/adminMenu.json)。2、本地接口请求文件位置:`/src/api/menu/index.ts`。
|
|
||||||
3、拉取代码后本地请求查看后端控制页面路由效果:`/src/store/modules/themeConfig.ts`中开启(isRequestRoutes 为 true,则开启后端控制路由)。
|
|
||||||
4、此页面效果只作为演示使用,若出现不可逆转的bug,请尝试 `F5` 刷新页面。5、默认启用的是 `前端控制路由`。"
|
|
||||||
type="warning"
|
|
||||||
:closable="false"
|
|
||||||
></el-alert>
|
|
||||||
<el-button type="primary" size="default" class="mt15" @click="onGoToFrontEndPage">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Position />
|
|
||||||
</el-icon>
|
|
||||||
立即前往前端控制路由
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="limitsBackEndEndPage">
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
// 立即前往前端控制路由
|
|
||||||
const onGoToFrontEndPage = () => {
|
|
||||||
router.push('/limits/frontEnd/page');
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,379 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<LimitsFrontEndPage style="padding: 0 !important" />
|
|
||||||
<!-- 演示1:组件方式 -->
|
|
||||||
<el-card shadow="hover" header="演示1:组件方式" class="mt15">
|
|
||||||
<el-row class="mb10" style="color: #808080">单个权限验证(:value="xxx"):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<Auth :value="'btn.add'">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auth>
|
|
||||||
<Auth :value="'btn.edit'">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auth>
|
|
||||||
<Auth :value="'btn.del'">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auth>
|
|
||||||
<Auth :value="'btn.link'">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Link />
|
|
||||||
</el-icon>
|
|
||||||
跳转
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auth>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row class="mb10 mt10" style="color: #808080">多个权限验证,满足一个则显示(:value="[xxx,xxx]"):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<Auths :value="['btn.addsss', 'btn.edit', 'btn.delsss', 'btn.linksss']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auths>
|
|
||||||
<Auths :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auths>
|
|
||||||
<Auths :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auths>
|
|
||||||
<Auths :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Link />
|
|
||||||
</el-icon>
|
|
||||||
跳转
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Auths>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row class="mb10 mt10" style="color: #808080">多个权限验证,全部满足则显示(:value="[xxx,xxx]"):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<AuthAll :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</AuthAll>
|
|
||||||
<AuthAll :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</AuthAll>
|
|
||||||
<AuthAll :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</AuthAll>
|
|
||||||
<AuthAll :value="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Link />
|
|
||||||
</el-icon>
|
|
||||||
跳转
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</AuthAll>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 演示2:指令方式 -->
|
|
||||||
<el-card shadow="hover" header="演示2:指令方式(页面初始化时执行)" class="mt15">
|
|
||||||
<el-row class="mb10" style="color: #808080">单个权限验证(v-auth="xxx"):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item" v-auth="'btn.add'">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auth="'btn.edit'">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auth="'btn.del'">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auth="'btn.link'">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Link />
|
|
||||||
</el-icon>
|
|
||||||
跳转
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row class="mb10 mt10" style="color: #808080">多个权限验证,满足一个则显示(v-auths="[xxx,xxx]"):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item" v-auths="['btn.addsss', 'btn.edit', 'btn.delsss', 'btn.linksss']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auths="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auths="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auths="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Link />
|
|
||||||
</el-icon>
|
|
||||||
跳转
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-row class="mb10 mt10" style="color: #808080">多个权限验证,全部满足则显示(v-auth-all="[xxx,xxx]"):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item" v-auth-all="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auth-all="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auth-all="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item" v-auth-all="['btn.add', 'btn.edit', 'btn.del', 'btn.link']">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Link />
|
|
||||||
</el-icon>
|
|
||||||
跳转
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<!-- 演示3:函数方式 -->
|
|
||||||
<el-card shadow="hover" header="演示3:函数方式(点击按钮查看有无权限,用于判断)" class="mt15">
|
|
||||||
<el-row class="mb10" style="color: #808080">auth('xxx')、auths(['xxx','xxx'])、authAll(['xxx','xxx']):</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default" @click="onAuthClick">
|
|
||||||
<el-icon>
|
|
||||||
<ele-DocumentAdd />
|
|
||||||
</el-icon>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default" @click="onAuthsClick">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Edit />
|
|
||||||
</el-icon>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default" @click="onAuthAllClick">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="limitsFrontEndBtn">
|
|
||||||
import { defineAsyncComponent } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import { auth, auths, authAll } from '/@/utils/authFunction';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const LimitsFrontEndPage = defineAsyncComponent(() => import('/@/views/limits/frontEnd/page/index.vue'));
|
|
||||||
const Auth = defineAsyncComponent(() => import('/@/components/auth/auth.vue'));
|
|
||||||
const Auths = defineAsyncComponent(() => import('/@/components/auth/auths.vue'));
|
|
||||||
const AuthAll = defineAsyncComponent(() => import('/@/components/auth/authAll.vue'));
|
|
||||||
|
|
||||||
// 单个权限验证
|
|
||||||
const onAuthClick = () => {
|
|
||||||
if (!auth('btn.add')) ElMessage.error('抱歉,您没有权限!');
|
|
||||||
else ElMessage.success('恭喜,您有权限!');
|
|
||||||
};
|
|
||||||
// 多个权限验证,满足一个则为 true
|
|
||||||
const onAuthsClick = () => {
|
|
||||||
if (!auths(['btn.add', 'btn.edit', 'btn.del', 'btn.link'])) ElMessage.error('抱歉,您没有权限!');
|
|
||||||
else ElMessage.success('恭喜,您有权限!');
|
|
||||||
};
|
|
||||||
// 多个权限验证,全部满足则为 true
|
|
||||||
const onAuthAllClick = () => {
|
|
||||||
if (!authAll(['btn.add', 'btn.edit', 'btn.del', 'btn.link'])) ElMessage.error('抱歉,您没有权限!');
|
|
||||||
else ElMessage.success('恭喜,您有权限!');
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.flex-warp {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-content: flex-start;
|
|
||||||
margin: 0 -5px;
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 5px;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-alert
|
|
||||||
title="温馨提示:此权限页面代码及效果只作为演示使用,若出现不可逆转的bug,请尝试 `F5` 刷新页面。若实际项目中非要实现此用户权限切换功能,
|
|
||||||
请在切换方法 `onRadioChange` 最后面添加刷新代码 `window.location.reload()`。 请注意:按钮权限页面中的演示2(指令模式)、演示3(函数模式)
|
|
||||||
切换用户时无法动态演示,想要动态演示,请按 `F5` 或者添加 `window.location.reload()`。"
|
|
||||||
type="warning"
|
|
||||||
:closable="false"
|
|
||||||
></el-alert>
|
|
||||||
<el-alert
|
|
||||||
:title="`当前用户页面权限:[${userInfos.roles}],当前用户按钮权限:[${userInfos.authBtnList}]`"
|
|
||||||
type="success"
|
|
||||||
:closable="false"
|
|
||||||
class="mt15"
|
|
||||||
></el-alert>
|
|
||||||
<el-card shadow="hover" header="切换用户演示,前端控制不同用户显示不同页面、按钮权限" class="mt15">
|
|
||||||
<el-radio-group v-model="userAuth" size="default" @change="onRadioChange">
|
|
||||||
<el-radio-button label="admin"></el-radio-button>
|
|
||||||
<el-radio-button label="common"></el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="limitsFrontEndPage">
|
|
||||||
import { onMounted, ref } from 'vue';
|
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { useUserInfo } from '/@/stores/userInfo';
|
|
||||||
import { frontEndsResetRoute, setAddRoute, setFilterMenuAndCacheTagsViewRoutes } from '/@/router/frontEnd';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const storesUserInfo = useUserInfo();
|
|
||||||
const { userInfos } = storeToRefs(storesUserInfo);
|
|
||||||
const userAuth = ref('');
|
|
||||||
|
|
||||||
// 初始化用户权限
|
|
||||||
const initUserAuth = () => {
|
|
||||||
userAuth.value = userInfos.value.roles[0];
|
|
||||||
};
|
|
||||||
// 用户权限改变时
|
|
||||||
const onRadioChange = async () => {
|
|
||||||
// 模拟数据
|
|
||||||
frontEndsResetRoute();
|
|
||||||
Cookies.set('userName', userAuth.value);
|
|
||||||
// 模拟切换不同权限用户
|
|
||||||
await storesUserInfo.setUserInfos();
|
|
||||||
await setAddRoute();
|
|
||||||
setFilterMenuAndCacheTagsViewRoutes();
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initUserAuth();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,174 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-form size="large" class="login-content-form">
|
|
||||||
<el-form-item class="login-animation1">
|
|
||||||
<el-input text :placeholder="$t('message.account.accountPlaceholder1')" v-model="state.ruleForm.userName" clearable autocomplete="off">
|
|
||||||
<template #prefix>
|
|
||||||
<el-icon class="el-input__icon"><ele-User /></el-icon>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="login-animation2">
|
|
||||||
<el-input
|
|
||||||
:type="state.isShowPassword ? 'text' : 'password'"
|
|
||||||
:placeholder="$t('message.account.accountPlaceholder2')"
|
|
||||||
v-model="state.ruleForm.password"
|
|
||||||
autocomplete="off"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<el-icon class="el-input__icon"><ele-Unlock /></el-icon>
|
|
||||||
</template>
|
|
||||||
<template #suffix>
|
|
||||||
<i
|
|
||||||
class="iconfont el-input__icon login-content-password"
|
|
||||||
:class="state.isShowPassword ? 'icon-yincangmima' : 'icon-xianshimima'"
|
|
||||||
@click="state.isShowPassword = !state.isShowPassword"
|
|
||||||
>
|
|
||||||
</i>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="login-animation3">
|
|
||||||
<el-col :span="15">
|
|
||||||
<el-input
|
|
||||||
text
|
|
||||||
maxlength="4"
|
|
||||||
:placeholder="$t('message.account.accountPlaceholder3')"
|
|
||||||
v-model="state.ruleForm.code"
|
|
||||||
clearable
|
|
||||||
autocomplete="off"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<el-icon class="el-input__icon"><ele-Position /></el-icon>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1"></el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-button class="login-content-code" v-waves>1234</el-button>
|
|
||||||
</el-col>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="login-animation4">
|
|
||||||
<el-button type="primary" class="login-content-submit" round v-waves @click="onSignIn" :loading="state.loading.signIn">
|
|
||||||
<span>{{ $t('message.account.accountBtnText') }}</span>
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="loginAccount">
|
|
||||||
import { reactive, computed } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
import Cookies from 'js-cookie';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
|
||||||
import { initFrontEndControlRoutes } from '/@/router/frontEnd';
|
|
||||||
import { initBackEndControlRoutes } from '/@/router/backEnd';
|
|
||||||
import { Session } from '/@/utils/storage';
|
|
||||||
import { formatAxis } from '/@/utils/formatTime';
|
|
||||||
import { NextLoading } from '/@/utils/loading';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const { t } = useI18n();
|
|
||||||
const storesThemeConfig = useThemeConfig();
|
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
const state = reactive({
|
|
||||||
isShowPassword: false,
|
|
||||||
ruleForm: {
|
|
||||||
userName: 'admin',
|
|
||||||
password: '123456',
|
|
||||||
code: '1234',
|
|
||||||
},
|
|
||||||
loading: {
|
|
||||||
signIn: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 时间获取
|
|
||||||
const currentTime = computed(() => {
|
|
||||||
return formatAxis(new Date());
|
|
||||||
});
|
|
||||||
// 登录
|
|
||||||
const onSignIn = async () => {
|
|
||||||
state.loading.signIn = true;
|
|
||||||
// 存储 token 到浏览器缓存
|
|
||||||
Session.set('token', Math.random().toString(36).substr(0));
|
|
||||||
// 模拟数据,对接接口时,记得删除多余代码及对应依赖的引入。用于 `/src/stores/userInfo.ts` 中不同用户登录判断(模拟数据)
|
|
||||||
Cookies.set('userName', state.ruleForm.userName);
|
|
||||||
if (!themeConfig.value.isRequestRoutes) {
|
|
||||||
// 前端控制路由,2、请注意执行顺序
|
|
||||||
const isNoPower = await initFrontEndControlRoutes();
|
|
||||||
signInSuccess(isNoPower);
|
|
||||||
} else {
|
|
||||||
// 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由
|
|
||||||
// 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/"
|
|
||||||
const isNoPower = await initBackEndControlRoutes();
|
|
||||||
// 执行完 initBackEndControlRoutes,再执行 signInSuccess
|
|
||||||
signInSuccess(isNoPower);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 登录成功后的跳转
|
|
||||||
const signInSuccess = (isNoPower: boolean | undefined) => {
|
|
||||||
if (isNoPower) {
|
|
||||||
ElMessage.warning('抱歉,您没有登录权限');
|
|
||||||
Session.clear();
|
|
||||||
} else {
|
|
||||||
// 初始化登录成功时间问候语
|
|
||||||
let currentTimeInfo = currentTime.value;
|
|
||||||
// 登录成功,跳到转首页
|
|
||||||
// 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中
|
|
||||||
if (route.query?.redirect) {
|
|
||||||
router.push({
|
|
||||||
path: <string>route.query?.redirect,
|
|
||||||
query: Object.keys(<string>route.query?.params).length > 0 ? JSON.parse(<string>route.query?.params) : '',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
router.push('/');
|
|
||||||
}
|
|
||||||
// 登录成功提示
|
|
||||||
const signInText = t('message.signInText');
|
|
||||||
ElMessage.success(`${currentTimeInfo},${signInText}`);
|
|
||||||
// 添加 loading,防止第一次进入界面时出现短暂空白
|
|
||||||
NextLoading.start();
|
|
||||||
}
|
|
||||||
state.loading.signIn = false;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.login-content-form {
|
|
||||||
margin-top: 20px;
|
|
||||||
@for $i from 1 through 4 {
|
|
||||||
.login-animation#{$i} {
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-num;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
animation-delay: calc($i/10) + s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-content-password {
|
|
||||||
display: inline-block;
|
|
||||||
width: 20px;
|
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-content-code {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
font-weight: bold;
|
|
||||||
letter-spacing: 5px;
|
|
||||||
}
|
|
||||||
.login-content-submit {
|
|
||||||
width: 100%;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
font-weight: 300;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<template>
|
|
||||||
<el-form size="large" class="login-content-form">
|
|
||||||
<el-form-item class="login-animation1">
|
|
||||||
<el-input text :placeholder="$t('message.mobile.placeholder1')" v-model="state.ruleForm.userName" clearable autocomplete="off">
|
|
||||||
<template #prefix>
|
|
||||||
<i class="iconfont icon-dianhua el-input__icon"></i>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="login-animation2">
|
|
||||||
<el-col :span="15">
|
|
||||||
<el-input text maxlength="4" :placeholder="$t('message.mobile.placeholder2')" v-model="state.ruleForm.code" clearable autocomplete="off">
|
|
||||||
<template #prefix>
|
|
||||||
<el-icon class="el-input__icon"><ele-Position /></el-icon>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="1"></el-col>
|
|
||||||
<el-col :span="8">
|
|
||||||
<el-button v-waves class="login-content-code">{{ $t('message.mobile.codeText') }}</el-button>
|
|
||||||
</el-col>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item class="login-animation3">
|
|
||||||
<el-button round type="primary" v-waves class="login-content-submit">
|
|
||||||
<span>{{ $t('message.mobile.btnText') }}</span>
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
<div class="font12 mt30 login-animation4 login-msg">{{ $t('message.mobile.msgText') }}</div>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="loginMobile">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
ruleForm: {
|
|
||||||
userName: '',
|
|
||||||
code: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.login-content-form {
|
|
||||||
margin-top: 20px;
|
|
||||||
@for $i from 1 through 4 {
|
|
||||||
.login-animation#{$i} {
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-num;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
animation-delay: calc($i/10) + s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-content-code {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.login-content-submit {
|
|
||||||
width: 100%;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
font-weight: 300;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
.login-msg {
|
|
||||||
color: var(--el-text-color-placeholder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="login-scan-container">
|
|
||||||
<div ref="qrcodeRef"></div>
|
|
||||||
<div class="font12 mt20 login-msg">
|
|
||||||
<i class="iconfont icon-saoyisao mr5"></i>
|
|
||||||
<span>{{ $t('message.scan.text') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="loginScan">
|
|
||||||
import { ref, onMounted, nextTick } from 'vue';
|
|
||||||
import QRCode from 'qrcodejs2-fixes';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const qrcodeRef = ref<HTMLElement | null>(null);
|
|
||||||
|
|
||||||
// 初始化生成二维码
|
|
||||||
const initQrcode = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
(<HTMLElement>qrcodeRef.value).innerHTML = '';
|
|
||||||
new QRCode(qrcodeRef.value, {
|
|
||||||
text: `https://qm.qq.com/cgi-bin/qm/qr?k=RdUY97Vx0T0vZ_1OOu-X1yFNkWgDwbjC&jump_from=webapi`,
|
|
||||||
width: 260,
|
|
||||||
height: 260,
|
|
||||||
colorDark: '#000000',
|
|
||||||
colorLight: '#ffffff',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initQrcode();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.login-scan-animation {
|
|
||||||
opacity: 0;
|
|
||||||
animation-name: error-num;
|
|
||||||
animation-duration: 0.5s;
|
|
||||||
animation-fill-mode: forwards;
|
|
||||||
}
|
|
||||||
.login-scan-container {
|
|
||||||
padding: 0 20px 20px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
text-align: center;
|
|
||||||
@extend .login-scan-animation;
|
|
||||||
animation-delay: 0.1s;
|
|
||||||
:deep(img) {
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
.login-msg {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: var(--el-text-color-placeholder);
|
|
||||||
@extend .login-scan-animation;
|
|
||||||
animation-delay: 0.2s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,254 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="login-container flex">
|
|
||||||
<div class="login-left">
|
|
||||||
<div class="login-left-logo">
|
|
||||||
<img :src="logoMini" />
|
|
||||||
<div class="login-left-logo-text">
|
|
||||||
<span>{{ getThemeConfig.globalViceTitle }}</span>
|
|
||||||
<span class="login-left-logo-text-msg">{{ getThemeConfig.globalViceTitleMsg }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="login-left-img">
|
|
||||||
<img :src="loginMain" />
|
|
||||||
</div>
|
|
||||||
<img :src="loginBg" class="login-left-waves" />
|
|
||||||
</div>
|
|
||||||
<div class="login-right flex">
|
|
||||||
<div class="login-right-warp flex-margin">
|
|
||||||
<span class="login-right-warp-one"></span>
|
|
||||||
<span class="login-right-warp-two"></span>
|
|
||||||
<div class="login-right-warp-mian">
|
|
||||||
<div class="login-right-warp-main-title">{{ getThemeConfig.globalTitle }} 欢迎您!</div>
|
|
||||||
<div class="login-right-warp-main-form">
|
|
||||||
<div v-if="!state.isScan">
|
|
||||||
<el-tabs v-model="state.tabsActiveName">
|
|
||||||
<el-tab-pane :label="$t('message.label.one1')" name="account">
|
|
||||||
<Account />
|
|
||||||
</el-tab-pane>
|
|
||||||
<el-tab-pane :label="$t('message.label.two2')" name="mobile">
|
|
||||||
<Mobile />
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
<Scan v-if="state.isScan" />
|
|
||||||
<div class="login-content-main-sacn" @click="state.isScan = !state.isScan">
|
|
||||||
<i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>
|
|
||||||
<div class="login-content-main-sacn-delta"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="loginIndex">
|
|
||||||
import { defineAsyncComponent, onMounted, reactive, computed } from 'vue';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
|
||||||
import { NextLoading } from '/@/utils/loading';
|
|
||||||
import logoMini from '/@/assets/logo-mini.svg';
|
|
||||||
import loginMain from '/@/assets/login-main.svg';
|
|
||||||
import loginBg from '/@/assets/login-bg.svg';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const Account = defineAsyncComponent(() => import('/@/views/login/component/account.vue'));
|
|
||||||
const Mobile = defineAsyncComponent(() => import('/@/views/login/component/mobile.vue'));
|
|
||||||
const Scan = defineAsyncComponent(() => import('/@/views/login/component/scan.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const storesThemeConfig = useThemeConfig();
|
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
||||||
const state = reactive({
|
|
||||||
tabsActiveName: 'account',
|
|
||||||
isScan: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取布局配置信息
|
|
||||||
const getThemeConfig = computed(() => {
|
|
||||||
return themeConfig.value;
|
|
||||||
});
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
NextLoading.done();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.login-container {
|
|
||||||
height: 100%;
|
|
||||||
background: var(--el-color-white);
|
|
||||||
.login-left {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
background-color: rgba(211, 239, 255, 1);
|
|
||||||
margin-right: 100px;
|
|
||||||
.login-left-logo {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
position: absolute;
|
|
||||||
top: 50px;
|
|
||||||
left: 80px;
|
|
||||||
z-index: 1;
|
|
||||||
animation: logoAnimation 0.3s ease;
|
|
||||||
img {
|
|
||||||
width: 52px;
|
|
||||||
height: 52px;
|
|
||||||
}
|
|
||||||
.login-left-logo-text {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
span {
|
|
||||||
margin-left: 10px;
|
|
||||||
font-size: 28px;
|
|
||||||
color: #26a59a;
|
|
||||||
}
|
|
||||||
.login-left-logo-text-msg {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #32a99e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-left-img {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: 100%;
|
|
||||||
height: 52%;
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
animation: error-num 0.6s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-left-waves {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: -100px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-right {
|
|
||||||
width: 700px;
|
|
||||||
.login-right-warp {
|
|
||||||
border: 1px solid var(--el-color-primary-light-3);
|
|
||||||
border-radius: 3px;
|
|
||||||
width: 500px;
|
|
||||||
height: 500px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: var(--el-color-white);
|
|
||||||
.login-right-warp-one,
|
|
||||||
.login-right-warp-two {
|
|
||||||
position: absolute;
|
|
||||||
display: block;
|
|
||||||
width: inherit;
|
|
||||||
height: inherit;
|
|
||||||
&::before,
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-right-warp-one {
|
|
||||||
&::before {
|
|
||||||
filter: hue-rotate(0deg);
|
|
||||||
top: 0px;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 3px;
|
|
||||||
background: linear-gradient(90deg, transparent, var(--el-color-primary));
|
|
||||||
animation: loginLeft 3s linear infinite;
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
filter: hue-rotate(60deg);
|
|
||||||
top: -100%;
|
|
||||||
right: 2px;
|
|
||||||
width: 3px;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(180deg, transparent, var(--el-color-primary));
|
|
||||||
animation: loginTop 3s linear infinite;
|
|
||||||
animation-delay: 0.7s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-right-warp-two {
|
|
||||||
&::before {
|
|
||||||
filter: hue-rotate(120deg);
|
|
||||||
bottom: 2px;
|
|
||||||
right: -100%;
|
|
||||||
width: 100%;
|
|
||||||
height: 3px;
|
|
||||||
background: linear-gradient(270deg, transparent, var(--el-color-primary));
|
|
||||||
animation: loginRight 3s linear infinite;
|
|
||||||
animation-delay: 1.4s;
|
|
||||||
}
|
|
||||||
&::after {
|
|
||||||
filter: hue-rotate(300deg);
|
|
||||||
bottom: -100%;
|
|
||||||
left: 0px;
|
|
||||||
width: 3px;
|
|
||||||
height: 100%;
|
|
||||||
background: linear-gradient(360deg, transparent, var(--el-color-primary));
|
|
||||||
animation: loginBottom 3s linear infinite;
|
|
||||||
animation-delay: 2.1s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-right-warp-mian {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
.login-right-warp-main-title {
|
|
||||||
height: 130px;
|
|
||||||
line-height: 130px;
|
|
||||||
font-size: 27px;
|
|
||||||
text-align: center;
|
|
||||||
letter-spacing: 3px;
|
|
||||||
animation: logoAnimation 0.3s ease;
|
|
||||||
animation-delay: 0.3s;
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
}
|
|
||||||
.login-right-warp-main-form {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 50px 50px;
|
|
||||||
.login-content-main-sacn {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
&-delta {
|
|
||||||
position: absolute;
|
|
||||||
width: 35px;
|
|
||||||
height: 70px;
|
|
||||||
z-index: 2;
|
|
||||||
top: 2px;
|
|
||||||
right: 21px;
|
|
||||||
background: var(--el-color-white);
|
|
||||||
transform: rotate(-45deg);
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
color: var(--el-color-primary) !important;
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
width: 47px;
|
|
||||||
height: 50px;
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 48px;
|
|
||||||
position: absolute;
|
|
||||||
right: 1px;
|
|
||||||
top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="notice-bar-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="滚动通知栏:默认">
|
|
||||||
<NoticeBar
|
|
||||||
text="🎉🎉🔥基于vue3.x 、Typescript、vite、Element plus等,适配手机、平板、pc
|
|
||||||
的后台开源免费模板库(vue2.x请切换vue-prev-admin分支),仓库地址:https://gitee.com/lyt-top/vue-next-admin"
|
|
||||||
/>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="滚动通知栏:设置样式" class="mt15">
|
|
||||||
<NoticeBar
|
|
||||||
text="🎉🎉🔥基于vue3.x 、Typescript、vite、Element plus等,适配手机、平板、pc
|
|
||||||
的后台开源免费模板库(vue2.x请切换vue-prev-admin分支),仓库地址:https://gitee.com/lyt-top/vue-next-admin"
|
|
||||||
leftIcon="iconfont icon-tongzhi2"
|
|
||||||
rightIcon="ele-ArrowRight"
|
|
||||||
background="#ecf5ff"
|
|
||||||
color="#409eff"
|
|
||||||
/>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="滚动通知栏:搭配 NoticeBar 和 Carousel 走马灯 组件可以实现垂直滚动的效果" class="mt15">
|
|
||||||
<NoticeBar :scrollable="true">
|
|
||||||
<el-carousel height="40px" direction="vertical" :autoplay="true" indicator-position="none" :interval="3000">
|
|
||||||
<el-carousel-item v-for="v in state.noticeList" :key="v">{{ v }} </el-carousel-item>
|
|
||||||
</el-carousel>
|
|
||||||
</NoticeBar>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="滚动通知栏:参数" class="mt15">
|
|
||||||
<el-table :data="state.tableData" style="width: 100%">
|
|
||||||
<el-table-column prop="a1" label="参数"> </el-table-column>
|
|
||||||
<el-table-column prop="a2" label="说明"> </el-table-column>
|
|
||||||
<el-table-column prop="a3" label="类型"> </el-table-column>
|
|
||||||
<el-table-column prop="a4" label="可选值"> </el-table-column>
|
|
||||||
<el-table-column prop="a5" label="默认值"> </el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="图标选择器(宽度自动):事件" class="mt15">
|
|
||||||
<el-table :data="state.tableData1" style="width: 100%">
|
|
||||||
<el-table-column prop="a1" label="事件名称"> </el-table-column>
|
|
||||||
<el-table-column prop="a2" label="说明"> </el-table-column>
|
|
||||||
<el-table-column prop="a3" label="类型"> </el-table-column>
|
|
||||||
<el-table-column prop="a4" label="回调参数"> </el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="makeNoticeBar">
|
|
||||||
import { defineAsyncComponent, reactive } from 'vue';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const NoticeBar = defineAsyncComponent(() => import('/@/components/noticeBar/index.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
noticeList: [
|
|
||||||
'🎉🎉🔥基于vue3.x 、Typescript、vite、Element plus等',
|
|
||||||
'适配手机、平板、pc的后台开源免费模板库(vue2.x请切换vue-prev-admin分支)',
|
|
||||||
'仓库地址:https://gitee.com/lyt-top/vue-next-admin',
|
|
||||||
'演示地址:https://lyt-top.gitee.io/vue-next-admin-preview/#/login',
|
|
||||||
],
|
|
||||||
tableData: [
|
|
||||||
{
|
|
||||||
a1: 'mode',
|
|
||||||
a2: '通知栏模式,用于右侧 icon 图标点击',
|
|
||||||
a3: 'string',
|
|
||||||
a4: 'closeable / link',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'text',
|
|
||||||
a2: '通知文本内容,scrollable 为 false 时生效',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'color',
|
|
||||||
a2: '通知文本颜色',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '#e6a23c',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'background',
|
|
||||||
a2: '通知背景色',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '#fdf6ec',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'size',
|
|
||||||
a2: '字体大小,单位px',
|
|
||||||
a3: 'number / string',
|
|
||||||
a4: '',
|
|
||||||
a5: '14',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'height',
|
|
||||||
a2: '通知栏高度,单位px',
|
|
||||||
a3: 'number / string',
|
|
||||||
a4: '',
|
|
||||||
a5: '40',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'delay',
|
|
||||||
a2: '动画延迟时间 (s)',
|
|
||||||
a3: 'number / string',
|
|
||||||
a4: '',
|
|
||||||
a5: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'speed',
|
|
||||||
a2: '滚动速率 (px/s)',
|
|
||||||
a3: 'number / string',
|
|
||||||
a4: '',
|
|
||||||
a5: '100',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'scrollable',
|
|
||||||
a2: '是否开启垂直滚动',
|
|
||||||
a3: 'boolean',
|
|
||||||
a4: 'true',
|
|
||||||
a5: 'false',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'leftIcon',
|
|
||||||
a2: '自定义左侧图标',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'rightIcon',
|
|
||||||
a2: '自定义右侧图标',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
tableData1: [
|
|
||||||
{
|
|
||||||
a1: 'close',
|
|
||||||
a2: '通知栏模式(mode)closeable 时回调事件',
|
|
||||||
a3: 'function',
|
|
||||||
a4: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'link',
|
|
||||||
a2: '通知栏模式(mode)link 时回调事件',
|
|
||||||
a3: 'function',
|
|
||||||
a4: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="selector-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="图标选择器(宽度自动):">
|
|
||||||
<IconSelector @get="onGetIcon" @clear="onClearIcon" v-model="state.modelIcon" />
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="图标选择器(宽度自动):参数" class="mt15">
|
|
||||||
<el-table :data="state.tableData" style="width: 100%">
|
|
||||||
<el-table-column prop="a1" label="参数"> </el-table-column>
|
|
||||||
<el-table-column prop="a2" label="说明"> </el-table-column>
|
|
||||||
<el-table-column prop="a3" label="类型"> </el-table-column>
|
|
||||||
<el-table-column prop="a4" label="可选值"> </el-table-column>
|
|
||||||
<el-table-column prop="a5" label="默认值"> </el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="图标选择器(宽度自动):事件" class="mt15">
|
|
||||||
<el-table :data="state.tableData1" style="width: 100%">
|
|
||||||
<el-table-column prop="a1" label="事件名称"> </el-table-column>
|
|
||||||
<el-table-column prop="a2" label="说明"> </el-table-column>
|
|
||||||
<el-table-column prop="a3" label="类型"> </el-table-column>
|
|
||||||
<el-table-column prop="a4" label="回调参数"> </el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="makeSelector">
|
|
||||||
import { defineAsyncComponent, reactive } from 'vue';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const IconSelector = defineAsyncComponent(() => import('/@/components/iconSelector/index.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
modelIcon: '',
|
|
||||||
tableData: [
|
|
||||||
{
|
|
||||||
a1: 'v-model',
|
|
||||||
a2: '双向绑定值',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'prepend',
|
|
||||||
a2: '输入框前置内容,只能字体图标',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: 'ele-Pointer',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'placeholder',
|
|
||||||
a2: '输入框占位文本',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '请输入内容搜索图标或者选择图标',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'size',
|
|
||||||
a2: '尺寸',
|
|
||||||
a3: 'string',
|
|
||||||
a4: 'large / default / small',
|
|
||||||
a5: 'default',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'title',
|
|
||||||
a2: '弹窗标题',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '请选择图标',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'disabled',
|
|
||||||
a2: '禁用',
|
|
||||||
a3: 'boolean',
|
|
||||||
a4: 'true',
|
|
||||||
a5: 'false',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'clearable',
|
|
||||||
a2: '是否可清空',
|
|
||||||
a3: 'boolean',
|
|
||||||
a4: 'false',
|
|
||||||
a5: 'true',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'emptyDescription',
|
|
||||||
a2: '自定义空状态描述文字',
|
|
||||||
a3: 'String',
|
|
||||||
a4: '',
|
|
||||||
a5: '无相关图标',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
tableData1: [
|
|
||||||
{
|
|
||||||
a1: 'get',
|
|
||||||
a2: '获取当前点击的 icon 图标',
|
|
||||||
a3: 'function',
|
|
||||||
a4: '(icon: string)',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'clear',
|
|
||||||
a2: '清空当前点击的 icon 图标',
|
|
||||||
a3: 'function',
|
|
||||||
a4: '(icon: string)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
// 获取当前点击的 icon 图标
|
|
||||||
const onGetIcon = (icon: string) => {
|
|
||||||
console.log(icon);
|
|
||||||
};
|
|
||||||
// 清空当前点击的 icon 图标
|
|
||||||
const onClearIcon = (icon: string) => {
|
|
||||||
console.log(icon);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="svg-demo-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="svgIcon:演示(支持本地svg)">
|
|
||||||
<SvgIcon name="iconfont icon-shuju1" color="red" :size="30" />
|
|
||||||
<SvgIcon name="ele-Trophy" color="var(--el-color-primary)" :size="30" />
|
|
||||||
<SvgIcon name="fa fa-flag-checkered" color="#09f" :size="30" />
|
|
||||||
<SvgIcon :name="logoMini" color="#09f" :size="30" />
|
|
||||||
</el-card>
|
|
||||||
<el-card shadow="hover" header="svgIcon:参数" class="mt15">
|
|
||||||
<el-table :data="state.tableData" style="width: 100%">
|
|
||||||
<el-table-column prop="a1" label="参数"> </el-table-column>
|
|
||||||
<el-table-column prop="a2" label="说明"> </el-table-column>
|
|
||||||
<el-table-column prop="a3" label="类型"> </el-table-column>
|
|
||||||
<el-table-column prop="a4" label="可选值"> </el-table-column>
|
|
||||||
<el-table-column prop="a5" label="默认值"> </el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="makeSvgDemo">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import logoMini from '/@/assets/logo-mini.svg';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
tableData: [
|
|
||||||
{
|
|
||||||
a1: 'name',
|
|
||||||
a2: 'svg 图标组件名字 / svg 路径 url',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'size',
|
|
||||||
a2: 'svg 大小',
|
|
||||||
a3: 'number',
|
|
||||||
a4: '',
|
|
||||||
a5: 14,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
a1: 'color',
|
|
||||||
a2: 'svg 颜色',
|
|
||||||
a3: 'string',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="table-demo-container layout-padding">
|
|
||||||
<div class="table-demo-padding layout-padding-view layout-padding-auto">
|
|
||||||
<TableSearch :search="state.tableData.search" @search="onSearch" />
|
|
||||||
<Table
|
|
||||||
ref="tableRef"
|
|
||||||
v-bind="state.tableData"
|
|
||||||
class="table-demo"
|
|
||||||
@delRow="onTableDelRow"
|
|
||||||
@pageChange="onTablePageChange"
|
|
||||||
@sortHeader="onSortHeader"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="makeTableDemo">
|
|
||||||
import { defineAsyncComponent, reactive, ref, onMounted } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const Table = defineAsyncComponent(() => import('/@/components/table/index.vue'));
|
|
||||||
const TableSearch = defineAsyncComponent(() => import('/@/views/make/tableDemo/search.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const tableRef = ref<RefType>();
|
|
||||||
const state = reactive<TableDemoState>({
|
|
||||||
tableData: {
|
|
||||||
// 列表数据(必传)
|
|
||||||
data: [],
|
|
||||||
// 表头内容(必传,注意格式)
|
|
||||||
header: [
|
|
||||||
{ key: 'name', colWidth: '', title: '应检尽检核酸采样点名称', type: 'text', isCheck: true },
|
|
||||||
{ key: 'address', colWidth: '', title: '详细地址', type: 'text', isCheck: true },
|
|
||||||
{ key: 'phone', colWidth: '', title: '采样点联系电话', type: 'text', isCheck: true },
|
|
||||||
{ key: 'time', colWidth: '', title: '开放时间', type: 'text', isCheck: true },
|
|
||||||
{ key: 'isSupport', colWidth: '', title: '是否支持24小时核酸检测', type: 'text', isCheck: true },
|
|
||||||
{ key: 'image', colWidth: '', width: '70', height: '40', title: '图片描述', type: 'image', isCheck: true },
|
|
||||||
],
|
|
||||||
// 配置项(必传)
|
|
||||||
config: {
|
|
||||||
total: 0, // 列表总数
|
|
||||||
loading: true, // loading 加载
|
|
||||||
isBorder: false, // 是否显示表格边框
|
|
||||||
isSerialNo: true, // 是否显示表格序号
|
|
||||||
isSelection: true, // 是否显示表格多选
|
|
||||||
isOperate: true, // 是否显示表格操作栏
|
|
||||||
},
|
|
||||||
// 搜索表单,动态生成(传空数组时,将不显示搜索,注意格式)
|
|
||||||
search: [
|
|
||||||
{ label: '采样点名称', prop: 'name', placeholder: '请输入应检尽检核酸采样点名称', required: true, type: 'input' },
|
|
||||||
{ label: '详细地址', prop: 'address', placeholder: '请输入详细地址', required: false, type: 'input' },
|
|
||||||
{ label: '联系电话', prop: 'phone', placeholder: '请输入采样点联系电话', required: false, type: 'input' },
|
|
||||||
{ label: '开放时间', prop: 'time', placeholder: '请选择', required: false, type: 'date' },
|
|
||||||
{
|
|
||||||
label: '支持24小时',
|
|
||||||
prop: 'isSupport',
|
|
||||||
placeholder: '请选择',
|
|
||||||
required: false,
|
|
||||||
type: 'select',
|
|
||||||
options: [
|
|
||||||
{ label: '是', value: 1 },
|
|
||||||
{ label: '否', value: 0 },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{ label: '图片描述', prop: 'image', placeholder: '请输入图片描述', required: false, type: 'input' },
|
|
||||||
{ label: '核酸机构', prop: 'mechanism', placeholder: '请输入核酸机构', required: false, type: 'input' },
|
|
||||||
],
|
|
||||||
// 搜索参数(不用传,用于分页、搜索时传给后台的值,`getTableData` 中使用)
|
|
||||||
param: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化列表数据
|
|
||||||
const getTableData = () => {
|
|
||||||
state.tableData.config.loading = true;
|
|
||||||
state.tableData.data = [];
|
|
||||||
for (let i = 0; i < 20; i++) {
|
|
||||||
state.tableData.data.push({
|
|
||||||
id: `123456789${i + 1}`,
|
|
||||||
name: `莲塘别墅广场${i + 1}`,
|
|
||||||
address: `中沧公寓中庭榕树下${i + 1}`,
|
|
||||||
phone: `0592-6081259${i + 1}`,
|
|
||||||
time: `6:00 ~ 24:00`,
|
|
||||||
isSupport: `${i % 2 === 0 ? '是' : '否'}`,
|
|
||||||
image: `https://img2.baidu.com/it/u=417454395,2713356475&fm=253&fmt=auto?w=200&h=200`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 数据总数(模拟,真实从接口取)
|
|
||||||
state.tableData.config.total = state.tableData.data.length;
|
|
||||||
setTimeout(() => {
|
|
||||||
state.tableData.config.loading = false;
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
// 搜索点击时表单回调
|
|
||||||
const onSearch = (data: EmptyObjectType) => {
|
|
||||||
state.tableData.param = Object.assign({}, state.tableData.param, { ...data });
|
|
||||||
tableRef.value.pageReset();
|
|
||||||
};
|
|
||||||
// 删除当前项回调
|
|
||||||
const onTableDelRow = (row: EmptyObjectType) => {
|
|
||||||
ElMessage.success(`删除${row.name}成功!`);
|
|
||||||
getTableData();
|
|
||||||
};
|
|
||||||
// 分页改变时回调
|
|
||||||
const onTablePageChange = (page: TableDemoPageType) => {
|
|
||||||
state.tableData.param.pageNum = page.pageNum;
|
|
||||||
state.tableData.param.pageSize = page.pageSize;
|
|
||||||
getTableData();
|
|
||||||
};
|
|
||||||
// 拖动显示列排序回调
|
|
||||||
const onSortHeader = (data: TableHeaderType[]) => {
|
|
||||||
state.tableData.header = data;
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
getTableData();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.table-demo-container {
|
|
||||||
.table-demo-padding {
|
|
||||||
padding: 15px;
|
|
||||||
.table-demo {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="table-search-container" v-if="props.search.length > 0">
|
|
||||||
<el-form ref="tableSearchRef" :model="state.form" size="default" label-width="100px" class="table-form">
|
|
||||||
<el-row>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20" v-for="(val, key) in search" :key="key" v-show="key === 0 || state.isToggle">
|
|
||||||
<template v-if="val.type !== ''">
|
|
||||||
<el-form-item
|
|
||||||
:label="val.label"
|
|
||||||
:prop="val.prop"
|
|
||||||
:rules="[{ required: val.required, message: `${val.label}不能为空`, trigger: val.type === 'input' ? 'blur' : 'change' }]"
|
|
||||||
>
|
|
||||||
<el-input v-model="state.form[val.prop]" :placeholder="val.placeholder" clearable v-if="val.type === 'input'" style="width: 100%" />
|
|
||||||
<el-date-picker
|
|
||||||
v-model="state.form[val.prop]"
|
|
||||||
type="date"
|
|
||||||
:placeholder="val.placeholder"
|
|
||||||
v-else-if="val.type === 'date'"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<el-select v-model="state.form[val.prop]" :placeholder="val.placeholder" v-else-if="val.type === 'select'" style="width: 100%">
|
|
||||||
<el-option v-for="item in val.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item class="table-form-btn" :label-width="search.length <= 1 ? '10px' : '100px'">
|
|
||||||
<template #label v-if="search.length > 1">
|
|
||||||
<div class="table-form-btn-toggle ml10" @click="state.isToggle = !state.isToggle">
|
|
||||||
<span>{{ state.isToggle ? '收筛选' : '展筛选' }}</span>
|
|
||||||
<SvgIcon :name="state.isToggle ? 'ele-ArrowUp' : 'ele-ArrowDown'" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div>
|
|
||||||
<el-button size="default" type="primary" @click="onSearch(tableSearchRef)">查询 </el-button>
|
|
||||||
<el-button size="default" type="info" class="ml10" @click="onReset(tableSearchRef)"> 重置 </el-button>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="makeTableDemoSearch">
|
|
||||||
import { reactive, ref, onMounted } from 'vue';
|
|
||||||
import type { FormInstance } from 'element-plus';
|
|
||||||
|
|
||||||
// 定义父组件传过来的值
|
|
||||||
const props = defineProps({
|
|
||||||
// 搜索表单
|
|
||||||
search: {
|
|
||||||
type: Array<TableSearchType>,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
|
||||||
const emit = defineEmits(['search']);
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const tableSearchRef = ref<FormInstance>();
|
|
||||||
const state = reactive({
|
|
||||||
form: {},
|
|
||||||
isToggle: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onSearch = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate((valid: boolean) => {
|
|
||||||
if (valid) {
|
|
||||||
emit('search', state.form);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 重置
|
|
||||||
const onReset = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.resetFields();
|
|
||||||
emit('search', state.form);
|
|
||||||
};
|
|
||||||
// 初始化 form 字段,取自父组件 search.prop
|
|
||||||
const initFormField = () => {
|
|
||||||
if (props.search.length <= 0) return false;
|
|
||||||
props.search.forEach((v) => (state.form[v.prop] = ''));
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initFormField();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.table-search-container {
|
|
||||||
display: flex;
|
|
||||||
.table-form {
|
|
||||||
flex: 1;
|
|
||||||
.table-form-btn-toggle {
|
|
||||||
white-space: nowrap;
|
|
||||||
user-select: none;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-input v-model="val" placeholder="menu11:请输入内容测试路由缓存"></el-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="menu11">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const val = ref('');
|
|
||||||
</script>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-input v-model="val" placeholder="menu121:请输入内容测试路由缓存"></el-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="menu121">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const val = ref('');
|
|
||||||
</script>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-input v-model="val" placeholder="menu122:请输入内容测试路由缓存"></el-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="menu122">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const val = ref('');
|
|
||||||
</script>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-input v-model="val" placeholder="menu13:请输入内容测试路由缓存"></el-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="menu13">
|
|
||||||
import { ref, onActivated, onMounted } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const val = ref('');
|
|
||||||
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
console.log(2222);
|
|
||||||
});
|
|
||||||
// keep-alive 钩子函数,页面进入时
|
|
||||||
onActivated(() => {
|
|
||||||
console.log(1111);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-input v-model="val" placeholder="menu2:请输入内容测试路由缓存"></el-input>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="menu2">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const val = ref('');
|
|
||||||
</script>
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="awesome-container layout-pd">
|
|
||||||
<el-card shadow="hover" :header="`fontawesome 字体图标(自动载入):${state.sheetsIconList.length - 24}个`">
|
|
||||||
<el-row class="iconfont-row">
|
|
||||||
<el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="2" v-for="(v, k) in state.sheetsIconList" :key="k">
|
|
||||||
<div class="iconfont-warp">
|
|
||||||
<div class="flex-margin">
|
|
||||||
<div class="iconfont-warp-value">
|
|
||||||
<i :class="v" class="fa"></i>
|
|
||||||
</div>
|
|
||||||
<div class="iconfont-warp-label mt10">{{ v }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesAwesome">
|
|
||||||
import { reactive, onMounted } from 'vue';
|
|
||||||
import initIconfont from '/@/utils/getStyleSheets';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
sheetsIconList: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化获取 css 样式,这里使用fontawesome的图标(记得加上前缀 `fa`),其它第三方请自行做判断
|
|
||||||
const initGetStyleSheets = () => {
|
|
||||||
initIconfont.awe().then((res: any) => (state.sheetsIconList = res));
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initGetStyleSheets();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.awesome-container {
|
|
||||||
.iconfont-row {
|
|
||||||
border-top: 1px solid var(--next-border-color-light);
|
|
||||||
border-left: 1px solid var(--next-border-color-light);
|
|
||||||
.iconfont-warp {
|
|
||||||
text-align: center;
|
|
||||||
border-right: 1px solid var(--next-border-color-light);
|
|
||||||
border-bottom: 1px solid var(--next-border-color-light);
|
|
||||||
height: 120px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px var(--next-color-dark-hover);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
.iconfont-warp-value {
|
|
||||||
i {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-label {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-value {
|
|
||||||
i {
|
|
||||||
color: #606266;
|
|
||||||
font-size: 32px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-label {
|
|
||||||
color: #99a9bf;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="drag-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="拖动指令效果(v-drag)作用于 Dialog 对话框">
|
|
||||||
<el-button type="primary" @click="state.dialogVisible = true" size="default">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Pointer />
|
|
||||||
</el-icon>
|
|
||||||
点击打开 Dialog
|
|
||||||
</el-button>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-card shadow="hover" header="自定义div" class="mt15">
|
|
||||||
<div class="drag-dom">
|
|
||||||
<div class="drag-header">
|
|
||||||
<el-button type="success" size="default" v-drag="['.drag-container .drag-dom', '.drag-container .drag-header']">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Pointer />
|
|
||||||
</el-icon>
|
|
||||||
按住进行拖动测试
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
|
|
||||||
<el-dialog v-model="state.dialogVisible" width="769px">
|
|
||||||
<template #header>
|
|
||||||
<div v-drag="['.drag-container .el-dialog', '.drag-container .el-dialog__header']">拖动指令效果(v-drag)</div>
|
|
||||||
</template>
|
|
||||||
<p>鼠标放标题头进行 Dialog 对话框拖动</p>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="state.dialogVisible = false" size="default">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="state.dialogVisible = false" size="default">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesDrag">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
dialogVisible: false,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.drag-container {
|
|
||||||
.drag-dom {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
.drag-header {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,168 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="dynamic-form-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="动态复杂表单">
|
|
||||||
<el-form :model="state.form" ref="formRulesOneRef" size="default" label-width="100px" class="mt35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col
|
|
||||||
:xs="val.xs"
|
|
||||||
:sm="val.sm"
|
|
||||||
:md="val.md"
|
|
||||||
:lg="val.md"
|
|
||||||
:xl="val.xl"
|
|
||||||
class="mb20"
|
|
||||||
v-show="val.isShow"
|
|
||||||
v-for="(val, key) in formData"
|
|
||||||
:key="key"
|
|
||||||
>
|
|
||||||
<template v-if="val.type !== ''">
|
|
||||||
<el-form-item
|
|
||||||
:label="val.label"
|
|
||||||
:prop="val.prop"
|
|
||||||
:rules="[{ required: val.required, message: `${val.label}不能为空`, trigger: val.type === 'input' ? 'blur' : 'change' }]"
|
|
||||||
v-if="val.type !== ''"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="state.form[val.prop]"
|
|
||||||
:placeholder="val.placeholder"
|
|
||||||
clearable
|
|
||||||
v-if="val.type === 'input'"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="val.disabled"
|
|
||||||
></el-input>
|
|
||||||
<el-date-picker
|
|
||||||
v-model="state.form[val.prop]"
|
|
||||||
type="date"
|
|
||||||
:placeholder="val.placeholder"
|
|
||||||
v-else-if="val.type === 'date'"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="val.disabled"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
<el-select
|
|
||||||
v-model="state.form[val.prop]"
|
|
||||||
:placeholder="val.placeholder"
|
|
||||||
v-else-if="val.type === 'select'"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="val.disabled"
|
|
||||||
>
|
|
||||||
<el-option v-for="item in val.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-input
|
|
||||||
type="textarea"
|
|
||||||
v-model="state.form[val.prop]"
|
|
||||||
:placeholder="val.placeholder"
|
|
||||||
clearable
|
|
||||||
v-if="val.type === 'textarea'"
|
|
||||||
style="width: 100%"
|
|
||||||
:disabled="val.disabled"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<el-row :gutter="35" v-for="(v, k) in state.form.list" :key="k">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" class="mb20">
|
|
||||||
<el-form-item label="年度" :prop="`list[${k}].year`" :rules="[{ required: true, message: `年度不能为空`, trigger: 'blur' }]">
|
|
||||||
<template #label>
|
|
||||||
<el-button type="primary" circle size="small" @click="onAddRow" v-if="k === 0">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Plus />
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
<el-button type="danger" circle size="small" @click="onDelRow(k)" v-else>
|
|
||||||
<el-icon>
|
|
||||||
<ele-Delete />
|
|
||||||
</el-icon>
|
|
||||||
</el-button>
|
|
||||||
<span class="ml10">年度</span>
|
|
||||||
</template>
|
|
||||||
<el-input v-model="state.form.list[k].year" style="width: 100%" placeholder="请输入"> </el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" class="mb20">
|
|
||||||
<el-form-item label="月度" :prop="`list[${k}].month`" :rules="[{ required: true, message: `月度不能为空`, trigger: 'blur' }]">
|
|
||||||
<el-input v-model="state.form.list[k].month" style="width: 100%" placeholder="请输入"> </el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="6" class="mb20">
|
|
||||||
<el-form-item label="日度" :prop="`list[${k}].day`" :rules="[{ required: true, message: `日度不能为空`, trigger: 'blur' }]">
|
|
||||||
<el-input v-model="state.form.list[k].day" style="width: 100%" placeholder="请输入"> </el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</template>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
<el-row class="flex mt15">
|
|
||||||
<div class="flex-margin">
|
|
||||||
<el-button size="default" @click="onResetForm(formRulesOneRef)">
|
|
||||||
<el-icon>
|
|
||||||
<ele-RefreshRight />
|
|
||||||
</el-icon>
|
|
||||||
重置表单
|
|
||||||
</el-button>
|
|
||||||
<el-button size="default" type="primary" @click="onSubmitForm(formRulesOneRef)">
|
|
||||||
<SvgIcon name="iconfont icon-shuxing" />
|
|
||||||
验证表单
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesDynamicForm">
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import type { FormInstance } from 'element-plus';
|
|
||||||
import { formData } from './mock';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const formRulesOneRef = ref<FormInstance>();
|
|
||||||
const state = reactive({
|
|
||||||
formData,
|
|
||||||
form: {
|
|
||||||
name: '',
|
|
||||||
email: '',
|
|
||||||
autograph: '',
|
|
||||||
occupation: '',
|
|
||||||
list: [
|
|
||||||
{
|
|
||||||
year: '',
|
|
||||||
month: '',
|
|
||||||
day: '',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
remarks: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 新增行
|
|
||||||
const onAddRow = () => {
|
|
||||||
state.form.list.push({
|
|
||||||
year: '',
|
|
||||||
month: '',
|
|
||||||
day: '',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 删除行
|
|
||||||
const onDelRow = (k: number) => {
|
|
||||||
state.form.list.splice(k, 1);
|
|
||||||
};
|
|
||||||
// 表单验证
|
|
||||||
const onSubmitForm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate((valid: boolean) => {
|
|
||||||
if (valid) {
|
|
||||||
ElMessage.success('验证成功');
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 重置表单
|
|
||||||
const onResetForm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
// 表单数据选项(自行扩展)
|
|
||||||
export const formData = [
|
|
||||||
{
|
|
||||||
label: '姓名',
|
|
||||||
prop: 'name',
|
|
||||||
placeholder: '请输入姓名',
|
|
||||||
clearable: true,
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
type: 'input',
|
|
||||||
i18n: false,
|
|
||||||
i18nText: '',
|
|
||||||
isShow: true,
|
|
||||||
xs: 24,
|
|
||||||
sm: 12,
|
|
||||||
md: 8,
|
|
||||||
lg: 6,
|
|
||||||
xl: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '邮箱',
|
|
||||||
prop: 'email',
|
|
||||||
placeholder: '请输入用户邮箱',
|
|
||||||
clearable: true,
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
type: 'input',
|
|
||||||
i18n: false,
|
|
||||||
i18nText: '',
|
|
||||||
isShow: true,
|
|
||||||
xs: 24,
|
|
||||||
sm: 12,
|
|
||||||
md: 8,
|
|
||||||
lg: 6,
|
|
||||||
xl: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '登陆时间',
|
|
||||||
prop: 'autograph',
|
|
||||||
placeholder: '选择时间',
|
|
||||||
clearable: true,
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
type: 'date',
|
|
||||||
i18n: false,
|
|
||||||
i18nText: '',
|
|
||||||
isShow: true,
|
|
||||||
xs: 24,
|
|
||||||
sm: 12,
|
|
||||||
md: 8,
|
|
||||||
lg: 6,
|
|
||||||
xl: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '职务',
|
|
||||||
prop: 'occupation',
|
|
||||||
placeholder: '请选择职务',
|
|
||||||
clearable: true,
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
type: 'select',
|
|
||||||
i18n: false,
|
|
||||||
i18nText: '',
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
label: '计算机 / 互联网 / 通信',
|
|
||||||
value: '1',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '生产 / 工艺 / 制造',
|
|
||||||
value: '2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '医疗 / 护理 / 制药',
|
|
||||||
value: '3',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
isShow: true,
|
|
||||||
xs: 24,
|
|
||||||
sm: 12,
|
|
||||||
md: 8,
|
|
||||||
lg: 6,
|
|
||||||
xl: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '',
|
|
||||||
prop: '',
|
|
||||||
placeholder: '',
|
|
||||||
clearable: true,
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
type: '',
|
|
||||||
i18n: false,
|
|
||||||
i18nText: '',
|
|
||||||
isShow: true,
|
|
||||||
xs: 24,
|
|
||||||
sm: 24,
|
|
||||||
md: 24,
|
|
||||||
lg: 24,
|
|
||||||
xl: 24,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '备注',
|
|
||||||
prop: 'remarks',
|
|
||||||
placeholder: '请输入',
|
|
||||||
clearable: true,
|
|
||||||
disabled: false,
|
|
||||||
required: true,
|
|
||||||
type: 'textarea',
|
|
||||||
i18n: false,
|
|
||||||
i18nText: '',
|
|
||||||
isShow: true,
|
|
||||||
xs: 24,
|
|
||||||
sm: 24,
|
|
||||||
md: 24,
|
|
||||||
lg: 24,
|
|
||||||
xl: 24,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="element-container layout-pd">
|
|
||||||
<el-card shadow="hover" :header="`element plus 字体图标(自动载入,增加了 ele- 前缀,使用时:ele-Aim):${state.sheetsIconList.length}个`">
|
|
||||||
<el-row class="iconfont-row">
|
|
||||||
<el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="2" v-for="(v, k) in state.sheetsIconList" :key="k">
|
|
||||||
<div class="iconfont-warp">
|
|
||||||
<div class="flex-margin">
|
|
||||||
<div class="iconfont-warp-value">
|
|
||||||
<SvgIcon :name="v" :size="30" />
|
|
||||||
</div>
|
|
||||||
<div class="iconfont-warp-label mt10">{{ v }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesElement">
|
|
||||||
import { reactive, onMounted } from 'vue';
|
|
||||||
import initIconfont from '/@/utils/getStyleSheets';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
sheetsIconList: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化获取 css 样式,获取 element plus 自带 svg 图标,增加了 ele- 前缀,使用时:ele-Aim
|
|
||||||
const initGetStyleSheets = () => {
|
|
||||||
initIconfont.ele().then((res: any) => {
|
|
||||||
state.sheetsIconList = res;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initGetStyleSheets();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.element-container {
|
|
||||||
.iconfont-row {
|
|
||||||
border-top: 1px solid var(--next-border-color-light);
|
|
||||||
border-left: 1px solid var(--next-border-color-light);
|
|
||||||
.iconfont-warp {
|
|
||||||
text-align: center;
|
|
||||||
border-right: 1px solid var(--next-border-color-light);
|
|
||||||
border-bottom: 1px solid var(--next-border-color-light);
|
|
||||||
height: 120px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px var(--next-color-dark-hover);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
.iconfont-warp-value {
|
|
||||||
i {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-label {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-value {
|
|
||||||
i {
|
|
||||||
color: #606266;
|
|
||||||
font-size: 32px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-label {
|
|
||||||
color: #99a9bf;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="w100 h100 flex">
|
|
||||||
<div class="flex-margin color-primary">filtering-details 测试界面</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFilteringDetails">
|
|
||||||
// 此处需有内容(注释也得),否则缓存将失败
|
|
||||||
</script>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="w100 h100 flex">
|
|
||||||
<div class="flex-margin color-primary">测试界面</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFilteringDetails1">
|
|
||||||
// 此处需有内容(注释也得),否则缓存将失败
|
|
||||||
</script>
|
|
||||||
@@ -1,344 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="filtering layout-pd">
|
|
||||||
<el-card
|
|
||||||
shadow="hover"
|
|
||||||
class="filtering-list br-top-no"
|
|
||||||
v-loading="state.tableData.loading"
|
|
||||||
element-loading-text="加载中..."
|
|
||||||
element-loading-background="rgba(255, 255, 255, 0.1)"
|
|
||||||
:class="{ 'min-h-360': state.tableData.data.length <= 0 }"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="(val, key) in filtering"
|
|
||||||
:key="key"
|
|
||||||
:ref="
|
|
||||||
(el) => {
|
|
||||||
if (el) dlRefs[key] = el;
|
|
||||||
}
|
|
||||||
"
|
|
||||||
class="filtering-list-flex"
|
|
||||||
>
|
|
||||||
<div class="filtering-list-title">{{ val.title }}</div>
|
|
||||||
<div class="filtering-list-item" :style="{ height: val.isMore ? 'auto' : '50px' }">
|
|
||||||
<span class="span" :class="v.active ? 'dd-active' : ''" v-for="(v, k) in val.children" :key="k" @click="onSelItem(val, v)">{{
|
|
||||||
v.label
|
|
||||||
}}</span>
|
|
||||||
<div class="dd-more" v-if="val.isShowMore" @click="val.isMore = !val.isMore">
|
|
||||||
<span>{{ val.isMore ? '收起' : '展开' }}</span>
|
|
||||||
<i :class="val.isMore ? 'el-icon-arrow-down' : 'el-icon-arrow-right'"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp mt15 mb15" v-if="state.tableData.data.length > 0">
|
|
||||||
<el-row :gutter="15">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb15" v-for="(v, k) in state.tableData.data" :key="k" @click="onTableItemClick(v)">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="item-img">
|
|
||||||
<img :src="v.img" />
|
|
||||||
</div>
|
|
||||||
<div class="item-txt">
|
|
||||||
<div class="item-txt-title">{{ v.title }}</div>
|
|
||||||
<div class="item-txt-other">
|
|
||||||
<div style="width: 100%">
|
|
||||||
<div class="item-txt-msg mb10">
|
|
||||||
<span>评价 {{ v.evaluate }}</span>
|
|
||||||
<span class="ml10">收藏 {{ v.collection }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="item-txt-msg item-txt-price">
|
|
||||||
<span class="font-price">
|
|
||||||
<span>¥</span>
|
|
||||||
<span class="font">{{ v.price }}</span>
|
|
||||||
</span>
|
|
||||||
<span>月销{{ v.monSales }}笔</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
<div v-else class="filtering-no-data">
|
|
||||||
<div class="no-data-box">
|
|
||||||
<i class="el-icon-search"></i>
|
|
||||||
<div class="no-txt">暂无数据</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<template v-if="state.tableData.data.length > 0">
|
|
||||||
<el-pagination
|
|
||||||
style="text-align: right"
|
|
||||||
background
|
|
||||||
@size-change="onHandleSizeChange"
|
|
||||||
@current-change="onHandleCurrentChange"
|
|
||||||
:page-sizes="[10, 20, 30]"
|
|
||||||
:current-page="state.tableData.param.pageNum"
|
|
||||||
:page-size="state.tableData.param.pageSize"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
:total="state.tableData.total"
|
|
||||||
>
|
|
||||||
</el-pagination>
|
|
||||||
</template>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFiltering">
|
|
||||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import { filtering, filterList } from './mock';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const dlRefs = ref<RefType[]>([]);
|
|
||||||
const router = useRouter();
|
|
||||||
const state = reactive({
|
|
||||||
filtering,
|
|
||||||
tableData: {
|
|
||||||
data: filterList,
|
|
||||||
total: 99,
|
|
||||||
loading: false,
|
|
||||||
param: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initBtnToggle();
|
|
||||||
window.onresize = () => {
|
|
||||||
initBtnToggle();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
// 初始化 `收起、展开` 按钮
|
|
||||||
const initBtnToggle = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
const els = dlRefs.value;
|
|
||||||
els.map((v: any, k: number) => {
|
|
||||||
v.scrollHeight < v.lastChild.scrollHeight ? (state.filtering[k].isShowMore = true) : (state.filtering[k].isShowMore = false);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 过滤当前选中的数据
|
|
||||||
const onSelItem = (val: FilteringRowType, v: FilteringChilType) => {
|
|
||||||
val.children.map((v: FilteringChilType) => (v.active = false));
|
|
||||||
v.active = true;
|
|
||||||
let arr = [];
|
|
||||||
state.filtering.map((item: FilteringRowType) => {
|
|
||||||
item.children.map((chil: FilteringChilType) => {
|
|
||||||
if (chil.active) {
|
|
||||||
arr.push({
|
|
||||||
...item,
|
|
||||||
children: [{ ...chil }],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
state.tableData.loading = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
state.tableData.loading = false;
|
|
||||||
}, 500);
|
|
||||||
};
|
|
||||||
// 当前列表项点击
|
|
||||||
const onTableItemClick = (v: FilterListType) => {
|
|
||||||
if (v.id === 1) {
|
|
||||||
router.push({
|
|
||||||
path: '/pages/filtering/details',
|
|
||||||
query: { id: v.id },
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
router.push({
|
|
||||||
path: '/pages/filtering/details1',
|
|
||||||
query: { id: v.id },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 分页点击
|
|
||||||
const onHandleSizeChange = (val: number) => {
|
|
||||||
state.tableData.param.pageSize = val;
|
|
||||||
};
|
|
||||||
// 分页点击
|
|
||||||
const onHandleCurrentChange = (val: number) => {
|
|
||||||
state.tableData.param.pageNum = val;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.filtering {
|
|
||||||
.filtering-list {
|
|
||||||
overflow: hidden;
|
|
||||||
border-bottom: none !important;
|
|
||||||
.filtering-list-flex {
|
|
||||||
&:last-of-type {
|
|
||||||
.filtering-list-item {
|
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.filtering-list-title {
|
|
||||||
float: left;
|
|
||||||
width: 64px;
|
|
||||||
font-weight: 700;
|
|
||||||
position: relative;
|
|
||||||
color: #909399;
|
|
||||||
margin: 15px 0;
|
|
||||||
&:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
border: 1px solid #909399;
|
|
||||||
border-width: 0 1px 1px 0;
|
|
||||||
width: 4px;
|
|
||||||
height: 4px;
|
|
||||||
transform: rotate(-45deg) translateY(-50%);
|
|
||||||
right: 10px;
|
|
||||||
top: 50%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.filtering-list-item {
|
|
||||||
border-bottom: 1px dotted var(--next-border-color-light);
|
|
||||||
margin-left: 64px;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
.span {
|
|
||||||
color: #8d8d91;
|
|
||||||
font-size: 14px;
|
|
||||||
float: left;
|
|
||||||
padding: 0 15px;
|
|
||||||
margin: 15px 0;
|
|
||||||
&:hover {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.dd-active {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
.dd-more {
|
|
||||||
font-size: 12px;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 16px;
|
|
||||||
color: #a5a5a5;
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: #8d8d91;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.br-top-no {
|
|
||||||
border-top: none;
|
|
||||||
.flex-warp {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-content: flex-start;
|
|
||||||
margin: 0 -5px;
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 5px;
|
|
||||||
width: 100%;
|
|
||||||
height: 360px;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
border: 1px solid var(--next-border-color-light);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
|
|
||||||
.item-txt-title {
|
|
||||||
color: var(--el-color-primary) !important;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
.item-img {
|
|
||||||
img {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
transform: translateZ(0) scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-img {
|
|
||||||
width: 100%;
|
|
||||||
height: 215px;
|
|
||||||
overflow: hidden;
|
|
||||||
img {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-txt {
|
|
||||||
flex: 1;
|
|
||||||
padding: 15px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
.item-txt-title {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
display: -webkit-box;
|
|
||||||
color: #666666;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
text-decoration: underline;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-txt-other {
|
|
||||||
flex: 1;
|
|
||||||
align-items: flex-end;
|
|
||||||
display: flex;
|
|
||||||
.item-txt-msg {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #8d8d91;
|
|
||||||
}
|
|
||||||
.item-txt-price {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
.font-price {
|
|
||||||
color: #ff5000;
|
|
||||||
.font {
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.el-card__body) {
|
|
||||||
height: 100%;
|
|
||||||
.filtering-no-data {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
.no-data-box {
|
|
||||||
color: #cccccc;
|
|
||||||
margin: auto;
|
|
||||||
i {
|
|
||||||
font-size: 70px;
|
|
||||||
}
|
|
||||||
.no-txt {
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.min-h-360 {
|
|
||||||
height: 360px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
// 导航数据
|
|
||||||
export const filtering = [
|
|
||||||
{
|
|
||||||
title: '权限',
|
|
||||||
isMore: false,
|
|
||||||
isShowMore: false,
|
|
||||||
id: 0,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: '01',
|
|
||||||
label: '全部',
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '02',
|
|
||||||
label: '普通用户',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '03',
|
|
||||||
label: '管理员',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '布局',
|
|
||||||
isMore: false,
|
|
||||||
isShowMore: false,
|
|
||||||
id: 1,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 11,
|
|
||||||
label: '全部',
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 12,
|
|
||||||
label: '默认',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 13,
|
|
||||||
label: '经典',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 14,
|
|
||||||
label: '横向',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 15,
|
|
||||||
label: '分栏',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '配置',
|
|
||||||
isMore: false,
|
|
||||||
isShowMore: false,
|
|
||||||
id: 2,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 21,
|
|
||||||
label: '全部',
|
|
||||||
active: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 22,
|
|
||||||
label: '开启 Breadcrumb',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 23,
|
|
||||||
label: '开启 Tags-View',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 24,
|
|
||||||
label: '固定 Header',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 25,
|
|
||||||
label: '侧边栏 Logo',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 26,
|
|
||||||
label: '开启折叠 NavMenu',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 27,
|
|
||||||
label: '开启一个 NavMenu 展开',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 28,
|
|
||||||
label: '登录用户头像',
|
|
||||||
active: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 列表数据
|
|
||||||
export const filterList = [
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2020-08/14/9d9c9a60-f0af-41aa-b617-683b07c87642.jpg',
|
|
||||||
title: '嘉陵江2020年第1号洪水”在嘉陵江支流涪江形成',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/news/pic/2020-08/13/0ea47d3c-feb9-4bd7-8597-a8a373aa6340c6ec12c7-3b33-4528-91a6-85ec8ca1df67_watermark.png',
|
|
||||||
title: '让《民法典》走近群众 盐田街道开展人民调解宣传活动',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/photo/pic/2020-08/12/a08d6eb0-1d53-4f76-a313-ad3e5d701f98.jpg',
|
|
||||||
title: '记者手记:可可西里,“挪”向“藏羚羊大产房”的14个半小时',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/photo/pic/2020-08/11/43cc0e14-9bca-45b9-9a8b-342e09d6a4c7.jpg',
|
|
||||||
title: '以优异成绩庆祝深圳经济特区建立40周年',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/photo/pic/2020-08/11/a4dc322b-68ec-40e6-8906-3124142c3e49.jpg',
|
|
||||||
title: '草原上的“太阳姑娘”',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/zhuanti/pic/2020-08/07/57f087b4-4812-46cc-adb9-ead73621284e.png',
|
|
||||||
title: '奇观天下|带你走进非洲野生动物观光第一目的地',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2020-09/02/t2_(101X54X600X335)7cd39301-d9cf-45f1-91c3-9575b1e5ce0e.jpg.2',
|
|
||||||
title: '五角大楼发布“中国军力报告” 华春莹: 罔顾事实,充满偏见',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2020-09/02/b8b41d9c-0508-4498-8d37-6e597493769f.jpg',
|
|
||||||
title: '最新地铁消息汇总:4号线北延、2号线三期、8号线一期等今年通车',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 8,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/photo/pic/2020-08/10/1635374c-f4d6-475c-ac47-1334176f365d.png',
|
|
||||||
title: '9月1日深圳新增5例无症状感染者!钟南山这段话冲上热搜!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://www.sznews.com/news/pic/2020-08/13/646e5458-92b7-4636-9940-9b0799babfe1.png',
|
|
||||||
title: '全能“小福宝” 为文明社区建设添砖加瓦',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 10,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="form-adapt-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="表单自适应演示(改变窗口查看效果)">
|
|
||||||
<el-form :model="state.form" size="default" label-width="100px" class="mt35 mb35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="姓名">
|
|
||||||
<el-input v-model="state.form.name" placeholder="请输入姓名" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="用户归属部门">
|
|
||||||
<el-input v-model="state.form.email" placeholder="请输入用户归属部门" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="登陆账户名">
|
|
||||||
<el-input v-model="state.form.autograph" placeholder="请输入登陆账户名" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="职务">
|
|
||||||
<el-select v-model="state.form.occupation" placeholder="请选择职务" clearable class="w100">
|
|
||||||
<el-option label="计算机 / 互联网 / 通信" value="1"></el-option>
|
|
||||||
<el-option label="生产 / 工艺 / 制造" value="2"></el-option>
|
|
||||||
<el-option label="医疗 / 护理 / 制药" value="3"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="手机">
|
|
||||||
<el-input v-model="state.form.phone" placeholder="请输入手机" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="性别">
|
|
||||||
<el-select v-model="state.form.sex" placeholder="请选择性别" clearable class="w100">
|
|
||||||
<el-option label="男" value="1"></el-option>
|
|
||||||
<el-option label="女" value="2"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="登录密码">
|
|
||||||
<el-input v-model="state.form.phone1" placeholder="请输入登录密码" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="权限角色">
|
|
||||||
<el-input v-model="state.form.phone2" placeholder="请输入权限角色" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="创建用户">
|
|
||||||
<el-input v-model="state.form.phone3" placeholder="请输入创建用户" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="修改用户">
|
|
||||||
<el-input v-model="state.form.phone4" placeholder="请输入修改用户" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="所属用户">
|
|
||||||
<el-input v-model="state.form.phone5" placeholder="请输入所属用户" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="所属部门">
|
|
||||||
<el-input v-model="state.form.phone6" placeholder="请输入所属部门" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary">
|
|
||||||
<SvgIcon name="iconfont icon-biaodan" />
|
|
||||||
更新个人信息
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesListAdapt">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
form: {
|
|
||||||
name: '',
|
|
||||||
email: '',
|
|
||||||
autograph: '',
|
|
||||||
occupation: '',
|
|
||||||
phone: '',
|
|
||||||
sex: '',
|
|
||||||
phone1: '',
|
|
||||||
phone2: '',
|
|
||||||
phone3: '',
|
|
||||||
phone4: '',
|
|
||||||
phone5: '',
|
|
||||||
phone6: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="form-i18n-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="表单国际化演示(不适用于动态项 form-item)">
|
|
||||||
<div style="text-align: center; margin-top: 15px">
|
|
||||||
<el-radio-group v-model="state.radio" size="default" @change="onRadioChange">
|
|
||||||
<el-radio-button label="zh-cn">中文简体</el-radio-button>
|
|
||||||
<el-radio-button label="en">英文</el-radio-button>
|
|
||||||
<el-radio-button label="zh-tw">中文繁体</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
</div>
|
|
||||||
<el-form :model="state.form" size="default" label-width="100px" class="mt35 mb35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8" class="mb20">
|
|
||||||
<el-form-item :label="$t('message.formI18nLabel.name')">
|
|
||||||
<el-input v-model="state.form.name" :placeholder="$t('message.formI18nPlaceholder.name')" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8" class="mb20">
|
|
||||||
<el-form-item :label="$t('message.formI18nLabel.email')">
|
|
||||||
<el-input v-model="state.form.email" :placeholder="$t('message.formI18nPlaceholder.email')" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="8" :xl="8" class="mb20">
|
|
||||||
<el-form-item :label="$t('message.formI18nLabel.autograph')">
|
|
||||||
<el-input v-model="state.form.autograph" :placeholder="$t('message.formI18nPlaceholder.autograph')" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFormI18n">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const { locale } = useI18n();
|
|
||||||
const state = reactive({
|
|
||||||
radio: 'zh-cn',
|
|
||||||
form: {
|
|
||||||
name: '',
|
|
||||||
email: '',
|
|
||||||
autograph: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 单选框改变时
|
|
||||||
const onRadioChange = () => {
|
|
||||||
locale.value = state.radio;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="form-rules-one-container">
|
|
||||||
<el-form :model="state.form" :rules="state.rules" ref="formRulesOneRef" size="default" label-width="100px" class="mt35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="姓名" prop="name">
|
|
||||||
<el-input v-model="state.form.name" placeholder="请输入姓名" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="邮箱" prop="email">
|
|
||||||
<el-input v-model="state.form.email" placeholder="请输入用户邮箱" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="登陆账户名" prop="autograph">
|
|
||||||
<el-input v-model="state.form.autograph" placeholder="请输入登陆账户名" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="职务" prop="occupation">
|
|
||||||
<el-select v-model="state.form.occupation" placeholder="请选择职务" clearable class="w100">
|
|
||||||
<el-option label="计算机 / 互联网 / 通信" value="1"></el-option>
|
|
||||||
<el-option label="生产 / 工艺 / 制造" value="2"></el-option>
|
|
||||||
<el-option label="医疗 / 护理 / 制药" value="3"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFormRulesOne">
|
|
||||||
import { reactive, onMounted } from 'vue';
|
|
||||||
|
|
||||||
// 定义父组件传过来的值
|
|
||||||
const props = defineProps({
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
form: { name: '', email: '', autograph: '', occupation: '' },
|
|
||||||
rules: {
|
|
||||||
name: { required: true, message: '请输入姓名', trigger: 'blur' },
|
|
||||||
email: { required: true, message: '请输入用户邮箱', trigger: 'blur' },
|
|
||||||
autograph: { required: true, message: '请输入登陆账户名', trigger: 'blur' },
|
|
||||||
occupation: { required: true, message: '请选择职务', trigger: 'change' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 赋值回显
|
|
||||||
const initForm = () => {
|
|
||||||
state.form = props.data as TableRulesOneProps;
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initForm();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="form-rules-three-container">
|
|
||||||
<el-form :model="state.form" :rules="state.rules" ref="formRulesThreeRef" size="default" label-width="100px" class="mt35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="创建用户" prop="createUser">
|
|
||||||
<el-input v-model="state.form.createUser" placeholder="请输入创建用户" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="修改用户" prop="editUser">
|
|
||||||
<el-input v-model="state.form.editUser" placeholder="请输入修改用户" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="所属用户" prop="user">
|
|
||||||
<el-input v-model="state.form.user" placeholder="请输入所属用户" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="所属部门" prop="department">
|
|
||||||
<el-input v-model="state.form.department" placeholder="请输入所属部门" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFormRulesThree">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
form: { createUser: '', editUser: '', user: '', department: '' },
|
|
||||||
rules: {
|
|
||||||
createUser: { required: true, message: '请输入创建用户', trigger: 'blur' },
|
|
||||||
editUser: { required: true, message: '请输入修改用户', trigger: 'blur' },
|
|
||||||
user: { required: true, message: '请输入所属用户', trigger: 'blur' },
|
|
||||||
department: { required: true, message: '请输入所属部门', trigger: 'blur' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="form-rules-two-container">
|
|
||||||
<el-form :model="state.form" :rules="state.rules" ref="formRulesTwoRef" size="default" label-width="100px" class="mt35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="手机" prop="phone">
|
|
||||||
<el-input v-model="state.form.phone" placeholder="请输入手机" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="性别">
|
|
||||||
<el-select v-model="state.form.sex" placeholder="请选择性别" clearable class="w100">
|
|
||||||
<el-option label="男" value="1"></el-option>
|
|
||||||
<el-option label="女" value="2"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="登录密码" prop="password">
|
|
||||||
<el-input v-model="state.form.password" placeholder="请输入登录密码" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="权限角色" prop="auth">
|
|
||||||
<el-input v-model="state.form.auth" placeholder="请输入权限角色" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFormRulesTwo">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
form: { phone: '', sex: '', password: '', auth: '' },
|
|
||||||
rules: {
|
|
||||||
phone: { required: true, message: '请输入手机', trigger: 'blur' },
|
|
||||||
password: { required: true, message: '请输入登录密码', trigger: 'blur' },
|
|
||||||
auth: { required: true, message: '请输入权限角色', trigger: 'blur' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="form-rules-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="表单组件1"> <FormRulesOne :data="state.formRulesOneData" ref="pagesFormRulesOneRef" /></el-card>
|
|
||||||
<el-card shadow="hover" header="表单组件2" class="mt15"><FormRulesTwo ref="pagesFormRulesTwoRef" /> </el-card>
|
|
||||||
<el-card shadow="hover" header="表单组件3" class="mt15"> <FormRulesThree ref="pagesFormRulesThreeRef" /></el-card>
|
|
||||||
<el-row class="flex mt15">
|
|
||||||
<div class="flex-margin">
|
|
||||||
<el-button size="default" @click="onResetForm">
|
|
||||||
<SvgIcon name="ele-RefreshRight" />
|
|
||||||
重置表单
|
|
||||||
</el-button>
|
|
||||||
<el-button size="default" type="primary" @click="onSubmitForm">
|
|
||||||
<SvgIcon name="iconfont icon-shuxing" />
|
|
||||||
验证表单
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesFormRules">
|
|
||||||
import { defineAsyncComponent, reactive, ref } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const FormRulesOne = defineAsyncComponent(() => import('/@/views/pages/formRules/component/formRulesOne.vue'));
|
|
||||||
const FormRulesTwo = defineAsyncComponent(() => import('/@/views/pages/formRules/component/formRulesTwo.vue'));
|
|
||||||
const FormRulesThree = defineAsyncComponent(() => import('/@/views/pages/formRules/component/formRulesThree.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const pagesFormRulesOneRef = ref();
|
|
||||||
const pagesFormRulesTwoRef = ref();
|
|
||||||
const pagesFormRulesThreeRef = ref();
|
|
||||||
const state = reactive({
|
|
||||||
formRulesOneData: {
|
|
||||||
name: 'lyt',
|
|
||||||
email: 'lyt123@.com',
|
|
||||||
autograph: 'lyt123456',
|
|
||||||
occupation: '1',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单组件验证
|
|
||||||
const formRulesValidate = (pageRef: RefType, sonRef: string) => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
pageRef.value.$refs[sonRef].validate((valid: boolean) => {
|
|
||||||
if (valid) resolve(valid);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 表单组件重置
|
|
||||||
const formRulesResetFields = () => {
|
|
||||||
pagesFormRulesOneRef.value.$refs.formRulesOneRef.resetFields();
|
|
||||||
pagesFormRulesTwoRef.value.$refs.formRulesTwoRef.resetFields();
|
|
||||||
pagesFormRulesThreeRef.value.$refs.formRulesThreeRef.resetFields();
|
|
||||||
};
|
|
||||||
// 验证表单
|
|
||||||
const onSubmitForm = () => {
|
|
||||||
Promise.all([
|
|
||||||
formRulesValidate(pagesFormRulesOneRef, 'formRulesOneRef'),
|
|
||||||
formRulesValidate(pagesFormRulesTwoRef, 'formRulesTwoRef'),
|
|
||||||
formRulesValidate(pagesFormRulesThreeRef, 'formRulesThreeRef'),
|
|
||||||
]).then(() => {
|
|
||||||
ElMessage.success('表单全部验证成功');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 重置表单
|
|
||||||
const onResetForm = () => {
|
|
||||||
formRulesResetFields();
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="iconfont-container layout-pd">
|
|
||||||
<el-card shadow="hover" :header="`iconfont 字体图标(自动载入):${state.sheetsIconList.length}个`">
|
|
||||||
<el-row class="iconfont-row">
|
|
||||||
<el-col :xs="12" :sm="8" :md="6" :lg="4" :xl="2" v-for="(v, k) in state.sheetsIconList" :key="k">
|
|
||||||
<div class="iconfont-warp">
|
|
||||||
<div class="flex-margin">
|
|
||||||
<div class="iconfont-warp-value">
|
|
||||||
<i :class="v" class="iconfont"></i>
|
|
||||||
</div>
|
|
||||||
<div class="iconfont-warp-label mt10">{{ v }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesIocnfont">
|
|
||||||
import { reactive, onMounted } from 'vue';
|
|
||||||
import initIconfont from '/@/utils/getStyleSheets';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
sheetsIconList: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化获取 css 样式,这里使用阿里的图标(记得加上前缀 `iconfont`),其它第三方请自行做判断
|
|
||||||
const initGetStyleSheets = () => {
|
|
||||||
initIconfont.ali().then((res: any) => (state.sheetsIconList = res));
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
initGetStyleSheets();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.iconfont-container {
|
|
||||||
.iconfont-row {
|
|
||||||
border-top: 1px solid var(--next-border-color-light);
|
|
||||||
border-left: 1px solid var(--next-border-color-light);
|
|
||||||
.iconfont-warp {
|
|
||||||
text-align: center;
|
|
||||||
border-right: 1px solid var(--next-border-color-light);
|
|
||||||
border-bottom: 1px solid var(--next-border-color-light);
|
|
||||||
height: 120px;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px var(--next-color-dark-hover);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
.iconfont-warp-value {
|
|
||||||
i {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-label {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-value {
|
|
||||||
i {
|
|
||||||
color: #606266;
|
|
||||||
font-size: 32px;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.iconfont-warp-label {
|
|
||||||
color: #99a9bf;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,185 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="lazy-img-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="图片懒加载演示(F12 切换到 Network Img下进行图片加载查看)">
|
|
||||||
<div class="flex-warp" v-if="state.tableData.data.length > 0">
|
|
||||||
<el-row :gutter="15">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb15" v-for="(v, k) in state.tableData.data" :key="k" @click="onTableItemClick(v)">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="item-img" v-loading="v.loading">
|
|
||||||
<img :data-img="v.img" :data-key="k" :data-lazy-img-list="k" />
|
|
||||||
</div>
|
|
||||||
<div class="item-txt">
|
|
||||||
<div class="item-txt-title">{{ v.title }}</div>
|
|
||||||
<div class="item-txt-other">
|
|
||||||
<div style="width: 100%">
|
|
||||||
<div class="item-txt-msg mb10">
|
|
||||||
<span>评价 {{ v.evaluate }}</span>
|
|
||||||
<span class="ml10">收藏 {{ v.collection }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="item-txt-msg item-txt-price">
|
|
||||||
<span class="font-price">
|
|
||||||
<span>¥</span>
|
|
||||||
<span class="font">{{ v.price }}</span>
|
|
||||||
</span>
|
|
||||||
<span>月销{{ v.monSales }}笔</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
<el-empty v-else description="暂无数据"></el-empty>
|
|
||||||
<template v-if="state.tableData.data.length > 0">
|
|
||||||
<el-pagination
|
|
||||||
style="text-align: right"
|
|
||||||
background
|
|
||||||
@size-change="onHandleSizeChange"
|
|
||||||
@current-change="onHandleCurrentChange"
|
|
||||||
:page-sizes="[10, 20, 30]"
|
|
||||||
:current-page="state.tableData.param.pageNum"
|
|
||||||
:page-size="state.tableData.param.pageSize"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
:total="state.tableData.total"
|
|
||||||
>
|
|
||||||
</el-pagination>
|
|
||||||
</template>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesLazyImg">
|
|
||||||
import { reactive, onMounted } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import other from '/@/utils/other';
|
|
||||||
import { filterList } from './mock';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const router = useRouter();
|
|
||||||
const state = reactive({
|
|
||||||
tableData: {
|
|
||||||
data: filterList,
|
|
||||||
total: 99,
|
|
||||||
loading: false,
|
|
||||||
param: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 当前列表项点击
|
|
||||||
const onTableItemClick = (v: FilterListType) => {
|
|
||||||
router.push({
|
|
||||||
path: '/pages/filteringDetails',
|
|
||||||
query: { id: v.id },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 分页点击
|
|
||||||
const onHandleSizeChange = (val: number) => {
|
|
||||||
state.tableData.param.pageSize = val;
|
|
||||||
};
|
|
||||||
// 分页点击
|
|
||||||
const onHandleCurrentChange = (val: number) => {
|
|
||||||
state.tableData.param.pageNum = val;
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(() => {
|
|
||||||
other.lazyImg('[data-lazy-img-list]', state.tableData.data);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.lazy-img-container {
|
|
||||||
.flex-warp {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-content: flex-start;
|
|
||||||
margin: 0 -5px;
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 5px;
|
|
||||||
width: 100%;
|
|
||||||
height: 360px;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
border: 1px solid var(--next-border-color-light);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
|
|
||||||
.item-txt-title {
|
|
||||||
color: var(--el-color-primary) !important;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
.item-img {
|
|
||||||
img {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
transform: translateZ(0) scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-img {
|
|
||||||
width: 100%;
|
|
||||||
height: 215px;
|
|
||||||
overflow: hidden;
|
|
||||||
img {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-txt {
|
|
||||||
flex: 1;
|
|
||||||
padding: 15px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
.item-txt-title {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
display: -webkit-box;
|
|
||||||
color: #666666;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
text-decoration: underline;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-txt-other {
|
|
||||||
flex: 1;
|
|
||||||
align-items: flex-end;
|
|
||||||
display: flex;
|
|
||||||
.item-txt-msg {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #8d8d91;
|
|
||||||
}
|
|
||||||
.item-txt-price {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
.font-price {
|
|
||||||
color: #ff5000;
|
|
||||||
.font {
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,313 +0,0 @@
|
|||||||
// 列表数据
|
|
||||||
export const filterList = [
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/09/e37326cc-4583-48f3-aa00-ecc2392d319d.jpg',
|
|
||||||
title: '36分钟,深圳平均通勤时间出炉!GDP10强城市中仅输杭州',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 1,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/09/78cf72b6-e2d9-459d-a368-470414a027f4679cf4ea-26fa-48c8-9fee-c2d092a91400.png',
|
|
||||||
title: '为爱而动,“红色鹊桥”三八妇女节交友联谊活动助力深圳女孩脱单',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 2,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/09/1faf3c6e-1250-4e6b-b072-4a331553e027.jpg',
|
|
||||||
title: '粤桂协作“背水一战” 解决广西大化县3.7万人饮水难题',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 3,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/09/9fcf6dd4-1e80-4497-bdc9-83dc7246d170.jpg.2',
|
|
||||||
title: '城镇就业女性平均薪酬6847元 女性职场渗透率提升',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 4,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/09/1bd78227-4126-4a43-bdf6-48ead6edd1bf.jpg.2',
|
|
||||||
title: '深圳:实现“从0到1”源头创新,推进大湾区综合性国家科学中心建设!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 5,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/08/9ea943a3-3ae8-4f49-8296-711ec36ef8c6_watermark.png',
|
|
||||||
title: '煖声音第126期|愿你有诗酒趁年华的洒脱,也有岁月沉淀后的坚定从容',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 6,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/08/a95ba232-1422-4f7e-b85f-c61d486c8659.jpg.2',
|
|
||||||
title: '姐妹们一起来吐槽,最不能接受男人的缺点!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 7,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/08/76816bf0-3899-4c7e-bc6e-079b5ba8725e.jpg',
|
|
||||||
title: '民生小事 | 手机遗落出租车 热心民警帮找回',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 8,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/08/28ed70d4-71f5-4abb-bf7b-0294bece9e43.jpg.2',
|
|
||||||
title: '“十三五”:深圳交上靓丽答卷 发展动力加快转换',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 9,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/05/d13ae31f-fd45-431a-b48e-c5895bbc193e.png',
|
|
||||||
title: '深圳湾公园一女子落水,三名男子接力及时施救',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 10,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210704/653/w930h523/20210704/d5d2-krwipas6444058.jpg',
|
|
||||||
title: '36分钟,深圳平均通勤时间出炉!GDP10强城市中仅输杭州',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 1,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210704/766/w930h636/20210704/b1ae-krwipas6332914.jpg',
|
|
||||||
title: '为爱而动,“红色鹊桥”三八妇女节交友联谊活动助力深圳女孩脱单',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 2,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210704/750/w930h620/20210704/2886-krwipas6264821.jpg',
|
|
||||||
title: '粤桂协作“背水一战” 解决广西大化县3.7万人饮水难题',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 3,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210704/750/w930h620/20210704/767c-krwipas6387862.jpg',
|
|
||||||
title: '城镇就业女性平均薪酬6847元 女性职场渗透率提升',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 4,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210704/111/w1024h687/20210704/1f65-krwipas5871436.jpg',
|
|
||||||
title: '盛夏的那考河湿地公园!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 5,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210704/657/w930h527/20210704/7eae-krwipas5866609.jpg',
|
|
||||||
title: '煖声音第126期|愿你有诗酒趁年华的洒脱,也有岁月沉淀后的坚定从容',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 6,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210703/760/w930h630/20210703/124e-krwipas5596390.jpg',
|
|
||||||
title: '姐妹们一起来吐槽,最不能接受男人的缺点!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 7,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210703/27/w930h697/20210703/9630-krwipas5514972.jpg',
|
|
||||||
title: '民生小事 | 手机遗落出租车 热心民警帮找回',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 8,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210703/750/w930h620/20210703/2fe3-krwipas5388050.jpg',
|
|
||||||
title: '“十三五”:深圳交上靓丽答卷 发展动力加快转换',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 9,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210703/724/w930h594/20210703/98b6-krwipas5234060.jpg',
|
|
||||||
title: '深圳湾公园一女子落水,三名男子接力及时施救',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 10,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210703/750/w930h620/20210703/f765-krwipas5194727.jpg',
|
|
||||||
title: '36分钟,深圳平均通勤时间出炉!GDP10强城市中仅输杭州',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 1,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210702/750/w930h620/20210702/5dde-krwipas4724976.jpg',
|
|
||||||
title: '为爱而动,“红色鹊桥”三八妇女节交友联谊活动助力深圳女孩脱单',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 2,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210702/750/w930h620/20210702/f45e-krwipas4566804.jpg',
|
|
||||||
title: '粤桂协作“背水一战” 解决广西大化县3.7万人饮水难题',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 3,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210702/750/w930h620/20210702/5579-krwipas4551382.jpg',
|
|
||||||
title: '城镇就业女性平均薪酬6847元 女性职场渗透率提升',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 4,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210702/750/w930h620/20210702/7c75-krwipas4543661.jpg',
|
|
||||||
title: '深圳:实现“从0到1”源头创新,推进大湾区综合性国家科学中心建设!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 5,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210702/653/w930h523/20210702/ece2-krwipas4411140.jpg',
|
|
||||||
title: '煖声音第126期|愿你有诗酒趁年华的洒脱,也有岁月沉淀后的坚定从容',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 6,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210702/750/w930h620/20210702/f5c2-krwipas4215211.jpg',
|
|
||||||
title: '姐妹们一起来吐槽,最不能接受男人的缺点!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 7,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210701/720/w930h590/20210701/eabc-krwipas3509204.jpg',
|
|
||||||
title: '民生小事 | 手机遗落出租车 热心民警帮找回',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 8,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210701/797/w930h667/20210701/4667-krwipas3365057.jpg',
|
|
||||||
title: '“十三五”:深圳交上靓丽答卷 发展动力加快转换',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 9,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210701/750/w930h620/20210701/baea-krwipas2976622.jpg',
|
|
||||||
title: '民众前往中共一大纪念馆参观',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 10,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://z0.sinaimg.cn/auto/resize?size=235_156&img=http://n.sinaimg.cn/spider20210630/617/w850h567/20210630/5c96-krwipas1819108.jpg',
|
|
||||||
title: '延吉灯光秀美轮美奂 市民徜徉璀璨夜景',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 10,
|
|
||||||
loading: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,178 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="list-adapt-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="列表自适应演示(改变窗口查看效果)">
|
|
||||||
<div class="flex-warp" v-if="state.tableData.data.length > 0">
|
|
||||||
<el-row :gutter="15">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb15" v-for="(v, k) in state.tableData.data" :key="k" @click="onTableItemClick(v)">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<div class="item-img">
|
|
||||||
<img :src="v.img" />
|
|
||||||
</div>
|
|
||||||
<div class="item-txt">
|
|
||||||
<div class="item-txt-title">{{ v.title }}</div>
|
|
||||||
<div class="item-txt-other">
|
|
||||||
<div style="width: 100%">
|
|
||||||
<div class="item-txt-msg mb10">
|
|
||||||
<span>评价 {{ v.evaluate }}</span>
|
|
||||||
<span class="ml10">收藏 {{ v.collection }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="item-txt-msg item-txt-price">
|
|
||||||
<span class="font-price">
|
|
||||||
<span>¥</span>
|
|
||||||
<span class="font">{{ v.price }}</span>
|
|
||||||
</span>
|
|
||||||
<span>月销{{ v.monSales }}笔</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
<el-empty v-else description="暂无数据"></el-empty>
|
|
||||||
<template v-if="state.tableData.data.length > 0">
|
|
||||||
<el-pagination
|
|
||||||
style="text-align: right"
|
|
||||||
background
|
|
||||||
@size-change="onHandleSizeChange"
|
|
||||||
@current-change="onHandleCurrentChange"
|
|
||||||
:page-sizes="[10, 20, 30]"
|
|
||||||
:current-page="state.tableData.param.pageNum"
|
|
||||||
:page-size="state.tableData.param.pageSize"
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
:total="state.tableData.total"
|
|
||||||
>
|
|
||||||
</el-pagination>
|
|
||||||
</template>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesListAdapt">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import { filterList } from './mock';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const router = useRouter();
|
|
||||||
const state = reactive({
|
|
||||||
tableData: {
|
|
||||||
data: filterList,
|
|
||||||
total: 99,
|
|
||||||
loading: false,
|
|
||||||
param: {
|
|
||||||
pageNum: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 当前列表项点击
|
|
||||||
const onTableItemClick = (v: FilterListType) => {
|
|
||||||
router.push({
|
|
||||||
path: '/pages/filteringDetails',
|
|
||||||
query: { id: v.id },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 分页点击
|
|
||||||
const onHandleSizeChange = (val: number) => {
|
|
||||||
state.tableData.param.pageSize = val;
|
|
||||||
};
|
|
||||||
// 分页点击
|
|
||||||
const onHandleCurrentChange = (val: number) => {
|
|
||||||
state.tableData.param.pageNum = val;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.flex-warp {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-content: flex-start;
|
|
||||||
margin: 0 -5px;
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 5px;
|
|
||||||
width: 100%;
|
|
||||||
height: 360px;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
border: 1px solid var(--next-border-color-light);
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
border: 1px solid var(--el-color-primary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
|
|
||||||
.item-txt-title {
|
|
||||||
color: var(--el-color-primary) !important;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
.item-img {
|
|
||||||
img {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
transform: translateZ(0) scale(1.05);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-img {
|
|
||||||
width: 100%;
|
|
||||||
height: 215px;
|
|
||||||
overflow: hidden;
|
|
||||||
img {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-txt {
|
|
||||||
flex: 1;
|
|
||||||
padding: 15px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
.item-txt-title {
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
display: -webkit-box;
|
|
||||||
color: #666666;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
&:hover {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
text-decoration: underline;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.item-txt-other {
|
|
||||||
flex: 1;
|
|
||||||
align-items: flex-end;
|
|
||||||
display: flex;
|
|
||||||
.item-txt-msg {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #8d8d91;
|
|
||||||
}
|
|
||||||
.item-txt-price {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
.font-price {
|
|
||||||
color: #ff5000;
|
|
||||||
.font {
|
|
||||||
font-size: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
// 列表数据
|
|
||||||
export const filterList = [
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/09/e37326cc-4583-48f3-aa00-ecc2392d319d.jpg',
|
|
||||||
title: '36分钟,深圳平均通勤时间出炉!GDP10强城市中仅输杭州',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/09/78cf72b6-e2d9-459d-a368-470414a027f4679cf4ea-26fa-48c8-9fee-c2d092a91400.png',
|
|
||||||
title: '为爱而动,“红色鹊桥”三八妇女节交友联谊活动助力深圳女孩脱单',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/09/1faf3c6e-1250-4e6b-b072-4a331553e027.jpg',
|
|
||||||
title: '粤桂协作“背水一战” 解决广西大化县3.7万人饮水难题',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/09/9fcf6dd4-1e80-4497-bdc9-83dc7246d170.jpg.2',
|
|
||||||
title: '城镇就业女性平均薪酬6847元 女性职场渗透率提升',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 4,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/09/1bd78227-4126-4a43-bdf6-48ead6edd1bf.jpg.2',
|
|
||||||
title: '深圳:实现“从0到1”源头创新,推进大湾区综合性国家科学中心建设!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/08/9ea943a3-3ae8-4f49-8296-711ec36ef8c6_watermark.png',
|
|
||||||
title: '煖声音第126期|愿你有诗酒趁年华的洒脱,也有岁月沉淀后的坚定从容',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 6,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/08/a95ba232-1422-4f7e-b85f-c61d486c8659.jpg.2',
|
|
||||||
title: '姐妹们一起来吐槽,最不能接受男人的缺点!',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 7,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/08/76816bf0-3899-4c7e-bc6e-079b5ba8725e.jpg',
|
|
||||||
title: '民生小事 | 手机遗落出租车 热心民警帮找回',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 8,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'https://news.sznews.com/pic/2021-03/08/28ed70d4-71f5-4abb-bf7b-0294bece9e43.jpg.2',
|
|
||||||
title: '“十三五”:深圳交上靓丽答卷 发展动力加快转换',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 9,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
img: 'http://news.sznews.com/pic/2021-03/05/d13ae31f-fd45-431a-b48e-c5895bbc193e.png',
|
|
||||||
title: '深圳湾公园一女子落水,三名男子接力及时施救',
|
|
||||||
evaluate: (Math.random() * 10).toFixed(2),
|
|
||||||
collection: (Math.random() * 100).toFixed(2),
|
|
||||||
price: (Math.random() * 10).toFixed(2),
|
|
||||||
monSales: (Math.random() * 20).toFixed(2),
|
|
||||||
id: 10,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="preview-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="element-plus 大图预览">
|
|
||||||
<el-image style="width: 100px; height: 100px; border-radius: 5px" :src="state.url" :preview-src-list="state.srcList" title="点击查看大图预览" />
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesPreview">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
url: 'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500',
|
|
||||||
srcList: [
|
|
||||||
'https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500',
|
|
||||||
'https://img2.baidu.com/it/u=2370931438,70387529&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
|
|
||||||
'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F0%2F582fc47531494.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1671617723&t=024966ede9f71fb7c39f6b06a712c1e3',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="steps-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="element-plus 步骤条">
|
|
||||||
<el-steps :active="stepsActive">
|
|
||||||
<el-step title="第一步">
|
|
||||||
<template #icon>
|
|
||||||
<SvgIcon name="iconfont icon-0_round_solid" :size="40" />
|
|
||||||
</template>
|
|
||||||
</el-step>
|
|
||||||
<el-step title="第二步">
|
|
||||||
<template #icon>
|
|
||||||
<SvgIcon name="iconfont icon-2_round_solid" :size="40" />
|
|
||||||
</template>
|
|
||||||
</el-step>
|
|
||||||
<el-step title="第三步">
|
|
||||||
<template #icon>
|
|
||||||
<SvgIcon name="iconfont icon-3_round_solid" :size="40" />
|
|
||||||
</template>
|
|
||||||
</el-step>
|
|
||||||
</el-steps>
|
|
||||||
<el-result icon="success" title="成功提示" subTitle="请根据提示进行操作" v-if="stepsActive === 1"> </el-result>
|
|
||||||
<el-result icon="warning" title="警告提示" subTitle="请根据提示进行操作" v-else-if="stepsActive === 2"> </el-result>
|
|
||||||
<el-result icon="error" title="错误提示" subTitle="请根据提示进行操作" v-else-if="stepsActive === 3"> </el-result>
|
|
||||||
<el-button @click="onNextSteps" size="default" class="mt15" type="primary">
|
|
||||||
<SvgIcon name="iconfont icon-step" />
|
|
||||||
下一步
|
|
||||||
</el-button>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesSteps">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const stepsActive = ref(1);
|
|
||||||
|
|
||||||
// 下一步点击
|
|
||||||
const onNextSteps = () => {
|
|
||||||
if (stepsActive.value++ > 2) stepsActive.value = 1;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-card shadow="hover" header="表单表格验证">
|
|
||||||
<el-form ref="tableRulesRef" :model="state.tableData" size="default">
|
|
||||||
<el-table :data="state.tableData.data" border class="module-table-uncollected">
|
|
||||||
<el-table-column
|
|
||||||
v-for="(item, index) in state.tableData.header"
|
|
||||||
:key="index"
|
|
||||||
show-overflow-tooltip
|
|
||||||
:prop="item.prop"
|
|
||||||
:width="item.width"
|
|
||||||
:label="item.label"
|
|
||||||
>
|
|
||||||
<template v-slot:header>
|
|
||||||
<span v-if="item.isRequired" class="color-danger">*</span>
|
|
||||||
<span class="pl5">{{ item.label }}</span>
|
|
||||||
<el-tooltip v-if="item.isTooltip" effect="dark" content="这是tooltip" placement="top">
|
|
||||||
<i class="iconfont icon-quanxian" />
|
|
||||||
</el-tooltip>
|
|
||||||
</template>
|
|
||||||
<template v-slot="scope">
|
|
||||||
<el-form-item
|
|
||||||
:prop="`data.${scope.$index}.${item.prop}`"
|
|
||||||
:rules="[{ required: item.isRequired, message: '不能为空', trigger: `${item.type}` == 'input' ? 'blur' : 'change' }]"
|
|
||||||
>
|
|
||||||
<el-select v-if="item.type === 'select'" v-model="scope.row[item.prop]" placeholder="请选择">
|
|
||||||
<el-option v-for="sel in state.tableData.option" :key="sel.value" :label="sel.label" :value="sel.value" />
|
|
||||||
</el-select>
|
|
||||||
<el-date-picker
|
|
||||||
v-else-if="item.type === 'date'"
|
|
||||||
v-model="scope.row[item.prop]"
|
|
||||||
type="date"
|
|
||||||
placeholder="选择日期"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<el-input v-else-if="item.type === 'input'" v-model="scope.row[item.prop]" placeholder="请输入内容" />
|
|
||||||
<el-input v-else-if="item.type === 'dialog'" v-model="scope.row[item.prop]" readonly placeholder="请输入内容">
|
|
||||||
<template v-slot:suffix>
|
|
||||||
<i class="iconfont icon-shouye_dongtaihui" />
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-form>
|
|
||||||
<el-row class="flex mt15">
|
|
||||||
<div class="flex-margin">
|
|
||||||
<el-button size="default" type="success" @click="onValidate(tableRulesRef)">表格验证</el-button>
|
|
||||||
<el-button size="default" type="primary" @click="onAddRow">新增一行</el-button>
|
|
||||||
</div>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesTableRules">
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import type { FormInstance } from 'element-plus';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const tableRulesRef = ref<FormInstance>();
|
|
||||||
const state = reactive<TableRulesState>({
|
|
||||||
tableData: {
|
|
||||||
data: [],
|
|
||||||
header: [
|
|
||||||
{ prop: 'a1', width: '', label: '一级分类', isRequired: true, type: 'select' },
|
|
||||||
{ prop: 'a2', width: '', label: '二级分类', isRequired: true, type: 'select' },
|
|
||||||
{ prop: 'a3', width: '', label: '三级分类', isRequired: true, type: 'select' },
|
|
||||||
{ prop: 'a4', width: '', label: '四级分类', isRequired: true, type: 'date' },
|
|
||||||
{ prop: 'a5', width: '', label: '五级分类', isRequired: true, type: 'input' },
|
|
||||||
{ prop: 'a6', width: '', label: '六级分类', isTooltip: true, type: 'dialog' },
|
|
||||||
{ prop: 'a7', width: '', label: '演示级分类', type: 'input' },
|
|
||||||
{ prop: 'a8', width: '', label: '颜色是分类', type: 'input' },
|
|
||||||
],
|
|
||||||
option: [
|
|
||||||
{ value: '选项1', label: '黄金糕' },
|
|
||||||
{ value: '选项2', label: '双皮奶' },
|
|
||||||
{ value: '选项3', label: '蚵仔煎' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表格验证
|
|
||||||
const onValidate = (formEl: FormInstance | undefined) => {
|
|
||||||
if (state.tableData.data.length <= 0) return ElMessage.warning('请先点击增加一行');
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate((valid) => {
|
|
||||||
if (!valid) return ElMessage.warning('表格项必填未填');
|
|
||||||
ElMessage.success('全部验证通过');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 新增一行
|
|
||||||
const onAddRow = () => {
|
|
||||||
state.tableData.data.push({
|
|
||||||
a1: '',
|
|
||||||
a2: '',
|
|
||||||
a3: '',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
a6: '',
|
|
||||||
a7: '',
|
|
||||||
a8: '',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="tree-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="element plus Tree 树形控件改成表格">
|
|
||||||
<div v-loading="state.treeLoading">
|
|
||||||
<div class="tree-head">
|
|
||||||
<div class="tree-head-check"><el-checkbox v-model="state.treeCheckAll" @change="onCheckAllChange"></el-checkbox></div>
|
|
||||||
<div class="tree-head-one">商品 ID</div>
|
|
||||||
<div style="flex: 1; display: flex">
|
|
||||||
<div class="tree-head-two">商品名称</div>
|
|
||||||
<div class="tree-head-three">描述</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-tree :data="state.treeTableData" show-checkbox node-key="id" ref="treeTableRef" :props="state.treeDefaultProps" @check="onCheckTree">
|
|
||||||
<template #default="{ node, data }">
|
|
||||||
<span class="tree-custom-node">
|
|
||||||
<span style="flex: 1">{{ node.label }}</span>
|
|
||||||
<span v-if="data.isShow" style="flex: 1; display: flex">
|
|
||||||
<span style="flex: 1">{{ data.label1 }}</span>
|
|
||||||
<span style="flex: 1">{{ data.label2 }}</span>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-tree>
|
|
||||||
</div>
|
|
||||||
<el-button @click="onSelect" class="mt15" size="default" type="primary">
|
|
||||||
<SvgIcon name="iconfont icon-shuxingtu" />
|
|
||||||
选择元素
|
|
||||||
</el-button>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesTree">
|
|
||||||
import { reactive, onBeforeMount, ref } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const treeTableRef = ref();
|
|
||||||
const state = reactive({
|
|
||||||
treeCheckAll: false,
|
|
||||||
treeLoading: false,
|
|
||||||
treeTableData: [] as RowTreeType[],
|
|
||||||
treeDefaultProps: {
|
|
||||||
children: 'children',
|
|
||||||
label: 'label',
|
|
||||||
},
|
|
||||||
treeSelArr: [] as RowTreeType[],
|
|
||||||
treeLength: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 初始化树的长度
|
|
||||||
const initTreeLengh = (arr: RowTreeType[]) => {
|
|
||||||
let count = 0;
|
|
||||||
arr.map((item) => {
|
|
||||||
if (item.children) {
|
|
||||||
count += item.children.length;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
state.treeLength = count + arr.length;
|
|
||||||
};
|
|
||||||
// 全选改变时
|
|
||||||
const onCheckAllChange = () => {
|
|
||||||
if (state.treeCheckAll) {
|
|
||||||
treeTableRef.value.setCheckedNodes(state.treeTableData);
|
|
||||||
} else {
|
|
||||||
treeTableRef.value.setCheckedKeys([]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 节点选中状态发生变化时的回调
|
|
||||||
const onCheckTree = () => {
|
|
||||||
state.treeSelArr = [];
|
|
||||||
state.treeSelArr = treeTableRef.value.getCheckedNodes();
|
|
||||||
state.treeSelArr.length == state.treeLength ? (state.treeCheckAll = true) : (state.treeCheckAll = false);
|
|
||||||
};
|
|
||||||
// 选择元素按钮
|
|
||||||
const onSelect = () => {
|
|
||||||
let treeArr = treeTableRef.value.getCheckedNodes();
|
|
||||||
if (treeArr.length <= 0) {
|
|
||||||
ElMessage.warning('请选择元素');
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
// console.log(treeTableRef.value.getCheckedNodes());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 初始化树模拟数据
|
|
||||||
const getTreeData = () => {
|
|
||||||
state.treeTableData = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
label: '12987121',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: true,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 11,
|
|
||||||
label: '一级 1-1',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 12,
|
|
||||||
label: '一级 1-2',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
label: '12987122',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: true,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 21,
|
|
||||||
label: '二级 2-1',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 22,
|
|
||||||
label: '二级 2-2',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
label: '12987123',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: true,
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
id: 31,
|
|
||||||
label: '二级 3-1',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 32,
|
|
||||||
label: '二级 3-2',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 33,
|
|
||||||
label: '二级 3-3',
|
|
||||||
label1: '好滋好味鸡蛋仔',
|
|
||||||
label2: '荷兰优质淡奶,奶香浓而不腻',
|
|
||||||
isShow: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
initTreeLengh(state.treeTableData);
|
|
||||||
};
|
|
||||||
// 页面加载前
|
|
||||||
onBeforeMount(() => {
|
|
||||||
getTreeData();
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.tree-container {
|
|
||||||
.tree-head {
|
|
||||||
height: 48px;
|
|
||||||
line-height: 48px;
|
|
||||||
border: 1px solid var(--next-border-color-light);
|
|
||||||
border-bottom: none;
|
|
||||||
display: flex;
|
|
||||||
padding-right: 8px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #909399;
|
|
||||||
.tree-head-check {
|
|
||||||
width: 38px;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
.tree-head-one,
|
|
||||||
.tree-head-two,
|
|
||||||
.tree-head-three {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.tree-head-one {
|
|
||||||
padding-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.el-tree {
|
|
||||||
overflow: hidden;
|
|
||||||
border-bottom: 1px solid var(--next-border-color-light);
|
|
||||||
.tree-custom-node {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding-right: 8px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
&:deep(.el-tree-node) {
|
|
||||||
border: 1px solid var(--next-border-color-light);
|
|
||||||
border-bottom: none;
|
|
||||||
color: #606266;
|
|
||||||
.el-tree-node__content {
|
|
||||||
line-height: 57px !important;
|
|
||||||
height: 57px !important;
|
|
||||||
}
|
|
||||||
.el-tree-node__children {
|
|
||||||
.el-tree-node {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
.el-tree-node__content {
|
|
||||||
border-top: 1px solid var(--next-border-color-light);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="waterfall-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="瀑布屏(布局一)" class="mb15">
|
|
||||||
<div class="waterfall-first">
|
|
||||||
<div class="waterfall-first-item" v-for="v in 30" :key="v" v-waves>
|
|
||||||
<div class="w100 h100 flex">
|
|
||||||
<span class="flex-margin">{{ v }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
<el-card shadow="hover" header="瀑布屏(布局二)">
|
|
||||||
<div class="waterfall-last">
|
|
||||||
<div class="waterfall-last-item" v-for="v in 30" :key="v" v-waves="'light'">
|
|
||||||
<div class="w100 h100 flex">
|
|
||||||
<span class="flex-margin">{{ v }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWaterfall">
|
|
||||||
// 此处需有内容(注释也得),否则缓存将失败
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.waterfall-container {
|
|
||||||
.waterfall-first {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(188px, 1fr));
|
|
||||||
grid-gap: 0.25em;
|
|
||||||
grid-auto-flow: row dense;
|
|
||||||
grid-auto-rows: 20px;
|
|
||||||
.waterfall-first-item {
|
|
||||||
width: 100%;
|
|
||||||
background: var(--el-color-primary);
|
|
||||||
color: var(--el-color-white);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border-radius: 3px;
|
|
||||||
&:nth-of-type(3n + 1) {
|
|
||||||
grid-row: auto / span 5;
|
|
||||||
}
|
|
||||||
&:nth-of-type(3n + 2) {
|
|
||||||
grid-row: auto / span 6;
|
|
||||||
}
|
|
||||||
&:nth-of-type(3n + 3) {
|
|
||||||
grid-row: auto / span 8;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.waterfall-last {
|
|
||||||
display: grid;
|
|
||||||
grid-gap: 0.25em;
|
|
||||||
grid-auto-flow: row dense;
|
|
||||||
grid-auto-rows: minmax(188px, 20vmin);
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
.waterfall-last-item {
|
|
||||||
height: 100%;
|
|
||||||
background: var(--el-color-primary);
|
|
||||||
color: var(--el-color-white);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border-radius: 3px;
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 576px) {
|
|
||||||
.waterfall-last {
|
|
||||||
grid-template-columns: repeat(7, 1fr);
|
|
||||||
.waterfall-last-item {
|
|
||||||
&:nth-of-type(9n + 9) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 8) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 7) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 6) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 5) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 4) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 3) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 2) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(9n + 1) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 576px) and (min-width: 1024px) {
|
|
||||||
.waterfall-last {
|
|
||||||
grid-template-columns: repeat(14, 1fr);
|
|
||||||
.waterfall-last-item {
|
|
||||||
&:nth-of-type(15n + 15) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 14) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 13) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 12) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 11) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 10) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 9) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 8) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 7) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 6) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 5) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 4) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 3) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 2) {
|
|
||||||
grid-column: auto / span 3;
|
|
||||||
}
|
|
||||||
&:nth-of-type(15n + 1) {
|
|
||||||
grid-column: auto / span 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="preview-container layout-pd">
|
|
||||||
<el-card shadow="hover" header="波浪指令效果(v-waves)作用于 btn">
|
|
||||||
<el-row class="mb10" style="color: #808080">可选参数 v-waves=" |light|red|orange|purple|green|teal"</el-row>
|
|
||||||
<div class="flex-warp">
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button size="default" v-waves>
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
默认效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default" v-waves="'light'">
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
light 效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="success" size="default" v-waves="'red'">
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
red 效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="info" size="default" v-waves="'orange'">
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
orange 效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="warning" size="default" v-waves="'purple'">
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
purple 效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="danger" size="default" v-waves="'green'">
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
green 效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="flex-warp-item">
|
|
||||||
<div class="flex-warp-item-box">
|
|
||||||
<el-button type="primary" size="default" v-waves="'teal'">
|
|
||||||
<SvgIcon name="iconfont icon-bolangnengshiyanchang" />
|
|
||||||
teal 效果
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
<el-card shadow="hover" header="波浪指令效果(v-waves)作用于 div" class="mt15">
|
|
||||||
<div class="waterfall-first">
|
|
||||||
<div class="waterfall-first-item" v-for="v in 12" :key="v" v-waves>
|
|
||||||
<div class="w100 h100 flex">
|
|
||||||
<span class="flex-margin">{{ v }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWaves">
|
|
||||||
// 此处需有内容(注释也得),否则缓存将失败
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.preview-container {
|
|
||||||
.flex-warp {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-content: flex-start;
|
|
||||||
margin: 0 -5px;
|
|
||||||
.flex-warp-item {
|
|
||||||
padding: 5px;
|
|
||||||
.flex-warp-item-box {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.waterfall-first {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(188px, 1fr));
|
|
||||||
grid-gap: 0.25em;
|
|
||||||
grid-auto-flow: row dense;
|
|
||||||
grid-auto-rows: 20px;
|
|
||||||
.waterfall-first-item {
|
|
||||||
width: 100%;
|
|
||||||
background: var(--el-color-primary);
|
|
||||||
color: var(--el-color-white);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border-radius: 3px;
|
|
||||||
&:nth-of-type(3n + 1) {
|
|
||||||
grid-row: auto / span 5;
|
|
||||||
}
|
|
||||||
&:nth-of-type(3n + 2) {
|
|
||||||
grid-row: auto / span 6;
|
|
||||||
}
|
|
||||||
&:nth-of-type(3n + 3) {
|
|
||||||
grid-row: auto / span 8;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
<template>
|
|
||||||
<transition name="el-zoom-in-center" ref="contextmenuRef">
|
|
||||||
<div
|
|
||||||
aria-hidden="true"
|
|
||||||
class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
|
|
||||||
role="tooltip"
|
|
||||||
data-popper-placement="bottom"
|
|
||||||
:style="`top: ${dropdowns.y + 5}px;left: ${dropdowns.x}px;`"
|
|
||||||
:key="Math.random()"
|
|
||||||
v-show="state.isShow"
|
|
||||||
>
|
|
||||||
<ul class="el-dropdown-menu">
|
|
||||||
<li
|
|
||||||
v-for="(v, k) in state.dropdownList"
|
|
||||||
class="el-dropdown-menu__item"
|
|
||||||
aria-disabled="false"
|
|
||||||
tabindex="-1"
|
|
||||||
:key="k"
|
|
||||||
@click="onCurrentClick(v.contextMenuClickId)"
|
|
||||||
>
|
|
||||||
<SvgIcon :name="v.icon" />
|
|
||||||
<span>{{ v.txt }}{{ state.item.type === 'line' ? '线' : '节点' }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="el-popper__arrow" style="left: 10px"></div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflowContextmenu">
|
|
||||||
import { computed, reactive, onMounted, onUnmounted, ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义父组件传过来的值
|
|
||||||
const props = defineProps({
|
|
||||||
dropdown: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {
|
|
||||||
return { x: '', y: '' };
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
|
||||||
const emit = defineEmits(['current']);
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const contextmenuRef = ref();
|
|
||||||
const state = reactive({
|
|
||||||
isShow: false,
|
|
||||||
dropdownList: [
|
|
||||||
{ contextMenuClickId: 0, txt: '删除', icon: 'ele-Delete' },
|
|
||||||
{ contextMenuClickId: 1, txt: '编辑', icon: 'ele-Edit' },
|
|
||||||
],
|
|
||||||
item: {
|
|
||||||
type: 'node',
|
|
||||||
},
|
|
||||||
conn: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 父级传过来的坐标 x,y 值
|
|
||||||
const dropdowns = computed(() => {
|
|
||||||
return props.dropdown;
|
|
||||||
});
|
|
||||||
// 当前项菜单点击
|
|
||||||
const onCurrentClick = (contextMenuClickId: number) => {
|
|
||||||
emit('current', Object.assign({}, { contextMenuClickId }, state.item), state.conn);
|
|
||||||
};
|
|
||||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
|
||||||
const openContextmenu = (item: WorkflowDrawerLabelType, conn = {}) => {
|
|
||||||
state.item = item;
|
|
||||||
state.conn = conn;
|
|
||||||
closeContextmenu();
|
|
||||||
setTimeout(() => {
|
|
||||||
state.isShow = true;
|
|
||||||
}, 10);
|
|
||||||
};
|
|
||||||
// 关闭右键菜单
|
|
||||||
const closeContextmenu = () => {
|
|
||||||
state.isShow = false;
|
|
||||||
};
|
|
||||||
// 监听页面监听进行右键菜单的关闭
|
|
||||||
onMounted(() => {
|
|
||||||
document.body.addEventListener('click', closeContextmenu);
|
|
||||||
document.body.addEventListener('contextmenu', closeContextmenu);
|
|
||||||
});
|
|
||||||
// 页面卸载时,移除右键菜单监听事件
|
|
||||||
onUnmounted(() => {
|
|
||||||
document.body.removeEventListener('click', closeContextmenu);
|
|
||||||
document.body.removeEventListener('contextmenu', closeContextmenu);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
openContextmenu,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.custom-contextmenu {
|
|
||||||
transform-origin: center top;
|
|
||||||
z-index: 2190;
|
|
||||||
position: fixed;
|
|
||||||
.el-dropdown-menu__item {
|
|
||||||
font-size: 12px !important;
|
|
||||||
white-space: nowrap;
|
|
||||||
i {
|
|
||||||
font-size: 12px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div>
|
|
||||||
<el-drawer :title="`${state.nodeData.type === 'line' ? '线' : '节点'}操作`" v-model="state.isOpen" size="320px">
|
|
||||||
<el-scrollbar>
|
|
||||||
<Lines v-if="state.nodeData.type === 'line'" @change="onLineChange" @close="close" ref="lineRef" />
|
|
||||||
<Nodes v-else @submit="onNodeSubmit" @close="close" ref="nodeRef" />
|
|
||||||
</el-scrollbar>
|
|
||||||
</el-drawer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflowDrawer">
|
|
||||||
import { defineAsyncComponent, reactive, ref, nextTick } from 'vue';
|
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
|
||||||
const emit = defineEmits(['label', 'node']);
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const Lines = defineAsyncComponent(() => import('./line.vue'));
|
|
||||||
const Nodes = defineAsyncComponent(() => import('./node.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const lineRef = ref();
|
|
||||||
const nodeRef = ref();
|
|
||||||
const state = reactive<WorkflowDrawerState>({
|
|
||||||
isOpen: false,
|
|
||||||
nodeData: {
|
|
||||||
type: 'node',
|
|
||||||
},
|
|
||||||
jsplumbConn: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 打开抽屉
|
|
||||||
const open = (item: WorkflowDrawerLabelType, conn: EmptyObjectType) => {
|
|
||||||
state.isOpen = true;
|
|
||||||
state.jsplumbConn = conn;
|
|
||||||
state.nodeData = item;
|
|
||||||
nextTick(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (item.type === 'line') lineRef.value.getParentData(item);
|
|
||||||
else nodeRef.value.getParentData(item);
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 关闭
|
|
||||||
const close = () => {
|
|
||||||
state.isOpen = false;
|
|
||||||
};
|
|
||||||
// 线 label 内容改变时
|
|
||||||
const onLineChange = (label: string) => {
|
|
||||||
state.jsplumbConn.label = label;
|
|
||||||
emit('label', state.jsplumbConn);
|
|
||||||
};
|
|
||||||
// 节点内容改变时
|
|
||||||
const onNodeSubmit = (data: object) => {
|
|
||||||
emit('node', data);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
open,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="pt15 pr15 pb15 pl15">
|
|
||||||
<el-form :model="state.line" size="default" label-width="50px">
|
|
||||||
<el-form-item label="来往">
|
|
||||||
<el-input v-model="state.line.contact" placeholder="来往" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="类型">
|
|
||||||
<el-input v-model="state.line.type" placeholder="类型" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="label">
|
|
||||||
<el-input v-model="state.line.label" placeholder="请输入label内容" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button @click="onLineTextReset">
|
|
||||||
<SvgIcon name="ele-RefreshRight" />
|
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button @click="onLineTextChange" type="primary">
|
|
||||||
<SvgIcon name="ele-Check" />
|
|
||||||
保存
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflowDrawerLine">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
|
||||||
const emit = defineEmits(['change', 'close']);
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive<EmptyObjectType>({
|
|
||||||
line: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取父组件数据
|
|
||||||
const getParentData = (data: object) => {
|
|
||||||
state.line = data;
|
|
||||||
};
|
|
||||||
// 重置
|
|
||||||
const onLineTextReset = () => {
|
|
||||||
state.line.label = '';
|
|
||||||
};
|
|
||||||
// 保存
|
|
||||||
const onLineTextChange = () => {
|
|
||||||
emit('change', state.line.label);
|
|
||||||
emit('close');
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
getParentData,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,254 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="workflow-drawer-node">
|
|
||||||
<el-tabs type="border-card" v-model="state.tabsActive">
|
|
||||||
<!-- 节点编辑 -->
|
|
||||||
<el-tab-pane label="节点编辑" name="1">
|
|
||||||
<el-scrollbar>
|
|
||||||
<el-form :model="state.node" :rules="state.nodeRules" ref="nodeFormRef" size="default" label-width="80px" class="pt15 pr15 pb15 pl15">
|
|
||||||
<el-form-item label="数据id" prop="id">
|
|
||||||
<el-input v-model="state.node.id" placeholder="请输入数据id" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="节点id" prop="nodeId">
|
|
||||||
<el-input v-model="state.node.nodeId" placeholder="请输入节点id" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="类型" prop="type">
|
|
||||||
<el-input v-model="state.node.type" placeholder="请输入类型" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="left坐标" prop="left">
|
|
||||||
<el-input v-model="state.node.left" placeholder="请输入left坐标" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="top坐标" prop="top">
|
|
||||||
<el-input v-model="state.node.top" placeholder="请输入top坐标" clearable disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="icon图标" prop="icon">
|
|
||||||
<el-input v-model="state.node.icon" placeholder="请输入icon图标" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="名称" prop="name">
|
|
||||||
<el-input v-model="state.node.name" placeholder="请输入名称" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button class="mb15" @click="onNodeRefresh">
|
|
||||||
<SvgIcon name="ele-RefreshRight" />
|
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" class="mb15" @click="onNodeSubmit">
|
|
||||||
<SvgIcon name="ele-Check" />
|
|
||||||
保存
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</el-scrollbar>
|
|
||||||
</el-tab-pane>
|
|
||||||
|
|
||||||
<!-- 扩展表单 -->
|
|
||||||
<el-tab-pane label="扩展表单" name="2">
|
|
||||||
<el-scrollbar>
|
|
||||||
<el-form :model="state.form" ref="extendFormRef" size="default" label-width="80px" class="pt15 pr15 pb15 pl15">
|
|
||||||
<el-form-item
|
|
||||||
:label="val.label"
|
|
||||||
:prop="val.prop"
|
|
||||||
v-for="(val, key) in state.node.from"
|
|
||||||
:key="key"
|
|
||||||
:rules="[{ required: val.required, message: `${val.label}不能为空`, trigger: 'blur' }]"
|
|
||||||
>
|
|
||||||
<el-input
|
|
||||||
v-model="state.form[val.prop]"
|
|
||||||
:placeholder="val.placeholder"
|
|
||||||
clearable
|
|
||||||
v-if="val.type === 'input'"
|
|
||||||
:disabled="val.disabled"
|
|
||||||
></el-input>
|
|
||||||
<el-select v-model="state.form[val.prop]" placeholder="请选择" v-if="val.type === 'select'" clearable :disabled="val.disabled">
|
|
||||||
<el-option v-for="item in val.options" :key="item.value" :label="item.label" :value="item.value"> </el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-checkbox-group v-model="state.form[val.prop]" v-if="val.type === 'checkbox'" :disabled="val.disabled">
|
|
||||||
<el-checkbox label="美食推荐" name="type"></el-checkbox>
|
|
||||||
<el-checkbox label="统计分析" name="type"></el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button class="mb15" @click="onExtendRefresh">
|
|
||||||
<SvgIcon name="ele-RefreshRight" />
|
|
||||||
重置
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" class="mb15" @click="onExtendSubmit" :loading="state.loading.extend">
|
|
||||||
<SvgIcon name="ele-Check" />
|
|
||||||
保存
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</el-scrollbar>
|
|
||||||
</el-tab-pane>
|
|
||||||
|
|
||||||
<!-- 图表可视化 -->
|
|
||||||
<el-tab-pane label="图表可视化" name="3">
|
|
||||||
<el-scrollbar>
|
|
||||||
<div class="flex-content-right">
|
|
||||||
<div style="height: 200px; width: 320px" ref="chartsMonitorRef"></div>
|
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflowDrawerNode">
|
|
||||||
import { reactive, ref, nextTick } from 'vue';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import * as echarts from 'echarts';
|
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
|
||||||
const emit = defineEmits(['submit', 'close']);
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const nodeFormRef = ref();
|
|
||||||
const extendFormRef = ref();
|
|
||||||
const chartsMonitorRef = ref();
|
|
||||||
const state = reactive<WorkflowDrawerNodeState>({
|
|
||||||
node: {},
|
|
||||||
nodeRules: {
|
|
||||||
id: [{ required: true, message: '请输入数据id', trigger: 'blur' }],
|
|
||||||
nodeId: [{ required: true, message: '请输入节点id', trigger: 'blur' }],
|
|
||||||
type: [{ required: true, message: '请输入类型', trigger: 'blur' }],
|
|
||||||
left: [{ required: true, message: '请输入left坐标', trigger: 'blur' }],
|
|
||||||
top: [{ required: true, message: '请输入top坐标', trigger: 'blur' }],
|
|
||||||
icon: [{ required: true, message: '请输入icon图标', trigger: 'blur' }],
|
|
||||||
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
||||||
},
|
|
||||||
form: {
|
|
||||||
module: [],
|
|
||||||
},
|
|
||||||
tabsActive: '1',
|
|
||||||
loading: {
|
|
||||||
extend: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取父组件数据
|
|
||||||
const getParentData = (data: object) => {
|
|
||||||
state.tabsActive = '1';
|
|
||||||
state.node = data;
|
|
||||||
initChartsMonitor();
|
|
||||||
};
|
|
||||||
// 节点编辑-重置
|
|
||||||
const onNodeRefresh = () => {
|
|
||||||
state.node.icon = '';
|
|
||||||
state.node.name = '';
|
|
||||||
};
|
|
||||||
// 节点编辑-保存
|
|
||||||
const onNodeSubmit = () => {
|
|
||||||
nodeFormRef.value.validate((valid: boolean) => {
|
|
||||||
if (valid) {
|
|
||||||
emit('submit', state.node);
|
|
||||||
emit('close');
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 扩展表单-重置
|
|
||||||
const onExtendRefresh = () => {
|
|
||||||
extendFormRef.value.resetFields();
|
|
||||||
};
|
|
||||||
// 扩展表单-保存
|
|
||||||
const onExtendSubmit = () => {
|
|
||||||
extendFormRef.value.validate((valid: boolean) => {
|
|
||||||
if (valid) {
|
|
||||||
state.loading.extend = true;
|
|
||||||
setTimeout(() => {
|
|
||||||
state.loading.extend = false;
|
|
||||||
ElMessage.success('保存成功');
|
|
||||||
emit('close');
|
|
||||||
}, 1000);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 图表可视化-初始化
|
|
||||||
const initChartsMonitor = () => {
|
|
||||||
const myChart = echarts.init(chartsMonitorRef.value);
|
|
||||||
const numsOne = [];
|
|
||||||
const numsTwo = [];
|
|
||||||
for (let i = 0; i < 7; i++) {
|
|
||||||
numsOne.push(`${Math.floor(Math.random() * 52 + 10)}:${Math.floor(Math.random() * 52 + 1)}`);
|
|
||||||
numsTwo.push(Math.floor(Math.random() * 52 + 1));
|
|
||||||
}
|
|
||||||
const option = {
|
|
||||||
grid: {
|
|
||||||
top: 50,
|
|
||||||
right: 30,
|
|
||||||
bottom: 30,
|
|
||||||
left: 50,
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
data: numsOne,
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
itemStyle: {
|
|
||||||
color: '#289df5',
|
|
||||||
borderColor: '#289df5',
|
|
||||||
areaStyle: {
|
|
||||||
type: 'default',
|
|
||||||
opacity: 0.1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: numsTwo,
|
|
||||||
type: 'line',
|
|
||||||
areaStyle: {},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
nextTick(() => {
|
|
||||||
myChart.resize();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
getParentData,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.workflow-drawer-node {
|
|
||||||
:deep {
|
|
||||||
.el-tabs {
|
|
||||||
box-shadow: unset;
|
|
||||||
border: unset;
|
|
||||||
.el-tabs__nav {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
.el-tabs__item {
|
|
||||||
flex: 1;
|
|
||||||
padding: unset;
|
|
||||||
text-align: center;
|
|
||||||
&:first-of-type.is-active {
|
|
||||||
border-left-color: transparent;
|
|
||||||
}
|
|
||||||
&:last-of-type.is-active {
|
|
||||||
border-right-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.el-tabs__content {
|
|
||||||
padding: 0;
|
|
||||||
height: calc(100vh - 90px);
|
|
||||||
.el-tab-pane {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="workflow-tool-help">
|
|
||||||
<el-dialog v-model="isShow" width="769px">
|
|
||||||
<template #header>
|
|
||||||
<div v-drag="['.workflow-tool-help .el-dialog', '.workflow-tool-help .el-dialog__header']">使用帮助</div>
|
|
||||||
</template>
|
|
||||||
<div>1、拖入:鼠标移入左侧导航中,鼠标形状改变时拖动到右侧网格状的视图中。</div>
|
|
||||||
<div class="mt10">2、移动:鼠标移入到视图中的某个节点元素,鼠标形状改变时拖动改变位置。</div>
|
|
||||||
<div class="mt10">3、连线:鼠标移入到视图中的某个节点元素的icon(图标),鼠标形状改变(变成"+"),按下鼠标左键进行拖线连接。</div>
|
|
||||||
<div class="mt10">4、节点:鼠标移入到视图中的某个节点元素,点击鼠标右键可进行删除、编辑节点。</div>
|
|
||||||
<div class="mt10 mb10">5、线条:鼠标移入到视图中的某个线条,线条颜色改变时,点击鼠标右键可进行删除、编辑线条。</div>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflowToolHelp">
|
|
||||||
import { ref } from 'vue';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const isShow = ref(false);
|
|
||||||
|
|
||||||
// 打开弹窗
|
|
||||||
const open = () => {
|
|
||||||
isShow.value = true;
|
|
||||||
};
|
|
||||||
// 关闭弹窗
|
|
||||||
const close = () => {
|
|
||||||
isShow.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 暴露变量
|
|
||||||
defineExpose({
|
|
||||||
open,
|
|
||||||
close,
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="workflow-tool">
|
|
||||||
<div class="pl15">{{ setToolTitle }}</div>
|
|
||||||
<div class="workflow-tool-right">
|
|
||||||
<div class="workflow-tool-icon" v-for="(v, k) in state.toolList" :key="k" :title="v.title" @click="onToolClick(v.fnName)">
|
|
||||||
<SvgIcon :name="v.icon" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflowTool">
|
|
||||||
import { computed, reactive } from 'vue';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
|
||||||
|
|
||||||
// 定义子组件向父组件传值/事件
|
|
||||||
const emit = defineEmits(['tool']);
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const storesThemeConfig = useThemeConfig();
|
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
||||||
const state = reactive({
|
|
||||||
toolList: [
|
|
||||||
{ icon: 'ele-Help', title: '帮助', fnName: 'help' },
|
|
||||||
{ icon: 'ele-Download', title: '下载', fnName: 'download' },
|
|
||||||
{ icon: 'ele-Check', title: '提交', fnName: 'submit' },
|
|
||||||
{ icon: 'ele-DocumentCopy', title: '复制', fnName: 'copy' },
|
|
||||||
{ icon: 'ele-Delete', title: '删除', fnName: 'del' },
|
|
||||||
{ icon: 'ele-FullScreen', title: '全屏', fnName: 'fullscreen' },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置 tool 标题
|
|
||||||
const setToolTitle = computed(() => {
|
|
||||||
let { globalTitle } = themeConfig.value;
|
|
||||||
return `${globalTitle}工作流`;
|
|
||||||
});
|
|
||||||
// 顶部工具栏
|
|
||||||
const onToolClick = (fnName: string) => {
|
|
||||||
emit('tool', fnName);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.workflow-tool {
|
|
||||||
height: 35px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
border-bottom: 1px solid var(--el-border-color-light, #ebeef5);
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
.workflow-tool-right {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
&-icon {
|
|
||||||
padding: 0 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
color: var(--next-bg-topBarColor);
|
|
||||||
height: 35px;
|
|
||||||
line-height: 35px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
&:hover {
|
|
||||||
background: rgba(0, 0, 0, 0.04);
|
|
||||||
i {
|
|
||||||
display: inline-block;
|
|
||||||
animation: logoAnimation 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,631 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="workflow-container layout-padding">
|
|
||||||
<div class="workflow-mask" v-if="state.isShow"></div>
|
|
||||||
<div class="layout-padding-auto layout-padding-view workflow-warp">
|
|
||||||
<div class="workflow">
|
|
||||||
<!-- 顶部工具栏 -->
|
|
||||||
<Tool @tool="onToolClick" />
|
|
||||||
|
|
||||||
<!-- 左侧导航区 -->
|
|
||||||
<div class="workflow-content">
|
|
||||||
<div class="workflow-left">
|
|
||||||
<el-scrollbar>
|
|
||||||
<div
|
|
||||||
ref="leftNavRefs"
|
|
||||||
v-for="val in state.leftNavList"
|
|
||||||
:key="val.id"
|
|
||||||
:style="{ height: val.isOpen ? 'auto' : '50px', overflow: 'hidden' }"
|
|
||||||
class="workflow-left-id"
|
|
||||||
>
|
|
||||||
<div class="workflow-left-title" @click="onTitleClick(val)">
|
|
||||||
<span>{{ val.title }}</span>
|
|
||||||
<SvgIcon :name="val.isOpen ? 'ele-ArrowDown' : 'ele-ArrowRight'" />
|
|
||||||
</div>
|
|
||||||
<div class="workflow-left-item" v-for="(v, k) in val.children" :key="k" :data-name="v.name" :data-icon="v.icon" :data-id="v.id">
|
|
||||||
<div class="workflow-left-item-icon">
|
|
||||||
<SvgIcon :name="v.icon" class="workflow-icon-drag" />
|
|
||||||
<div class="font10 pl5 name">{{ v.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 右侧绘画区 -->
|
|
||||||
<div class="workflow-right" ref="workflowRightRef">
|
|
||||||
<div
|
|
||||||
v-for="(v, k) in state.jsplumbData.nodeList"
|
|
||||||
:key="v.nodeId"
|
|
||||||
:id="v.nodeId"
|
|
||||||
:data-node-id="v.nodeId"
|
|
||||||
:class="v.class"
|
|
||||||
:style="{ left: v.left, top: v.top }"
|
|
||||||
@click="onItemCloneClick(k)"
|
|
||||||
@contextmenu.prevent="onContextmenu(v, k, $event)"
|
|
||||||
>
|
|
||||||
<div class="workflow-right-box" :class="{ 'workflow-right-active': state.jsPlumbNodeIndex === k }">
|
|
||||||
<div class="workflow-left-item-icon">
|
|
||||||
<SvgIcon :name="v.icon" class="workflow-icon-drag" />
|
|
||||||
<div class="font10 pl5 name">{{ v.name }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 节点右键菜单 -->
|
|
||||||
<Contextmenu :dropdown="state.dropdownNode" ref="contextmenuNodeRef" @current="onCurrentNodeClick" />
|
|
||||||
<!-- 线右键菜单 -->
|
|
||||||
<Contextmenu :dropdown="state.dropdownLine" ref="contextmenuLineRef" @current="onCurrentLineClick" />
|
|
||||||
<!-- 抽屉表单、线 -->
|
|
||||||
<Drawer ref="drawerRef" @label="setLineLabel" @node="setNodeContent" />
|
|
||||||
|
|
||||||
<!-- 顶部工具栏-帮助弹窗 -->
|
|
||||||
<Help ref="helpRef" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="pagesWorkflow">
|
|
||||||
import { defineAsyncComponent, reactive, onMounted, onUnmounted, nextTick, ref } from 'vue';
|
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
|
||||||
import { jsPlumb } from 'jsplumb';
|
|
||||||
import Sortable from 'sortablejs';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
|
||||||
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
|
|
||||||
import commonFunction from '/@/utils/commonFunction';
|
|
||||||
import { leftNavList } from './js/mock';
|
|
||||||
import { jsplumbDefaults, jsplumbMakeSource, jsplumbMakeTarget, jsplumbConnect } from './js/config';
|
|
||||||
|
|
||||||
// 引入组件
|
|
||||||
const Tool = defineAsyncComponent(() => import('./component/tool/index.vue'));
|
|
||||||
const Contextmenu = defineAsyncComponent(() => import('./component/contextmenu/index.vue'));
|
|
||||||
const Drawer = defineAsyncComponent(() => import('./component/drawer/index.vue'));
|
|
||||||
const Help = defineAsyncComponent(() => import('./component/tool/help.vue'));
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const leftNavRefs = ref([]);
|
|
||||||
const workflowRightRef = ref();
|
|
||||||
const contextmenuNodeRef = ref();
|
|
||||||
const contextmenuLineRef = ref();
|
|
||||||
const drawerRef = ref();
|
|
||||||
const helpRef = ref();
|
|
||||||
const stores = useTagsViewRoutes();
|
|
||||||
const storesThemeConfig = useThemeConfig();
|
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
||||||
const { copyText } = commonFunction();
|
|
||||||
const state = reactive<WorkflowState>({
|
|
||||||
leftNavList: [],
|
|
||||||
dropdownNode: { x: '', y: '' },
|
|
||||||
dropdownLine: { x: '', y: '' },
|
|
||||||
isShow: false,
|
|
||||||
jsPlumb: null,
|
|
||||||
jsPlumbNodeIndex: null,
|
|
||||||
jsplumbDefaults,
|
|
||||||
jsplumbMakeSource,
|
|
||||||
jsplumbMakeTarget,
|
|
||||||
jsplumbConnect,
|
|
||||||
jsplumbData: {
|
|
||||||
nodeList: [],
|
|
||||||
lineList: [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设置 宽度小于 768,不支持操
|
|
||||||
const setClientWidth = () => {
|
|
||||||
const clientWidth = document.body.clientWidth;
|
|
||||||
clientWidth < 768 ? (state.isShow = true) : (state.isShow = false);
|
|
||||||
};
|
|
||||||
// 左侧导航-数据初始化
|
|
||||||
const initLeftNavList = () => {
|
|
||||||
state.leftNavList = leftNavList;
|
|
||||||
state.jsplumbData = {
|
|
||||||
nodeList: [
|
|
||||||
{ nodeId: 'huej738hbji', left: '148px', top: '93px', class: 'workflow-right-clone', icon: 'iconfont icon-gongju', name: '引擎', id: '11' },
|
|
||||||
{
|
|
||||||
nodeId: '52kcszzyxrd',
|
|
||||||
left: '458px',
|
|
||||||
top: '203px',
|
|
||||||
class: 'workflow-right-clone',
|
|
||||||
icon: 'iconfont icon-shouye_dongtaihui',
|
|
||||||
name: '模版',
|
|
||||||
id: '12',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
nodeId: 'nltskl6k4me',
|
|
||||||
left: '164px',
|
|
||||||
top: '350px',
|
|
||||||
class: 'workflow-right-clone',
|
|
||||||
icon: 'iconfont icon-zhongduancanshuchaxun',
|
|
||||||
name: '名称',
|
|
||||||
id: '13',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
lineList: [
|
|
||||||
{ sourceId: 'huej738hbji', targetId: '52kcszzyxrd', label: '传送' },
|
|
||||||
{ sourceId: 'huej738hbji', targetId: 'nltskl6k4me', label: '' },
|
|
||||||
],
|
|
||||||
};
|
|
||||||
};
|
|
||||||
// 左侧导航-初始化拖动
|
|
||||||
const initSortable = () => {
|
|
||||||
leftNavRefs.value.forEach((v) => {
|
|
||||||
Sortable.create(v as HTMLDivElement, {
|
|
||||||
group: {
|
|
||||||
name: 'vue-next-admin-1',
|
|
||||||
pull: 'clone',
|
|
||||||
put: false,
|
|
||||||
},
|
|
||||||
animation: 0,
|
|
||||||
sort: false,
|
|
||||||
draggable: '.workflow-left-item',
|
|
||||||
forceFallback: true,
|
|
||||||
onEnd: function (evt: any) {
|
|
||||||
const { name, icon, id } = evt.clone.dataset;
|
|
||||||
const { layerX, layerY, clientX, clientY } = evt.originalEvent;
|
|
||||||
const el = workflowRightRef.value!;
|
|
||||||
const { x, y, width, height } = el.getBoundingClientRect();
|
|
||||||
if (clientX < x || clientX > width + x || clientY < y || y > y + height) {
|
|
||||||
ElMessage.warning('请把节点拖入到画布中');
|
|
||||||
} else {
|
|
||||||
// 节点id(唯一)
|
|
||||||
const nodeId = Math.random().toString(36).substr(2, 12);
|
|
||||||
// 处理节点数据
|
|
||||||
const node = {
|
|
||||||
nodeId,
|
|
||||||
left: `${layerX - 40}px`,
|
|
||||||
top: `${layerY - 15}px`,
|
|
||||||
class: 'workflow-right-clone',
|
|
||||||
name,
|
|
||||||
icon,
|
|
||||||
id,
|
|
||||||
};
|
|
||||||
// 右侧视图内容数组
|
|
||||||
state.jsplumbData.nodeList.push(node);
|
|
||||||
// 元素加载完毕时
|
|
||||||
nextTick(() => {
|
|
||||||
// 整个节点作为source或者target
|
|
||||||
state.jsPlumb.makeSource(nodeId, state.jsplumbMakeSource);
|
|
||||||
// // 整个节点作为source或者target
|
|
||||||
state.jsPlumb.makeTarget(nodeId, state.jsplumbMakeTarget, jsplumbConnect);
|
|
||||||
// 设置节点可以拖拽(此处为id值,非class)
|
|
||||||
state.jsPlumb.draggable(nodeId, {
|
|
||||||
containment: 'parent',
|
|
||||||
stop: (el: any) => {
|
|
||||||
state.jsplumbData.nodeList.forEach((v) => {
|
|
||||||
if (v.nodeId === el.el.id) {
|
|
||||||
// 节点x, y重新赋值,防止再次从左侧导航中拖拽节点时,x, y恢复默认
|
|
||||||
v.left = `${el.pos[0]}px`;
|
|
||||||
v.top = `${el.pos[1]}px`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 初始化 jsPlumb
|
|
||||||
const initJsPlumb = () => {
|
|
||||||
(<any>jsPlumb).ready(() => {
|
|
||||||
state.jsPlumb = (<any>jsPlumb).getInstance({
|
|
||||||
detachable: false,
|
|
||||||
Container: 'workflow-right',
|
|
||||||
});
|
|
||||||
state.jsPlumb.fire('jsPlumbDemoLoaded', state.jsPlumb);
|
|
||||||
// 导入默认配置
|
|
||||||
state.jsPlumb.importDefaults(state.jsplumbDefaults);
|
|
||||||
// 会使整个jsPlumb立即重绘。
|
|
||||||
state.jsPlumb.setSuspendDrawing(false, true);
|
|
||||||
// 初始化节点、线的链接
|
|
||||||
initJsPlumbConnection();
|
|
||||||
// 点击线弹出右键菜单
|
|
||||||
state.jsPlumb.bind('contextmenu', (conn: any, originalEvent: MouseEvent) => {
|
|
||||||
originalEvent.preventDefault();
|
|
||||||
const { sourceId, targetId } = conn;
|
|
||||||
const { clientX, clientY } = originalEvent;
|
|
||||||
state.dropdownLine.x = clientX;
|
|
||||||
state.dropdownLine.y = clientY;
|
|
||||||
const v: any = state.jsplumbData.nodeList.find((v) => v.nodeId === targetId);
|
|
||||||
const line: any = state.jsplumbData.lineList.find((v) => v.sourceId === sourceId && v.targetId === targetId);
|
|
||||||
v.type = 'line';
|
|
||||||
v.label = line.label;
|
|
||||||
contextmenuLineRef.value.openContextmenu(v, conn);
|
|
||||||
});
|
|
||||||
// 连线之前
|
|
||||||
state.jsPlumb.bind('beforeDrop', (conn: any) => {
|
|
||||||
const { sourceId, targetId } = conn;
|
|
||||||
const item = state.jsplumbData.lineList.find((v) => v.sourceId === sourceId && v.targetId === targetId);
|
|
||||||
if (item) {
|
|
||||||
ElMessage.warning('关系已存在,不可重复连接');
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 连线时
|
|
||||||
state.jsPlumb.bind('connection', (conn: any) => {
|
|
||||||
const { sourceId, targetId } = conn;
|
|
||||||
state.jsplumbData.lineList.push({
|
|
||||||
sourceId,
|
|
||||||
targetId,
|
|
||||||
label: '',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// 删除连线时回调函数
|
|
||||||
state.jsPlumb.bind('connectionDetached', (conn: any) => {
|
|
||||||
const { sourceId, targetId } = conn;
|
|
||||||
state.jsplumbData.lineList = state.jsplumbData.lineList.filter((line) => {
|
|
||||||
if (line.sourceId == sourceId && line.targetId == targetId) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 初始化节点、线的链接
|
|
||||||
const initJsPlumbConnection = () => {
|
|
||||||
// 节点
|
|
||||||
state.jsplumbData.nodeList.forEach((v) => {
|
|
||||||
// 整个节点作为source或者target
|
|
||||||
state.jsPlumb.makeSource(v.nodeId, state.jsplumbMakeSource);
|
|
||||||
// 整个节点作为source或者target
|
|
||||||
state.jsPlumb.makeTarget(v.nodeId, state.jsplumbMakeTarget, jsplumbConnect);
|
|
||||||
// 设置节点可以拖拽(此处为id值,非class)
|
|
||||||
state.jsPlumb.draggable(v.nodeId, {
|
|
||||||
containment: 'parent',
|
|
||||||
stop: (el: any) => {
|
|
||||||
state.jsplumbData.nodeList.forEach((v) => {
|
|
||||||
if (v.nodeId === el.el.id) {
|
|
||||||
// 节点x, y重新赋值,防止再次从左侧导航中拖拽节点时,x, y恢复默认
|
|
||||||
v.left = `${el.pos[0]}px`;
|
|
||||||
v.top = `${el.pos[1]}px`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// 线
|
|
||||||
state.jsplumbData.lineList.forEach((v) => {
|
|
||||||
state.jsPlumb.connect(
|
|
||||||
{
|
|
||||||
source: v.sourceId,
|
|
||||||
target: v.targetId,
|
|
||||||
label: v.label,
|
|
||||||
},
|
|
||||||
state.jsplumbConnect
|
|
||||||
);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 左侧导航-菜单标题点击
|
|
||||||
const onTitleClick = (val: any) => {
|
|
||||||
val.isOpen = !val.isOpen;
|
|
||||||
};
|
|
||||||
// 右侧内容区-当前项点击
|
|
||||||
const onItemCloneClick = (k: number) => {
|
|
||||||
state.jsPlumbNodeIndex = k;
|
|
||||||
};
|
|
||||||
// 右侧内容区-当前项右键菜单点击
|
|
||||||
const onContextmenu = (v: any, k: number, e: MouseEvent) => {
|
|
||||||
state.jsPlumbNodeIndex = k;
|
|
||||||
const { clientX, clientY } = e;
|
|
||||||
state.dropdownNode.x = clientX;
|
|
||||||
state.dropdownNode.y = clientY;
|
|
||||||
v.type = 'node';
|
|
||||||
v.label = '';
|
|
||||||
let item: any = {};
|
|
||||||
state.leftNavList.forEach((l) => {
|
|
||||||
if (l.children) if (l.children.find((c: any) => c.id === v.id)) item = l.children.find((c: any) => c.id === v.id);
|
|
||||||
});
|
|
||||||
v.from = item.form;
|
|
||||||
contextmenuNodeRef.value.openContextmenu(v);
|
|
||||||
};
|
|
||||||
// 右侧内容区-当前项右键菜单点击回调(节点)
|
|
||||||
const onCurrentNodeClick = (item: any) => {
|
|
||||||
const { contextMenuClickId, nodeId } = item;
|
|
||||||
if (contextMenuClickId === 0) {
|
|
||||||
const nodeIndex = state.jsplumbData.nodeList.findIndex((item) => item.nodeId === nodeId);
|
|
||||||
state.jsplumbData.nodeList.splice(nodeIndex, 1);
|
|
||||||
state.jsPlumb.removeAllEndpoints(nodeId);
|
|
||||||
state.jsPlumbNodeIndex = null;
|
|
||||||
} else if (contextMenuClickId === 1) {
|
|
||||||
drawerRef.value.open(item);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 右侧内容区-当前项右键菜单点击回调(线)
|
|
||||||
const onCurrentLineClick = (item: any, conn: any) => {
|
|
||||||
const { contextMenuClickId } = item;
|
|
||||||
const { endpoints } = conn;
|
|
||||||
const intercourse: any = [];
|
|
||||||
endpoints.forEach((v: any) => {
|
|
||||||
intercourse.push({
|
|
||||||
id: v.element.id,
|
|
||||||
innerText: v.element.innerText,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
item.contact = `${intercourse[0].innerText}(${intercourse[0].id}) => ${intercourse[1].innerText}(${intercourse[1].id})`;
|
|
||||||
if (contextMenuClickId === 0) state.jsPlumb.deleteConnection(conn);
|
|
||||||
else if (contextMenuClickId === 1) drawerRef.value.open(item, conn);
|
|
||||||
};
|
|
||||||
// 设置线的 label
|
|
||||||
const setLineLabel = (obj: any) => {
|
|
||||||
const { sourceId, targetId, label } = obj;
|
|
||||||
const conn = state.jsPlumb.getConnections({
|
|
||||||
source: sourceId,
|
|
||||||
target: targetId,
|
|
||||||
})[0];
|
|
||||||
conn.setLabel(label);
|
|
||||||
if (!label || label === '') {
|
|
||||||
conn.addClass('workflow-right-empty-label');
|
|
||||||
} else {
|
|
||||||
conn.removeClass('workflow-right-empty-label');
|
|
||||||
conn.addClass('workflow-right-label');
|
|
||||||
}
|
|
||||||
state.jsplumbData.lineList.forEach((v) => {
|
|
||||||
if (v.sourceId === sourceId && v.targetId === targetId) v.label = label;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 设置节点内容
|
|
||||||
const setNodeContent = (obj: any) => {
|
|
||||||
const { nodeId, name, icon } = obj;
|
|
||||||
// 设置节点 name 与 icon
|
|
||||||
state.jsplumbData.nodeList.forEach((v) => {
|
|
||||||
if (v.nodeId === nodeId) {
|
|
||||||
v.name = name;
|
|
||||||
v.icon = icon;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// 重绘
|
|
||||||
nextTick(() => {
|
|
||||||
state.jsPlumb.setSuspendDrawing(false, true);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 顶部工具栏-当前项点击
|
|
||||||
const onToolClick = (fnName: String) => {
|
|
||||||
switch (fnName) {
|
|
||||||
case 'help':
|
|
||||||
onToolHelp();
|
|
||||||
break;
|
|
||||||
case 'download':
|
|
||||||
onToolDownload();
|
|
||||||
break;
|
|
||||||
case 'submit':
|
|
||||||
onToolSubmit();
|
|
||||||
break;
|
|
||||||
case 'copy':
|
|
||||||
onToolCopy();
|
|
||||||
break;
|
|
||||||
case 'del':
|
|
||||||
onToolDel();
|
|
||||||
break;
|
|
||||||
case 'fullscreen':
|
|
||||||
onToolFullscreen();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 顶部工具栏-帮助
|
|
||||||
const onToolHelp = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
helpRef.value.open();
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 顶部工具栏-下载
|
|
||||||
const onToolDownload = () => {
|
|
||||||
const { globalTitle } = themeConfig.value;
|
|
||||||
const href = 'data:text/json;charset=utf-8,' + encodeURIComponent(JSON.stringify(state.jsplumbData, null, '\t'));
|
|
||||||
const aLink = document.createElement('a');
|
|
||||||
aLink.setAttribute('href', href);
|
|
||||||
aLink.setAttribute('download', `${globalTitle}工作流.json`);
|
|
||||||
aLink.click();
|
|
||||||
aLink.remove();
|
|
||||||
ElMessage.success('下载成功');
|
|
||||||
};
|
|
||||||
// 顶部工具栏-提交
|
|
||||||
const onToolSubmit = () => {
|
|
||||||
// console.log(state.jsplumbData);
|
|
||||||
ElMessage.success('数据提交成功');
|
|
||||||
};
|
|
||||||
// 顶部工具栏-复制
|
|
||||||
const onToolCopy = () => {
|
|
||||||
copyText(JSON.stringify(state.jsplumbData));
|
|
||||||
};
|
|
||||||
// 顶部工具栏-删除
|
|
||||||
const onToolDel = () => {
|
|
||||||
ElMessageBox.confirm('此操作将清空画布,是否继续?', '提示', {
|
|
||||||
confirmButtonText: '清空',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
state.jsplumbData.nodeList.forEach((v) => {
|
|
||||||
state.jsPlumb.removeAllEndpoints(v.nodeId);
|
|
||||||
});
|
|
||||||
nextTick(() => {
|
|
||||||
state.jsplumbData = {
|
|
||||||
nodeList: [],
|
|
||||||
lineList: [],
|
|
||||||
};
|
|
||||||
ElMessage.success('清空画布成功');
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
};
|
|
||||||
// 顶部工具栏-全屏
|
|
||||||
const onToolFullscreen = () => {
|
|
||||||
stores.setCurrenFullscreen(true);
|
|
||||||
};
|
|
||||||
// 页面加载时
|
|
||||||
onMounted(async () => {
|
|
||||||
await initLeftNavList();
|
|
||||||
initSortable();
|
|
||||||
initJsPlumb();
|
|
||||||
setClientWidth();
|
|
||||||
window.addEventListener('resize', setClientWidth);
|
|
||||||
});
|
|
||||||
// 页面卸载时
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener('resize', setClientWidth);
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.workflow-container {
|
|
||||||
position: relative;
|
|
||||||
.workflow-warp {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.workflow {
|
|
||||||
display: flex;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
.workflow-content {
|
|
||||||
display: flex;
|
|
||||||
height: calc(100% - 35px);
|
|
||||||
.workflow-left {
|
|
||||||
width: 220px;
|
|
||||||
height: 100%;
|
|
||||||
border-right: 1px solid var(--el-border-color-light, #ebeef5);
|
|
||||||
:deep(.el-collapse-item__content) {
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
.workflow-left-title {
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
border-top: 1px solid var(--el-border-color-light, #ebeef5);
|
|
||||||
color: var(--el-text-color-primary);
|
|
||||||
cursor: default;
|
|
||||||
span {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.workflow-left-item {
|
|
||||||
display: inline-block;
|
|
||||||
width: calc(50% - 15px);
|
|
||||||
position: relative;
|
|
||||||
cursor: move;
|
|
||||||
margin: 0 0 10px 10px;
|
|
||||||
.workflow-left-item-icon {
|
|
||||||
height: 35px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
padding: 5px 10px;
|
|
||||||
border: 1px dashed transparent;
|
|
||||||
background: var(--next-bg-color);
|
|
||||||
border-radius: 3px;
|
|
||||||
i,
|
|
||||||
.name {
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
border: 1px dashed var(--el-color-primary);
|
|
||||||
background: var(--el-color-primary-light-9);
|
|
||||||
border-radius: 5px;
|
|
||||||
i,
|
|
||||||
.name {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
& .workflow-left-id:first-of-type {
|
|
||||||
.workflow-left-title {
|
|
||||||
border-top: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.workflow-right {
|
|
||||||
flex: 1;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
height: 100%;
|
|
||||||
background-image: linear-gradient(90deg, rgb(156 214 255 / 15%) 10%, rgba(0, 0, 0, 0) 10%),
|
|
||||||
linear-gradient(rgb(156 214 255 / 15%) 10%, rgba(0, 0, 0, 0) 10%);
|
|
||||||
background-size: 10px 10px;
|
|
||||||
.workflow-right-clone {
|
|
||||||
position: absolute;
|
|
||||||
.workflow-right-box {
|
|
||||||
height: 35px;
|
|
||||||
align-items: center;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
padding: 0 10px;
|
|
||||||
border-radius: 3px;
|
|
||||||
cursor: move;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
min-width: 94.5px;
|
|
||||||
background: var(--el-color-white);
|
|
||||||
border: 1px solid var(--el-border-color-light, #ebeef5);
|
|
||||||
.workflow-left-item-icon {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 35px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
border: 1px dashed var(--el-color-primary);
|
|
||||||
background: var(--el-color-primary-light-9);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
i {
|
|
||||||
cursor: Crosshair;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.workflow-right-active {
|
|
||||||
border: 1px dashed var(--el-color-primary);
|
|
||||||
background: var(--el-color-primary-light-9);
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
:deep(.jtk-overlay):not(.aLabel) {
|
|
||||||
padding: 4px 10px;
|
|
||||||
border: 1px solid var(--el-border-color-light, #ebeef5) !important;
|
|
||||||
color: var(--el-text-color-secondary) !important;
|
|
||||||
background: var(--el-color-white) !important;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 10px;
|
|
||||||
}
|
|
||||||
:deep(.jtk-overlay.workflow-right-empty-label) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.workflow-mask {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
&::after {
|
|
||||||
content: '手机版不支持 jsPlumb 操作';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
z-index: 1;
|
|
||||||
background: rgba(255, 255, 255, 0.9);
|
|
||||||
color: #666666;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
// jsplumb 默认配置
|
|
||||||
export const jsplumbDefaults = {
|
|
||||||
// 多个锚点 [源锚点,目标锚点]
|
|
||||||
Anchors: [
|
|
||||||
'Top',
|
|
||||||
'TopCenter',
|
|
||||||
'TopRight',
|
|
||||||
'TopLeft',
|
|
||||||
'Right',
|
|
||||||
'RightMiddle',
|
|
||||||
'Bottom',
|
|
||||||
'BottomCenter',
|
|
||||||
'BottomRight',
|
|
||||||
'BottomLeft',
|
|
||||||
'Left',
|
|
||||||
'LeftMiddle',
|
|
||||||
],
|
|
||||||
// 连线的容器id
|
|
||||||
Container: 'workflow-right',
|
|
||||||
// 设置链接线的形状,如直线或者曲线之类的。anchor可以去设置锚点的位置。可选值"<Bezier|Flowchart|StateMachine|Straight>"
|
|
||||||
Connector: ['Bezier', { curviness: 100 }],
|
|
||||||
// 节点是否可以用鼠标拖动使其断开,默认为true。即用鼠标链接上的连线,也可以使用鼠标拖动让其断开。设置成false,可以让其拖动也不会自动断开
|
|
||||||
ConnectionsDetachable: false,
|
|
||||||
// 删除线的时候节点不删除
|
|
||||||
DeleteEndpointsOnDetach: false,
|
|
||||||
// 每当添加或以其他方式创建 Endpoint 并且 jsPlumb 尚未给出任何明确的 Endpoint 定义时将使用
|
|
||||||
Endpoint: ['Blank', { Overlays: '' }],
|
|
||||||
// 连接中源和目标端点的默认外观
|
|
||||||
EndpointStyle: { fill: '#1879ffa1', outlineWidth: 1 },
|
|
||||||
// jsPlumb 的内部日志记录是否打开
|
|
||||||
LogEnabled: true,
|
|
||||||
// 连接器的默认外观
|
|
||||||
PaintStyle: {
|
|
||||||
stroke: '#E0E3E7',
|
|
||||||
strokeWidth: 1,
|
|
||||||
outlineStroke: 'transparent',
|
|
||||||
outlineWidth: 10,
|
|
||||||
},
|
|
||||||
// 用于配置任何可拖动元素的默认选项jsPlumb.draggable
|
|
||||||
DragOptions: { cursor: 'pointer', zIndex: 2000 },
|
|
||||||
// 添加到连接器和端点的默认叠加层。已弃用:从 4.x 开始,将不支持此功能。并非所有叠加层都可以连接到连接器和端点。
|
|
||||||
Overlays: [
|
|
||||||
[
|
|
||||||
'Arrow',
|
|
||||||
{
|
|
||||||
width: 10, // 箭头尾部的宽度
|
|
||||||
length: 8, // 从箭头的尾部到头部的距离
|
|
||||||
location: 1, // 位置,建议使用0~1之间
|
|
||||||
direction: 1, // 方向,默认值为1(表示向前),可选-1(表示向后)
|
|
||||||
foldback: 0.623, // 折回,也就是尾翼的角度,默认0.623,当为1时,为正三角
|
|
||||||
},
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Label',
|
|
||||||
{
|
|
||||||
label: '',
|
|
||||||
location: 0.5,
|
|
||||||
cssClass: 'aLabel',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
// 默认渲染模式 svg、canvas
|
|
||||||
RenderMode: 'svg',
|
|
||||||
// 悬停状态下连接的默认外观
|
|
||||||
HoverPaintStyle: { stroke: '#b0b2b5', strokeWidth: 1 },
|
|
||||||
// 悬停状态下端点的默认外观
|
|
||||||
EndpointHoverStyle: { fill: 'red' },
|
|
||||||
// 端点和连接的默认范围。范围提供了对哪些端点可以连接到哪些其他端点的基本控制
|
|
||||||
Scope: 'jsPlumb_DefaultScope',
|
|
||||||
};
|
|
||||||
|
|
||||||
// 整个节点作为source或者target
|
|
||||||
export const jsplumbMakeSource = {
|
|
||||||
// 设置可以拖拽的类名,只要鼠标移动到该类名上的DOM,就可以拖拽连线
|
|
||||||
filter: '.workflow-icon-drag',
|
|
||||||
filterExclude: false,
|
|
||||||
anchor: 'Continuous',
|
|
||||||
// 是否允许自己连接自己
|
|
||||||
allowLoopback: true,
|
|
||||||
maxConnections: -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
// 整个节点作为source或者target
|
|
||||||
export const jsplumbMakeTarget = {
|
|
||||||
filter: '.workflow-icon-drag',
|
|
||||||
filterExclude: false,
|
|
||||||
// 是否允许自己连接自己
|
|
||||||
anchor: 'Continuous',
|
|
||||||
allowLoopback: true,
|
|
||||||
dropOptions: { hoverClass: 'ef-drop-hover' },
|
|
||||||
};
|
|
||||||
|
|
||||||
// 连线参数
|
|
||||||
export const jsplumbConnect = {
|
|
||||||
isSource: true,
|
|
||||||
isTarget: true,
|
|
||||||
// 动态锚点、提供了4个方向 Continuous、AutoDefault
|
|
||||||
anchor: 'Continuous',
|
|
||||||
};
|
|
||||||
@@ -1,262 +0,0 @@
|
|||||||
// 左侧菜单导航数据
|
|
||||||
export const leftNavList = [
|
|
||||||
{
|
|
||||||
title: '工作流',
|
|
||||||
icon: 'iconfont icon-shouye',
|
|
||||||
isOpen: true,
|
|
||||||
id: '1',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-gongju',
|
|
||||||
name: '引擎',
|
|
||||||
id: '11',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '客户姓名',
|
|
||||||
prop: 'name',
|
|
||||||
placeholder: '请输入客户姓名',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
label: '性别',
|
|
||||||
prop: 'sex',
|
|
||||||
placeholder: '请选择性别',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: '0',
|
|
||||||
label: '女',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '1',
|
|
||||||
label: '男',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '员工编号',
|
|
||||||
prop: 'number',
|
|
||||||
placeholder: '请输入员工编号',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '办公电话',
|
|
||||||
prop: 'mobile',
|
|
||||||
placeholder: '请输入办公电话',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
label: '权限分配',
|
|
||||||
prop: 'role',
|
|
||||||
placeholder: '请选择性别',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: '0',
|
|
||||||
label: '编辑权限',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '1',
|
|
||||||
label: '删除权限',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'checkbox',
|
|
||||||
label: '模块选择',
|
|
||||||
prop: 'module',
|
|
||||||
placeholder: '请选择模块',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-shouye_dongtaihui',
|
|
||||||
name: '模版',
|
|
||||||
id: '12',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '等级',
|
|
||||||
prop: 'grade',
|
|
||||||
placeholder: '请输入等级',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '登记密码',
|
|
||||||
prop: 'password',
|
|
||||||
placeholder: '请输入登记密码',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-zhongduancanshuchaxun',
|
|
||||||
name: '名称',
|
|
||||||
id: '13',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '数据表',
|
|
||||||
prop: 'dataSheet',
|
|
||||||
placeholder: '请输入数据表',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '字段配置',
|
|
||||||
prop: 'field',
|
|
||||||
placeholder: '请输入字段配置',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-zhongduancanshu',
|
|
||||||
name: '版本',
|
|
||||||
id: '14',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '发布模板',
|
|
||||||
prop: 'publish',
|
|
||||||
placeholder: '请输入发布模板',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-bolangnengshiyanchang',
|
|
||||||
name: '建模',
|
|
||||||
id: '15',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '内容模板',
|
|
||||||
prop: 'content',
|
|
||||||
placeholder: '请输入内容模板',
|
|
||||||
required: true,
|
|
||||||
disabled: false,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-xingqiu',
|
|
||||||
name: '节点',
|
|
||||||
id: '16',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称6',
|
|
||||||
prop: 'name16',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '流程',
|
|
||||||
isOpen: true,
|
|
||||||
icon: 'iconfont icon-caijian',
|
|
||||||
id: '2',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-fuwenben',
|
|
||||||
name: '实例',
|
|
||||||
id: '21',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称7',
|
|
||||||
prop: 'name21',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-fuwenbenkuang',
|
|
||||||
name: '轨迹',
|
|
||||||
id: '22',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称8',
|
|
||||||
prop: 'name22',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-shangchuan',
|
|
||||||
name: '数据',
|
|
||||||
id: '23',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称9',
|
|
||||||
prop: 'name23',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '任务',
|
|
||||||
isOpen: true,
|
|
||||||
icon: 'iconfont icon-shuju',
|
|
||||||
id: '3',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-icon-',
|
|
||||||
name: '参与人',
|
|
||||||
id: '31',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称1',
|
|
||||||
prop: 'name31',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-gerenzhongxin',
|
|
||||||
name: '执行人',
|
|
||||||
id: '32',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称2',
|
|
||||||
prop: 'name32',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: 'iconfont icon-fangkuang',
|
|
||||||
name: '工单',
|
|
||||||
id: '33',
|
|
||||||
form: [
|
|
||||||
{
|
|
||||||
type: 'input',
|
|
||||||
label: '活动名称3',
|
|
||||||
prop: 'name33',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="flex-margin color-primary">
|
|
||||||
<div>paramsCommonDetails</div>
|
|
||||||
<div class="mt10 mb10">路径:path: {{ route.path }}</div>
|
|
||||||
<div>参数:query: {{ route.query }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="paramsCommonDetails">
|
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const route = useRoute();
|
|
||||||
</script>
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="flex-margin" style="width: 400px">
|
|
||||||
<el-result icon="success" title="普通路由" subTitle="可 `开启 TagsView 共用` 进行单标签测试">
|
|
||||||
<template #extra>
|
|
||||||
<el-alert type="success" :closable="false" class="mb30">
|
|
||||||
<template #default>
|
|
||||||
<div>1、设置非国际化:格式:tagsViewName=xxx</div>
|
|
||||||
<br />
|
|
||||||
<div>2、设置国际化:格式:tagsViewName=JSON.stringify({"zh-cn":"测试用","en":"test+page","zh-tw":"測試用"})</div>
|
|
||||||
<br />
|
|
||||||
<div>3、设置国际化后,去顶栏切换语言查看演示效果</div>
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
4、 <a href="https://gitee.com/q7but" target="_black">感谢@q7but</a>、
|
|
||||||
<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/22/files" target="_black">!22 add 添加自定义 tagVIewName 拓展,支持国际化</a>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-alert>
|
|
||||||
<el-input v-model="state.tagsViewName" placeholder="请输入tagsView 名称" clearable class="mb15" style="width: 400px"></el-input>
|
|
||||||
<el-input v-model="state.value" placeholder="请输入路由参数 id 值" clearable style="width: 400px"></el-input>
|
|
||||||
<el-button type="primary" size="default" class="mt15" @click="onGoDetailsClick">
|
|
||||||
<SvgIcon name="iconfont icon-putong" />
|
|
||||||
普通路由传参
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" size="default" class="mt15" @click="onChangeI18n">
|
|
||||||
<SvgIcon name="iconfont icon-fuhao-zhongwen" />
|
|
||||||
{{ state.tagsViewNameIsI18n ? '普通的演示' : '国际化演示' }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-result>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="paramsCommon">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const router = useRouter();
|
|
||||||
const state = reactive<ParamsState>({
|
|
||||||
value: '',
|
|
||||||
tagsViewName: '',
|
|
||||||
tagsViewNameIsI18n: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 跳转到详情
|
|
||||||
/**
|
|
||||||
* 设置 tagsView 名称:
|
|
||||||
* 传不同的 tagsViewName 值
|
|
||||||
*/
|
|
||||||
const onGoDetailsClick = () => {
|
|
||||||
const params: EmptyObjectType = { id: state.value };
|
|
||||||
if (state.tagsViewName) params.tagsViewName = state.tagsViewName;
|
|
||||||
router.push({
|
|
||||||
path: '/params/common/details',
|
|
||||||
query: params,
|
|
||||||
});
|
|
||||||
state.value = '';
|
|
||||||
};
|
|
||||||
// 模拟测试内容
|
|
||||||
const onChangeI18n = () => {
|
|
||||||
state.tagsViewNameIsI18n = !state.tagsViewNameIsI18n;
|
|
||||||
if (state.tagsViewNameIsI18n) {
|
|
||||||
state.tagsViewName = JSON.stringify({
|
|
||||||
'zh-cn': '测试用',
|
|
||||||
en: 'test page',
|
|
||||||
'zh-tw': '測試用',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
state.tagsViewName = '我是普通路由测试tagsViewName(非国际化)';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="flex-margin color-primary">
|
|
||||||
<div>paramsDynamicDetails</div>
|
|
||||||
<div class="mt10 mb10">路径:path: {{ route.path }}</div>
|
|
||||||
<div>参数:params: {{ route.params }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="paramsDynamicDetails">
|
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const route = useRoute();
|
|
||||||
</script>
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-padding">
|
|
||||||
<div class="layout-padding-auto layout-padding-view">
|
|
||||||
<div class="flex-margin" style="width: 400px">
|
|
||||||
<el-result icon="warning" title="动态路由" subTitle="可 `开启 TagsView 共用` 进行单标签测试">
|
|
||||||
<template #extra>
|
|
||||||
<el-alert type="success" :closable="false" class="mb30">
|
|
||||||
<template #default>
|
|
||||||
<div>1、设置非国际化:格式:tagsViewName=xxx</div>
|
|
||||||
<br />
|
|
||||||
<div>2、设置国际化:格式:tagsViewName=JSON.stringify({"zh-cn":"测试用","en":"test+page","zh-tw":"測試用"})</div>
|
|
||||||
<br />
|
|
||||||
<div>3、设置国际化后,去顶栏切换语言查看演示效果</div>
|
|
||||||
<br />
|
|
||||||
<div>
|
|
||||||
4、 <a href="https://gitee.com/q7but" target="_black">感谢@q7but</a>、
|
|
||||||
<a href="https://gitee.com/lyt-top/vue-next-admin/pulls/22/files" target="_black">!22 add 添加自定义 tagVIewName 拓展,支持国际化</a>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-alert>
|
|
||||||
<el-input v-model="state.tagsViewName" placeholder="请输入tagsView 名称" clearable class="mb15" style="width: 400px"></el-input>
|
|
||||||
<el-input v-model="state.value" placeholder="请输入路由参数id值" clearable style="width: 400px"></el-input>
|
|
||||||
<el-button type="primary" size="default" class="mt15" @click="onGoDetailsClick">
|
|
||||||
<SvgIcon name="iconfont icon-dongtai" />
|
|
||||||
动态路由传参
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" size="default" class="mt15" @click="onChangeI18n">
|
|
||||||
<SvgIcon name="iconfont icon-fuhao-zhongwen" />
|
|
||||||
{{ state.tagsViewNameIsI18n ? '普通的演示' : '国际化演示' }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-result>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="paramsDynamic">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const router = useRouter();
|
|
||||||
const state = reactive<ParamsState>({
|
|
||||||
value: '',
|
|
||||||
tagsViewName: '',
|
|
||||||
tagsViewNameIsI18n: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 跳转到详情
|
|
||||||
const onGoDetailsClick = () => {
|
|
||||||
if (!state.tagsViewName) return ElMessage.warning('动态路由tagsViewName为必填,因为路由配置了');
|
|
||||||
if (!state.value) return ElMessage.warning('路由参数id值为必填');
|
|
||||||
// name 值为路由中的 name
|
|
||||||
router.push({
|
|
||||||
name: 'paramsDynamicDetails',
|
|
||||||
params: {
|
|
||||||
t: 'vue-next-admin',
|
|
||||||
id: state.value,
|
|
||||||
tagsViewName: state.tagsViewName,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
state.value = '';
|
|
||||||
};
|
|
||||||
// 模拟测试内容
|
|
||||||
const onChangeI18n = () => {
|
|
||||||
state.tagsViewNameIsI18n = !state.tagsViewNameIsI18n;
|
|
||||||
if (state.tagsViewNameIsI18n) {
|
|
||||||
state.tagsViewName = JSON.stringify({
|
|
||||||
'zh-cn': '我是动态路由',
|
|
||||||
en: 'Im dynamic routing',
|
|
||||||
'zh-tw': '我是動態路由',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
state.tagsViewName = '我是动态路由测试tagsViewName(非国际化)';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
@@ -1,373 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="personal layout-pd">
|
|
||||||
<el-row>
|
|
||||||
<!-- 个人信息 -->
|
|
||||||
<el-col :xs="24" :sm="16">
|
|
||||||
<el-card shadow="hover" header="个人信息">
|
|
||||||
<div class="personal-user">
|
|
||||||
<div class="personal-user-left">
|
|
||||||
<el-upload class="h100 personal-user-left-upload" action="https://jsonplaceholder.typicode.com/posts/" multiple :limit="1">
|
|
||||||
<img src="https://img2.baidu.com/it/u=1978192862,2048448374&fm=253&fmt=auto&app=138&f=JPEG?w=504&h=500" />
|
|
||||||
</el-upload>
|
|
||||||
</div>
|
|
||||||
<div class="personal-user-right">
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="24" class="personal-title mb18">{{ currentTime }},admin,生活变的再糟糕,也不妨碍我变得更好! </el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-row>
|
|
||||||
<el-col :xs="24" :sm="8" class="personal-item mb6">
|
|
||||||
<div class="personal-item-label">昵称:</div>
|
|
||||||
<div class="personal-item-value">小柒</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="16" class="personal-item mb6">
|
|
||||||
<div class="personal-item-label">身份:</div>
|
|
||||||
<div class="personal-item-value">超级管理</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-row>
|
|
||||||
<el-col :xs="24" :sm="8" class="personal-item mb6">
|
|
||||||
<div class="personal-item-label">登录IP:</div>
|
|
||||||
<div class="personal-item-value">192.168.1.1</div>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="16" class="personal-item mb6">
|
|
||||||
<div class="personal-item-label">登录时间:</div>
|
|
||||||
<div class="personal-item-value">2021-02-05 18:47:26</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<!-- 消息通知 -->
|
|
||||||
<el-col :xs="24" :sm="8" class="pl15 personal-info">
|
|
||||||
<el-card shadow="hover">
|
|
||||||
<template #header>
|
|
||||||
<span>消息通知</span>
|
|
||||||
<span class="personal-info-more">更多</span>
|
|
||||||
</template>
|
|
||||||
<div class="personal-info-box">
|
|
||||||
<ul class="personal-info-ul">
|
|
||||||
<li v-for="(v, k) in state.newsInfoList" :key="k" class="personal-info-li">
|
|
||||||
<a :href="v.link" target="_block" class="personal-info-li-title">{{ v.title }}</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<!-- 营销推荐 -->
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-card shadow="hover" class="mt15" header="营销推荐">
|
|
||||||
<el-row :gutter="15" class="personal-recommend-row">
|
|
||||||
<el-col :sm="6" v-for="(v, k) in state.recommendList" :key="k" class="personal-recommend-col">
|
|
||||||
<div class="personal-recommend" :style="{ 'background-color': v.bg }">
|
|
||||||
<SvgIcon :name="v.icon" :size="70" :style="{ color: v.iconColor }" />
|
|
||||||
<div class="personal-recommend-auto">
|
|
||||||
<div>{{ v.title }}</div>
|
|
||||||
<div class="personal-recommend-msg">{{ v.msg }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
|
|
||||||
<!-- 更新信息 -->
|
|
||||||
<el-col :span="24">
|
|
||||||
<el-card shadow="hover" class="mt15 personal-edit" header="更新信息">
|
|
||||||
<div class="personal-edit-title">基本信息</div>
|
|
||||||
<el-form :model="state.personalForm" size="default" label-width="40px" class="mt35 mb35">
|
|
||||||
<el-row :gutter="35">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="昵称">
|
|
||||||
<el-input v-model="state.personalForm.name" placeholder="请输入昵称" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="邮箱">
|
|
||||||
<el-input v-model="state.personalForm.email" placeholder="请输入邮箱" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="签名">
|
|
||||||
<el-input v-model="state.personalForm.autograph" placeholder="请输入签名" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="职业">
|
|
||||||
<el-select v-model="state.personalForm.occupation" placeholder="请选择职业" clearable class="w100">
|
|
||||||
<el-option label="计算机 / 互联网 / 通信" value="1"></el-option>
|
|
||||||
<el-option label="生产 / 工艺 / 制造" value="2"></el-option>
|
|
||||||
<el-option label="医疗 / 护理 / 制药" value="3"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="手机">
|
|
||||||
<el-input v-model="state.personalForm.phone" placeholder="请输入手机" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="4" class="mb20">
|
|
||||||
<el-form-item label="性别">
|
|
||||||
<el-select v-model="state.personalForm.sex" placeholder="请选择性别" clearable class="w100">
|
|
||||||
<el-option label="男" value="1"></el-option>
|
|
||||||
<el-option label="女" value="2"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary">
|
|
||||||
<el-icon>
|
|
||||||
<ele-Position />
|
|
||||||
</el-icon>
|
|
||||||
更新个人信息
|
|
||||||
</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<div class="personal-edit-title mb15">账号安全</div>
|
|
||||||
<div class="personal-edit-safe-box">
|
|
||||||
<div class="personal-edit-safe-item">
|
|
||||||
<div class="personal-edit-safe-item-left">
|
|
||||||
<div class="personal-edit-safe-item-left-label">账户密码</div>
|
|
||||||
<div class="personal-edit-safe-item-left-value">当前密码强度:强</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-item-right">
|
|
||||||
<el-button text type="primary">立即修改</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-box">
|
|
||||||
<div class="personal-edit-safe-item">
|
|
||||||
<div class="personal-edit-safe-item-left">
|
|
||||||
<div class="personal-edit-safe-item-left-label">密保手机</div>
|
|
||||||
<div class="personal-edit-safe-item-left-value">已绑定手机:132****4108</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-item-right">
|
|
||||||
<el-button text type="primary">立即修改</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-box">
|
|
||||||
<div class="personal-edit-safe-item">
|
|
||||||
<div class="personal-edit-safe-item-left">
|
|
||||||
<div class="personal-edit-safe-item-left-label">密保问题</div>
|
|
||||||
<div class="personal-edit-safe-item-left-value">已设置密保问题,账号安全大幅度提升</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-item-right">
|
|
||||||
<el-button text type="primary">立即设置</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-box">
|
|
||||||
<div class="personal-edit-safe-item">
|
|
||||||
<div class="personal-edit-safe-item-left">
|
|
||||||
<div class="personal-edit-safe-item-left-label">绑定QQ</div>
|
|
||||||
<div class="personal-edit-safe-item-left-value">已绑定QQ:110****566</div>
|
|
||||||
</div>
|
|
||||||
<div class="personal-edit-safe-item-right">
|
|
||||||
<el-button text type="primary">立即设置</el-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="personal">
|
|
||||||
import { reactive, computed } from 'vue';
|
|
||||||
import { formatAxis } from '/@/utils/formatTime';
|
|
||||||
import { newsInfoList, recommendList } from './mock';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive<PersonalState>({
|
|
||||||
newsInfoList,
|
|
||||||
recommendList,
|
|
||||||
personalForm: {
|
|
||||||
name: '',
|
|
||||||
email: '',
|
|
||||||
autograph: '',
|
|
||||||
occupation: '',
|
|
||||||
phone: '',
|
|
||||||
sex: '',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 当前时间提示语
|
|
||||||
const currentTime = computed(() => {
|
|
||||||
return formatAxis(new Date());
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import '../../theme/mixins/index.scss';
|
|
||||||
.personal {
|
|
||||||
.personal-user {
|
|
||||||
height: 130px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
.personal-user-left {
|
|
||||||
width: 100px;
|
|
||||||
height: 130px;
|
|
||||||
border-radius: 3px;
|
|
||||||
:deep(.el-upload) {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
.personal-user-left-upload {
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
img {
|
|
||||||
animation: logoAnimation 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.personal-user-right {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0 15px;
|
|
||||||
.personal-title {
|
|
||||||
font-size: 18px;
|
|
||||||
@include text-ellipsis(1);
|
|
||||||
}
|
|
||||||
.personal-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 13px;
|
|
||||||
.personal-item-label {
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
@include text-ellipsis(1);
|
|
||||||
}
|
|
||||||
.personal-item-value {
|
|
||||||
@include text-ellipsis(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.personal-info {
|
|
||||||
.personal-info-more {
|
|
||||||
float: right;
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
font-size: 13px;
|
|
||||||
&:hover {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.personal-info-box {
|
|
||||||
height: 130px;
|
|
||||||
overflow: hidden;
|
|
||||||
.personal-info-ul {
|
|
||||||
list-style: none;
|
|
||||||
.personal-info-li {
|
|
||||||
font-size: 13px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
.personal-info-li-title {
|
|
||||||
display: inline-block;
|
|
||||||
@include text-ellipsis(1);
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
& a:hover {
|
|
||||||
color: var(--el-color-primary);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.personal-recommend-row {
|
|
||||||
.personal-recommend-col {
|
|
||||||
.personal-recommend {
|
|
||||||
position: relative;
|
|
||||||
height: 100px;
|
|
||||||
border-radius: 3px;
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
&:hover {
|
|
||||||
i {
|
|
||||||
right: 0px !important;
|
|
||||||
bottom: 0px !important;
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
position: absolute;
|
|
||||||
right: -10px;
|
|
||||||
bottom: -10px;
|
|
||||||
font-size: 70px;
|
|
||||||
transform: rotate(-30deg);
|
|
||||||
transition: all ease 0.3s;
|
|
||||||
}
|
|
||||||
.personal-recommend-auto {
|
|
||||||
padding: 15px;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 5%;
|
|
||||||
color: var(--next-color-white);
|
|
||||||
.personal-recommend-msg {
|
|
||||||
font-size: 12px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.personal-edit {
|
|
||||||
.personal-edit-title {
|
|
||||||
position: relative;
|
|
||||||
padding-left: 10px;
|
|
||||||
color: var(--el-text-color-regular);
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
width: 2px;
|
|
||||||
height: 10px;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
background: var(--el-color-primary);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.personal-edit-safe-box {
|
|
||||||
border-bottom: 1px solid var(--el-border-color-light, #ebeef5);
|
|
||||||
padding: 15px 0;
|
|
||||||
.personal-edit-safe-item {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
.personal-edit-safe-item-left {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
.personal-edit-safe-item-left-label {
|
|
||||||
color: var(--el-text-color-regular);
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
.personal-edit-safe-item-left-value {
|
|
||||||
color: var(--el-text-color-secondary);
|
|
||||||
@include text-ellipsis(1);
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:last-of-type {
|
|
||||||
padding-bottom: 0;
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/**
|
|
||||||
* 消息通知
|
|
||||||
* @returns 返回模拟数据
|
|
||||||
*/
|
|
||||||
export const newsInfoList = [
|
|
||||||
{
|
|
||||||
title: '[发布] 2021年02月28日发布基于 vue3.x + vite v1.0.0 版本',
|
|
||||||
date: '02/28',
|
|
||||||
link: 'https://gitee.com/lyt-top/vue-next-admin',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '[发布] 2021年04月15日发布 vue2.x + webpack 重构版本',
|
|
||||||
date: '04/15',
|
|
||||||
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '[重构] 2021年04月10日 重构 vue2.x + webpack v1.0.0 版本',
|
|
||||||
date: '04/10',
|
|
||||||
link: 'https://gitee.com/lyt-top/vue-next-admin/tree/vue-prev-admin/',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '[预览] 2020年12月08日,基于 vue3.x 版本后台模板的预览',
|
|
||||||
date: '12/08',
|
|
||||||
link: 'http://lyt-top.gitee.io/vue-next-admin-preview/#/login',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '[预览] 2020年11月15日,基于 vue2.x 版本后台模板的预览',
|
|
||||||
date: '11/15',
|
|
||||||
link: 'https://lyt-top.gitee.io/vue-prev-admin-preview/#/login',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 营销推荐
|
|
||||||
* @returns 返回模拟数据
|
|
||||||
*/
|
|
||||||
export const recommendList = [
|
|
||||||
{
|
|
||||||
title: '优惠券',
|
|
||||||
msg: '现金券、折扣券、营销必备',
|
|
||||||
icon: 'ele-Food',
|
|
||||||
bg: '#48D18D',
|
|
||||||
iconColor: '#64d89d',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '多人拼团',
|
|
||||||
msg: '社交电商、开辟流量',
|
|
||||||
icon: 'ele-ShoppingCart',
|
|
||||||
bg: '#F95959',
|
|
||||||
iconColor: '#F86C6B',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '分销中心',
|
|
||||||
msg: '轻松招募分销员,成功推广奖励',
|
|
||||||
icon: 'ele-School',
|
|
||||||
bg: '#8595F4',
|
|
||||||
iconColor: '#92A1F4',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '秒杀',
|
|
||||||
msg: '超低价抢购引导更多销量',
|
|
||||||
icon: 'ele-AlarmClock',
|
|
||||||
bg: '#FEBB50',
|
|
||||||
iconColor: '#FDC566',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,17 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="login-container">
|
<div class="login-container flex">
|
||||||
<div class="login-icon-group">
|
<div class="login-left">
|
||||||
<div class="login-icon-group-title">
|
<div class="login-left-logo">
|
||||||
<img :src="logoMini" />
|
<img :src="logoMini" />
|
||||||
<div class="login-icon-group-title-text font25">{{ getThemeConfig.globalViceTitle }}</div>
|
<div class="login-left-logo-text">
|
||||||
|
<span>{{ getThemeConfig.globalViceTitle }}</span>
|
||||||
|
<span class="login-left-logo-text-msg">{{ getThemeConfig.globalViceTitleMsg }}</span>
|
||||||
</div>
|
</div>
|
||||||
<img :src="loginIconTwo" class="login-icon-group-icon" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="login-content">
|
<div class="login-left-img">
|
||||||
<div class="login-content-main">
|
<img :src="loginMain" />
|
||||||
<h4 class="login-content-title ml15">{{ getThemeConfig.globalTitle }}后台管理系统</h4>
|
</div>
|
||||||
<div v-if="!isScan">
|
<img :src="loginBg" class="login-left-waves" />
|
||||||
<el-tabs v-model="tabsActiveName">
|
</div>
|
||||||
|
<div class="login-right flex">
|
||||||
|
<div class="login-right-warp flex-margin">
|
||||||
|
<span class="login-right-warp-one"></span>
|
||||||
|
<span class="login-right-warp-two"></span>
|
||||||
|
<div class="login-right-warp-mian">
|
||||||
|
<div class="login-right-warp-main-title">{{ getThemeConfig.globalTitle }} 欢迎您!</div>
|
||||||
|
<div class="login-right-warp-main-form">
|
||||||
|
<div v-if="!state.isScan">
|
||||||
|
<el-tabs v-model="state.tabsActiveName">
|
||||||
<el-tab-pane :label="$t('message.label.one1')" name="account">
|
<el-tab-pane :label="$t('message.label.one1')" name="account">
|
||||||
<Account />
|
<Account />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
@@ -20,146 +30,187 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</div>
|
</div>
|
||||||
<Scan v-if="isScan" />
|
<Scan v-if="state.isScan" />
|
||||||
<div class="login-content-main-sacn" @click="isScan = !isScan">
|
<div class="login-content-main-sacn" @click="state.isScan = !state.isScan">
|
||||||
<i class="iconfont" :class="isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>
|
<i class="iconfont" :class="state.isScan ? 'icon-diannao1' : 'icon-barcode-qr'"></i>
|
||||||
<div class="login-content-main-sacn-delta"></div>
|
<div class="login-content-main-sacn-delta"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts" name="loginIndex">
|
||||||
import { toRefs, reactive, computed, defineComponent, onMounted } from 'vue';
|
import { defineAsyncComponent, onMounted, reactive, computed } from 'vue';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useThemeConfig } from '/@/stores/themeConfig';
|
import { useThemeConfig } from '/@/stores/themeConfig';
|
||||||
import logoMini from '/@/assets/logo-mini.svg';
|
|
||||||
import loginIconTwo from '/@/assets/login-icon-two.svg';
|
|
||||||
import { NextLoading } from '/@/utils/loading';
|
import { NextLoading } from '/@/utils/loading';
|
||||||
import Account from '/@/views/system/login/component/account.vue';
|
import logoMini from '/@/assets/logo-mini.svg';
|
||||||
import Mobile from '/@/views/system/login/component/mobile.vue';
|
import loginMain from '/@/assets/login-main.svg';
|
||||||
import Scan from '/@/views/system/login/component/scan.vue';
|
import loginBg from '/@/assets/login-bg.svg';
|
||||||
|
|
||||||
// 定义接口来定义对象的类型
|
// 引入组件
|
||||||
interface LoginState {
|
const Account = defineAsyncComponent(() => import('/@/views/system/login/component/account.vue'));
|
||||||
tabsActiveName: string;
|
const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));
|
||||||
isScan: boolean;
|
const Scan = defineAsyncComponent(() => import('/@/views/system/login/component/scan.vue'));
|
||||||
}
|
|
||||||
|
|
||||||
export default defineComponent({
|
// 定义变量内容
|
||||||
name: 'loginIndex',
|
const storesThemeConfig = useThemeConfig();
|
||||||
components: { Account, Mobile, Scan },
|
const { themeConfig } = storeToRefs(storesThemeConfig);
|
||||||
setup() {
|
const state = reactive({
|
||||||
const storesThemeConfig = useThemeConfig();
|
|
||||||
const { themeConfig } = storeToRefs(storesThemeConfig);
|
|
||||||
const state = reactive<LoginState>({
|
|
||||||
tabsActiveName: 'account',
|
tabsActiveName: 'account',
|
||||||
isScan: false,
|
isScan: false,
|
||||||
});
|
});
|
||||||
// 获取布局配置信息
|
|
||||||
const getThemeConfig = computed(() => {
|
// 获取布局配置信息
|
||||||
|
const getThemeConfig = computed(() => {
|
||||||
return themeConfig.value;
|
return themeConfig.value;
|
||||||
});
|
});
|
||||||
// 页面加载时
|
// 页面加载时
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
NextLoading.done();
|
NextLoading.done();
|
||||||
});
|
|
||||||
return {
|
|
||||||
logoMini,
|
|
||||||
loginIconTwo,
|
|
||||||
getThemeConfig,
|
|
||||||
...toRefs(state),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.login-container {
|
.login-container {
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: relative;
|
|
||||||
background: var(--el-color-white);
|
background: var(--el-color-white);
|
||||||
.login-icon-group {
|
.login-left {
|
||||||
width: 100%;
|
flex: 1;
|
||||||
height: 100%;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
.login-icon-group-title {
|
background-color: rgba(211, 239, 255, 1);
|
||||||
|
margin-right: 100px;
|
||||||
|
.login-left-logo {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50px;
|
top: 50px;
|
||||||
left: 80px;
|
left: 80px;
|
||||||
display: flex;
|
z-index: 1;
|
||||||
align-items: center;
|
animation: logoAnimation 0.3s ease;
|
||||||
img {
|
img {
|
||||||
width: 30px;
|
width: 52px;
|
||||||
height: 30px;
|
height: 52px;
|
||||||
}
|
}
|
||||||
&-text {
|
.login-left-logo-text {
|
||||||
padding-left: 15px;
|
display: flex;
|
||||||
color: var(--el-color-primary);
|
flex-direction: column;
|
||||||
|
span {
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #26a59a;
|
||||||
|
}
|
||||||
|
.login-left-logo-text-msg {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #32a99e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&::before {
|
}
|
||||||
content: '';
|
.login-left-img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
top: 50%;
|
||||||
left: 0;
|
left: 50%;
|
||||||
width: 60%;
|
transform: translate(-50%, -50%);
|
||||||
overflow: hidden;
|
width: 100%;
|
||||||
height: 80%;
|
height: 52%;
|
||||||
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='1200' height='770' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M58.4 47.77C104.6 59.51 135.26 67.37 162.11 78.04C188.97 88.72 226.33 102.69 265.92 123.55C305.51 144.4 366.96 167.09 441.43 121.52C515.9 75.95 546.48 61.01 577.69 46.27C608.9 31.53 625.86 23.69 680.26 12.28C734.65 0.87 837.29 10.7 867.29 21.8C897.29 32.9 935.51 51.9 962.21 95.45C988.9 139.01 972.91 177.36 951.37 221.39C929.83 265.43 883.49 306 890.44 337.33C897.4 368.66 974.73 412.18 974.73 411.47C974.73 412.18 1066.36 457.62 1106.36 491.06C1146.36 524.5 1178.8 563.36 1184.03 579.63C1189.26 595.9 1200.4 622.49 1181.55 676.88C1162.71 731.26 1127.16 764.32 1115.31 778.64C1103.45 792.96 5.34 783.61 4.32 784.63C3.3 785.65 -172.34 2.38 1.13 35.04L58.4 47.77L58.4 47.77Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
img {
|
||||||
background: var(--el-color-primary-light-5);
|
width: 100%;
|
||||||
transition: all 0.3s ease;
|
height: 100%;
|
||||||
|
animation: error-num 0.6s ease;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.login-left-waves {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: -100px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.login-right {
|
||||||
|
width: 700px;
|
||||||
|
.login-right-warp {
|
||||||
|
border: 1px solid var(--el-color-primary-light-3);
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 500px;
|
||||||
|
height: 500px;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: var(--el-color-white);
|
||||||
|
.login-right-warp-one,
|
||||||
|
.login-right-warp-two {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: inherit;
|
||||||
|
height: inherit;
|
||||||
|
&::before,
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
width: 150px;
|
|
||||||
height: 300px;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
-webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='150' height='300' xmlns='http://www.w3.org/2000/svg' fill='none'%3E%3Cg%3E%3Cpath id='svg_1' d='M-0.56 -0.28C41.94 36.17 67.73 18.94 93.33 33.96C118.93 48.98 107.58 73.56 101.94 89.76C96.29 105.96 50.09 217.83 47.87 231.18C45.64 244.52 46.02 255.2 64.4 270.05C82.79 284.91 121.99 292.31 111.98 289.81C101.97 287.32 153.96 301.48 151.83 299.9C149.69 298.32 149.98 -1.36 149.71 -1.18C149.98 -1.36 -43.06 -36.74 -0.56 -0.28L-0.56 -0.28Z' fill='%23409eff'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E");
|
|
||||||
background: var(--el-color-primary-light-5);
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
&-icon {
|
|
||||||
width: 60%;
|
|
||||||
height: 70%;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.login-content {
|
|
||||||
width: 500px;
|
|
||||||
padding: 20px;
|
|
||||||
position: absolute;
|
|
||||||
right: 200px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%) translate3d(0, 0, 0);
|
|
||||||
background-color: var(--el-color-white);
|
|
||||||
border: 5px solid var(--el-color-primary-light-8);
|
|
||||||
border-radius: 5px;
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
height: 460px;
|
}
|
||||||
.login-content-main {
|
}
|
||||||
margin: 0 auto;
|
.login-right-warp-one {
|
||||||
width: 80%;
|
&::before {
|
||||||
.login-content-title {
|
filter: hue-rotate(0deg);
|
||||||
color: var(--el-text-color-primary);
|
top: 0px;
|
||||||
font-weight: 500;
|
left: 0;
|
||||||
font-size: 22px;
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: linear-gradient(90deg, transparent, var(--el-color-primary));
|
||||||
|
animation: loginLeft 3s linear infinite;
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
filter: hue-rotate(60deg);
|
||||||
|
top: -100%;
|
||||||
|
right: 2px;
|
||||||
|
width: 3px;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(180deg, transparent, var(--el-color-primary));
|
||||||
|
animation: loginTop 3s linear infinite;
|
||||||
|
animation-delay: 0.7s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.login-right-warp-two {
|
||||||
|
&::before {
|
||||||
|
filter: hue-rotate(120deg);
|
||||||
|
bottom: 2px;
|
||||||
|
right: -100%;
|
||||||
|
width: 100%;
|
||||||
|
height: 3px;
|
||||||
|
background: linear-gradient(270deg, transparent, var(--el-color-primary));
|
||||||
|
animation: loginRight 3s linear infinite;
|
||||||
|
animation-delay: 1.4s;
|
||||||
|
}
|
||||||
|
&::after {
|
||||||
|
filter: hue-rotate(300deg);
|
||||||
|
bottom: -100%;
|
||||||
|
left: 0px;
|
||||||
|
width: 3px;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(360deg, transparent, var(--el-color-primary));
|
||||||
|
animation: loginBottom 3s linear infinite;
|
||||||
|
animation-delay: 2.1s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.login-right-warp-mian {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
.login-right-warp-main-title {
|
||||||
|
height: 130px;
|
||||||
|
line-height: 130px;
|
||||||
|
font-size: 27px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
letter-spacing: 4px;
|
letter-spacing: 3px;
|
||||||
margin: 15px 0 30px;
|
animation: logoAnimation 0.3s ease;
|
||||||
white-space: nowrap;
|
animation-delay: 0.3s;
|
||||||
z-index: 5;
|
color: var(--el-text-color-primary);
|
||||||
position: relative;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.login-right-warp-main-form {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0 50px 50px;
|
||||||
.login-content-main-sacn {
|
.login-content-main-sacn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -169,7 +220,7 @@ export default defineComponent({
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: all ease 0.3s;
|
transition: all ease 0.3s;
|
||||||
color: var(--el-text-color-primary);
|
color: var(--el-color-primary);
|
||||||
&-delta {
|
&-delta {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 35px;
|
width: 35px;
|
||||||
@@ -191,8 +242,11 @@ export default defineComponent({
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 2px;
|
right: 1px;
|
||||||
top: -1px;
|
top: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,475 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="layout-pd">
|
|
||||||
<el-card shadow="hover" header="正则验证(一些项目中常用的正则)">
|
|
||||||
<el-form :model="state.ruleForm" :rules="state.rules" class="tools-warp-form" size="default" label-position="top">
|
|
||||||
<el-form-item label="验证百分比(不可以小数):" prop="a22">
|
|
||||||
<div class="tools-warp-form-msg">验证可以输入大于0小于100的数字</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a22" @input="onVerifyNumberPercentage($event)" placeholder="请输入数字进行测试">
|
|
||||||
<template #append> % </template>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="验证百分比(可以小数):" prop="a23" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">验证可以输入大于0小于100的数字</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a23" @input="onVerifyNumberPercentageFloat($event)" placeholder="请输入数字进行测试">
|
|
||||||
<template #append> % </template>
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="小数或整数:" prop="a1" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证可以输入小数或整数,0 开始, . 只能出现一次,保留小数点后保留2位小数。(负数时,模拟拼接负号给后台)。
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a1" @input="onVerifyNumberIntegerAndFloat($event)" placeholder="请输入小数或整数进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="正整数:" prop="a2" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">验证只可以输入正整数,0 开始后面将不可以输入。</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a2" @input="onVerifiyNumberInteger($event)" placeholder="请输入整数进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="去掉中文及空格:" prop="a3" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">验证不可以输入空格与中文。</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a3" @input="onVerifyCnAndSpace($event)" placeholder="请输入内容进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="去掉英文及空格:" prop="a4" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">验证不可以输入空格与英文。</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a4" @input="onVerifyEnAndSpace($event)" placeholder="请输入内容进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="禁止输入空格:" prop="a5" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">验证不可以输入空格。</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a5" @input="onVerifyAndSpace($event)" placeholder="请输入内容进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="金额用 `,` 区分开:" prop="a6" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">金额添加 `,` 进行区分,便于阅读。{{ state.ruleForm.a6 }}</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a6" @input="onVerifyNumberComma($event)" placeholder="请输入金额进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="匹配文字变色(搜索时):" prop="a7" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">示例:<span v-html="state.text"></span></div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a7" @input="onVerifyTextColor($event)" placeholder="请输入示例中的部分文字"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="数字转中文大写:" prop="a8" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证数字转成中文的大写。<span class="tools-warp-form-msg-red">{{ state.cnText }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a8" @input="onVerifyNumberCnUppercase($event)" placeholder="请输入金额进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="手机号码:" prop="a9" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证手机号码 (true: 正确,false: 不正确)。<span class="tools-warp-form-msg-red">{{ state.phone }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a9" @input="onVerifyPhone($event)" placeholder="请输入手机号进行测试" maxlength="11"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="国内电话号码:" prop="a10" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证国内电话号码 (true: 正确,false: 不正确)。<span class="tools-warp-form-msg-red">{{ state.telePhone }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a10" @input="onVerifyTelPhone($event)" placeholder="请输入国内电话号码进行测试" maxlength="12">
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="登录账号:" prop="a11" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证登录账号是否正确。字母开头,允许5-16字节,允许字母数字下划线 (true: 正确,false: 不正确)。<span class="tools-warp-form-msg-red">{{
|
|
||||||
state.account
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a11" @input="onVerifyAccount($event)" placeholder="请输入账号进行测试" maxlength="16"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码:" prop="a12" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证密码是否正确。以字母开头,长度在6~16之间,只能包含字母、数字和下划线 (true: 正确,false: 不正确)。<span
|
|
||||||
class="tools-warp-form-msg-red"
|
|
||||||
>{{ state.password }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a12" @input="onVerifyPassword($event)" placeholder="请输入密码进行测试" maxlength="16"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="强密码:" prop="a13" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证强密码是否正确。字母+数字+特殊字符,长度在6-16之间 (true: 正确,false: 不正确)。<span class="tools-warp-form-msg-red">{{
|
|
||||||
state.passwordPowerful
|
|
||||||
}}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a13" @input="onVerifyPasswordPowerful($event)" placeholder="请输入密码进行测试" maxlength="16">
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="密码强度:" prop="a14" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证密码强度。返回 强、中、弱。(弱:纯数字,纯字母,纯特殊字符,中:字母+数字,字母+特殊字符,数字+特殊字符,强:字母+数字+特殊字符)<span
|
|
||||||
class="tools-warp-form-msg-red"
|
|
||||||
>{{ state.passwordStrength }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a14" @input="onVerifyPasswordStrength($event)" placeholder="请输入密码进行测试" maxlength="16">
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="IP地址:" prop="a15" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证IP地址是否正确。(true: 正确,false: 不正确)。<span class="tools-warp-form-msg-red">{{ state.iPAddress }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a15" @input="onVerifyIPAddress($event)" placeholder="请输入IP地址进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="邮箱:" prop="a16" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证邮箱是否正确。(true: 正确,false:不正确)。<span class="tools-warp-form-msg-red">{{ state.email }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a16" @input="onVerifyEmail($event)" placeholder="请输入邮箱进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="身份证:" prop="a17" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证身份证是否正确。(true: 正确,false:不正确)。<span class="tools-warp-form-msg-red">{{ state.idCard }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a17" @input="onVerifyIDCard($event)" placeholder="请输入身份证进行测试" maxlength="18"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="姓名:" prop="a18" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证姓名是否正确,包括少数民族名字。(true: 正确,false:不正确)。<span class="tools-warp-form-msg-red">{{ state.fullName }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a18" @input="onVerifyFullName($event)" placeholder="请输入姓名进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="邮政编码:" prop="a19" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证邮政编码是否正确,不能以 0 开始。(true: 正确,false:不正确)。<span class="tools-warp-form-msg-red">{{ state.postalCode }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a19" @input="onVerifyPostalCode($event)" placeholder="请输入邮政编码进行测试" maxlength="6"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="url:" prop="a20" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证url是否正确。(true: 正确,false:不正确)。<span class="tools-warp-form-msg-red">{{ state.url }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a20" @input="onVerifyUrl($event)" placeholder="请输入内容进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="车牌号:" prop="a21" class="mt20">
|
|
||||||
<div class="tools-warp-form-msg">
|
|
||||||
验证车牌号是否正确。(true: 正确,false:不正确)。<span class="tools-warp-form-msg-red">{{ state.carNum }}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<el-input v-model="state.ruleForm.a21" @input="onVerifyCarNum($event)" placeholder="请输入车牌号进行测试"> </el-input>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup lang="ts" name="tools">
|
|
||||||
import { reactive } from 'vue';
|
|
||||||
import {
|
|
||||||
verifyNumberPercentage,
|
|
||||||
verifyNumberPercentageFloat,
|
|
||||||
verifyNumberIntegerAndFloat,
|
|
||||||
verifiyNumberInteger,
|
|
||||||
verifyCnAndSpace,
|
|
||||||
verifyEnAndSpace,
|
|
||||||
verifyAndSpace,
|
|
||||||
verifyNumberComma,
|
|
||||||
verifyTextColor,
|
|
||||||
verifyNumberCnUppercase,
|
|
||||||
verifyPhone,
|
|
||||||
verifyTelPhone,
|
|
||||||
verifyAccount,
|
|
||||||
verifyPassword,
|
|
||||||
verifyPasswordPowerful,
|
|
||||||
verifyPasswordStrength,
|
|
||||||
verifyIPAddress,
|
|
||||||
verifyEmail,
|
|
||||||
verifyIdCard,
|
|
||||||
verifyFullName,
|
|
||||||
verifyPostalCode,
|
|
||||||
verifyUrl,
|
|
||||||
verifyCarNum,
|
|
||||||
} from '/@/utils/toolsValidate';
|
|
||||||
|
|
||||||
// 定义变量内容
|
|
||||||
const state = reactive({
|
|
||||||
text: '世间美好,与你环环相扣,祝你开心每一天!',
|
|
||||||
phone: false,
|
|
||||||
cnText: '',
|
|
||||||
telePhone: false,
|
|
||||||
account: false,
|
|
||||||
password: false,
|
|
||||||
passwordPowerful: false,
|
|
||||||
passwordStrength: '',
|
|
||||||
iPAddress: false,
|
|
||||||
email: false,
|
|
||||||
idCard: false,
|
|
||||||
fullName: false,
|
|
||||||
postalCode: false,
|
|
||||||
url: false,
|
|
||||||
carNum: false,
|
|
||||||
/**
|
|
||||||
* 变量名为了方便,随便取了,
|
|
||||||
* 实际中,按正常程序进行命名
|
|
||||||
*/
|
|
||||||
ruleForm: {
|
|
||||||
a1: '',
|
|
||||||
a2: '',
|
|
||||||
a3: '',
|
|
||||||
a4: '',
|
|
||||||
a5: '',
|
|
||||||
a6: '',
|
|
||||||
a7: '',
|
|
||||||
a8: '',
|
|
||||||
a9: '',
|
|
||||||
a10: '',
|
|
||||||
a11: '',
|
|
||||||
a12: '',
|
|
||||||
a13: '',
|
|
||||||
a14: '',
|
|
||||||
a15: '',
|
|
||||||
a16: '',
|
|
||||||
a17: '',
|
|
||||||
a18: '',
|
|
||||||
a19: '',
|
|
||||||
a20: '',
|
|
||||||
a21: '',
|
|
||||||
a22: '',
|
|
||||||
a23: '',
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
a1: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入小数或整数进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a2: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入正整数进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a3: [{ required: true, message: '请输入内容进行测试', trigger: 'change' }],
|
|
||||||
a4: [{ required: true, message: '请输入内容进行测试', trigger: 'change' }],
|
|
||||||
a5: [{ required: true, message: '请输入内容进行测试', trigger: 'change' }],
|
|
||||||
a6: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入小数或整数进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a7: [{ required: true, message: '请输入内容进行测试', trigger: 'change' }],
|
|
||||||
a8: [{ required: true, message: '请输入金额进行测试', trigger: 'change' }],
|
|
||||||
a9: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入手机号进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a10: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入国内电话号码进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a11: [{ required: true, message: '请输入账号进行测试', trigger: 'change' }],
|
|
||||||
a12: [{ required: true, message: '请输入密码进行测试', trigger: 'change' }],
|
|
||||||
a13: [{ required: true, message: '请输入密码进行测试', trigger: 'change' }],
|
|
||||||
a14: [{ required: true, message: '请输入密码进行测试', trigger: 'change' }],
|
|
||||||
a15: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入IP地址进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a16: [{ required: true, message: '请输入邮箱进行测试', trigger: 'change' }],
|
|
||||||
a17: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入身份证进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a18: [{ required: true, message: '请输入姓名进行测试', trigger: 'change' }],
|
|
||||||
a19: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入邮政编码进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a20: [{ required: true, message: '请输入内容进行测试', trigger: 'change' }],
|
|
||||||
a21: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
message: '请输入车牌号进行测试',
|
|
||||||
trigger: 'change',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
a22: [{ required: true, message: '请输入数字进行测试', trigger: 'change' }],
|
|
||||||
a23: [{ required: true, message: '请输入数字进行测试', trigger: 'change' }],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 验证百分比(不可以小数)
|
|
||||||
const onVerifyNumberPercentage = (val: string) => {
|
|
||||||
state.ruleForm.a22 = verifyNumberPercentage(val);
|
|
||||||
};
|
|
||||||
// 验证百分比(可以小数)
|
|
||||||
const onVerifyNumberPercentageFloat = (val: string) => {
|
|
||||||
state.ruleForm.a23 = verifyNumberPercentageFloat(val);
|
|
||||||
};
|
|
||||||
// 小数或整数
|
|
||||||
const onVerifyNumberIntegerAndFloat = (val: string) => {
|
|
||||||
state.ruleForm.a1 = verifyNumberIntegerAndFloat(val);
|
|
||||||
};
|
|
||||||
// 正整数
|
|
||||||
const onVerifiyNumberInteger = (val: string) => {
|
|
||||||
state.ruleForm.a2 = verifiyNumberInteger(val);
|
|
||||||
};
|
|
||||||
// 去掉中文及空格
|
|
||||||
const onVerifyCnAndSpace = (val: string) => {
|
|
||||||
state.ruleForm.a3 = verifyCnAndSpace(val);
|
|
||||||
};
|
|
||||||
// 去掉英文及空格
|
|
||||||
const onVerifyEnAndSpace = (val: string) => {
|
|
||||||
state.ruleForm.a4 = verifyEnAndSpace(val);
|
|
||||||
};
|
|
||||||
// 禁止输入空格
|
|
||||||
const onVerifyAndSpace = (val: string) => {
|
|
||||||
state.ruleForm.a5 = verifyAndSpace(val);
|
|
||||||
};
|
|
||||||
// 金额用 `,` 区分开
|
|
||||||
const onVerifyNumberComma = (val: string) => {
|
|
||||||
state.ruleForm.a6 = verifyNumberComma(val);
|
|
||||||
};
|
|
||||||
// 匹配文字变色(搜索时)
|
|
||||||
const onVerifyTextColor = (val: string) => {
|
|
||||||
state.ruleForm.a7 = verifyAndSpace(val);
|
|
||||||
if (state.ruleForm.a7 === '') state.text = `世间美好,与你环环相扣,祝你开心每一天!`;
|
|
||||||
else state.text = verifyTextColor(state.ruleForm.a7, state.text);
|
|
||||||
};
|
|
||||||
// 数字转中文大写
|
|
||||||
const onVerifyNumberCnUppercase = (val: string) => {
|
|
||||||
state.ruleForm.a8 = verifyNumberIntegerAndFloat(val);
|
|
||||||
if (state.ruleForm.a8 === '') state.cnText = '';
|
|
||||||
else state.cnText = verifyNumberCnUppercase(state.ruleForm.a8);
|
|
||||||
};
|
|
||||||
// 手机号码
|
|
||||||
const onVerifyPhone = (val: string) => {
|
|
||||||
state.phone = verifyPhone(val);
|
|
||||||
};
|
|
||||||
// 国内电话号码
|
|
||||||
const onVerifyTelPhone = (val: string) => {
|
|
||||||
state.telePhone = verifyTelPhone(val);
|
|
||||||
};
|
|
||||||
// 登录账号
|
|
||||||
const onVerifyAccount = (val: string) => {
|
|
||||||
state.ruleForm.a11 = verifyCnAndSpace(val);
|
|
||||||
state.account = verifyAccount(state.ruleForm.a11);
|
|
||||||
};
|
|
||||||
// 密码
|
|
||||||
const onVerifyPassword = (val: string) => {
|
|
||||||
state.ruleForm.a12 = verifyCnAndSpace(val);
|
|
||||||
state.password = verifyPassword(state.ruleForm.a12);
|
|
||||||
};
|
|
||||||
// 强密码
|
|
||||||
const onVerifyPasswordPowerful = (val: string) => {
|
|
||||||
state.ruleForm.a13 = verifyCnAndSpace(val);
|
|
||||||
state.passwordPowerful = verifyPasswordPowerful(state.ruleForm.a13);
|
|
||||||
};
|
|
||||||
// 密码强度
|
|
||||||
const onVerifyPasswordStrength = (val: string) => {
|
|
||||||
state.ruleForm.a14 = verifyCnAndSpace(val);
|
|
||||||
state.passwordStrength = verifyPasswordStrength(state.ruleForm.a14);
|
|
||||||
};
|
|
||||||
// IP地址
|
|
||||||
const onVerifyIPAddress = (val: string) => {
|
|
||||||
state.iPAddress = verifyIPAddress(val);
|
|
||||||
};
|
|
||||||
// 邮箱
|
|
||||||
const onVerifyEmail = (val: string) => {
|
|
||||||
state.ruleForm.a16 = verifyCnAndSpace(val);
|
|
||||||
state.email = verifyEmail(state.ruleForm.a16);
|
|
||||||
};
|
|
||||||
// 身份证
|
|
||||||
const onVerifyIDCard = (val: string) => {
|
|
||||||
state.ruleForm.a17 = verifyCnAndSpace(val);
|
|
||||||
state.idCard = verifyIdCard(state.ruleForm.a17);
|
|
||||||
};
|
|
||||||
// 姓名
|
|
||||||
const onVerifyFullName = (val: string) => {
|
|
||||||
state.ruleForm.a18 = verifyAndSpace(val);
|
|
||||||
state.fullName = verifyFullName(state.ruleForm.a18);
|
|
||||||
};
|
|
||||||
// 邮政编码
|
|
||||||
const onVerifyPostalCode = (val: string) => {
|
|
||||||
state.ruleForm.a19 = verifiyNumberInteger(val);
|
|
||||||
state.postalCode = verifyPostalCode(state.ruleForm.a19);
|
|
||||||
};
|
|
||||||
// url
|
|
||||||
const onVerifyUrl = (val: string) => {
|
|
||||||
state.ruleForm.a20 = verifyAndSpace(val);
|
|
||||||
state.url = verifyUrl(state.ruleForm.a20);
|
|
||||||
};
|
|
||||||
// 车牌号
|
|
||||||
const onVerifyCarNum = (val: string) => {
|
|
||||||
state.ruleForm.a21 = verifyAndSpace(val);
|
|
||||||
state.carNum = verifyCarNum(state.ruleForm.a21);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
.tools-warp-form {
|
|
||||||
:deep(.el-form-item--small.el-form-item) {
|
|
||||||
margin-bottom: 0 !important;
|
|
||||||
}
|
|
||||||
.tools-warp-form-msg {
|
|
||||||
color: #666666;
|
|
||||||
font-size: 14px;
|
|
||||||
width: 100%;
|
|
||||||
.tools-warp-form-msg-red {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tools-warp-form-msg + div {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 607 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 783 KiB |
@@ -1,51 +0,0 @@
|
|||||||
// 地图模拟数据
|
|
||||||
export const echartsMapList = [
|
|
||||||
{ name: '深圳市人民政府', value: '100' },
|
|
||||||
{ name: '莲花山公园', value: '100' },
|
|
||||||
{ name: '世界之窗', value: '100' },
|
|
||||||
{ name: '华侨城欢乐谷', value: '100' },
|
|
||||||
{ name: '宝安区西乡', value: '100' },
|
|
||||||
];
|
|
||||||
|
|
||||||
// 地图经纬度数据
|
|
||||||
export const echartsMapData: object = {
|
|
||||||
深圳市人民政府: [114.064524, 22.549225],
|
|
||||||
莲花山公园: [114.0658, 22.560072],
|
|
||||||
世界之窗: [113.979419, 22.540579],
|
|
||||||
华侨城欢乐谷: [113.986066, 22.548056],
|
|
||||||
宝安区西乡: [113.869053, 22.581714],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 地图图片显示
|
|
||||||
export const echartsMapImgs = [
|
|
||||||
{
|
|
||||||
url: 'https://img1.baidu.com/it/u=2425496005,2401702709&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
|
|
||||||
name: '深圳市人民政府',
|
|
||||||
add: '深圳市福田区福中三路市民中心C区',
|
|
||||||
dec: '深圳市人民政府是根据《中华人民共和国地方各级人民代表大会和地方各级人民政府组织法》设立的,是深圳市人民代表大会的执行机关,是深圳市的国家行政机关。',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://img0.baidu.com/it/u=2666213152,2487785512&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
|
|
||||||
name: '莲花山公园',
|
|
||||||
add: '广东省深圳市福田区莲花街道莲花北社区红荔路6030号',
|
|
||||||
dec: '莲花山公园筹建于1992年10月10日 ,1997年6月23日正式对外局部开放。',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://img1.baidu.com/it/u=1595204841,1838139326&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
|
|
||||||
name: '世界之窗',
|
|
||||||
add: '深圳市南山区深南大道9037号',
|
|
||||||
dec: '这里,世界首座实景拍摄悬空式球幕影院“飞跃美利坚””,为游客提供集休闲放松于一体的都市时尚生活空间。',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://img0.baidu.com/it/u=1586832283,2276617306&fm=253&fmt=auto&app=138&f=JPEG?w=476&h=500',
|
|
||||||
name: '华侨城欢乐谷',
|
|
||||||
add: '广东省深圳市南山区沙河街道星河街社区侨城西街1号',
|
|
||||||
dec: '深圳欢乐谷注重满足人们参与、体验的新型诱游需求,营造出自然、清新、活泼、惊奇、热烈、刺激的休闲旅游氛围。',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
url: 'https://img0.baidu.com/it/u=2899429152,3158963267&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200',
|
|
||||||
name: '宝安区西乡',
|
|
||||||
add: '西乡街道下辖25个社区',
|
|
||||||
dec: '西乡街道,隶属于广东省深圳市宝安区,位于宝安区西南部,东接石岩街道,南接新安街道,西至珠江口岸边,北接航城街道。',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
// 顶部下来菜单
|
|
||||||
export const dropdownList: Array<object> = [
|
|
||||||
{
|
|
||||||
label: '广东省农业农村厅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '广西省农业农村厅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '四川省农业农村厅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '湖北省农业农村厅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '福建省农业农村厅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '山东省农业农村厅',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '江西省农业农村厅',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// sky 天气
|
|
||||||
export const skyList: Array<object> = [
|
|
||||||
{
|
|
||||||
v1: '时间',
|
|
||||||
v2: '天气',
|
|
||||||
v3: '温度',
|
|
||||||
v4: '湿度',
|
|
||||||
v5: '降水概率',
|
|
||||||
v6: '风向',
|
|
||||||
v7: '风力',
|
|
||||||
type: 'title',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
v1: '今天',
|
|
||||||
v2: 'ele-Sunny',
|
|
||||||
v3: '20°/26°',
|
|
||||||
v4: '80%',
|
|
||||||
v5: '50%',
|
|
||||||
v6: '东南风',
|
|
||||||
v7: '13m/s',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
v1: '明天',
|
|
||||||
v2: 'ele-Lightning',
|
|
||||||
v3: '20°/26°',
|
|
||||||
v4: '80%',
|
|
||||||
v5: '50%',
|
|
||||||
v6: '东南风',
|
|
||||||
v7: '13m/s',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
v1: '后天',
|
|
||||||
v2: 'ele-Sunny',
|
|
||||||
v3: '20°/26°',
|
|
||||||
v4: '80%',
|
|
||||||
v5: '50%',
|
|
||||||
v6: '东南风',
|
|
||||||
v7: '13m/s',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 当前设置状态
|
|
||||||
export const dBtnList: Array<object> = [
|
|
||||||
{
|
|
||||||
v1: '地块A-灌溉',
|
|
||||||
v2: '阳光玫瑰种植',
|
|
||||||
v3: '126天',
|
|
||||||
v4: '设备在线',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
v1: '地块B-收割',
|
|
||||||
v2: '阳光玫瑰种植',
|
|
||||||
v3: '360天',
|
|
||||||
v4: '设备预警',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 当前设备监测
|
|
||||||
export const chartData4List: Array<object> = [
|
|
||||||
{
|
|
||||||
label: '温度',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '光照',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '湿度',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '风力',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '张力',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '气压',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 3DEarth 地图周围按钮组
|
|
||||||
export const earth3DBtnList: Array<object> = [
|
|
||||||
{
|
|
||||||
topLevelClass: 'fixed-top',
|
|
||||||
icon: 'ele-MagicStick',
|
|
||||||
label: '环境监测',
|
|
||||||
type: 0,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
topLevelClass: 'fixed-right',
|
|
||||||
icon: 'ele-MoonNight',
|
|
||||||
label: '精准管理',
|
|
||||||
type: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
topLevelClass: 'fixed-bottom',
|
|
||||||
icon: 'ele-TrendCharts',
|
|
||||||
label: '数据报表',
|
|
||||||
type: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
topLevelClass: 'fixed-left',
|
|
||||||
icon: 'ele-Van',
|
|
||||||
label: '产品追溯',
|
|
||||||
type: 3,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
@@ -2,6 +2,7 @@ import vue from '@vitejs/plugin-vue';
|
|||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import { defineConfig, loadEnv, ConfigEnv } from 'vite';
|
import { defineConfig, loadEnv, ConfigEnv } from 'vite';
|
||||||
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
import vueSetupExtend from 'vite-plugin-vue-setup-extend';
|
||||||
|
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||||
|
|
||||||
const pathResolve = (dir: string) => {
|
const pathResolve = (dir: string) => {
|
||||||
return resolve(__dirname, '.', dir);
|
return resolve(__dirname, '.', dir);
|
||||||
@@ -9,13 +10,14 @@ const pathResolve = (dir: string) => {
|
|||||||
|
|
||||||
const alias: Record<string, string> = {
|
const alias: Record<string, string> = {
|
||||||
'/@': pathResolve('./src/'),
|
'/@': pathResolve('./src/'),
|
||||||
|
'@views': pathResolve('./src/views'),
|
||||||
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js',
|
'vue-i18n': 'vue-i18n/dist/vue-i18n.cjs.js',
|
||||||
};
|
};
|
||||||
|
|
||||||
const viteConfig = defineConfig((mode: ConfigEnv) => {
|
const viteConfig = defineConfig((mode: ConfigEnv) => {
|
||||||
const env = loadEnv(mode.mode, process.cwd());
|
const env = loadEnv(mode.mode, process.cwd());
|
||||||
return {
|
return {
|
||||||
plugins: [vue(), vueSetupExtend()],
|
plugins: [vue(), vueJsx(),vueSetupExtend()],
|
||||||
root: process.cwd(),
|
root: process.cwd(),
|
||||||
resolve: { alias },
|
resolve: { alias },
|
||||||
base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
|
base: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,
|
||||||
|
|||||||
665
web/yarn.lock
665
web/yarn.lock
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user