移除废弃文件
This commit is contained in:
parent
37c6502440
commit
69d66b0a17
706
CHANGELOG.md
706
CHANGELOG.md
@ -1,705 +1 @@
|
||||
# CHANGELOG
|
||||
|
||||
## Pending
|
||||
|
||||
- 💎 优化 `搜索页面` 跳转以及显示问题
|
||||
|
||||
## 2.5.0
|
||||
|
||||
- 🌟 新增 `BasicTable` 组件 可通过 `immediate` 参数,手动控制加载数据
|
||||
- 💎 升级 `axios` 到 `1.7.2` 采用 `AbortController` 取消请求的方案
|
||||
- 💎 优化 调整 `vite/client` 的加载方式
|
||||
- 💎 优化 `BasicColumn` 类型,支持泛型传入
|
||||
- 🐞 修复 `BasicTable` 切换页数量,未重置勾选数据
|
||||
- `依赖升级`
|
||||
|
||||
## 2.4.4
|
||||
|
||||
- 🌟 新增 `深色主题` 切换组件,并在顶部右侧展示
|
||||
- 🌟 新增 `深色主题` 切换过度样式
|
||||
- 💎 优化 `多页签` 过度样式
|
||||
- 💎 优化 `code` 类型定义
|
||||
- 💎 升级 `vite` 到 `5.x` 版本
|
||||
- `依赖升级`
|
||||
|
||||
## 2.4.3
|
||||
|
||||
- 💎 优化 `BasicSelect` 组件逻辑,支持响应式 `options`
|
||||
- 💎 优化 `BasicColumn` 类型定义
|
||||
- `依赖升级`
|
||||
|
||||
## 2.4.2
|
||||
|
||||
- 💎 优化 `defineComponent` 语法 为 `setup`
|
||||
- `依赖升级`
|
||||
|
||||
## 2.4.1
|
||||
|
||||
- 🌟 新增 `v-debounce` 全局指令
|
||||
- 🌟 新增 `v-throttle` 全局指令
|
||||
- 💎 优化 `横向菜单` 显示内容,支持收起溢出的菜单
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.4.0
|
||||
|
||||
- 🌟 新增 `BasicForm` 支持 `validate` 方法单独验证
|
||||
- 💎 优化 `BasicForm` 提交按钮加载效果
|
||||
- 💎 优化 `setLoadingSub` 改名为 `setLoading`
|
||||
- 🐞 修复 `菜单折叠后` 层级问题
|
||||
- 🐞 修复 `BasicTable` 使用插槽报错问题
|
||||
- 🌟 新增 `BasicTable` 导出 `setLoading`
|
||||
- 🌟 新增 `TableSelect` 结合 `Form` 组件使用示例
|
||||
- 🌟 新增 `TableSelect` 导出 `getTableRef` 和 `updateTableSelectedKeys` 方法
|
||||
- 🐞 修复 `多页签` 异常初始化
|
||||
- 🐞 修复 `面包屑` 跳转警告
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.9 (2023-07-21)
|
||||
|
||||
- 🐞 修复 `getTreeValues` 方法
|
||||
- 🐞 修复 `搜索页面` 跳转异常
|
||||
- 🌟 新增 `TableSelect` 支持 `formValues` 配置查询表单参数
|
||||
- 🌟 新增 `BasicForm` 支持 `isEnterSubmit` 配置,监听回车事件提交
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.8 (2023-06-03)
|
||||
|
||||
- 🌟 新增 `BasicForm` 支持 `valueFormat` 特性
|
||||
- 💎 优化 `useECharts` 监听菜单收缩变化
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.7 (2023-04-26)
|
||||
|
||||
- 🌟 新增 `BasicForm` 支持 `ImageUpload` 组件
|
||||
- 🌟 新增 `BasicTable` 支持 `helpMessage` 配置
|
||||
- 🐞 修复 `PageWrapper` 横向菜单宽度异常
|
||||
- 💎 优化 `Code And TypeScript`
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.6 (2023-03-23)
|
||||
|
||||
- 🌟 新增 `sendFormData` `get` `put` `delete` 请求方法
|
||||
- 🌟 新增 `权限判断` 示例页面,功能示例>权限判断
|
||||
- 🌟 新增 `Authority` 全局注册权限判断组件
|
||||
- 💎 优化 `hasPermission` 权限判断方法,兼容两种格式
|
||||
- 🐞 修复 `BasicTable` 分页异常判断逻辑
|
||||
- 🐞 修复 `顶部拆分菜单` 当只有顶级菜单时 `ui` 显示异常
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.3.5 (2023-02-02)
|
||||
|
||||
- 🌟 新增 `项目配置` 开关
|
||||
- 🌟 新增 `添加角色` 页面模板
|
||||
- 🌟 新增 `BasicForm` 支持 `setSchema` 方法
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.4 (2022-12-23)
|
||||
|
||||
- 🌟 新增 `菜单管理2` 页面,用表格展示
|
||||
- 🐞 修复 `pinia 失去响应式`
|
||||
- 🐞 修复 `getTreeAll` 方法错误
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.3.3 (2022-12-12)
|
||||
|
||||
- 🌟 新增 `env.test` 环境打包配置
|
||||
- 🌟 新增 `rollup-plugin-visualizer` 打包分析插件支持
|
||||
- 🌟 增强 `menuSetting` 配置灵活性
|
||||
- 💎 移除 `BasicForm` 创建 `placeholder` 中文提示
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.3.2 (2022-10-12)
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- 🌟 `BasicForm` 变更 `submit` 方法返回 `values` 整个表单值对象
|
||||
|
||||
## Feats
|
||||
|
||||
- 🌟 `BasicForm` 增强 `field` 参数支持 `a.b.c` 语法
|
||||
- 🌟 `BasicModal` 优化 嵌套弹窗,支持拖拽
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.1 (2022-09-13)
|
||||
|
||||
- 🌟 升级 `vite` 支持 `3.x`
|
||||
- 💎 重构 `TableSelect` 组件,优化单选,分页多选
|
||||
- 🐞 修复 `BasicUpload` 组件,图片回显问题
|
||||
- `依赖升级`
|
||||
|
||||
## 2.3.0 (2022-08-28)
|
||||
|
||||
- 💎 升级 `naiveui v2.32.2`
|
||||
- 💎 优化 `类型导入` 错误
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.9 (2022-08-02)
|
||||
|
||||
- 💎 优化 `BasicColumn` 类型定义
|
||||
- 🐞 修复 `修复ts类型` 错误
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.8 (2022-07-18)
|
||||
|
||||
- 🌟 新增 `BasicForm` 支持 `setSchema` 方法
|
||||
- 🌟 新增 `BasicSelect` 取消 `request` 必传,支持直接传入 `options`
|
||||
- 🌟 新增 `TableSetting` 支持 `宽度配置` 且支持最大高度滚动
|
||||
- 🐞 修复 `网络请求异常` 弹窗按钮背景色异常
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.7 (2022-07-09)
|
||||
|
||||
- 🌟 新增 `meta.documentTitle` 网页标题 优先 title 字段
|
||||
- 🌟 新增 `meta.title` 支持定制 `Render` `多页签` `面包屑` 同步渲染
|
||||
- 🌟 新增 `meta.authEvery` 是否验证每一个权限都包含
|
||||
- 🌟 新增 `basicModal` 支持 `prefixFooter` `centerFooter` `suffixFooter` 插槽,用于定制其他元素
|
||||
- 🌟 新增 `basicModal` 导出 `handleSubmit` 方法
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.6 (2022-07-01)
|
||||
|
||||
- 🌟 新增 `meta.tagView` 配置,是否显示在多页签中
|
||||
- 🌟 新增 `meta.breadcrumbView` 配置,是否显示在面包屑中
|
||||
- 🌟 新增 `TableImg` 组件,可在外部使用
|
||||
- 🌟 新增 `Authority` 权限控制组件
|
||||
- 🐞 修复 `useDialog` 方法参数定义
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.2.5 (2022-06-20)
|
||||
|
||||
- 🌟 新增 `tableSelect` 组件支持 `v-model`
|
||||
- 🌟 新增 `Region` 支持配置 `labelField` 和 `valueField` 属性
|
||||
- 🐞 修复 `activeMenu` 路由配置,刷新浏览器之后失效
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.4 (2022-06-10)
|
||||
|
||||
### ✨ 新增功能
|
||||
- 新增 `BasicTable` 支持 `autoScrollX` 属性,用于自动计算 `columns` 总和
|
||||
- 新增 `BasicTable` 表格列支持 `draggable` 配置是可拖拽
|
||||
- 新增 `useDialog` `useLoadingBar` `useMessage` 可在 `setup` 外使用
|
||||
- `依赖升级`
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复 `URL` 正则表达式错误
|
||||
- 修复 `useECharts` 报错和暗色模式问题
|
||||
|
||||
### 💎 优化
|
||||
- 移除 `挂载` window 写法
|
||||
- 移除 `额外挂载` appProvider
|
||||
|
||||
|
||||
## 2.2.3 (2022-05-25)
|
||||
|
||||
### ✨ 新增功能
|
||||
- 新增 `BasicTable` 导出 `getTableRef` 方法,用于调用组件原生事件
|
||||
- 新增 `basicModal` 操作按钮 `showAction` 可控制是否显示底部按钮
|
||||
- `依赖升级`
|
||||
|
||||
### ✨ 新增示例
|
||||
- 新增 `BasicForm` 结合 `表格选择器` 示例
|
||||
- 更新 `README.md` 说明
|
||||
|
||||
### 💎 优化
|
||||
- 优化 `组件参数` ts 类型定义
|
||||
- 优化 `上传组件` 样式错位
|
||||
|
||||
## 2.2.2 (2022-04-29)
|
||||
### ✨ 新增功能
|
||||
- 新增 `BasicTable` 拖拽列 `columns-change` 方法
|
||||
- 新增 `BasicForm` 支持 `BasicSelect` 组件,示例在:组件-表单-基础使用
|
||||
- 新增 `BasicTable` 日期编辑,新增格式化示例,示例在:组件-表格-单元格编辑
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.1 (2022-04-19)
|
||||
### ✨ 新增功能
|
||||
- 新增 `表格选择器` 组件
|
||||
- 新增 `BasicTable` 设置选中行 `setCheckedRowKeys` 方法
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `开发环境` 运行控制台错误提示
|
||||
|
||||
### 💻 新增页面
|
||||
- 新增 `表格选择器` 示例
|
||||
- `依赖升级`
|
||||
|
||||
## 2.2.0 (2022-03-23)
|
||||
|
||||
### ✨ 新增功能
|
||||
- 新增 `多级菜单缓存`
|
||||
- `依赖升级`
|
||||
|
||||
### 💻 新增页面
|
||||
- 新增 `多级菜单缓存`
|
||||
- `依赖升级`
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `BasicForm` 隐藏表单,存在占位问题
|
||||
|
||||
## 2.1.9 (2022-02-18)
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `BasicUpload` 组件,回显问题
|
||||
- 修复 `BasicForm` 组件 `collapsed` 无效
|
||||
- 修复 `表格编辑` 时间格式化异常 [#92](https://github.com/jekip/naive-ui-admin/issues/92)
|
||||
|
||||
## 2.1.8 (2022-01-26)
|
||||
|
||||
### 💎 功能优化
|
||||
- 优化 `BasicForm` 导出操作方法
|
||||
|
||||
### ✨ 新增功能
|
||||
- 新增 `basicModal` 动态创建 `id` 支持嵌套弹窗拖动
|
||||
- 新增 `BasicTable` 表格查询展开收起,配合 `form` 表单
|
||||
- 新增 `BasicTable` 选中行 `alert` 提示,可配置开关
|
||||
- 新增 `BasicTable` `tableSetting` 配置新增 `query` 字段
|
||||
- 新增 `多页签` 状态设置,特定场景,可实现二次确认提示是否关闭(参考:功能示例->多页签操作)
|
||||
- `依赖升级`
|
||||
|
||||
## 2.1.7 (2022-01-11)
|
||||
|
||||
### 💎 功能优化
|
||||
- 优化 `::v-deep` 修改为 `:deep`
|
||||
- 优化 `页面ts类型`
|
||||
- 优化 `表格单元格编辑`
|
||||
### 🐛 问题修复
|
||||
- 移除 `引导页示例`
|
||||
- 修复 `css变量前缀` 和UI组件库不一致
|
||||
|
||||
### ✨ 新增功能
|
||||
- 新增 `Tailwindcss 3.x` 移除 `windicss`
|
||||
- 新增 `项目配置` 悬浮入口
|
||||
- `依赖升级`
|
||||
|
||||
## 2.1.6 (2021-12-30)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `路由history跳转锚点` 多标签重复创建问题
|
||||
- 变更 `多标签操作` `setTitle` 方法,传 `fullPath` 路径(依然存在缺陷)
|
||||
|
||||
### ✨ Features
|
||||
- 新增 `菜单权限-FIXED模式` 随机(普通管理员/超级管理员)角色权限演示
|
||||
- 新增 `菜单权限-BACK模式` 随机(普通管理员/超级管理员)角色权限演示
|
||||
- 说明 `超级管理员` 拥有 `主控台、列表页面` 权限,`普通管理员` 拥有 `主控台` 权限,可退出登录,或者刷新页面测试
|
||||
- 测试 `退出登录>重新登录` 或者 `刷新页面` 查看效果
|
||||
- `依赖升级`
|
||||
|
||||
## 2.1.5 (2021-12-13)
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `BasicTable` 选择行与列配置拖拽异常
|
||||
- 修复 `BasicTable` 分页总数,无法响应式
|
||||
- 修复 `Axios` api地址拼接异常
|
||||
|
||||
### ✨ Features
|
||||
- 破坏 `Axios` 取消默认导出 `http` 可支持多个请求导出
|
||||
- 搜索 `import http from '@/utils/http/axios'` 替换为 `import { http } from '@/utils/http/axios`
|
||||
- `依赖升级`
|
||||
|
||||
## 2.1.4 (2021-11-25)
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `BasicTable` 自适应高度问题
|
||||
- 破坏 `meta.alwaysShow` 取消路由自动计算根路由特性
|
||||
|
||||
### ✨ Features
|
||||
- 新增 `BasicTable` 斑马纹开关配置
|
||||
- 新增 `BasicTable` 分页配置,默认显示总条数,不需要的地方可单独重置
|
||||
- 新增 `useTabs` 暴露 `closeCurrent`,`setTitle` 方法,用于外部页面操作多页签
|
||||
- 新增 `功能示例->多页签操作示例`
|
||||
|
||||
## 2.1.3 (2021-11-23)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `ActionItem` 类型定义问题
|
||||
- 修复 `BasicForm` 自定义提交逻辑,按钮一直处于 loading
|
||||
|
||||
### ✨ Features
|
||||
- 新增 `BasicForm.setLoadingSub` 方法
|
||||
- `依赖升级`
|
||||
|
||||
## 2.1.2 (2021-11-18)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `锁屏界面` 黑暗主题适配问题
|
||||
- 修复 `登录页面` 异常情况,按钮一直处于 loading
|
||||
- 修复 `顶部混合菜单` 一级菜单,内容区域布局问题
|
||||
- 修复 `BasicSelect` 存储 `localStorage` 空白key
|
||||
- 修复 `多标签` 当 `router.push` 带上 `query` 参数报错
|
||||
|
||||
### ✨ Features
|
||||
- 新增 `按需引入NaiveUi并自动创建.d.ts声明` 可获得代码提示和类型检查
|
||||
|
||||
|
||||
## 2.1.1 (2021-11-15)
|
||||
|
||||
### ✨ Features
|
||||
- 优化 `骨架结构布局` 破坏性调整,按需更新(建议是升级)
|
||||
- 新增 `侧栏是否固定配置项`
|
||||
- 新增 `BasicTable` 选中行内部维护,新增 `restCheckedRowKeys` 和 `checked-row-change` 方法
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.1.0 (2021-11-11)
|
||||
|
||||
### ✨ Features
|
||||
- 优化 `加载图标`
|
||||
- 优化 `顶部分割菜单`
|
||||
- 新增 `表格全屏`
|
||||
- 新增 `内容页全屏`
|
||||
|
||||
## 2.0.9 (2021-11-05)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 优化 `页面卡片间距` 用 `mt-3` 统一
|
||||
|
||||
### ✨ Features
|
||||
- 引入 `windicss` 代替 `tailwindcss` 提高开发效率
|
||||
- 引入 `pnpm` 代替 `yarn` 升级方法,删除 `node_modules` 运行 pnpm install
|
||||
- `依赖升级`
|
||||
|
||||
## 2.0.8 (2021-11-03)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `表格编辑` 事件穿透问题
|
||||
- 修复 `切换全屏` 菜单展开问题,取消自动展开特性
|
||||
- 修复 `切换全屏` 图标和提示语问题
|
||||
- 还原 `tailwindcss2.x` 默认样式存在问题
|
||||
|
||||
### ✨ Features
|
||||
- 新增 `BasicTable` 表格设置工具栏可配置
|
||||
|
||||
|
||||
## 2.0.7 (2021-11-02)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复 `多标签` 样式优化
|
||||
- 修复 `多标签缓存设置` 关闭标签,清除缓存
|
||||
- 修复 `BasicTable` 操作刷新参数异常
|
||||
- 修复 `深色模式` 菜单选中色无法切换问题
|
||||
|
||||
### ✨ Features
|
||||
- 新增 `多标签关闭` 清除关闭页面缓存特性
|
||||
- 破坏 `tailwindcss升级3.x` 移除导入的默认样式
|
||||
- `依赖升级`
|
||||
|
||||
## 2.0.6 (2021-10-25)
|
||||
|
||||
### ✨ Features
|
||||
- `深色主题`优化滚动条样式
|
||||
- `BasicTable.actionColumn` 操作组件配置增强,支持`图标,大小`
|
||||
- `BasicTable.actionColumn` 新增`dropDownProps`更多按钮组件,支持配置,和 `actionColumn一致`
|
||||
- `BasicTable` 组件新增`updateTableDataRecord`,`deleteTableDataRecord`,`getColumns`,`setColumns`方法
|
||||
- `BasicForm.schemas` 新增`hidden`,配置隐藏域表单,可配合`defaultValue`设置默认值,常用于编辑
|
||||
|
||||
|
||||
## 2.0.5 (2021-10-14)
|
||||
- 移除`rxjs`依赖和相关文件
|
||||
- 修复`面包屑`显示隐藏路由
|
||||
- 修复`多标签`关闭当前页判断不准确
|
||||
- 修复`多标签`跳转路由参数丢失
|
||||
- 修复`路由带参`路由相同,参数不同缓存无效
|
||||
- 修复`BasicTable`组件编辑行`switch`组件默认值不生效
|
||||
|
||||
### ✨ Features
|
||||
- 新增`useGo`和`useRedo`路由跳转方法
|
||||
- `BasicForm`组件,提交按钮,loading 动画状态优化
|
||||
- `BasicTable`组件重构为`script setup`语法
|
||||
- `BasicTable`组件导出`updateTableData`,`setTableData`,`getDataSource`方法
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
|
||||
## 2.0.4 (2021-10-09)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
- 修复`富文本`默认值不生效问题
|
||||
- 修复`多标签`无法及时更新文字问题
|
||||
- 修复`BasicTable`组件配置默认分页数量不生效问题
|
||||
- 优化`刷新功能`面包屑闪现`Redirect`路由地址问题
|
||||
- 优化`axios拦截器`中无法使用,Dialog,Message,等提示性质组件
|
||||
|
||||
### ✨ Features
|
||||
- `独立精简版分支`
|
||||
|
||||
|
||||
## 2.0.3 (2021-09-28)
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复`深色主题`顶部右侧搜索组件和部分页面布局不适配问题
|
||||
- 修复`ts类型定义`完善
|
||||
|
||||
### ✨ Features
|
||||
- `多标签`组件交互重写更加人性化配置和交互
|
||||
- `BasicTable`组件支持dataSource纯表格数据 非 request 加载情况
|
||||
- `BasicTable`组件新增`redoHeight`重新计算表格高度方法
|
||||
- `BasicForm`组件新增`advanced`展开收起回调方法
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.0.2 (2021-09-24)
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复`多标签`关闭左右侧,关闭全部不准确问题
|
||||
- 修复`多标签切换开关`内容区域间距问题
|
||||
- 修复`权限判断`hooks 中方法判断问题
|
||||
- 修复`顶部混合菜单`会受左侧菜单收缩效果影响问题
|
||||
|
||||
### ✨ Features
|
||||
- `BasicTable`组件新增,`restReload`方法(重置页码刷新)
|
||||
- `依赖升级`
|
||||
|
||||
|
||||
## 2.0.1 (2021-09-20)
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复`BasicTable`配置选择项异常
|
||||
|
||||
|
||||
### ✨ Features
|
||||
- 新增`PageWrapper`布局组件
|
||||
- 新增`PageFooter`布局组件
|
||||
- 新增`BasicTable->actionColumn`配置增强,可设置`popconfirm`二次确认
|
||||
- 优化`BasicTable`全选反选部分选择效果
|
||||
- 移除`BasicTable`配置里面勾选列功能,用处不大,增加不必要代码量
|
||||
- 新增`高级表单`布局页面
|
||||
- 依赖升级
|
||||
|
||||
|
||||
## 2.0.0 (2021-09-15)
|
||||
|
||||
## 💄 破坏性更新
|
||||
|
||||
### ✨ Features
|
||||
|
||||
🔥🔥🔥 代码重构 `script setup` 语法,源码更加易读,性能更优,ts 类型更加全面
|
||||
|
||||
#### 💻 页面
|
||||
|
||||
- 🌟 `全新登录/注册页面`
|
||||
- 🌟 `全新主控台页面`
|
||||
- 🌟 `用户管理`
|
||||
- 🌟 `字典管理`
|
||||
|
||||
#### ✨ 优化
|
||||
- 🌟 `主结构布局优化`
|
||||
- 🌟 `表格主从结构`
|
||||
- 🌟 `多标签页可关闭左右侧标签`
|
||||
- 🌟 `多标签页可自动滚动到当前页面`
|
||||
- 🌟 `弹窗组件拖拽可配置`
|
||||
|
||||
#### 🏷️ 功能
|
||||
|
||||
- 🌟 `右键菜单`
|
||||
- 🌟 `文件下载`
|
||||
- 🌟 `Excel导出`
|
||||
- 🌟 `剪贴板`
|
||||
- 🌟 `打印`
|
||||
- 🌟 `滚动条`
|
||||
- 🌟 `消息通知`
|
||||
- 🌟 `主控台图表示例`
|
||||
- 🌟 `引导`
|
||||
- 🌟 `修改密码`
|
||||
- 🌟 `固定主体区域可配置`
|
||||
- 🌟 `pinia 持久化存储`
|
||||
|
||||
#### 📦 组件
|
||||
|
||||
- 🌟 `省市区`
|
||||
- 🌟 `顶部搜索`
|
||||
- 🌟 `二维码`
|
||||
- 🌟 `密码强度`
|
||||
- 🌟 `图片裁剪,支持圆形矩形`
|
||||
- 🌟 `选择器增强,支持缓存`
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## 1.5.5 (2021-08-14)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复路由只存在一个子路由,图标不显示问题
|
||||
- UI样式美化
|
||||
|
||||
- ### ✨ Features
|
||||
- 支持 Vue 3.2.x
|
||||
- 代码全部按 `script setup` 语法重写(完成80%)
|
||||
- 新增 `回到顶部` 功能
|
||||
- 新增 `拖拽` 示例页面
|
||||
- 新增 `富文本` 组件
|
||||
- 新增 `路由切换动画` 可在项目设置切换
|
||||
- 依赖升级
|
||||
|
||||
# CHANGELOG
|
||||
|
||||
## 1.5.4 (2021-08-10)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- `暗色模式下多页签背景问题 ` 合并 [#23](https://github.com/jekip/naive-ui-admin/pull/23)
|
||||
感谢 [@Dishone](https://github.com/Dishone)
|
||||
- `表格设置列,重复添加action列样式错乱问题` 合并 [#24](https://github.com/jekip/naive-ui-admin/pull/24)
|
||||
感谢 [@CasbaL](https://github.com/CasbaL)
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `路由支持(内联外部地址)`配置
|
||||
- 新增 `顶部菜单` logo展示 -(破坏性更新)
|
||||
- 优化 `动态路由配置` 取消`constantRouterComponents.ts`,中组件映射配置,更名为 `router-icons.ts`
|
||||
- 优化 `admin_info接口结构`,roles 更名为:permissions,roles.roleName,更名为:label
|
||||
- 优化 多级路由,当没有配置`redirect`时,默认为第一个子路由,配置则优先按配置
|
||||
- 依赖升级
|
||||
|
||||
# 1.5.3 (2021-08-09)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复顶部菜单,选中联动
|
||||
- 修复混合菜单模式,切换其他模式菜单未重置
|
||||
- 实例基础列表,和表格组件实例,开启横向滚动特性
|
||||
- `naiveui` 升级成最新版
|
||||
|
||||
- ### ✨ Features
|
||||
- table组件,默认开启 `ellipsis` 特性
|
||||
|
||||
# 1.5.2 (2021-08-06)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复已知bug
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `混合菜单模式`
|
||||
- 新增 `根路由`
|
||||
- 新增 `关于` 根路由示例页面
|
||||
- 文档同步更新,组件和示例
|
||||
|
||||
# 1.5.1 (2021-08-05)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复windows系统获取项目换行符问题
|
||||
- 修复表格分页计算问题 [@Chika99](https://github.com/Chika99)
|
||||
- 修复锁屏样式自适应问题 [@Chika99](https://github.com/Chika99)
|
||||
- 依赖 dayjs 移除,用date-fns,和UI框架底层保持一致
|
||||
- 修复已知bug
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `baseForm` 组件,和`基础`,`useForm`使用方式
|
||||
- 新增 `baseModal`,组件,和 `useForm`使用方式
|
||||
- 新增`子菜单` new Tag标签
|
||||
- 菜单支持 `根路由`配置
|
||||
|
||||
# 1.5.0 (2021-07-30)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复表格列配置,拖拽时最后的操作列重复增加
|
||||
- 多标签页交互优化
|
||||
|
||||
- ### ✨ Features
|
||||
- `项目文档`已上线
|
||||
- `Application`组件加载机制优化,解决路由守卫,Axios中可使用,Dialog,Message 等之类组件
|
||||
- `BasicTable` 组件新增`高度自适应`,`单元格编辑`,`整行编辑` 特性
|
||||
- `nprogress` 移除,用 `Loading Bar`代替
|
||||
- 打包支持`gzip`,`brotli` 压缩
|
||||
- 新增代理`VITE_PROXY`配置
|
||||
- 路由菜单,支持多级菜单
|
||||
- 依赖升级
|
||||
- 本次更新,有破坏性更新,涉及文件重命名,增删调整
|
||||
|
||||
# 1.4.0 (2021-07-21)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- vite降至2.3.6
|
||||
- 多标签页交互优化
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `TableAction` 组件
|
||||
- 新增 `菜单权限管理` 示例
|
||||
- 新增 `角色权限管理` 示例
|
||||
- 持续更新更多实用组件及示例,感谢Star
|
||||
|
||||
# 1.3.0 (2021-07-19)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复多标签页左右切换按钮自适应展示
|
||||
- 修复登录页面出现多标签页
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `Upload` 组件及配置
|
||||
- 新增 `VITE_GLOB_IMG_URL` 图片前缀地址,配合Upload
|
||||
- 新增 `滑块验证码` 组件
|
||||
- 新增 `登录页面-滑块验证码` 示例
|
||||
- 持续更新更多实用组件及示例,感谢Star
|
||||
|
||||
# 1.2.0 (2021-07-16)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复面包屑显示登录页面
|
||||
- 菜单支持只展开当前父级菜单
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `列表页面-基础列表` 示例页面
|
||||
- 新增 `异常页面-404-403-500` 示例页面
|
||||
- 新增 `结果页面-成功-失败-信息` 示例页面
|
||||
- 新增 `设置页面-个人设置-系统设置` 示例页面
|
||||
- tips `示例页面,可能在深色主题显示不佳`
|
||||
- 持续更新更多实用示例,同时也演示`Naive UI`使用方法
|
||||
|
||||
# 1.1.0 (2021-07-15)
|
||||
|
||||
- ### ✨ Features
|
||||
- 新增 `基础表单` 示例页面
|
||||
- 新增 `分步表单` 示例页面
|
||||
- 新增 `表单详情` 示例页面
|
||||
- 持续更新更多实用示例,同时也演示`Naive UI`使用方法
|
||||
|
||||
# 1.0.0 (2021-07-12)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修复页面切换面包屑未及时更新
|
||||
|
||||
- ### ✨ Features
|
||||
- 1.0骨架发布
|
||||
- Naive UI 升级至2.15.4
|
||||
- 菜单新增排序字段
|
||||
- 新增 `ProTable` 组件,封装了常用的分页列配置等逻辑
|
||||
- 新增 `ProTable` 组件示例页面
|
||||
- 持续更新中...
|
||||
|
||||
# 0.1.1-beta (2021-07-07)
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- 修正黑色主题,页面背景色和导航风格问题
|
||||
|
||||
- ### ✨ Features
|
||||
- 主控台,工作台,自适应支持
|
||||
- 左侧菜单屏幕可视宽度<=950 自动收起
|
||||
- 页脚是否显示,可配置
|
||||
- 新增页面缓存,演示页面在>工作台>动态卡片>输入框
|
||||
|
||||
# 0.1.0-beta (2021-07-04)
|
||||
|
||||
- Naive Ui Admin 骨架
|
||||
- ### ✨ Features
|
||||
- 菜单模式(左侧/顶部)
|
||||
- 权限(固定角色/动态路由菜单)
|
||||
- 主题(深色/浅色)引用 naiveui 特性,黑暗主题/自定义组件,暗黑主题信手捏来
|
||||
- 系统主题(十种安全色,可切换预览,可自定义)
|
||||
- 导航风格(三种,可自由搭配,暗色侧边/白色侧边和通栏/暗色侧边和顶部通栏)
|
||||
- 多页签,持久化,拖拽,关闭,固定
|
||||
- 面包屑,图标,子菜单下拉联动展示
|
||||
- 漂亮的锁屏界面
|
||||
- 在线配置抽屉(布局预览功能)
|
||||
- 主控台,简单写了一下,能看了
|
||||
- 工作台随意撸了一下(不想写style)用 tailwindcss大开杀戒了
|
||||
- echarts,官网例子很全了,没啥好撸的,偷懒再次引用vben作者的代码,再感谢一次,哈哈
|
||||
- 挑个合适的时间,发布一下源码到 github
|
||||
## 更新日志
|
80
README.md
80
README.md
@ -1,79 +1 @@
|
||||
## 简介
|
||||
|
||||
[NaiveAdminPro](https://github.com/jekip/naive-ui-admin) 是一个基于 [Vue3.0](https://github.com/vuejs/vue-next)、[Vite](https://github.com/vitejs/vite)、 [Naive UI](https://www.naiveui.com/)、[TypeScript](https://www.typescriptlang.org/) 的中后台解决方案,它使用了最新的前端技术栈,并提炼了典型的业务模型,页面,包括二次封装组件、动态菜单、权限校验、粒子化权限控制等功能,它可以帮助你快速搭建企业级中后台项目,相信不管是从新技术使用还是其他方面,都能帮助到你。
|
||||
|
||||
## 特性
|
||||
- **最新技术栈**:使用 Vue3/vite2 等前端前沿技术开发
|
||||
- **TypeScript**: 应用程序级 JavaScript 的语言
|
||||
- **主题**:可配置的主题
|
||||
- **Mock 数据** 内置 Mock 数据方案
|
||||
- **权限** 内置完善的动态路由权限生成方案
|
||||
- **组件** 二次封装了多个常用的组件
|
||||
|
||||
|
||||
## 在线预览
|
||||
- [naive-admin-pro](https://pro.naiveadmin.com)
|
||||
|
||||
账号:admin,密码:123456(随意)
|
||||
|
||||
## 文档
|
||||
|
||||
[文档地址](https://www.naiveadmin.com/guide/introduction)
|
||||
|
||||
## 准备
|
||||
|
||||
- [node](http://nodejs.org/) 和 [git](https://git-scm.com/) -项目开发环境
|
||||
- [pnpm](https://www.pnpm.cn/) pnpm - 速度快、节省磁盘空间的软件包管理器
|
||||
- [Vite](https://vitejs.dev/) - 熟悉 vite 特性
|
||||
- [Vue3](https://v3.vuejs.org/) - 熟悉 Vue 基础语法
|
||||
- [TypeScript](https://www.typescriptlang.org/) - 熟悉`TypeScript`基本语法
|
||||
- [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法
|
||||
- [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router 基本使用
|
||||
- [Naive-ui-admin](https://www.naiveui.com/) - ui 基本使用
|
||||
- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法
|
||||
|
||||
## 安装使用
|
||||
|
||||
- 获取项目代码
|
||||
|
||||
```bash
|
||||
git clone git@codeup.aliyun.com:naiveadmin/naive-admin-pro.git
|
||||
```
|
||||
|
||||
- 安装依赖
|
||||
|
||||
```bash
|
||||
cd naive-admin-pro
|
||||
|
||||
pnpm install(如果电脑没有安装 pnpm 的,可以执行 npm install -g pnpm@next-7,node版本推荐16.x以上)
|
||||
|
||||
```
|
||||
|
||||
- 运行
|
||||
|
||||
```bash
|
||||
pnpm run dev
|
||||
```
|
||||
|
||||
- 打包
|
||||
|
||||
```bash
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
## 更新日志
|
||||
|
||||
[CHANGELOG](./CHANGELOG.md)
|
||||
|
||||
## 浏览器支持
|
||||
|
||||
本地开发推荐使用`Chrome 80+` 浏览器
|
||||
|
||||
支持现代浏览器, 不支持 IE
|
||||
|
||||
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt=" Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||
| :-: | :-: | :-: | :-: | :-: |
|
||||
| not support | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
|
||||
|
||||
## 维护者
|
||||
[@Ah jung](https://github.com/jekip)
|
||||
### 云恒WMS
|
12
package.json
12
package.json
@ -1,10 +1,12 @@
|
||||
{
|
||||
"name": "naive-admin-pro",
|
||||
"version": "2.5.0",
|
||||
"name": "yunheng",
|
||||
"version": "2.0.0",
|
||||
"description": "云恒WMS",
|
||||
"license": "Apache-2.0",
|
||||
"author": {
|
||||
"name": "Ahjung",
|
||||
"email": "735878602@qq.com",
|
||||
"url": "https://github.com/jekip"
|
||||
"name": "云恒WMS",
|
||||
"email": "yunhengcloud@163.com",
|
||||
"url": "https://www.baidu.com"
|
||||
},
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
@ -22,24 +22,22 @@
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="文档地址">
|
||||
<div class="flex items-center">
|
||||
<a href="https://www.naiveadmin.com" class="py-2" target="_blank">查看文档地址</a>
|
||||
<a href="https://www.baidu.com" class="py-2" target="_blank">查看文档地址</a>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="预览地址">
|
||||
<div class="flex items-center">
|
||||
<a href="https://pro.naiveadmin.com" class="py-2" target="_blank">查看预览地址</a>
|
||||
<a href="https://www.baidu.com" class="py-2" target="_blank">查看预览地址</a>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="Github">
|
||||
<div class="flex items-center">
|
||||
<a href="https://github.com/jekip/naive-ui-admin" class="py-2" target="_blank"
|
||||
>查看Github地址</a
|
||||
>
|
||||
<a href="https://github.com/" class="py-2" target="_blank">查看Github地址</a>
|
||||
</div>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="QQ交流群">
|
||||
<div class="flex items-center">
|
||||
<a href="https://jq.qq.com/?_wv=1027&k=xib9dU4C" class="py-2" target="_blank"
|
||||
<a href="https://www.baidu.com" class="py-2" target="_blank"
|
||||
>点击链接加入群聊【Naive Admin】</a
|
||||
>
|
||||
</div>
|
||||
|
@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="图片裁剪示例">
|
||||
适用于,头像上传,图片上传之前需要进行裁剪,简单说就是,需要图片上传并且需要裁剪,就可以用这个组件快速实现,需要真实接口才能进行上传测试!
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard" title="圆形裁剪">
|
||||
<!--圆形裁剪-->
|
||||
<Cropper
|
||||
ref="cropperCircled"
|
||||
:circled="true"
|
||||
:src="src"
|
||||
:uploadApi="upload"
|
||||
title="圆形头像上传"
|
||||
/>
|
||||
<n-space>
|
||||
<n-button class="mt-3 ml-12" @click="cropperCircledImg">选择图片</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard" title="矩形裁剪">
|
||||
<!--矩形裁剪-->
|
||||
<Cropper ref="cropperRectangle" :src="src" title="矩形头像上传" />
|
||||
<n-space>
|
||||
<n-button class="mt-3 ml-12" @click="cropperRectangleImg">选择图片</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard" title="自定义内容,选择权交给您">
|
||||
<!--圆形裁剪-->
|
||||
<Cropper
|
||||
ref="cropperCircled"
|
||||
:circled="true"
|
||||
:src="src"
|
||||
:uploadApi="upload"
|
||||
title="圆形头像上传"
|
||||
>
|
||||
<n-button class="mt-3 ml-12" @click="cropperCircledImg">自定义裁剪图片</n-button>
|
||||
</Cropper>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Cropper } from '@/components/Cropper';
|
||||
import { upload } from '@/api/common/';
|
||||
|
||||
const src = ref('https://img.naiveadmin.com/assets/avatar/avatar-2.jpg');
|
||||
|
||||
const cropperCircled = ref();
|
||||
|
||||
const cropperRectangle = ref();
|
||||
|
||||
function cropperCircledImg() {
|
||||
cropperCircled.value.openCropper();
|
||||
}
|
||||
|
||||
function cropperRectangleImg() {
|
||||
cropperRectangle.value.openCropper();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
@ -1,161 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="拖拽"> 常用于卡片,事项,预约,流程,计划等, </n-card>
|
||||
</div>
|
||||
|
||||
<n-alert title="花式拖拽演示" type="info" class="mt-3">
|
||||
每个卡片,都可以上下拖拽顺序,另外不同卡片,也可以拖拽过去,拖拽过来,都不在话下呢,快试试O(∩_∩)O哈哈~
|
||||
</n-alert>
|
||||
|
||||
<n-grid
|
||||
cols="1 s:2 m:3 l:4 xl:4 2xl:4"
|
||||
class="mt-3 proCard"
|
||||
responsive="screen"
|
||||
:x-gap="12"
|
||||
:y-gap="8"
|
||||
>
|
||||
<n-grid-item>
|
||||
<n-card
|
||||
title="需求池"
|
||||
:segmented="{ content: true, footer: true }"
|
||||
size="small"
|
||||
:bordered="false"
|
||||
>
|
||||
<template #header-extra>
|
||||
<n-tag type="info">月</n-tag>
|
||||
</template>
|
||||
|
||||
<Draggable
|
||||
class="draggable-ul"
|
||||
animation="300"
|
||||
:list="demandList"
|
||||
group="people"
|
||||
itemKey="name"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="cursor-move draggable-li">
|
||||
<n-tag type="info">需求</n-tag><span class="ml-2">{{ element.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</n-card>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-card
|
||||
title="开发中"
|
||||
:segmented="{ content: true, footer: true }"
|
||||
size="small"
|
||||
:bordered="false"
|
||||
>
|
||||
<template #header-extra>
|
||||
<n-tag type="info">月</n-tag>
|
||||
</template>
|
||||
|
||||
<Draggable
|
||||
class="draggable-ul"
|
||||
animation="300"
|
||||
:list="exploitList"
|
||||
group="people"
|
||||
itemKey="name"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="cursor-move draggable-li">
|
||||
<n-tag type="warning">开发中</n-tag><span class="ml-2">{{ element.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</n-card>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-card
|
||||
title="已完成"
|
||||
:segmented="{ content: true, footer: true }"
|
||||
size="small"
|
||||
:bordered="false"
|
||||
>
|
||||
<template #header-extra>
|
||||
<n-tag type="info">月</n-tag>
|
||||
</template>
|
||||
<Draggable
|
||||
class="draggable-ul"
|
||||
animation="300"
|
||||
:list="completeList"
|
||||
group="people"
|
||||
itemKey="name"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="cursor-move draggable-li">
|
||||
<n-tag type="error">已完成</n-tag><span class="ml-2">{{ element.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</n-card>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-card
|
||||
title="已验收"
|
||||
:segmented="{ content: true, footer: true }"
|
||||
size="small"
|
||||
:bordered="false"
|
||||
>
|
||||
<template #header-extra>
|
||||
<n-tag type="info">月</n-tag>
|
||||
</template>
|
||||
<Draggable
|
||||
class="draggable-ul"
|
||||
animation="300"
|
||||
:list="approvedList"
|
||||
group="people"
|
||||
itemKey="name"
|
||||
>
|
||||
<template #item="{ element }">
|
||||
<div class="cursor-move draggable-li">
|
||||
<n-tag type="success">已验收</n-tag><span class="ml-2">{{ element.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</n-card>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive } from 'vue';
|
||||
import Draggable from 'vuedraggable';
|
||||
|
||||
const demandList = reactive([
|
||||
{ name: '预约表单页面,能填写预约相关信息', id: 1 },
|
||||
{ name: '促销活动页面,包含促销广告展示', id: 2 },
|
||||
{ name: '商品列表,需要一个到货提醒功能', id: 3 },
|
||||
{ name: '商品需要一个评价功能', id: 4 },
|
||||
{ name: '商品图片需要提供放大镜', id: 5 },
|
||||
{ name: '订单需要提供删除到回收站', id: 6 },
|
||||
{ name: '用户头像上传,需要支持裁剪', id: 7 },
|
||||
{ name: '据说Vue3.2发布了,setup啥时候支持?', id: 8 },
|
||||
]);
|
||||
|
||||
const exploitList = reactive([{ name: '商品图片需要提供放大镜', id: 5 }]);
|
||||
|
||||
const completeList = reactive([{ name: '商品图片需要提供放大镜', id: 5 }]);
|
||||
|
||||
const approvedList = reactive([{ name: '商品图片需要提供放大镜', id: 5 }]);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.draggable-ul {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
margin-top: -16px;
|
||||
|
||||
.draggable-li {
|
||||
width: 100%;
|
||||
padding: 16px 10px;
|
||||
border-bottom: 1px solid var(--n-border-color);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,225 +0,0 @@
|
||||
<template>
|
||||
<PageWrapper
|
||||
title="基础表单"
|
||||
content="基础表单,用于向用户收集表单信息,并展示业务逻辑交互使用示例"
|
||||
showFooter
|
||||
>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<div class="BasicForm">
|
||||
<BasicForm
|
||||
ref="basicFormRef"
|
||||
submitButtonText="提交预约"
|
||||
layout="horizontal"
|
||||
:gridProps="{ cols: 1 }"
|
||||
:schemas="schemas"
|
||||
@submit="handleSubmit"
|
||||
@reset="handleReset"
|
||||
/>
|
||||
</div>
|
||||
</n-card>
|
||||
<template #leftFooter>
|
||||
<n-space>
|
||||
<n-button @click="verifyMobile">只验证手机号码</n-button>
|
||||
<n-button @click="setName">设置姓名</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, computed, unref } from 'vue';
|
||||
import { BasicForm, FormSchema } from '@/components/Form/index';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { useVerificate } from '@/hooks/web/useVerificate';
|
||||
|
||||
const basicFormRef = ref();
|
||||
const isMakeSource = ref(true);
|
||||
const { isMobile } = useVerificate();
|
||||
|
||||
const getIsMakeSource = computed(() => {
|
||||
return isMakeSource.value;
|
||||
});
|
||||
|
||||
const schemas: FormSchema[] = reactive([
|
||||
{
|
||||
field: 'id',
|
||||
defaultValue: 128,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
field: 'identity',
|
||||
defaultValue: '我是一个隐藏字段内容',
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
field: 'info.name',
|
||||
component: 'NInput',
|
||||
label: '姓名',
|
||||
labelMessage: '这是一个提示',
|
||||
// defaultValue: '啊俊',
|
||||
componentProps: {
|
||||
placeholder: '请输入姓名',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请输入姓名', trigger: ['blur'] }],
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
component: 'NInputNumber',
|
||||
label: '手机',
|
||||
componentProps: {
|
||||
placeholder: '请输入手机号码',
|
||||
showButton: false,
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
key: 'mobile',
|
||||
required: true,
|
||||
validator: isMobile,
|
||||
trigger: ['input', 'blur'],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
component: 'NSelect',
|
||||
label: '类型',
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: [
|
||||
{
|
||||
label: '舒适性',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '经济性',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeDate',
|
||||
component: 'NDatePicker',
|
||||
label: '预约时间',
|
||||
defaultValue: 1183135260000,
|
||||
componentProps: {
|
||||
type: 'date',
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
// 根据 上面选择的类型,获取页面其他逻辑字段 处理显示表单
|
||||
// 可用字段 schema, values, model, field
|
||||
hidden: ({ model }) => {
|
||||
return !model.type;
|
||||
},
|
||||
rules: [{ required: true, type: 'number', message: '请选择预约时间', trigger: ['change'] }],
|
||||
},
|
||||
{
|
||||
field: 'makeTime',
|
||||
component: 'NTimePicker',
|
||||
label: '停留时间',
|
||||
componentProps: {
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeProject',
|
||||
component: 'NCheckbox',
|
||||
label: '预约项目',
|
||||
componentProps: {
|
||||
placeholder: '请选择预约项目',
|
||||
options: [
|
||||
{
|
||||
label: '种牙',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '补牙',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '根管',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
// 动态切换 来源 表单是否显示
|
||||
isMakeSource.value = e.includes(3);
|
||||
basicFormRef.value.setSchema(getNewSchemas());
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeSource',
|
||||
component: 'NRadioGroup',
|
||||
label: '来源',
|
||||
hidden: getIsMakeSource.value,
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '网上',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '门店',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
function setName() {
|
||||
basicFormRef.value.setFieldsValue({
|
||||
'info.name': '我是啊俊',
|
||||
});
|
||||
}
|
||||
|
||||
function verifyMobile() {
|
||||
basicFormRef.value.validate(['mobile']);
|
||||
}
|
||||
|
||||
function getNewSchemas() {
|
||||
const newSchemas = unref(schemas);
|
||||
newSchemas.forEach((item) => {
|
||||
if (item.field === 'makeSource') {
|
||||
item.hidden = !isMakeSource.value;
|
||||
}
|
||||
});
|
||||
return newSchemas;
|
||||
}
|
||||
|
||||
const message = useMessage();
|
||||
|
||||
function handleSubmit(values: Recordable) {
|
||||
message.success(JSON.stringify(values));
|
||||
}
|
||||
|
||||
function handleReset(values: Recordable) {
|
||||
message.success(JSON.stringify(values));
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.BasicForm {
|
||||
width: 550px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
padding-top: 20px;
|
||||
}
|
||||
</style>
|
@ -1,223 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="基础表单"> useForm 表单,用于向用户收集表单信息 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<div class="BasicForm">
|
||||
<BasicForm @register="register" @submit="handleSubmit" @reset="handleReset">
|
||||
<template #statusSlot="{ model, field }">
|
||||
<n-input v-model:value="model[field]" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
<n-divider />
|
||||
<n-button strong secondary type="tertiary" @click="eidtSchemas" block
|
||||
>改变 Schemas</n-button
|
||||
>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
component: 'NInput',
|
||||
label: '姓名',
|
||||
labelMessage: '这是一个提示',
|
||||
giProps: {
|
||||
span: 1,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请输入姓名',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请输入姓名', trigger: ['blur'] }],
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
component: 'NInputNumber',
|
||||
label: '手机',
|
||||
componentProps: {
|
||||
placeholder: '请输入手机号码',
|
||||
showButton: false,
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
component: 'NSelect',
|
||||
label: '类型',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: [
|
||||
{
|
||||
label: '舒适性',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '经济性',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeDate',
|
||||
component: 'NDatePicker',
|
||||
label: '预约时间',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
defaultValue: 1183135260000,
|
||||
componentProps: {
|
||||
type: 'date',
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeTime',
|
||||
component: 'NTimePicker',
|
||||
label: '停留时间',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
clearable: true,
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeProject',
|
||||
component: 'NCheckbox',
|
||||
label: '预约项目',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请选择预约项目',
|
||||
options: [
|
||||
{
|
||||
label: '种牙',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '补牙',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '根管',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeSource',
|
||||
component: 'NRadioGroup',
|
||||
label: '来源',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '网上',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '门店',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
label: '状态',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
//插槽
|
||||
slot: 'statusSlot',
|
||||
},
|
||||
];
|
||||
|
||||
const message = useMessage();
|
||||
|
||||
const [register, { setSchema }] = useForm({
|
||||
gridProps: { cols: 1 },
|
||||
collapsedRows: 3,
|
||||
labelWidth: 120,
|
||||
layout: 'horizontal',
|
||||
submitButtonText: '提交预约',
|
||||
schemas,
|
||||
});
|
||||
|
||||
function eidtSchemas() {
|
||||
setSchema([
|
||||
{
|
||||
field: 'name',
|
||||
component: 'NInput',
|
||||
label: '姓名',
|
||||
labelMessage: '这是一个提示',
|
||||
giProps: {
|
||||
span: 1,
|
||||
},
|
||||
componentProps: {
|
||||
// placeholder: '请输入姓名',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请输入姓名', trigger: ['blur'] }],
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
function handleSubmit(values: Recordable) {
|
||||
if (values) {
|
||||
console.log(values);
|
||||
message.success(JSON.stringify(values));
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
}
|
||||
}
|
||||
|
||||
function handleReset(values: Recordable) {
|
||||
console.log(values);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.BasicForm {
|
||||
width: 550px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
padding-top: 20px;
|
||||
}
|
||||
</style>
|
@ -1,332 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="模态框">
|
||||
模态框,用于向用户收集或展示信息,Modal 采用 Dialog 预设,扩展拖拽效果
|
||||
<br />
|
||||
以下是 useModal
|
||||
方式,ref方式,也支持,使用方式和其他组件一致,如:modalRef.value.closeModal()
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="提示" type="warning" class="mb-3">
|
||||
组件暴露了,setProps 方法,用于修改组件内部
|
||||
Props,比如标题,等,具体参考UI框架文档,DialogReactive Properties
|
||||
</n-alert>
|
||||
<n-alert title="Modal嵌套Form" type="info">
|
||||
使用 useModal 进行弹窗展示和操作,并演示了在Modal内和Form组件,组合使用方法
|
||||
<br />
|
||||
<br />
|
||||
<n-button type="primary" @click="showModal">打开Modal嵌套Form例子</n-button>
|
||||
</n-alert>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="个性化轻量级" type="info">
|
||||
使用 useModal 进行弹窗展示和操作,自定义配置,实现轻量级效果,更多配置,请参考文档
|
||||
<br />
|
||||
<br />
|
||||
<n-button type="primary" @click="showLightModal">轻量级确认</n-button>
|
||||
</n-alert>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="多个Modal嵌套" type="info">
|
||||
使用 useModal 进行弹窗展示,并且嵌套 Modal 使用方法
|
||||
<br />
|
||||
<br />
|
||||
<n-button type="primary" @click="showNestedModal">打开多个Modal嵌套</n-button>
|
||||
</n-alert>
|
||||
</n-card>
|
||||
|
||||
<basicModal
|
||||
@register="modalRegister"
|
||||
ref="modalRef"
|
||||
class="basicModal basicFormModal"
|
||||
@on-ok="okModal"
|
||||
>
|
||||
<template #default>
|
||||
<BasicForm @register="register" @reset="handleReset" class="basicForm">
|
||||
<template #statusSlot="{ model, field }">
|
||||
<n-input v-model:value="model[field]" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
</template>
|
||||
</basicModal>
|
||||
|
||||
<basicModal
|
||||
@register="lightModalRegister"
|
||||
class="basicModalLight"
|
||||
ref="modalRef"
|
||||
@on-ok="lightOkModal"
|
||||
>
|
||||
<template #default>
|
||||
<p class="text-gray-500" style="padding-left: 35px">一些对话框内容</p>
|
||||
</template>
|
||||
</basicModal>
|
||||
|
||||
<basicModal @register="nestedModalRegister" ref="modalRefOne" :showAction="false">
|
||||
<template #default>
|
||||
<div class="my-6">
|
||||
<n-h3>我是第一个弹窗,支持拖动哦~</n-h3>
|
||||
<n-button type="primary" @click="showNestedModalTow">在打开一个Modal</n-button>
|
||||
</div>
|
||||
</template>
|
||||
</basicModal>
|
||||
|
||||
<basicModal @register="nestedTowModalRegister" ref="modalRefTow" :showAction="false">
|
||||
<template #default>
|
||||
<div class="my-12">
|
||||
<n-h3>我是第二个弹窗,也是可以拖动的哦~</n-h3>
|
||||
</div>
|
||||
</template>
|
||||
</basicModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { basicModal, useModal } from '@/components/Modal';
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
component: 'NInput',
|
||||
label: '姓名',
|
||||
labelMessage: '这是一个提示',
|
||||
giProps: {
|
||||
span: 1,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请输入姓名',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请输入姓名', trigger: ['blur'] }],
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
component: 'NInputNumber',
|
||||
label: '手机',
|
||||
componentProps: {
|
||||
placeholder: '请输入手机号码',
|
||||
showButton: false,
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
component: 'NSelect',
|
||||
label: '类型',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: [
|
||||
{
|
||||
label: '舒适性',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '经济性',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeDate',
|
||||
component: 'NDatePicker',
|
||||
label: '预约时间',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
defaultValue: 1183135260000,
|
||||
componentProps: {
|
||||
type: 'date',
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeTime',
|
||||
component: 'NTimePicker',
|
||||
label: '停留时间',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
clearable: true,
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeProject',
|
||||
component: 'NCheckbox',
|
||||
label: '预约项目',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请选择预约项目',
|
||||
options: [
|
||||
{
|
||||
label: '种牙',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '补牙',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '根管',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeSource',
|
||||
component: 'NRadioGroup',
|
||||
label: '来源',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '网上',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '门店',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
label: '状态',
|
||||
giProps: {
|
||||
//span: 24,
|
||||
},
|
||||
//插槽
|
||||
slot: 'statusSlot',
|
||||
},
|
||||
];
|
||||
|
||||
const modalRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const [modalRegister, { openModal, closeModal, setSubLoading }] = useModal({
|
||||
title: '新增预约',
|
||||
width: 600,
|
||||
});
|
||||
|
||||
const [
|
||||
lightModalRegister,
|
||||
{ openModal: lightOpenModal, closeModal: lightCloseModal, setSubLoading: lightSetSubLoading },
|
||||
] = useModal({
|
||||
title: '确认对话框',
|
||||
showIcon: true,
|
||||
type: 'warning',
|
||||
closable: false,
|
||||
maskClosable: true,
|
||||
});
|
||||
|
||||
const [register, { submit }] = useForm({
|
||||
gridProps: { cols: 1 },
|
||||
collapsedRows: 3,
|
||||
labelWidth: 120,
|
||||
layout: 'horizontal',
|
||||
submitButtonText: '提交预约',
|
||||
showActionButtonGroup: false,
|
||||
schemas,
|
||||
});
|
||||
|
||||
const [nestedModalRegister, { openModal: nestedOpenModal }] = useModal({
|
||||
title: '嵌套弹窗',
|
||||
width: 350,
|
||||
});
|
||||
|
||||
const [nestedTowModalRegister, { openModal: nestedOpenTowModal }] = useModal({
|
||||
title: '第二个弹窗',
|
||||
width: 550,
|
||||
});
|
||||
|
||||
function showNestedModal() {
|
||||
nestedOpenModal();
|
||||
}
|
||||
|
||||
function showNestedModalTow() {
|
||||
nestedOpenTowModal();
|
||||
}
|
||||
|
||||
async function okModal() {
|
||||
const formRes = await submit();
|
||||
if (formRes) {
|
||||
closeModal();
|
||||
message.success('提交成功');
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
setSubLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function lightOkModal() {
|
||||
lightCloseModal();
|
||||
lightSetSubLoading();
|
||||
}
|
||||
|
||||
function showLightModal() {
|
||||
lightOpenModal();
|
||||
}
|
||||
|
||||
function showModal() {
|
||||
openModal();
|
||||
}
|
||||
|
||||
function handleReset(values: Recordable) {
|
||||
console.log(values);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.n-dialog.basicFormModal {
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
.n-dialog.basicModalLight {
|
||||
width: 410px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.basicForm {
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.n-dialog.basicModalLight {
|
||||
width: 416px;
|
||||
padding-top: 26px;
|
||||
}
|
||||
</style>
|
@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="密码强度校验组件">
|
||||
用于常用密码强度设置,通常要求比较严格一点密码适用,验证,灵活配置,脱离 Form
|
||||
单独使用也可以哦~
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="基础效果" type="info"> 密码长度,6-32,复杂密码</n-alert>
|
||||
<Password class="mt-3" />
|
||||
|
||||
<n-alert title="设定密码长度" type="info">比如来个,( 12 - 16 个字符 )</n-alert>
|
||||
<Password :min-length="12" :max-length="16" class="mt-3" />
|
||||
|
||||
<n-alert title="简单密码" type="info"
|
||||
>不需要满足字母、数字及特殊字符两种或以上组合条件
|
||||
</n-alert>
|
||||
<Password class="mt-3" :complexity="false" />
|
||||
|
||||
<n-alert title="自定义密码强度等级提示语" type="info">
|
||||
支持4个等级配置,1 - 4 默认4个等级名称分别为: 1. 弱不禁风 2. 平淡无奇 3. 出神入化 4.
|
||||
登峰造极
|
||||
</n-alert>
|
||||
<Password class="mt-3" :level="{ 1: '很Low', 2: '一般Low', 3: '没那么Low', 4: '不Low了' }" />
|
||||
|
||||
<n-alert title="再次确认密码" type="info" />
|
||||
<Password :repeat="true" class="mt-3" />
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { Password } from '@/components/Password';
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
@ -1,162 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="二维码组件">
|
||||
二维码组件使用示例,通常用于一些商品、促销活动、或者分享推广二维码展示
|
||||
</n-card>
|
||||
</div>
|
||||
<n-grid class="mt-3" cols="1 s:2 m:2 l:3 xl:3 2xl:3" responsive="screen" :x-gap="12" :y-gap="9">
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="基础实例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode :value="qrCodeUrl" />
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card
|
||||
:segmented="{ content: true }"
|
||||
:bordered="false"
|
||||
size="small"
|
||||
title="渲染成img标签示例"
|
||||
>
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode :value="qrCodeUrl" tag="img" />
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="配置样式示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
:options="{
|
||||
color: { dark: '#55D187' },
|
||||
}"
|
||||
/>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="本地logo示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode :value="qrCodeUrl" :logo="LogoImg" />
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="在线logo示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
logo="https://assets.naiveadmin.com/images/logo.png"
|
||||
:options="{
|
||||
color: { dark: '#55D187' },
|
||||
}"
|
||||
/>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="LOGO配置示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
:logo="{
|
||||
src: 'https://assets.naiveadmin.com/images/logo.png',
|
||||
logoSize: 0.2,
|
||||
borderSize: 0.05,
|
||||
borderRadius: 50,
|
||||
bgColor: 'blue',
|
||||
}"
|
||||
/>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="下载示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode :value="qrCodeUrl" ref="qrRef" :logo="LogoImg" />
|
||||
</n-space>
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<n-button class="mt-3" type="primary" @click="download"> 下载 </n-button>
|
||||
</n-space>
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<div class="msg">(在线logo会导致图片跨域,需要下载图片需要自行解决跨域问题)</div>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="扩展绘制示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode
|
||||
:value="qrCodeUrl"
|
||||
:width="200"
|
||||
:options="{ margin: 5 }"
|
||||
ref="qrDiyRef"
|
||||
:logo="LogoImg"
|
||||
@done="onQrcodeDone"
|
||||
/>
|
||||
</n-space>
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<n-button class="mt-3" type="primary" @click="downloadDiy"> 下载 </n-button>
|
||||
</n-space>
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<div class="msg">要进行扩展绘制则不能将tag设为img</div>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
<n-gi>
|
||||
<n-card :segmented="{ content: true }" :bordered="false" size="small" title="配置大小示例">
|
||||
<n-space justify="center" class="qrcode-space">
|
||||
<QrCode :value="qrCodeUrl" :width="280" />
|
||||
</n-space>
|
||||
</n-card>
|
||||
</n-gi>
|
||||
</n-grid>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { QrCode, QrCodeActionType } from '@/components/Qrcode/index';
|
||||
import LogoImg from '@/assets/images/logo.png';
|
||||
const qrCodeUrl = 'https://www.naiveadmin.com';
|
||||
|
||||
const qrRef = ref<Nullable<QrCodeActionType>>(null);
|
||||
const qrDiyRef = ref<Nullable<QrCodeActionType>>(null);
|
||||
|
||||
function download() {
|
||||
const qrEl = unref(qrRef);
|
||||
if (!qrEl) return;
|
||||
qrEl.download('img');
|
||||
}
|
||||
|
||||
function downloadDiy() {
|
||||
const qrEl = unref(qrDiyRef);
|
||||
if (!qrEl) return;
|
||||
qrEl.download('Qrcode');
|
||||
}
|
||||
|
||||
function onQrcodeDone({ ctx }: any) {
|
||||
if (ctx instanceof CanvasRenderingContext2D) {
|
||||
// 额外绘制
|
||||
ctx.fillStyle = 'black';
|
||||
ctx.font = '16px "微软雅黑"';
|
||||
ctx.textBaseline = 'bottom';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.fillText('扫描关注Star点一点', 100, 195, 200);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.qrcode-space {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
transition: bottom 0.4s;
|
||||
&:hover {
|
||||
bottom: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="地区">
|
||||
地区组件,用于选择省市区,比如填写地址,配送地址,等...
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="添加场景" type="info"> 自动加载数据,显示省市区</n-alert>
|
||||
<Region class="Region mt-3" @change="regionChange" />
|
||||
<n-divider />
|
||||
|
||||
<n-alert title="回显场景" type="info"> 设置默认值,自动加载数据,并且选中</n-alert>
|
||||
<Region v-model:value="regionIds" class="Region mt-3" @change="regionChange" />
|
||||
<n-divider />
|
||||
|
||||
<n-alert title="只显示省市" type="info" />
|
||||
<Region
|
||||
v-model:value="regionIds"
|
||||
:hideArea="true"
|
||||
class="Region mt-3"
|
||||
@change="regionChange"
|
||||
/>
|
||||
<n-divider />
|
||||
|
||||
<n-alert title="只显示省" type="info" />
|
||||
<Region :onlyProvince="true" class="Region mt-3" @change="regionChange" />
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Region } from '@/components/Region';
|
||||
|
||||
const regionIds = ref([1, 11, 111]);
|
||||
|
||||
//地区变动回调
|
||||
function regionChange(result) {
|
||||
console.log(result);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.Region {
|
||||
width: 320px;
|
||||
}
|
||||
</style>
|
@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="富文本">
|
||||
富文本,用于展示图文信息,比如商品详情,文章详情等...
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<QuillEditor
|
||||
ref="quillEditor"
|
||||
:options="options"
|
||||
v-model:content="myContent"
|
||||
style="height: 350px"
|
||||
@ready="readyQuill"
|
||||
class="quillEditor"
|
||||
/>
|
||||
<template #footer>
|
||||
<n-space>
|
||||
<n-button @click="addText">增加文本</n-button>
|
||||
<n-button @click="addImg">增加图片</n-button>
|
||||
<n-button @click="getHtml">获取HTML</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
<n-card :bordered="false" class="mt-3 proCard" title="HTML 内容">
|
||||
<n-input
|
||||
v-model:value="myContentHtml"
|
||||
type="textarea"
|
||||
placeholder="html"
|
||||
:autosize="{
|
||||
minRows: 3,
|
||||
maxRows: 6,
|
||||
}"
|
||||
/>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { QuillEditor } from '@vueup/vue-quill';
|
||||
import '@vueup/vue-quill/dist/vue-quill.snow.css';
|
||||
const quillEditor = ref();
|
||||
const myContent = ref(
|
||||
'<h4>Naive Ui Admin 是一个基于 vue3,vite2,TypeScript 的中后台解决方案</h4>',
|
||||
);
|
||||
const myContentHtml = ref(
|
||||
'<h4>Naive Ui Admin 是一个基于 vue3,vite2,TypeScript 的中后台解决方案</h4>',
|
||||
);
|
||||
|
||||
const options = reactive({
|
||||
modules: {
|
||||
toolbar: [
|
||||
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
||||
['blockquote', 'code-block'],
|
||||
|
||||
[{ header: 1 }, { header: 2 }], // custom button values
|
||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||
[{ script: 'sub' }, { script: 'super' }], // superscript/subscript
|
||||
[{ indent: '-1' }, { indent: '+1' }], // outdent/indent
|
||||
[{ direction: 'rtl' }], // text direction
|
||||
|
||||
[{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
||||
|
||||
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
|
||||
[{ font: [] }],
|
||||
[{ align: [] }],
|
||||
['clean'],
|
||||
['image'],
|
||||
],
|
||||
},
|
||||
theme: 'snow',
|
||||
placeholder: '输入您喜欢的内容吧!',
|
||||
});
|
||||
|
||||
function readyQuill() {
|
||||
console.log('Quill准备好了');
|
||||
}
|
||||
|
||||
function getHtml() {
|
||||
myContentHtml.value = getHtmlVal();
|
||||
}
|
||||
|
||||
function addText() {
|
||||
const html = getHtmlVal() + '新增加的内容';
|
||||
quillEditor.value.setHTML(html);
|
||||
}
|
||||
|
||||
function addImg() {
|
||||
const html =
|
||||
getHtmlVal() +
|
||||
'<img style="width:100px" src="https://www.baidu.com/img/flexible/logo/pc/result.png"/>';
|
||||
quillEditor.value.setHTML(html);
|
||||
}
|
||||
|
||||
function getHtmlVal() {
|
||||
return quillEditor.value.getHTML();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
quillEditor.value.setHTML(myContent.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.ql-toolbar.ql-snow {
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid #eee;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
.ql-container.ql-snow {
|
||||
border: none;
|
||||
}
|
||||
</style>
|
@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="选择器">
|
||||
扩展选择器组件,用于各种表单选择器,简化使用,内置缓存,可对相同的数据减少http请求,也可手动刷新数据源
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="基础使用" type="info">
|
||||
自动加载数据,首次加载缓存,之后同一个KEY不在获取新数据</n-alert
|
||||
>
|
||||
<div class="mt-3">
|
||||
<n-space align="center">
|
||||
<BasicSelect
|
||||
ref="basicSelectRef"
|
||||
v-model:value="selectValue"
|
||||
:request="loadSelectData"
|
||||
@update:value="handleUpdateValue"
|
||||
cache
|
||||
cacheKey="SELECT_CLASSIFY"
|
||||
style="width: 150px"
|
||||
><template #action>如果你点开了这个例子,你可能需要它</template></BasicSelect
|
||||
>
|
||||
<n-button @click="setSelectData">设置选中值</n-button>
|
||||
<n-button @click="getSelectValue">获取选中值</n-button>
|
||||
<n-button @click="getSelectData">获取数据源</n-button>
|
||||
<n-button @click="refreshSelectData">刷新数据</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="自定义数据" type="info">
|
||||
自定义一个响应式数据源,在特定的场景,可能也有用</n-alert
|
||||
>
|
||||
<div class="mt-3">
|
||||
<n-space align="center">
|
||||
<BasicSelect
|
||||
ref="customBasicSelectRef"
|
||||
:options="customOptions"
|
||||
@update:value="handleUpdateValue"
|
||||
style="width: 150px"
|
||||
/>
|
||||
<n-button @click="setCustomOptions">更新自定义值</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { getClassifyList } from '@/api/select/select';
|
||||
import { BasicSelect } from '@/components/Select';
|
||||
import { useMessage } from 'naive-ui';
|
||||
const message = useMessage();
|
||||
const selectValue = ref('hot');
|
||||
const basicSelectRef = ref();
|
||||
const customBasicSelectRef = ref();
|
||||
const customOptions = ref([
|
||||
{
|
||||
label: '热门',
|
||||
value: 'hot',
|
||||
},
|
||||
{
|
||||
label: '推荐',
|
||||
value: 'rec',
|
||||
},
|
||||
]);
|
||||
|
||||
const params = {
|
||||
type: 1,
|
||||
};
|
||||
|
||||
async function loadSelectData(res) {
|
||||
//这里可以进行数据转换处理
|
||||
return (await getClassifyList({ ...res, ...params })).map((item, index) => {
|
||||
return {
|
||||
...item,
|
||||
index,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function handleUpdateValue(value, option) {
|
||||
message.info('value: ' + JSON.stringify(value));
|
||||
message.info('option: ' + JSON.stringify(option));
|
||||
}
|
||||
|
||||
function refreshSelectData() {
|
||||
basicSelectRef?.value.fetch();
|
||||
}
|
||||
|
||||
function setSelectData() {
|
||||
selectValue.value = 'new';
|
||||
}
|
||||
|
||||
function getSelectValue() {
|
||||
message.info('value: ' + JSON.stringify(selectValue.value));
|
||||
}
|
||||
|
||||
function getSelectData() {
|
||||
message.info('Data: ' + JSON.stringify(basicSelectRef?.value.getData()));
|
||||
}
|
||||
|
||||
function setCustomOptions() {
|
||||
customOptions.value = [
|
||||
{
|
||||
label: '新品',
|
||||
value: 'new',
|
||||
},
|
||||
{
|
||||
label: '限购',
|
||||
value: 'pur',
|
||||
},
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less"></style>
|
@ -1,104 +0,0 @@
|
||||
import { h } from 'vue';
|
||||
import { NAvatar, NTag } from 'naive-ui';
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '编码',
|
||||
key: 'no',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
editComponent: 'NInput',
|
||||
// 默认必填校验
|
||||
editRule: (currentValue) => {
|
||||
return new Promise((resolve) => {
|
||||
if (!currentValue) {
|
||||
resolve('请输入名称');
|
||||
}
|
||||
resolve('');
|
||||
});
|
||||
},
|
||||
edit: true,
|
||||
width: 80,
|
||||
editCellRender: (value) => {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
style: {
|
||||
marginRight: '6px',
|
||||
},
|
||||
type: 'info',
|
||||
},
|
||||
{
|
||||
default: () => value,
|
||||
},
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NAvatar, {
|
||||
size: 48,
|
||||
src: row.avatar,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '地址',
|
||||
key: 'address',
|
||||
editComponent: 'NSelect',
|
||||
editComponentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '广东省',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '浙江省',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
edit: true,
|
||||
width: 200,
|
||||
ellipsis: false,
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
key: 'beginTime',
|
||||
edit: true,
|
||||
width: 160,
|
||||
editComponent: 'NDatePicker',
|
||||
editComponentProps: {
|
||||
type: 'datetime',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
},
|
||||
ellipsis: false,
|
||||
},
|
||||
{
|
||||
title: '结束日期',
|
||||
key: 'endTime',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'date',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '停留时间',
|
||||
key: 'time',
|
||||
width: 80,
|
||||
},
|
||||
];
|
@ -1,107 +0,0 @@
|
||||
<template>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
title="表格列表"
|
||||
titleTooltip="这是一个提示"
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
:scroll-x="1360"
|
||||
:table-setting="{ width: 252 }"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<template #toolbar>
|
||||
<n-button type="primary" @click="reloadTable">刷新数据</n-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, h } from 'vue';
|
||||
import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
|
||||
import { getTableList } from '@/api/table/list';
|
||||
import { columns } from './basicColumns';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const actionRef = ref();
|
||||
|
||||
const params = reactive({
|
||||
pageSize: 5,
|
||||
name: 'xiaoMa',
|
||||
});
|
||||
|
||||
const actionColumn: BasicColumn = reactive({
|
||||
width: 150,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: 'button',
|
||||
actions: createActions(record),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function createActions(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
// 根据权限控制是否显示: 有权限,会显示,支持多个
|
||||
auth: ['basic_list'],
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
auth: ['basic_list'],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
return await getTableList({ ...params, ...res });
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
actionRef.value.reload();
|
||||
}
|
||||
|
||||
function handleDelete(record) {
|
||||
console.log(record);
|
||||
dialog.info({
|
||||
title: '提示',
|
||||
content: `您想删除${record.name}`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
message.success('删除成功');
|
||||
},
|
||||
onNegativeClick: () => {},
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record) {
|
||||
console.log(record);
|
||||
message.success('您点击了编辑按钮');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,80 +0,0 @@
|
||||
import { h } from 'vue';
|
||||
import { NAvatar, NTag } from 'naive-ui';
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
type: 'expand',
|
||||
expandable: (rowData) => rowData.name !== 'Jim Green',
|
||||
renderExpand: (rowData) => {
|
||||
return `${rowData.name} is a good guy.`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '编码',
|
||||
key: 'no',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NAvatar, {
|
||||
size: 48,
|
||||
src: row.avatar,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '地址',
|
||||
key: 'address',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
key: 'beginTime',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '结束日期',
|
||||
key: 'endTime',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(
|
||||
NTag,
|
||||
{
|
||||
type: row.status ? 'success' : 'error',
|
||||
},
|
||||
{
|
||||
default: () => (row.status ? '启用' : '禁用'),
|
||||
},
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'date',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '停留时间',
|
||||
key: 'time',
|
||||
width: 80,
|
||||
},
|
||||
];
|
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
title="表格列表"
|
||||
titleTooltip="这是一个提示"
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
@edit-end="editEnd"
|
||||
@edit-change="onEditChange"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
:scroll-x="1360"
|
||||
:row-props="rowProps"
|
||||
>
|
||||
<template #toolbar>
|
||||
<n-button type="primary" @click="reloadTable">刷新数据</n-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref } from 'vue';
|
||||
import { BasicTable } from '@/components/Table';
|
||||
import { getTableList } from '@/api/table/list';
|
||||
import { columns } from './CellColumns';
|
||||
|
||||
const actionRef = ref();
|
||||
const params = reactive({
|
||||
pageSize: 5,
|
||||
name: 'xiaoMa',
|
||||
});
|
||||
|
||||
function rowProps(rows) {
|
||||
return {
|
||||
style: 'cursor: pointer;',
|
||||
onclick: function () {
|
||||
console.log('row点击事件触发');
|
||||
console.log(rows);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function onEditChange({ column, value, record }) {
|
||||
if (column.key === 'id') {
|
||||
record.editValueRefs.name4.value = `${value}`;
|
||||
}
|
||||
console.log(column, value, record);
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
return await getTableList({ ...params, ...res });
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
console.log(actionRef.value);
|
||||
actionRef.value.reload();
|
||||
}
|
||||
|
||||
function editEnd({ record, index, key, value }) {
|
||||
console.log('record', record);
|
||||
console.log('index', index);
|
||||
console.log('key', key);
|
||||
console.log('value', value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,118 +0,0 @@
|
||||
<template>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
title="表格列表"
|
||||
titleTooltip="这是一个提示"
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
@edit-end="editEnd"
|
||||
@edit-change="onEditChange"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
:scroll-x="1590"
|
||||
>
|
||||
<template #toolbar>
|
||||
<n-button type="primary" @click="reloadTable">刷新数据</n-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, h } from 'vue';
|
||||
import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
|
||||
import { getTableList } from '@/api/table/list';
|
||||
import { columns } from './rowColumns';
|
||||
|
||||
const actionRef = ref();
|
||||
const currentEditKeyRef = ref('');
|
||||
const params = reactive({
|
||||
pageSize: 5,
|
||||
name: 'xiaoMa',
|
||||
});
|
||||
|
||||
const actionColumn: BasicColumn = reactive({
|
||||
width: 150,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: 'button',
|
||||
actions: createActions(record),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function handleEdit(record) {
|
||||
console.log(record);
|
||||
currentEditKeyRef.value = record.key;
|
||||
record.onEdit?.(true);
|
||||
}
|
||||
|
||||
function handleCancel(record) {
|
||||
currentEditKeyRef.value = '';
|
||||
record.onEdit?.(false, false);
|
||||
}
|
||||
|
||||
function onEditChange({ column, value, record }) {
|
||||
if (column.key === 'id') {
|
||||
record.editValueRefs.name4.value = `${value}`;
|
||||
}
|
||||
console.log(column, value, record);
|
||||
}
|
||||
|
||||
async function handleSave(record) {
|
||||
const pass = await record.onEdit?.(false, true);
|
||||
if (pass) {
|
||||
currentEditKeyRef.value = '';
|
||||
}
|
||||
}
|
||||
|
||||
function createActions(record) {
|
||||
if (!record.editable) {
|
||||
return [
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
label: '保存',
|
||||
onClick: handleSave.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '取消',
|
||||
onClick: handleCancel.bind(null, record),
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
return await getTableList({ ...params, ...res });
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
console.log(actionRef.value);
|
||||
actionRef.value.reload();
|
||||
}
|
||||
|
||||
function editEnd({ record, index, key, value }) {
|
||||
console.log('record', record);
|
||||
console.log('index', index);
|
||||
console.log('key', key);
|
||||
console.log('value', value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,97 +0,0 @@
|
||||
import { h } from 'vue';
|
||||
import { NAvatar } from 'naive-ui';
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '编码',
|
||||
key: 'no',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
editComponent: 'NInput',
|
||||
editRow: true,
|
||||
// 默认必填校验
|
||||
editRule: true,
|
||||
edit: true,
|
||||
width: 200,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NAvatar, {
|
||||
size: 48,
|
||||
src: row.avatar,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '地址',
|
||||
key: 'address',
|
||||
editRow: true,
|
||||
editComponent: 'NSelect',
|
||||
editComponentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '广东省',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '浙江省',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
edit: true,
|
||||
width: 200,
|
||||
ellipsis: false,
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
key: 'beginTime',
|
||||
editRow: true,
|
||||
edit: true,
|
||||
width: 240,
|
||||
editComponent: 'NDatePicker',
|
||||
editComponentProps: {
|
||||
type: 'datetime',
|
||||
valueFormat: 'yyyy-MM-dd HH:mm:ss',
|
||||
},
|
||||
ellipsis: false,
|
||||
},
|
||||
{
|
||||
title: '结束日期',
|
||||
key: 'endTime',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
key: 'status',
|
||||
editRow: true,
|
||||
edit: true,
|
||||
width: 100,
|
||||
editComponent: 'NSwitch',
|
||||
editValueMap: (value) => {
|
||||
return value ? '启用' : '禁用';
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'date',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '停留时间',
|
||||
key: 'time',
|
||||
width: 80,
|
||||
},
|
||||
];
|
@ -1,32 +0,0 @@
|
||||
import { h } from 'vue';
|
||||
import { NAvatar } from 'naive-ui';
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
width: 100,
|
||||
render(row) {
|
||||
return h(NAvatar, {
|
||||
size: 48,
|
||||
src: row.avatar,
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '地址',
|
||||
key: 'address',
|
||||
width: 150,
|
||||
},
|
||||
];
|
@ -1,188 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="表格选择器">
|
||||
选择器增强,用于展示多列数据表格选择器,可实现单选/多选,还能配置表单查询,项目实测,还是挺实用的
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="单选" type="info"> 始终只能选择一个,切换分页也是如此 </n-alert>
|
||||
<div class="mt-3">
|
||||
<n-space align="center">
|
||||
<TableSelect
|
||||
ref="TableSelectRef"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
placeholder="请选择内容(单选)"
|
||||
v-model:value="tableSelectData"
|
||||
:tableProps="{
|
||||
rowKey: (row) => row.id,
|
||||
request: loadDataTable,
|
||||
columns: columns,
|
||||
pagination: {
|
||||
simple: true,
|
||||
},
|
||||
}"
|
||||
@change="tableSelectChange"
|
||||
/>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="多选" type="info" class="mt-3">
|
||||
支持选择多个,切换分页也不影响,试试吧
|
||||
</n-alert>
|
||||
<div class="mt-3">
|
||||
<n-space align="center">
|
||||
<TableSelect
|
||||
ref="TableSelectRef"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
placeholder="请选择内容(多选)"
|
||||
:multiple="true"
|
||||
:tableProps="{
|
||||
rowKey: (row) => row.id,
|
||||
request: loadDataTable,
|
||||
columns: columns,
|
||||
pagination: {
|
||||
simple: true,
|
||||
},
|
||||
}"
|
||||
@change="tableSelectChange"
|
||||
v-model:value="tableSelectData"
|
||||
/>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="多选" type="info">
|
||||
支持配置表单,搜索查询,适用于,查询数据较多,支持分页多选
|
||||
</n-alert>
|
||||
<div class="mt-3">
|
||||
<n-space align="center">
|
||||
<TableSelect
|
||||
ref="TableSelectRef"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
placeholder="请选择内容(多选)"
|
||||
v-model:formValues="formValues"
|
||||
:multiple="true"
|
||||
:formProps="formPropsOption"
|
||||
:tableProps="{
|
||||
rowKey: (row) => row.id,
|
||||
request: loadDataTable,
|
||||
columns: columns,
|
||||
pagination: {
|
||||
simple: true,
|
||||
},
|
||||
}"
|
||||
@change="tableSelectChange"
|
||||
/>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="配合Form" type="info"> 外面配合 Form 组件,结合搜索查询 </n-alert>
|
||||
<div class="mt-3">
|
||||
<BasicForm
|
||||
ref="basicFormRef"
|
||||
submitButtonText="提交预约"
|
||||
layout="horizontal"
|
||||
:gridProps="{ cols: 1 }"
|
||||
:schemas="FormSchemas"
|
||||
@submit="handleSubmit"
|
||||
@reset="handleReset"
|
||||
>
|
||||
<template #tableSelect="{ model, field }">
|
||||
<TableSelect
|
||||
ref="TableSelectRef"
|
||||
labelField="name"
|
||||
valueField="id"
|
||||
placeholder="请选择内容"
|
||||
v-model:value="model[field]"
|
||||
:multiple="true"
|
||||
:formProps="formPropsOption"
|
||||
:tableProps="{
|
||||
rowKey: (row) => row.id,
|
||||
request: loadDataTable,
|
||||
columns: columns,
|
||||
pagination: {
|
||||
simple: true,
|
||||
},
|
||||
}"
|
||||
@change="tableSelectChange"
|
||||
/>
|
||||
</template>
|
||||
</BasicForm>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { TableSelect } from '@/components/TableSelect';
|
||||
import { getTableSelectList } from '@/api/table/list';
|
||||
import { columns } from './basicColumns';
|
||||
import { BasicForm, FormSchema } from '@/components/Form/index';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
const tableSelectData = ref(['啊俊']);
|
||||
const formValues = ref();
|
||||
const TableSelectRef = ref();
|
||||
const message = useMessage();
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
labelMessage: '可以通过名称搜索查询哦',
|
||||
component: 'NInput',
|
||||
label: '名称',
|
||||
componentProps: {
|
||||
placeholder: '请输入名称',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
// rules: [{ required: true, message: '请输入名称', trigger: ['blur'] }],
|
||||
},
|
||||
];
|
||||
|
||||
const FormSchemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
label: '名称',
|
||||
slot: 'tableSelect',
|
||||
},
|
||||
];
|
||||
|
||||
const formPropsOption = {
|
||||
gridProps: { cols: '2' },
|
||||
labelWidth: 80,
|
||||
submitButtonText: '查询',
|
||||
showAdvancedButton: false,
|
||||
schemas,
|
||||
};
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
return await getTableSelectList({ ...formValues.value, ...res });
|
||||
};
|
||||
|
||||
function handleSubmit(values: Recordable) {
|
||||
message.success(JSON.stringify(values));
|
||||
}
|
||||
|
||||
function handleReset(values: Recordable) {
|
||||
message.success(JSON.stringify(values));
|
||||
TableSelectRef.value.updateSelectedRowKeys();
|
||||
}
|
||||
|
||||
function tableSelectChange(list) {
|
||||
console.log('list', list);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,111 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="上传图片"> 上传图片,用于向用户收集图片信息 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-grid cols="2 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen">
|
||||
<n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1">
|
||||
<n-form
|
||||
:label-width="80"
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
ref="formRef"
|
||||
class="py-8"
|
||||
>
|
||||
<n-form-item label="预约姓名" path="name">
|
||||
<n-input v-model:value="formValue.name" placeholder="输入姓名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="预约号码" path="mobile">
|
||||
<n-input placeholder="电话号码" v-model:value="formValue.mobile" />
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item label="病例图片" path="images">
|
||||
<BasicUpload
|
||||
:action="`${uploadUrl}/v1.0/files`"
|
||||
:headers="uploadHeaders"
|
||||
:data="{ type: '0' }"
|
||||
name="files"
|
||||
:width="100"
|
||||
:height="100"
|
||||
@uploadChange="uploadChange"
|
||||
v-model:value="formValue.images"
|
||||
helpText="单个文件不超过2MB,最多只能上传10个文件"
|
||||
/>
|
||||
</n-form-item>
|
||||
<div style="margin-left: 80px">
|
||||
<n-space>
|
||||
<n-button type="primary" @click="formSubmit">提交预约</n-button>
|
||||
<n-button @click="resetForm">重置</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, reactive } from 'vue';
|
||||
import { useMessage, FormRules } from 'naive-ui';
|
||||
import { BasicUpload } from '@/components/Upload';
|
||||
import { useGlobSetting } from '@/hooks/setting';
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
|
||||
const rules: FormRules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: '请输入预约姓名',
|
||||
trigger: 'blur',
|
||||
},
|
||||
remark: {
|
||||
required: true,
|
||||
message: '请输入预约备注',
|
||||
trigger: 'blur',
|
||||
},
|
||||
images: {
|
||||
required: true,
|
||||
type: 'array',
|
||||
message: '请上传病例图片',
|
||||
trigger: 'change',
|
||||
},
|
||||
};
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const { uploadUrl } = globSetting;
|
||||
|
||||
const formValue = reactive({
|
||||
name: '',
|
||||
mobile: '',
|
||||
//图片列表 通常查看和编辑使用 绝对路径 | 相对路径都可以
|
||||
images: ['https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png'],
|
||||
});
|
||||
|
||||
const uploadHeaders: any = reactive({
|
||||
platform: 'miniPrograms',
|
||||
timestamp: new Date().getTime(),
|
||||
token: 'Q6fFCuhc1vkKn5JNFWaCLf6gRAc5n0LQHd08dSnG4qo=',
|
||||
});
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
message.success('验证成功');
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formRef.value.restoreValidation();
|
||||
}
|
||||
|
||||
function uploadChange(list: string[]) {
|
||||
formValue.images = unref(list);
|
||||
}
|
||||
</script>
|
@ -1,75 +0,0 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="权限判断">
|
||||
中后台系统,权限事关重要,可能在任意页面都会存在,前端可以通过多种方式来实现权限控制
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="方法判断"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-space>
|
||||
<n-button type="success" v-if="hasPermission(['delete_user'])" @click="handleDeleteSueeess"
|
||||
>有删除用户权限可见</n-button
|
||||
>
|
||||
<n-button type="error" @click="handleDeleteError">没有删除列表权限</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="指令判断"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-space>
|
||||
<n-button type="error" v-permission="{ action: ['delete_list'], effect: 'disabled' }"
|
||||
>没有删除列表权限禁用</n-button
|
||||
>
|
||||
<n-button type="error" v-permission="{ action: ['delete_list'] }"
|
||||
>没有删除列表权限隐藏</n-button
|
||||
>
|
||||
</n-space>
|
||||
</n-card>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="组件判断"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-space>
|
||||
<Authority :value="['delete_user']">
|
||||
<n-button type="success" @click="handleDeleteSueeess">有删除用户权限可见</n-button>
|
||||
</Authority>
|
||||
<Authority :value="['delete_list']">
|
||||
<n-button type="error" @click="handleDeleteSueeess">没有删除列表权限隐藏</n-button>
|
||||
</Authority>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { usePermission } from '@/hooks/web/usePermission';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
const message = useMessage();
|
||||
const { hasPermission } = usePermission();
|
||||
|
||||
function handleDeleteSueeess() {
|
||||
if (hasPermission(['delete_user'])) {
|
||||
message.success('恭喜,您拥有该操作权限');
|
||||
}
|
||||
}
|
||||
|
||||
function handleDeleteError() {
|
||||
if (!hasPermission(['delete_list'])) {
|
||||
message.warning('抱歉,您没有操作权限');
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,97 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="右键菜单"> 右键菜单示例,指定元素右键显示操作菜单 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert :show-icon="false" title="右键展示菜单" type="info">
|
||||
<n-button class="mt-2" type="primary" @contextmenu="handleContextMenu">右键试试</n-button>
|
||||
</n-alert>
|
||||
|
||||
<n-alert :show-icon="false" title="头像组件右键展示菜单" type="info" class="mt-3">
|
||||
<n-avatar
|
||||
:size="80"
|
||||
src="https://naive-ui-admin-docs.vercel.app/logo.png"
|
||||
@contextmenu="handleContextMenu"
|
||||
/>
|
||||
</n-alert>
|
||||
|
||||
<n-dropdown
|
||||
placement="bottom-start"
|
||||
@select="handleSelect"
|
||||
trigger="manual"
|
||||
:x="xRef"
|
||||
:y="yRef"
|
||||
:options="options"
|
||||
:show="showDropdownRef"
|
||||
:on-clickoutside="onClickoutside"
|
||||
/>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, nextTick } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import {
|
||||
MailOutlined,
|
||||
AndroidOutlined,
|
||||
EllipsisOutlined,
|
||||
QqOutlined,
|
||||
WechatOutlined,
|
||||
} from '@vicons/antd';
|
||||
import { renderIcon } from '@/utils';
|
||||
const options = [
|
||||
{
|
||||
label: '发送到邮箱',
|
||||
key: 'email',
|
||||
icon: renderIcon(MailOutlined),
|
||||
},
|
||||
{
|
||||
label: '发送到手机',
|
||||
key: 'mobile',
|
||||
icon: renderIcon(AndroidOutlined),
|
||||
},
|
||||
{
|
||||
label: '其他',
|
||||
key: 'others',
|
||||
icon: renderIcon(EllipsisOutlined),
|
||||
children: [
|
||||
{
|
||||
label: 'QQ',
|
||||
key: 'qq',
|
||||
icon: renderIcon(QqOutlined),
|
||||
},
|
||||
{
|
||||
label: '微信',
|
||||
key: 'weixin',
|
||||
icon: renderIcon(WechatOutlined),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const showDropdownRef = ref(false);
|
||||
const message = useMessage();
|
||||
const xRef = ref(0);
|
||||
const yRef = ref(0);
|
||||
|
||||
function handleSelect(key) {
|
||||
showDropdownRef.value = false;
|
||||
message.info(`${key}-这个是你点击的菜单吧?`);
|
||||
}
|
||||
|
||||
function handleContextMenu(e) {
|
||||
e.preventDefault();
|
||||
showDropdownRef.value = false;
|
||||
nextTick().then(() => {
|
||||
showDropdownRef.value = true;
|
||||
xRef.value = e.clientX;
|
||||
yRef.value = e.clientY;
|
||||
});
|
||||
}
|
||||
|
||||
function onClickoutside() {
|
||||
message.info('您点击了外部区域,菜单不见了哈!');
|
||||
showDropdownRef.value = false;
|
||||
}
|
||||
</script>
|
@ -1,70 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="文本复制">
|
||||
文本复制示例,用于常规订单号,编号,快速复制等场景
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="基本信息"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-descriptions label-placement="left" class="py-2">
|
||||
<n-descriptions-item>
|
||||
<template #label>收款人姓名</template>
|
||||
啊俊
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="收款账户">NaiveUiAdmin@qq.com</n-descriptions-item>
|
||||
<n-descriptions-item label="付款类型">支付宝</n-descriptions-item>
|
||||
<n-descriptions-item label="付款账户">
|
||||
{{ account }}
|
||||
<n-button size="small" type="info" @click="handleAccountCopy">复制</n-button>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="转账金额">
|
||||
<n-space>
|
||||
<n-input v-model:value="money" />
|
||||
<n-button type="info" @click="handleMoneyCopy">复制</n-button>
|
||||
</n-space>
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="状态">
|
||||
<n-tag type="success"> 已到账</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref } from 'vue';
|
||||
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
const { clipboardRef, copiedRef } = useCopyToClipboard();
|
||||
|
||||
const account = ref('NaiveUiAdmin@163.com');
|
||||
const money = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
function handleAccountCopy() {
|
||||
const value = unref(account.value);
|
||||
clipboardRef.value = value;
|
||||
if (unref(copiedRef)) {
|
||||
message.success(`拷贝成功:${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
function handleMoneyCopy() {
|
||||
const value = unref(money.value);
|
||||
if (!value) {
|
||||
message.warning('请输入要复制的内容!');
|
||||
return;
|
||||
}
|
||||
clipboardRef.value = value;
|
||||
if (unref(copiedRef)) {
|
||||
message.success(`拷贝成功:${value}`);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,61 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="文件下载">
|
||||
文件下载示例,用于各种场景下载文件或者图片
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert :show-icon="false" title="后台接口文件流下载" type="info">
|
||||
<n-button class="mt-2" type="primary" @click="downloadFile">文件流下载</n-button>
|
||||
</n-alert>
|
||||
<n-divider />
|
||||
<n-alert :show-icon="false" title="文件地址下载" type="info">
|
||||
<n-button class="mt-2" type="primary" @click="downloadFileUrl">文件地址下载</n-button>
|
||||
</n-alert>
|
||||
<n-divider />
|
||||
<n-alert :show-icon="false" title="base64流下载" type="info">
|
||||
<n-button class="mt-2" type="primary" @click="downloadFileBase64">base64流下载</n-button>
|
||||
</n-alert>
|
||||
<n-divider />
|
||||
<n-alert
|
||||
:show-icon="false"
|
||||
title="图片Url下载,如果有跨域问题,需要先处理图片跨域,才能下载"
|
||||
type="info"
|
||||
>
|
||||
<n-button class="mt-2" type="primary" @click="downloadFileImgUrl">图片Url下载</n-button>
|
||||
</n-alert>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {
|
||||
downloadByUrl,
|
||||
downloadByData,
|
||||
downloadByBase64,
|
||||
downloadByOnlineUrl,
|
||||
} from '@/utils/file/download';
|
||||
import imgBase64 from './imgBase64';
|
||||
|
||||
const getName = new Date().valueOf();
|
||||
|
||||
function downloadFile() {
|
||||
downloadByData('测试下载文件流', `${getName}-file.txt`);
|
||||
}
|
||||
|
||||
function downloadFileUrl() {
|
||||
downloadByUrl({
|
||||
url: 'https://naive-ui-admin-docs.vercel.app/logo.png',
|
||||
target: '_self',
|
||||
});
|
||||
}
|
||||
|
||||
function downloadFileBase64() {
|
||||
downloadByBase64(imgBase64, `${getName}.png`);
|
||||
}
|
||||
|
||||
function downloadFileImgUrl() {
|
||||
downloadByOnlineUrl('https://naive-ui-admin-docs.vercel.app/logo.png', `${getName}.png`);
|
||||
}
|
||||
</script>
|
File diff suppressed because one or more lines are too long
@ -1,220 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="导出示例"> 可以选择导出格式 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<BasicTable
|
||||
title="表格列表"
|
||||
titleTooltip="这是一个提示"
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
:scroll-x="1360"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<template #toolbar>
|
||||
<n-button type="primary" @click="openModal">导出数据</n-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
|
||||
<basicModal @register="modalRegister" ref="modalRef" class="basicModal" @on-ok="okModal">
|
||||
<template #default>
|
||||
<BasicForm
|
||||
@register="register"
|
||||
@submit="handleSubmit"
|
||||
@reset="handleReset"
|
||||
class="basicForm"
|
||||
>
|
||||
<template #statusSlot="{ model, field }">
|
||||
<n-input v-model:value="model[field]" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
</template>
|
||||
</basicModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, unref, ref, h } from 'vue';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { basicModal, useModal } from '@/components/Modal';
|
||||
import { BasicForm, FormSchema, useForm } from '@/components/Form/index';
|
||||
import { getTableList } from '@/api/table/list';
|
||||
import { columns } from '../../comp/table/basicColumns';
|
||||
import { jsonToSheetXlsx } from '@/components/Excel';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'filename',
|
||||
component: 'NInput',
|
||||
label: '文件名',
|
||||
labelMessage: '导出的文件以该名称命名',
|
||||
giProps: {
|
||||
span: 1,
|
||||
},
|
||||
componentProps: {
|
||||
placeholder: '请输入文件名称',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请输入导出的文件名称', trigger: ['blur'] }],
|
||||
},
|
||||
{
|
||||
field: 'bookType',
|
||||
component: 'NSelect',
|
||||
label: '文件类型',
|
||||
componentProps: {
|
||||
placeholder: '请选择文件类型',
|
||||
options: [
|
||||
{
|
||||
label: 'xlsx',
|
||||
value: 'xlsx',
|
||||
},
|
||||
{
|
||||
label: 'html',
|
||||
value: 'html',
|
||||
},
|
||||
{
|
||||
label: 'csv',
|
||||
value: 'csv',
|
||||
},
|
||||
{
|
||||
label: 'txt',
|
||||
value: 'txt',
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
rules: [{ required: true, message: '请选择文件类型', trigger: ['change'] }],
|
||||
},
|
||||
];
|
||||
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const actionRef = ref();
|
||||
const modalRef = ref();
|
||||
const tableData = ref();
|
||||
|
||||
const params = reactive({
|
||||
pageSize: 5,
|
||||
name: 'xiaoMa',
|
||||
});
|
||||
|
||||
const [modalRegister, { openModal }] = useModal({
|
||||
title: '导出数据',
|
||||
});
|
||||
|
||||
const [register, { submit }] = useForm({
|
||||
gridProps: { cols: 1 },
|
||||
collapsedRows: 3,
|
||||
labelWidth: 120,
|
||||
layout: 'horizontal',
|
||||
showActionButtonGroup: false,
|
||||
schemas,
|
||||
});
|
||||
|
||||
const actionColumn = reactive({
|
||||
width: 150,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: 'button',
|
||||
actions: createActions(record),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
async function okModal() {
|
||||
const formRes = await submit();
|
||||
if (formRes) {
|
||||
modalRef.value.closeModal();
|
||||
message.success('提交成功');
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
modalRef.value.setSubLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function handleReset(values: Recordable) {
|
||||
console.log(values);
|
||||
}
|
||||
|
||||
function createActions(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
// 根据权限控制是否显示: 有权限,会显示,支持多个
|
||||
auth: ['basic_list'],
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
auth: ['basic_list'],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getTableList({ ...params, ...res });
|
||||
tableData.value = result.list;
|
||||
return result;
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function handleDelete(record) {
|
||||
console.log(record);
|
||||
dialog.info({
|
||||
title: '提示',
|
||||
content: `您想删除${record.name}`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
message.success('删除成功');
|
||||
},
|
||||
onNegativeClick: () => {},
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record) {
|
||||
console.log(record);
|
||||
message.success('您点击了编辑按钮');
|
||||
}
|
||||
|
||||
function handleSubmit(values: Recordable) {
|
||||
console.log(values);
|
||||
// 默认Object.keys(data[0])作为header
|
||||
const { filename, bookType } = values;
|
||||
jsonToSheetXlsx({
|
||||
data: unref(tableData),
|
||||
filename: `${filename.split('.').shift()}.${bookType}`,
|
||||
write2excelOpts: {
|
||||
bookType,
|
||||
},
|
||||
});
|
||||
message.success(JSON.stringify(values));
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,145 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="导出示例"> 根据JSON格式的数据进行导出 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<BasicTable
|
||||
title="表格列表"
|
||||
titleTooltip="这是一个提示"
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="actionRef"
|
||||
:actionColumn="actionColumn"
|
||||
:scroll-x="1360"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<template #toolbar>
|
||||
<n-space>
|
||||
<n-button type="primary" @click="customHeader">导出自定义表头</n-button>
|
||||
<n-button type="primary" @click="defaultHeader">导出默认表头</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, h, unref } from 'vue';
|
||||
import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
|
||||
import { getTableList } from '@/api/table/list';
|
||||
import { columns } from '../../comp/table/basicColumns';
|
||||
import { jsonToSheetXlsx } from '@/components/Excel';
|
||||
import { useDialog, useMessage } from 'naive-ui';
|
||||
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const actionRef = ref();
|
||||
const tableData = ref();
|
||||
|
||||
const params = reactive({
|
||||
pageSize: 5,
|
||||
name: 'xiaoMa',
|
||||
});
|
||||
|
||||
const actionColumn: BasicColumn = reactive({
|
||||
width: 150,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
align: 'center',
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: 'button',
|
||||
actions: createActions(record),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function createActions(record) {
|
||||
return [
|
||||
{
|
||||
label: '删除',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
// 根据权限控制是否显示: 有权限,会显示,支持多个
|
||||
auth: ['basic_list'],
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
auth: ['basic_list'],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getTableList({ ...params, ...res });
|
||||
tableData.value = result.list;
|
||||
return result;
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys);
|
||||
}
|
||||
|
||||
function handleDelete(record) {
|
||||
console.log(record);
|
||||
dialog.info({
|
||||
title: '提示',
|
||||
content: `您想删除${record.name}`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: () => {
|
||||
message.success('删除成功');
|
||||
},
|
||||
onNegativeClick: () => {},
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record) {
|
||||
console.log(record);
|
||||
message.success('您点击了编辑按钮');
|
||||
}
|
||||
|
||||
function defaultHeader() {
|
||||
// 默认Object.keys(data[0])作为header
|
||||
jsonToSheetXlsx({
|
||||
data: unref(tableData),
|
||||
filename: '使用key作为默认表头.xlsx',
|
||||
});
|
||||
}
|
||||
|
||||
function customHeader() {
|
||||
jsonToSheetXlsx({
|
||||
data: unref(tableData),
|
||||
header: {
|
||||
id: 'ID',
|
||||
no: '编码',
|
||||
name: '名称',
|
||||
avatar: '头像',
|
||||
address: '地址',
|
||||
beginTime: '开始日期',
|
||||
endTime: '结束时间',
|
||||
status: '状态',
|
||||
date: '创建时间',
|
||||
time: '停留时间',
|
||||
},
|
||||
filename: '自定义表头.xlsx',
|
||||
json2sheetOpts: {
|
||||
// 指定顺序
|
||||
//header: ['id', 'no','name','avatar','address','beginTime','endTime','status','date','time'],
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,41 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="打印场景"> json打印表格,图片打印 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-space>
|
||||
<n-button type="primary" @click="jsonPrint">打印表格</n-button>
|
||||
<n-button type="primary" @click="imagePrint">打印图片</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import printJS from 'print-js';
|
||||
|
||||
function jsonPrint() {
|
||||
printJS({
|
||||
printable: [
|
||||
{ name: '汪伟', email: '735869@gmail.com', phone: '186****5653' },
|
||||
{ name: '雷秀英', email: '235656452@gmail.com', phone: '135****6536' },
|
||||
{ name: '邹芳', email: '24586526@gmail.com', phone: '159****5869' },
|
||||
],
|
||||
properties: ['name', 'email', 'phone'],
|
||||
type: 'json',
|
||||
});
|
||||
}
|
||||
|
||||
function imagePrint() {
|
||||
printJS({
|
||||
printable: [
|
||||
'https://naive-ui-admin-docs.vercel.app/logo.png',
|
||||
'https://naive-ui-admin-docs.vercel.app/logo.png',
|
||||
],
|
||||
type: 'image',
|
||||
header: 'Multiple Images',
|
||||
imageStyle: 'width:100%;',
|
||||
});
|
||||
}
|
||||
</script>
|
@ -1,96 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="滚动场景"> 比如,卡片列表,文章列表滚动</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-alert title="UI框架内置滚动条" type="info"
|
||||
>如果你只是想简单的,实现一个滚动,可以这么写
|
||||
</n-alert>
|
||||
<div class="mt-3 scrollbar-box">
|
||||
<n-scrollbar>
|
||||
<p v-for="item in list" :key="item.id">{{ item.name }}</p>
|
||||
</n-scrollbar>
|
||||
</div>
|
||||
|
||||
<n-alert class="mt-3" title="指令方式" type="info"
|
||||
>基于,perfect-scrollbar 使用方式可参考该插件
|
||||
</n-alert>
|
||||
<div class="mt-3 scrollbar-main">
|
||||
<div v-scrollBar class="scrollbar-box">
|
||||
<p v-for="item in list" :key="item.id">{{ item.name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<n-alert class="mt-3" title="UI框架内置滚动条" type="info">演示,函数触发滚动条位置</n-alert>
|
||||
<div class="mt-3 scrollbar-box">
|
||||
<n-scrollbar ref="scrollbar">
|
||||
<p v-for="item in list" :key="item.id">{{ item.name }}</p>
|
||||
</n-scrollbar>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<n-space>
|
||||
<n-button @click="goScrollbar(120)">滚动到120位置</n-button>
|
||||
<n-button @click="goScrollbar(900)">滚动到900位置</n-button>
|
||||
<n-button @click="goScrollbar(0)">滚动到顶部</n-button>
|
||||
<n-button @click="goScrollbar(99999)">滚动到底部</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import 'perfect-scrollbar/css/perfect-scrollbar.css';
|
||||
|
||||
interface IList {
|
||||
id: string | number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
function getList() {
|
||||
const arr: IList[] = [];
|
||||
for (let index = 0; index < 40; index++) {
|
||||
arr.push({
|
||||
id: `${index}`,
|
||||
name: '这内容下面可能还有很多个,鼠标放进来使劲的滚动吧',
|
||||
});
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
const list = getList();
|
||||
|
||||
const scrollbar = ref();
|
||||
|
||||
function goScrollbar(y) {
|
||||
scrollbar.value.scrollTo(0, y);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
// 如果使用 perfect-scrollbar初始化的DOM,
|
||||
// 内部有使用border/margin/padding等会改变元素原有宽高的样式,
|
||||
// 就会造成滚动条无限滚动的bug;
|
||||
.scrollbar-main {
|
||||
width: 360px;
|
||||
border: 1px solid #eee;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollbar-box {
|
||||
width: 360px;
|
||||
height: 350px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #eee;
|
||||
padding: 10px;
|
||||
|
||||
p {
|
||||
padding: 5px 0;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="多页签">
|
||||
有些时候,可能要操作多页签标题,比如页面特定交互,详情页面区分,该操作仅限于,当前打开过并且显示的标签
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="多页签操作"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-space>
|
||||
<n-button type="primary" @click="setTabsTitle">更新当前页面标题</n-button>
|
||||
<n-button type="primary" @click="setTabsTitleSpecific">更新指定页面标题</n-button>
|
||||
<n-button type="primary" @click="closeCurrent">关闭当前页</n-button>
|
||||
</n-space>
|
||||
<n-h2>设置多页签状态</n-h2>
|
||||
<n-space>
|
||||
<n-button type="warning" @click="setTabState('undone')">设置当前页面状态未完成</n-button>
|
||||
<n-button type="success" @click="setTabState('done')">设置当前页面状态已完成</n-button>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted } from 'vue';
|
||||
import { useTabs } from '@/hooks/web/useTags';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
const useTagsHooks = useTabs();
|
||||
const message = useMessage();
|
||||
|
||||
function setTabsTitle() {
|
||||
useTagsHooks.setTitle('货品详情:编码-3695');
|
||||
message.success('设置成功');
|
||||
}
|
||||
|
||||
function setTabsTitleSpecific() {
|
||||
useTagsHooks.setTitle('指定页面标题', { name: '/list/basic-list' });
|
||||
message.success('设置成功');
|
||||
}
|
||||
|
||||
function closeCurrent() {
|
||||
useTagsHooks.closeCurrent();
|
||||
}
|
||||
|
||||
function setTabState(state: string) {
|
||||
useTagsHooks.setTabState({
|
||||
state,
|
||||
dialogOptions: {
|
||||
content: '页面尚未提交,是否关闭?',
|
||||
},
|
||||
});
|
||||
const msg =
|
||||
state === 'undone'
|
||||
? '设置成功,点击当前页标签关闭按钮,试试效果'
|
||||
: '取消成功,当前页标签,可以正常关闭';
|
||||
message.success(msg);
|
||||
}
|
||||
|
||||
//如果需要每次进入页面,都自定义,需要在 onMounted 中调用
|
||||
onMounted(() => {
|
||||
//setTabsTitle();
|
||||
});
|
||||
</script>
|
@ -1,374 +0,0 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="高级表单">
|
||||
当一次性提交大量数据时,可使用高级表单,根据自身情况选择是否使用 BasicForm
|
||||
组件,以下布局支持自适应
|
||||
</n-card>
|
||||
</div>
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:label-width="100"
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
class="mt-3 proCard"
|
||||
title="预约信息"
|
||||
size="small"
|
||||
:segmented="{
|
||||
content: true,
|
||||
}"
|
||||
content-style="padding: 20px 20px 0 0;"
|
||||
>
|
||||
<n-grid cols="1 s:1 m:2 l:3 xl:4 2xl:4" responsive="screen">
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约姓名" path="name">
|
||||
<n-input v-model:value="formValue.name" placeholder="输入姓名" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约号码" path="mobile">
|
||||
<n-input v-model:value="formValue.mobile" placeholder="电话号码" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约时间" path="datetime">
|
||||
<n-date-picker class="w-full" v-model:value="formValue.datetime" type="datetime" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约医生" path="doctor">
|
||||
<n-select
|
||||
v-model:value="formValue.doctor"
|
||||
:options="doctorList"
|
||||
placeholder="请选择预约医生"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约事项" path="matter">
|
||||
<n-select
|
||||
v-model:value="formValue.matter"
|
||||
:options="matterList"
|
||||
multiple
|
||||
placeholder="请选择预约事项"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约备注" path="remark">
|
||||
<n-input v-model:value="formValue.remark" placeholder="请输入预约备注" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="预约备注" path="remark">
|
||||
<n-input v-model:value="formValue.remark" placeholder="请输入预约备注" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="出生日期" path="dateBirth">
|
||||
<n-date-picker class="w-full" v-model:value="formValue.dateBirth" type="datetime" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<n-grid-item>
|
||||
<n-form-item label="性别" path="sex">
|
||||
<n-radio-group v-model:value="formValue.sex" name="sex">
|
||||
<n-space>
|
||||
<n-radio :value="1">男</n-radio>
|
||||
<n-radio :value="2">女</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
|
||||
<!-- <div style="margin-left: 80px">-->
|
||||
<!-- <n-space>-->
|
||||
<!-- <n-button type="primary" @click="formSubmit">提交预约</n-button>-->
|
||||
<!-- <n-button @click="resetForm">重置</n-button>-->
|
||||
<!-- </n-space>-->
|
||||
<!-- </div>-->
|
||||
</n-grid>
|
||||
</n-card>
|
||||
|
||||
<n-card
|
||||
:bordered="false"
|
||||
class="mt-3 proCard"
|
||||
title="就诊信息"
|
||||
size="small"
|
||||
:segmented="{
|
||||
content: true,
|
||||
}"
|
||||
content-style="padding: 20px 20px 0 0;"
|
||||
>
|
||||
<n-grid cols="1 s:1 m:2 l:3 xl:4 2xl:4" responsive="screen">
|
||||
<n-grid-item>
|
||||
<n-form-item label="过敏史" path="allergiChistory">
|
||||
<n-input v-model:value="formValue.allergiChistory" placeholder="请输入过敏史" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="既往史" path="pastHistory">
|
||||
<n-input v-model:value="formValue.pastHistory" placeholder="请输入既往史" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="传染史" path="contagion">
|
||||
<n-input v-model:value="formValue.contagion" placeholder="请输入传染史" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="身份证号" path="idNo">
|
||||
<n-input v-model:value="formValue.idNo" placeholder="请输入身份证号" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="介绍人" path="introducer">
|
||||
<n-input v-model:value="formValue.introducer" placeholder="请输入介绍人" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="就诊医生" path="seeDoctor">
|
||||
<n-select
|
||||
v-model:value="formValue.seeDoctor"
|
||||
:options="doctorList"
|
||||
placeholder="请选择就诊医生"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="初诊日期" path="firstDatetime">
|
||||
<n-date-picker
|
||||
class="w-full"
|
||||
v-model:value="formValue.firstDatetime"
|
||||
type="datetime"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="近次复诊" path="subsequent">
|
||||
<n-date-picker class="w-full" v-model:value="formValue.subsequent" type="datetime" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<!-- <n-grid-item>-->
|
||||
<!-- <n-form-item label="图片" path="img">-->
|
||||
<!-- <BasicUpload-->
|
||||
<!-- v-model:value="uploadList"-->
|
||||
<!-- :action="`${uploadUrl}/v1.0/files`"-->
|
||||
<!-- :data="{ type: 0 }"-->
|
||||
<!-- :headers="uploadHeaders"-->
|
||||
<!-- :height="100"-->
|
||||
<!-- :width="100"-->
|
||||
<!-- helpText="单个文件不超过20MB,最多只能上传10个文件"-->
|
||||
<!-- name="files"-->
|
||||
<!-- @uploadChange="uploadChange"-->
|
||||
<!-- />-->
|
||||
<!-- </n-form-item>-->
|
||||
<!-- </n-grid-item>-->
|
||||
</n-grid>
|
||||
</n-card>
|
||||
|
||||
<n-card
|
||||
:bordered="false"
|
||||
class="mt-3 proCard"
|
||||
title="就诊信息"
|
||||
size="small"
|
||||
:segmented="{
|
||||
content: true,
|
||||
}"
|
||||
content-style="padding: 20px 20px 0 0;"
|
||||
>
|
||||
<n-grid cols="1 s:1 m:2 l:3 xl:4 2xl:4" responsive="screen">
|
||||
<n-grid-item>
|
||||
<n-form-item label="过敏史" path="allergiChistory">
|
||||
<n-input v-model:value="formValue.allergiChistory" placeholder="请输入过敏史" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="既往史" path="pastHistory">
|
||||
<n-input v-model:value="formValue.pastHistory" placeholder="请输入既往史" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="传染史" path="contagion">
|
||||
<n-input v-model:value="formValue.contagion" placeholder="请输入传染史" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="身份证号" path="idNo">
|
||||
<n-input v-model:value="formValue.idNo" placeholder="请输入身份证号" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="介绍人" path="introducer">
|
||||
<n-input v-model:value="formValue.introducer" placeholder="请输入介绍人" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="就诊医生" path="seeDoctor">
|
||||
<n-select
|
||||
v-model:value="formValue.seeDoctor"
|
||||
:options="doctorList"
|
||||
placeholder="请选择就诊医生"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="初诊日期" path="firstDatetime">
|
||||
<n-date-picker
|
||||
class="w-full"
|
||||
v-model:value="formValue.firstDatetime"
|
||||
type="datetime"
|
||||
/>
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<n-form-item label="近次复诊" path="subsequent">
|
||||
<n-date-picker class="w-full" v-model:value="formValue.subsequent" type="datetime" />
|
||||
</n-form-item>
|
||||
</n-grid-item>
|
||||
<!-- <n-grid-item>-->
|
||||
<!-- <n-form-item label="图片" path="img">-->
|
||||
<!-- <BasicUpload-->
|
||||
<!-- v-model:value="uploadList"-->
|
||||
<!-- :action="`${uploadUrl}/v1.0/files`"-->
|
||||
<!-- :data="{ type: 0 }"-->
|
||||
<!-- :headers="uploadHeaders"-->
|
||||
<!-- :height="100"-->
|
||||
<!-- :width="100"-->
|
||||
<!-- helpText="单个文件不超过20MB,最多只能上传10个文件"-->
|
||||
<!-- name="files"-->
|
||||
<!-- @uploadChange="uploadChange"-->
|
||||
<!-- />-->
|
||||
<!-- </n-form-item>-->
|
||||
<!-- </n-grid-item>-->
|
||||
</n-grid>
|
||||
</n-card>
|
||||
</n-form>
|
||||
<template #rightFooter>
|
||||
<n-space>
|
||||
<n-button @click="resetForm">重置</n-button>
|
||||
<n-button type="primary" @click="formSubmit">提交</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, reactive } from 'vue';
|
||||
import { PageWrapper } from '@/components/Page';
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { FormRules } from 'naive-ui';
|
||||
|
||||
const matterList = [
|
||||
{
|
||||
label: '种牙',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '补牙',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '根管',
|
||||
value: 3,
|
||||
},
|
||||
];
|
||||
|
||||
const doctorList = [
|
||||
{
|
||||
label: '李医生',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '黄医生',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '张医生',
|
||||
value: 3,
|
||||
},
|
||||
];
|
||||
|
||||
const rules: FormRules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: '请输入预约姓名',
|
||||
trigger: 'blur',
|
||||
},
|
||||
remark: {
|
||||
required: true,
|
||||
message: '请输入预约备注',
|
||||
trigger: 'blur',
|
||||
},
|
||||
mobile: {
|
||||
required: true,
|
||||
message: '请输入预约电话号码',
|
||||
trigger: ['input'],
|
||||
},
|
||||
datetime: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择预约时间',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
seeDoctor: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择就诊时间',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
firstDatetime: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择初诊时间',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
doctor: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择预约医生',
|
||||
trigger: 'change',
|
||||
},
|
||||
};
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const defaultValueRef = () => ({
|
||||
name: '',
|
||||
mobile: '',
|
||||
remark: '',
|
||||
sex: 1,
|
||||
matter: null,
|
||||
doctor: null,
|
||||
datetime: [],
|
||||
});
|
||||
|
||||
let formValue: any = reactive(defaultValueRef());
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
message.success('验证成功');
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formRef.value.resetFields();
|
||||
formValue = Object.assign(unref(formValue), defaultValueRef());
|
||||
}
|
||||
</script>
|
@ -1,199 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="基础表单">
|
||||
表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。表单域标签也可支持响应式。
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-grid cols="1 s:1 m:3 l:3 xl:3 2xl:3" responsive="screen">
|
||||
<n-grid-item offset="0 s:0 m:1 l:1 xl:1 2xl:1">
|
||||
<n-form
|
||||
ref="formRef"
|
||||
:label-width="80"
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
class="py-8"
|
||||
label-placement="left"
|
||||
>
|
||||
<n-form-item label="预约姓名" path="name">
|
||||
<n-input v-model:value="formValue.name" placeholder="输入姓名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="预约号码" path="mobile">
|
||||
<n-input v-model:value="formValue.mobile" placeholder="电话号码" />
|
||||
</n-form-item>
|
||||
<n-form-item label="预约时间" path="datetime">
|
||||
<n-date-picker v-model:value="formValue.datetime" type="datetime" />
|
||||
</n-form-item>
|
||||
<n-form-item label="预约医生" path="doctor">
|
||||
<n-select
|
||||
v-model:value="formValue.doctor"
|
||||
:options="doctorList"
|
||||
placeholder="请选择预约医生"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="预约事项" path="matter">
|
||||
<n-select
|
||||
v-model:value="formValue.matter"
|
||||
:options="matterList"
|
||||
multiple
|
||||
placeholder="请选择预约事项"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="性别" path="sex">
|
||||
<n-radio-group v-model:value="formValue.sex" name="sex">
|
||||
<n-space>
|
||||
<n-radio :value="1">男</n-radio>
|
||||
<n-radio :value="2">女</n-radio>
|
||||
</n-space>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
<n-form-item label="预约备注" path="remark">
|
||||
<n-input
|
||||
v-model:value="formValue.remark"
|
||||
placeholder="请输入预约备注"
|
||||
type="textarea"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="图片" path="img">
|
||||
<BasicUpload
|
||||
v-model:value="uploadList"
|
||||
:action="`${uploadUrl}/v1.0/files`"
|
||||
:data="{ type: '0' }"
|
||||
:headers="uploadHeaders"
|
||||
:height="100"
|
||||
:width="100"
|
||||
helpText="单个文件不超过20MB,最多只能上传10个文件"
|
||||
name="files"
|
||||
@uploadChange="uploadChange"
|
||||
/>
|
||||
</n-form-item>
|
||||
<div style="margin-left: 80px">
|
||||
<n-space>
|
||||
<n-button type="primary" @click="formSubmit">提交预约</n-button>
|
||||
<n-button @click="resetForm">重置</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-form>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'BasicForm',
|
||||
};
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { ref, unref, reactive } from 'vue';
|
||||
import { useMessage, FormRules } from 'naive-ui';
|
||||
import { BasicUpload } from '@/components/Upload';
|
||||
import { useGlobSetting } from '@/hooks/setting';
|
||||
|
||||
const globSetting = useGlobSetting();
|
||||
|
||||
const matterList = [
|
||||
{
|
||||
label: '种牙',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '补牙',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '根管',
|
||||
value: 3,
|
||||
},
|
||||
];
|
||||
|
||||
const doctorList = [
|
||||
{
|
||||
label: '李医生',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '黄医生',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '张医生',
|
||||
value: 3,
|
||||
},
|
||||
];
|
||||
|
||||
const rules: FormRules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: '请输入预约姓名',
|
||||
trigger: 'blur',
|
||||
},
|
||||
remark: {
|
||||
required: true,
|
||||
message: '请输入预约备注',
|
||||
trigger: 'blur',
|
||||
},
|
||||
mobile: {
|
||||
required: true,
|
||||
message: '请输入预约电话号码',
|
||||
trigger: ['input'],
|
||||
},
|
||||
datetime: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择预约时间',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
doctor: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择预约医生',
|
||||
trigger: 'change',
|
||||
},
|
||||
};
|
||||
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const { uploadUrl } = globSetting;
|
||||
|
||||
const defaultValueRef = () => ({
|
||||
name: '',
|
||||
mobile: '',
|
||||
remark: '',
|
||||
sex: 1,
|
||||
matter: null,
|
||||
doctor: null,
|
||||
datetime: [],
|
||||
});
|
||||
|
||||
let formValue = reactive(defaultValueRef());
|
||||
const uploadList = ref([
|
||||
'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||||
]);
|
||||
const uploadHeaders: any = reactive({
|
||||
platform: 'miniPrograms',
|
||||
timestamp: new Date().getTime(),
|
||||
token: 'Q6fFCuhc1vkKn5JNFWaCLf6gRAc5n0LQHd08dSnG4qo=',
|
||||
});
|
||||
|
||||
function formSubmit() {
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
message.success('验证成功');
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
formRef.value.restoreValidation();
|
||||
formValue = Object.assign(unref(formValue), defaultValueRef());
|
||||
}
|
||||
|
||||
function uploadChange(list: string[]) {
|
||||
console.log(list);
|
||||
}
|
||||
</script>
|
@ -1,124 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="表单详情">
|
||||
表单除了提交数据,有时也用于显示只读信息。
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="基本信息"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-descriptions label-placement="left" class="py-2">
|
||||
<n-descriptions-item>
|
||||
<template #label>收款人姓名</template>
|
||||
啊俊
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="收款账户">NaiveUiAdmin@qq.com</n-descriptions-item>
|
||||
<n-descriptions-item label="付款类型">支付宝</n-descriptions-item>
|
||||
<n-descriptions-item label="付款账户">NaiveUiAdmin@163.com</n-descriptions-item>
|
||||
<n-descriptions-item label="转账金额">¥1980.00</n-descriptions-item>
|
||||
<n-descriptions-item label="状态">
|
||||
<n-tag type="success"> 已到账</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-card>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="其它信息"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-descriptions label-placement="left" class="py-2">
|
||||
<n-descriptions-item>
|
||||
<template #label>城市</template>
|
||||
深圳
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="性别">男</n-descriptions-item>
|
||||
<n-descriptions-item label="邮箱">NaiveUiAdmin@qq.com</n-descriptions-item>
|
||||
<n-descriptions-item label="地址">广东省深圳市南山区</n-descriptions-item>
|
||||
<n-descriptions-item label="生日">1991-06-04</n-descriptions-item>
|
||||
<n-descriptions-item label="认证">
|
||||
<n-tag type="success"> 已认证</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
</n-card>
|
||||
<n-card
|
||||
:bordered="false"
|
||||
title="表格信息"
|
||||
class="mt-3 proCard"
|
||||
size="small"
|
||||
:segmented="{ content: true }"
|
||||
>
|
||||
<n-table :bordered="false" :single-line="false">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>姓名</th>
|
||||
<th>性别</th>
|
||||
<th>城市</th>
|
||||
<th>生日</th>
|
||||
<th width="150">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Ah jung</td>
|
||||
<td>男</td>
|
||||
<td>深圳</td>
|
||||
<td>1993-11-09</td>
|
||||
<td>
|
||||
<n-space>
|
||||
<n-button size="small" type="error">删除</n-button>
|
||||
<n-button size="small" type="info">查看</n-button>
|
||||
</n-space>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>西门飞雪</td>
|
||||
<td>男</td>
|
||||
<td>广州</td>
|
||||
<td>1991-09-11</td>
|
||||
<td>
|
||||
<n-space>
|
||||
<n-button size="small" type="error">删除</n-button>
|
||||
<n-button size="small" type="info">查看</n-button>
|
||||
</n-space>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>泰坦巨人</td>
|
||||
<td>男</td>
|
||||
<td>北京</td>
|
||||
<td>1990-11-03</td>
|
||||
<td>
|
||||
<n-space>
|
||||
<n-button size="small" type="error">删除</n-button>
|
||||
<n-button size="small" type="info">查看</n-button>
|
||||
</n-space>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>猎魔人</td>
|
||||
<td>女</td>
|
||||
<td>上海</td>
|
||||
<td>1992-03-11</td>
|
||||
<td>
|
||||
<n-space>
|
||||
<n-button size="small" type="error">删除</n-button>
|
||||
<n-button size="small" type="info">查看</n-button>
|
||||
</n-space>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</n-table>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,122 +0,0 @@
|
||||
<template>
|
||||
<n-form
|
||||
ref="form1Ref"
|
||||
:label-width="90"
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
style="max-width: 500px; margin: 40px auto 0 80px"
|
||||
>
|
||||
<n-form-item label="付款账户" path="myAccount">
|
||||
<n-select
|
||||
v-model:value="formValue.myAccount"
|
||||
:options="myAccountList"
|
||||
placeholder="请选择付款账户"
|
||||
/>
|
||||
</n-form-item>
|
||||
<n-form-item label="收款账户" path="account">
|
||||
<n-input-group>
|
||||
<n-select
|
||||
v-model:value="formValue.accountType"
|
||||
:options="accountTypeList"
|
||||
:style="{ width: '20%' }"
|
||||
placeholder="请选择"
|
||||
/>
|
||||
<n-input
|
||||
v-model:value="formValue.account"
|
||||
:style="{ width: '80%' }"
|
||||
placeholder="请输入收款账户"
|
||||
/>
|
||||
</n-input-group>
|
||||
</n-form-item>
|
||||
<n-form-item label="收款人姓名" path="name">
|
||||
<n-input v-model:value="formValue.name" placeholder="请输入收款人姓名" />
|
||||
</n-form-item>
|
||||
<n-form-item label="转账金额" path="money">
|
||||
<n-input v-model:value="formValue.money" placeholder="请输入转账金额">
|
||||
<template #prefix>
|
||||
<span class="text-gray-400">¥</span>
|
||||
</template>
|
||||
</n-input>
|
||||
</n-form-item>
|
||||
<div style="margin-left: 80px">
|
||||
<n-space>
|
||||
<n-button type="primary" @click="formSubmit">下一步</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { FormRules, useMessage } from 'naive-ui';
|
||||
|
||||
const myAccountList = [
|
||||
{
|
||||
label: 'NaiveUiAdmin@163.com',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: 'NaiveUiAdmin@qq.com',
|
||||
value: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const accountTypeList = [
|
||||
{
|
||||
label: '微信',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '支付宝',
|
||||
value: 2,
|
||||
},
|
||||
];
|
||||
|
||||
const emit = defineEmits(['nextStep']);
|
||||
|
||||
const form1Ref: any = ref(null);
|
||||
const message = useMessage();
|
||||
|
||||
const formValue = ref({
|
||||
accountType: 1,
|
||||
myAccount: null,
|
||||
account: 'xioama@qq.com',
|
||||
money: '1980',
|
||||
name: 'Ah jung',
|
||||
});
|
||||
|
||||
const rules: FormRules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: '请输入收款人姓名',
|
||||
trigger: 'blur',
|
||||
},
|
||||
account: {
|
||||
required: true,
|
||||
message: '请输入收款账户',
|
||||
trigger: 'blur',
|
||||
},
|
||||
money: {
|
||||
required: true,
|
||||
message: '请输入转账金额',
|
||||
trigger: 'blur',
|
||||
},
|
||||
myAccount: {
|
||||
required: true,
|
||||
type: 'number',
|
||||
message: '请选择付款账户',
|
||||
trigger: 'change',
|
||||
},
|
||||
};
|
||||
|
||||
function formSubmit() {
|
||||
form1Ref.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
emit('nextStep');
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
@ -1,73 +0,0 @@
|
||||
<template>
|
||||
<n-form
|
||||
ref="form2Ref"
|
||||
:label-width="90"
|
||||
:model="formValue"
|
||||
:rules="rules"
|
||||
label-placement="left"
|
||||
style="max-width: 500px; margin: 40px auto 0 80px"
|
||||
>
|
||||
<n-form-item label="付款账户" path="myAccount">
|
||||
<span>NaiveUiAdmin@163.com</span>
|
||||
</n-form-item>
|
||||
<n-form-item label="收款账户" path="account">
|
||||
<span>NaiveUiAdmin@qq.com</span>
|
||||
</n-form-item>
|
||||
<n-form-item label="收款人姓名" path="name">
|
||||
<span>Ah jung</span>
|
||||
</n-form-item>
|
||||
<n-form-item label="转账金额" path="money">
|
||||
<span>¥1980</span>
|
||||
</n-form-item>
|
||||
<n-divider />
|
||||
<n-form-item label="支付密码" path="password">
|
||||
<n-input v-model:value="formValue.password" type="password" />
|
||||
</n-form-item>
|
||||
<div style="margin-left: 80px">
|
||||
<n-space>
|
||||
<n-button :loading="loading" type="primary" @click="formSubmit">提交</n-button>
|
||||
<n-button @click="prevStep">上一步</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useMessage } from 'naive-ui';
|
||||
|
||||
const form2Ref: any = ref(null);
|
||||
const message = useMessage();
|
||||
const loading = ref(false);
|
||||
|
||||
const formValue = ref({
|
||||
password: '086611',
|
||||
});
|
||||
|
||||
const rules = {
|
||||
password: {
|
||||
required: true,
|
||||
message: '请输入支付密码',
|
||||
trigger: 'blur',
|
||||
},
|
||||
};
|
||||
|
||||
const emit = defineEmits(['prevStep', 'nextStep']);
|
||||
|
||||
function prevStep() {
|
||||
emit('prevStep');
|
||||
}
|
||||
|
||||
function formSubmit() {
|
||||
loading.value = true;
|
||||
form2Ref.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
setTimeout(() => {
|
||||
emit('nextStep');
|
||||
}, 1500);
|
||||
} else {
|
||||
message.error('验证失败,请填写完整信息');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-result class="step-result" description="预计两小时内到账" status="success" title="操作成功">
|
||||
<template #default>
|
||||
<div class="information">
|
||||
<n-grid class="my-1" cols="2 s:2 m:3 l:3 xl:3 2xl:3" responsive="screen">
|
||||
<n-gi>付款账户:</n-gi>
|
||||
<n-gi>NaiveUiAdmin@163.com</n-gi>
|
||||
</n-grid>
|
||||
<n-grid class="my-1" cols="2 s:2 m:3 l:3 xl:3 2xl:3" responsive="screen">
|
||||
<n-gi>收款账户:</n-gi>
|
||||
<n-gi>xiaoma@qq.com</n-gi>
|
||||
</n-grid>
|
||||
<n-grid class="my-1" cols="2 s:2 m:3 l:3 xl:3 2xl:3" responsive="screen">
|
||||
<n-gi>收款人姓名:</n-gi>
|
||||
<n-gi>啊俊</n-gi>
|
||||
</n-grid>
|
||||
<n-grid class="my-1" cols="2 s:2 m:3 l:3 xl:3 2xl:3" responsive="screen">
|
||||
<n-gi>转账金额:</n-gi>
|
||||
<n-gi>¥<span class="money">1980</span> 元</n-gi>
|
||||
</n-grid>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex justify-center">
|
||||
<n-button class="mr-4" type="primary" @click="finish">再转一笔</n-button>
|
||||
<n-button @click="prevStep">查看账单</n-button>
|
||||
</div>
|
||||
</template>
|
||||
</n-result>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const emit = defineEmits(['finish', 'prevStep']);
|
||||
|
||||
function prevStep() {
|
||||
emit('prevStep');
|
||||
}
|
||||
|
||||
function finish() {
|
||||
emit('finish');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.step-result {
|
||||
max-width: 560px;
|
||||
margin: 40px auto 0;
|
||||
|
||||
:deep(.n-result-content) {
|
||||
background-color: #fafafa;
|
||||
padding: 24px 40px;
|
||||
}
|
||||
|
||||
.information {
|
||||
line-height: 22px;
|
||||
|
||||
.ant-row:not(:last-child) {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.money {
|
||||
font-family: 'Helvetica Neue', sans-serif;
|
||||
font-weight: 500;
|
||||
font-size: 20px;
|
||||
line-height: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="分步表单">
|
||||
将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。
|
||||
</n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard">
|
||||
<n-space vertical class="steps" justify="center">
|
||||
<n-steps :current="currentTab" :status="currentStatus">
|
||||
<n-step title="填写转账信息" description="确保填写正确" />
|
||||
<n-step title="确认转账信息" description="确认转账信息" />
|
||||
<n-step title="完成转账" description="恭喜您,转账成功" />
|
||||
</n-steps>
|
||||
<step1 v-if="currentTab === 1" @nextStep="nextStep" />
|
||||
<step2 v-if="currentTab === 2" @nextStep="nextStep" @prevStep="prevStep" />
|
||||
<step3 v-if="currentTab === 3" @prevStep="prevStep" @finish="finish" />
|
||||
</n-space>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import step1 from './Step1.vue';
|
||||
import step2 from './Step2.vue';
|
||||
import step3 from './Step3.vue';
|
||||
|
||||
const currentTab = ref(1);
|
||||
const currentStatus = ref('process');
|
||||
|
||||
function nextStep() {
|
||||
if (currentTab.value < 3) {
|
||||
currentTab.value += 1;
|
||||
}
|
||||
}
|
||||
|
||||
function prevStep() {
|
||||
if (currentTab.value > 1) {
|
||||
currentTab.value -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
function finish() {
|
||||
currentTab.value = 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.steps {
|
||||
max-width: 750px;
|
||||
margin: 16px auto;
|
||||
}
|
||||
</style>
|
@ -1 +0,0 @@
|
||||
<template> 项目文档 </template>
|
@ -1,62 +0,0 @@
|
||||
import { h } from 'vue';
|
||||
import { TableImg } from '@/components/TableImg';
|
||||
import { BasicColumn } from '@/components/Table';
|
||||
|
||||
export const columns: BasicColumn[] = [
|
||||
{
|
||||
type: 'selection',
|
||||
width: 60,
|
||||
},
|
||||
{
|
||||
title: 'id',
|
||||
key: 'id',
|
||||
width: 100,
|
||||
sorter: (row1, row2) => row1.id - row2.id,
|
||||
},
|
||||
{
|
||||
title: '名称',
|
||||
key: 'name',
|
||||
helpMessage: '这是一个提示,参数可以自定义',
|
||||
helpMessageProps: {
|
||||
showArrow: false,
|
||||
},
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '头像',
|
||||
key: 'avatar',
|
||||
width: 200,
|
||||
render(row) {
|
||||
return h(TableImg, {
|
||||
imgList: [row.avatar, row.avatar],
|
||||
spaceProps: {
|
||||
justify: 'space-between',
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '地址',
|
||||
key: 'address',
|
||||
auth: ['basic_list'], // 同时根据权限控制是否显示
|
||||
ifShow: (_column) => {
|
||||
return true; // 根据业务控制是否显示
|
||||
},
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
title: '开始日期',
|
||||
key: 'beginTime',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '结束日期',
|
||||
key: 'endTime',
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
key: 'date',
|
||||
width: 100,
|
||||
},
|
||||
];
|
@ -1,381 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<n-card :bordered="false" class="pt-3 mb-3 proCard">
|
||||
<BasicForm
|
||||
@register="register"
|
||||
@submit="handleSubmit"
|
||||
@reset="handleReset"
|
||||
@advanced="formAdvanced"
|
||||
>
|
||||
<template #statusSlot="{ model, field }">
|
||||
<n-input v-model:value="model[field]" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
</n-card>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="tableRef"
|
||||
:actionColumn="actionColumn"
|
||||
@checked-row-change="onCheckedRow"
|
||||
@columns-change="onColumnsChange"
|
||||
:autoScrollX="true"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<n-button type="primary" @click="addTable">
|
||||
<template #icon>
|
||||
<n-icon>
|
||||
<PlusOutlined />
|
||||
</n-icon>
|
||||
</template>
|
||||
新建
|
||||
</n-button>
|
||||
</template>
|
||||
|
||||
<template #toolbar>
|
||||
<n-button type="primary" @click="reloadTable">刷新数据</n-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
<n-modal v-model:show="showModal" :show-icon="false" preset="dialog" title="新建">
|
||||
<n-form
|
||||
:model="formParams"
|
||||
:rules="rules"
|
||||
ref="formRef"
|
||||
label-placement="left"
|
||||
:label-width="80"
|
||||
class="py-4"
|
||||
>
|
||||
<n-form-item label="名称" path="name">
|
||||
<n-input placeholder="请输入名称" v-model:value="formParams.name" />
|
||||
</n-form-item>
|
||||
<n-form-item label="地址" path="address">
|
||||
<n-input type="textarea" placeholder="请输入地址" v-model:value="formParams.address" />
|
||||
</n-form-item>
|
||||
<n-form-item label="日期" path="date">
|
||||
<n-date-picker type="datetime" placeholder="请选择日期" v-model:value="formParams.date" />
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
|
||||
<template #action>
|
||||
<n-space>
|
||||
<n-button @click="() => (showModal = false)">取消</n-button>
|
||||
<n-button type="info" :loading="formBtnLoading" @click="confirmForm">确定</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { useMessage, FormRules } from 'naive-ui';
|
||||
import { BasicTable, TableAction, BasicColumn } from '@/components/Table';
|
||||
import { BasicForm, useForm, FormSchema } from '@/components/Form/index';
|
||||
import { getTableList } from '@/api/table/list';
|
||||
import { columns } from './columns';
|
||||
import { PlusOutlined, DeleteOutlined, FormOutlined } from '@vicons/antd';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { renderIcon } from '@/utils';
|
||||
|
||||
const rules: FormRules = {
|
||||
name: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入名称',
|
||||
},
|
||||
address: {
|
||||
required: true,
|
||||
trigger: ['blur', 'input'],
|
||||
message: '请输入地址',
|
||||
},
|
||||
date: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
trigger: ['blur', 'change'],
|
||||
message: '请选择日期',
|
||||
},
|
||||
};
|
||||
|
||||
const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
labelMessage: '这是一个提示',
|
||||
component: 'NInput',
|
||||
label: '姓名',
|
||||
componentProps: {
|
||||
placeholder: '请输入姓名',
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
// rules: [{ required: true, message: '请输入姓名', trigger: ['blur'] }],
|
||||
},
|
||||
{
|
||||
field: 'mobile',
|
||||
component: 'NInputNumber',
|
||||
label: '手机',
|
||||
componentProps: {
|
||||
placeholder: '请输入手机号码',
|
||||
showButton: false,
|
||||
onInput: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'type',
|
||||
component: 'NSelect',
|
||||
label: '类型',
|
||||
componentProps: {
|
||||
placeholder: '请选择类型',
|
||||
options: [
|
||||
{
|
||||
label: '舒适性',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '经济性',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeDate',
|
||||
component: 'NDatePicker',
|
||||
label: '预约时间',
|
||||
defaultValue: 1183135260000,
|
||||
componentProps: {
|
||||
type: 'date',
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeTime',
|
||||
component: 'NTimePicker',
|
||||
label: '停留时间',
|
||||
componentProps: {
|
||||
clearable: true,
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'status',
|
||||
label: '状态',
|
||||
//插槽
|
||||
slot: 'statusSlot',
|
||||
},
|
||||
{
|
||||
field: 'makeProject',
|
||||
component: 'NCheckbox',
|
||||
label: '预约项目',
|
||||
componentProps: {
|
||||
placeholder: '请选择预约项目',
|
||||
options: [
|
||||
{
|
||||
label: '种牙',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '补牙',
|
||||
value: 2,
|
||||
},
|
||||
{
|
||||
label: '根管',
|
||||
value: 3,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'makeSource',
|
||||
component: 'NRadioGroup',
|
||||
label: '来源',
|
||||
componentProps: {
|
||||
options: [
|
||||
{
|
||||
label: '网上',
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
label: '门店',
|
||||
value: 2,
|
||||
},
|
||||
],
|
||||
onUpdateValue: (e: any) => {
|
||||
console.log(e);
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const formRef: any = ref(null);
|
||||
const message = useMessage();
|
||||
const tableRef = ref();
|
||||
|
||||
const showModal = ref(false);
|
||||
const formBtnLoading = ref(false);
|
||||
const formParams = reactive({
|
||||
name: '',
|
||||
address: '',
|
||||
date: null,
|
||||
});
|
||||
|
||||
const params = ref({
|
||||
name: '',
|
||||
id: route.params.id,
|
||||
});
|
||||
|
||||
const actionColumn: BasicColumn = reactive({
|
||||
width: 220,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'button',
|
||||
actions: [
|
||||
{
|
||||
label: '删除',
|
||||
type: 'error',
|
||||
size: 'medium',
|
||||
icon: renderIcon(DeleteOutlined),
|
||||
onPositiveClick: handleDelete.bind(null, record),
|
||||
onNegativeClick: handleNegative.bind(null, record),
|
||||
isConfirm: true,
|
||||
confirmContent: '您真的,确定要删除吗?',
|
||||
positiveText: '确定删除',
|
||||
},
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'warning',
|
||||
size: 'medium',
|
||||
icon: renderIcon(FormOutlined),
|
||||
onPositiveClick: handleEdit.bind(null, record),
|
||||
onNegativeClick: handleNegative.bind(null, record),
|
||||
isConfirm: true,
|
||||
confirmContent: '您真的,确定要编辑吗?',
|
||||
},
|
||||
],
|
||||
dropDownProps: {
|
||||
label: '更多',
|
||||
type: 'info',
|
||||
size: 'medium',
|
||||
icon: renderIcon(DeleteOutlined),
|
||||
// iconPlacement: 'left',
|
||||
},
|
||||
dropDownActions: [
|
||||
{
|
||||
label: '启用',
|
||||
size: 'medium',
|
||||
key: 'enabled',
|
||||
// 根据业务控制是否显示: 非enable状态的不显示启用按钮
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '禁用',
|
||||
key: 'disabled',
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
],
|
||||
select: (key) => {
|
||||
message.info(`您点击了,${key} 按钮`);
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const [register, {}] = useForm({
|
||||
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
|
||||
labelWidth: 80,
|
||||
schemas,
|
||||
});
|
||||
|
||||
function onColumnsChange(columns) {
|
||||
console.log('columns', columns);
|
||||
}
|
||||
|
||||
function formAdvanced(status) {
|
||||
console.log(status);
|
||||
tableRef.value.redoHeight();
|
||||
}
|
||||
|
||||
function addTable() {
|
||||
showModal.value = true;
|
||||
}
|
||||
|
||||
const loadDataTable = async (res) => {
|
||||
return await getTableList({ ...formParams, ...params.value, ...res });
|
||||
};
|
||||
|
||||
function onCheckedRow(rowKeys) {
|
||||
console.log(rowKeys.value);
|
||||
}
|
||||
|
||||
function reloadTable() {
|
||||
tableRef.value.reload();
|
||||
}
|
||||
|
||||
function confirmForm(e) {
|
||||
e.preventDefault();
|
||||
formBtnLoading.value = true;
|
||||
formRef.value.validate((errors) => {
|
||||
if (!errors) {
|
||||
message.success('新建成功');
|
||||
setTimeout(() => {
|
||||
showModal.value = false;
|
||||
reloadTable();
|
||||
});
|
||||
} else {
|
||||
message.error('请填写完整信息');
|
||||
}
|
||||
formBtnLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
function handleEdit(record: Recordable) {
|
||||
console.log('点击了编辑', record);
|
||||
router.push({ name: 'BasicInfo', params: { id: record.id } });
|
||||
}
|
||||
|
||||
function handleDelete(record: Recordable) {
|
||||
console.log('点击了删除', record);
|
||||
window['$message'].info('点击了删除');
|
||||
}
|
||||
|
||||
function handleNegative(record: Recordable) {
|
||||
console.log('点击了取消', record);
|
||||
message.info('点击了取消');
|
||||
}
|
||||
|
||||
function handleSubmit(values: Recordable) {
|
||||
console.log(values);
|
||||
params.value = Object.assign(formParams, values) as any;
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function handleReset(values: Recordable) {
|
||||
console.log(values);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="n-layout-page-header">
|
||||
<n-card :bordered="false" title="基础详情"> 基础详情,有时也用于显示只读信息。 </n-card>
|
||||
</div>
|
||||
<n-card :bordered="false" class="mt-3 proCard" size="small" :segmented="{ content: true }">
|
||||
<n-descriptions label-placement="left" class="py-2">
|
||||
<n-descriptions-item>
|
||||
<template #label>收款人姓名</template>
|
||||
啊俊
|
||||
</n-descriptions-item>
|
||||
<n-descriptions-item label="收款账户">NaiveUiAdmin@qq.com</n-descriptions-item>
|
||||
<n-descriptions-item label="付款类型">支付宝</n-descriptions-item>
|
||||
<n-descriptions-item label="付款账户">NaiveUiAdmin@163.com</n-descriptions-item>
|
||||
<n-descriptions-item label="转账金额">¥1980.00</n-descriptions-item>
|
||||
<n-descriptions-item label="状态">
|
||||
<n-tag type="success"> 已到账</n-tag>
|
||||
</n-descriptions-item>
|
||||
</n-descriptions>
|
||||
<div class="w-full">
|
||||
<n-space>
|
||||
<label>测试页面缓存</label>
|
||||
<n-input placeholder="输入点内容试试" />
|
||||
<n-button type="primary" @click="setTabsTitle">更新当前页面标题</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'BasicInfo',
|
||||
};
|
||||
</script>
|
||||
<script lang="ts" setup>
|
||||
import { useMessage } from 'naive-ui';
|
||||
import { useTabs } from '@/hooks/web/useTags';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
const route = useRoute(); // 第一步
|
||||
const useTagsHooks = useTabs();
|
||||
const message = useMessage();
|
||||
|
||||
function setTabsTitle() {
|
||||
const id = route.params && route.params.id;
|
||||
useTagsHooks.setTitle(`基础详情:id-${id}`, {
|
||||
fullPath: `/list/basic-info/${id}`,
|
||||
});
|
||||
message.success('设置成功');
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
@ -1,63 +0,0 @@
|
||||
<template>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<div class="result-box">
|
||||
<n-result status="error" title="操作失败" description="请核对并修改以下信息后,再重新提交。">
|
||||
<div class="result-box-extra">
|
||||
<p>您提交的内容有如下错误:</p>
|
||||
<p class="mt-3">
|
||||
<n-space align="center">
|
||||
<n-icon size="20" color="#f0a020">
|
||||
<InfoCircleOutlined />
|
||||
</n-icon>
|
||||
<span>认证照片不够清晰</span>
|
||||
<n-button type="info" text>立即修改</n-button>
|
||||
</n-space>
|
||||
</p>
|
||||
<p class="mt-3">
|
||||
<n-space>
|
||||
<n-icon size="20" color="#f0a020">
|
||||
<InfoCircleOutlined />
|
||||
</n-icon>
|
||||
<span>备注包含敏感字符,并且不能包含政治相关</span>
|
||||
<n-button type="info" text>立即修改</n-button>
|
||||
</n-space>
|
||||
</p>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="flex justify-center mb-4">
|
||||
<n-space align="center">
|
||||
<n-button type="info" @click="goHome">回到首页</n-button>
|
||||
<n-button>查看详情</n-button>
|
||||
<n-button>打印</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
</n-result>
|
||||
</div>
|
||||
</n-card>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
import { InfoCircleOutlined } from '@vicons/antd';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function goHome() {
|
||||
router.push('/');
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.result-box {
|
||||
width: 72%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
|
||||
&-extra {
|
||||
padding: 24px 40px;
|
||||
text-align: left;
|
||||
background: var(--n-border-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,67 +0,0 @@
|
||||
<template>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<div class="result-box">
|
||||
<n-result
|
||||
status="info"
|
||||
title="提示"
|
||||
description="本次提交,将在24小时候内自动转入对方账户,如操作失误,请及时撤回"
|
||||
>
|
||||
<div class="result-box-extra">
|
||||
<p>您提交的内容如下:</p>
|
||||
<p class="mt-3">
|
||||
<n-space align="center">
|
||||
<n-icon size="20" color="#18a058">
|
||||
<CheckCircleOutlined />
|
||||
</n-icon>
|
||||
<span>转入支付宝账户(189****5426):¥1980元</span>
|
||||
<n-button type="info" text>立即撤回</n-button>
|
||||
</n-space>
|
||||
</p>
|
||||
<p class="mt-3">
|
||||
<n-space>
|
||||
<n-icon size="20" color="#18a058">
|
||||
<CheckCircleOutlined />
|
||||
</n-icon>
|
||||
<span>转入支付宝账户(187****5426):¥2980元</span>
|
||||
<n-button type="info" text>立即撤回</n-button>
|
||||
</n-space>
|
||||
</p>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="flex justify-center mb-4">
|
||||
<n-space align="center">
|
||||
<n-button type="info" @click="goHome">回到首页</n-button>
|
||||
<n-button>查看详情</n-button>
|
||||
<n-button>全部撤回</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
</n-result>
|
||||
</div>
|
||||
</n-card>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
import { CheckCircleOutlined } from '@vicons/antd';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function goHome() {
|
||||
router.push('/');
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.result-box {
|
||||
width: 72%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
|
||||
&-extra {
|
||||
padding: 24px 40px;
|
||||
text-align: left;
|
||||
background: var(--n-border-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,48 +0,0 @@
|
||||
<template>
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<div class="result-box">
|
||||
<n-result
|
||||
status="success"
|
||||
title="操作成功"
|
||||
description="提交结果页用于反馈一系列操作任务的处理结果,如果仅是简单操作,灰色区域可以显示一些补充的信息。"
|
||||
>
|
||||
<div class="result-box-extra">
|
||||
<p>已提交申请,等待财务部门审核。</p>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="flex justify-center mb-4">
|
||||
<n-space align="center">
|
||||
<n-button type="info" @click="goHome">回到首页</n-button>
|
||||
<n-button>查看详情</n-button>
|
||||
<n-button>打印</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
</template>
|
||||
</n-result>
|
||||
</div>
|
||||
</n-card>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
function goHome() {
|
||||
router.push('/');
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.result-box {
|
||||
width: 72%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
|
||||
&-extra {
|
||||
padding: 24px 40px;
|
||||
text-align: left;
|
||||
background: var(--n-border-color);
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -80,7 +80,7 @@
|
||||
const [modalRegister, { openModal, setSubLoading }] = useModal({
|
||||
title: '分配权限',
|
||||
subBtuText: '确定',
|
||||
width: 400,
|
||||
width: 450,
|
||||
});
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user