Compare commits

...

No commits in common. "v1.2.5" and "master" have entirely different histories.

1979 changed files with 112146 additions and 70493 deletions

4
.gitattributes vendored
View File

@ -1,4 +0,0 @@
*.js linguist-language=java
*.css linguist-language=java
*.html linguist-language=java
*.btl linguist-language=java

View File

@ -0,0 +1,13 @@
### 当前使用版本、分支(必填,否则不予处理)
### 该问题是如何引起的?(确定最新版也有问题再提!!!)
### 重现步骤(如果有就写完整)
### 报错信息

55
.gitignore vendored
View File

@ -1,45 +1,34 @@
# Compiled class file
*.class
*.iml
*.idea
target/
logs/
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
*.tar.gz
*.rar
target/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
# eclipse
.settings/
.classpath
.project
logs/
# idea
.idea/
*.iml
.murphy.yml
*velocity.log*
# Eclipse #
.classpath
.project
.settings/
.DS_Store
_dockerCerts/
### STS ###
.apt_generated
.factorypath
.springBeans
node_modules/
dist/
package-lock.json
yarn.lock
rebel.xml
### IntelliJ IDEA ###
.idea
*.iws
*.ipr
*.log
tmp/
!DmJdbcDriver18.jar
!kingbase8-8.6.0.jar

351
README.md
View File

@ -1,268 +1,235 @@
<div align="center">
<p align="center">
<img src="./_web/public/logo.png" height="150" alt="logo"/>
<img src="./snowy-admin-web/public/img/logo.png" height="150" alt="logo"/>
</p>
</div>
### 框架介绍
<div align="center"><h3 align="center">xiaonuo-vue为XiaoNuo生态技术框架环境中的vue版本</h3></div>
<div align="center"><h3 align="center">前后端分离架构,开箱即用,紧随前沿技术</h3></div>
## 框架介绍
SnowySnowyAdmin是国内首个国密前后端分离快速开发平台集成国密加解密插件
软件层面完全符合等保测评要求,同时实现国产化机型、中间件、数据库适配,是您的不二之选!
技术框架与密码结合,让更多的人认识密码,使用密码;更是让前后分离“密”不可分。
采用SpringBoot+MybatisPlus+AntDesignVue+Vite 等更多优秀组件及前沿技术开发,注释丰富,代码简洁,开箱即用!
Snowy谐音“小诺”恰应小诺团队名称意思为”下雪的、纯洁的“寓意框架追求简洁至上大道至简。
<p align="center">
<p align="center">
<a href="https://gitee.com/xiaonuobase/snowy">
<img src="https://gitee.com/xiaonuobase/snowy/badge/star.svg?theme=dark" alt="Gitee star">
</a>
<a href="https://gitee.com/xiaonuobase/snowy">
<img src="https://gitee.com/xiaonuobase/snowy/badge/fork.svg?theme=dark" alt="Gitee fork">
</a>
<a href="https://www.antdv.com/docs/vue/introduce-cn/">
<img src="https://img.shields.io/badge/vue-2.x-blue.svg" alt="bootstrap">
</a>
<a href="https://www.antdv.com/docs/vue/introduce-cn/">
<img src="https://img.shields.io/badge/vue--ant--design-2.1.0-blue.svg" alt="bootstrap">
<img src="https://img.shields.io/badge/vue-3.2-blue.svg" alt="bootstrap">
</a>
<a href="http://spring.io/projects/spring-boot">
<img src="https://img.shields.io/badge/spring--boot-2.3.1-green.svg" alt="spring-boot">
<img src="https://img.shields.io/badge/vite-2.8-green.svg" alt="spring-boot">
</a>
<a href="https://www.antdv.com/docs/vue/introduce-cn/">
<img src="https://img.shields.io/badge/vue--ant--design-3.2-blue.svg" alt="bootstrap">
</a>
<a href="http://spring.io/projects/spring-boot">
<img src="https://img.shields.io/badge/spring--boot-2.5-green.svg" alt="spring-boot">
</a>
<a href="http://mp.baomidou.com">
<img src="https://img.shields.io/badge/mybatis--plus-3.3.2-blue.svg" alt="mybatis-plus">
<img src="https://img.shields.io/badge/mybatis--plus-3.5-blue.svg" alt="mybatis-plus">
</a>
<a href="./LICENSE">
<img src="https://img.shields.io/badge/license-Apache%202-red" alt="license Apache 2.0">
</a>
<a href="https://gitee.com/xiaonuobase/xiaonuo-vue">
<img src="https://gitee.com/xiaonuobase/xiaonuo-vue/badge/star.svg?theme=dark" alt="Gitee star">
</a>
<a href="https://gitee.com/xiaonuobase/xiaonuo-vue">
<img src="https://gitee.com/xiaonuobase/xiaonuo-vue/badge/fork.svg?theme=dark" alt="Gitee fork">
</a>
<a href="https://github.com/xiaonuobase/xiaonuo-vue">
<img src="https://img.shields.io/github/stars/xiaonuobase/xiaonuo-vue?style=social" alt="GitHub stars">
</a>
<a href="https://github.com/xiaonuobase/xiaonuo-vue">
<img src="https://img.shields.io/github/forks/xiaonuobase/xiaonuo-vue?style=social" alt="GitHub forks">
</a>
<a href="https://github.com/xiaonuobase/xiaonuo-vue">
<img src="https://img.shields.io/github/repo-size/xiaonuobase/xiaonuo-vue" alt="size">
<a href="https://old.murphysec.com/dr/mQ1xAybeOLMLOxH8pU" alt="OSCS Status">
<img src="https://www.oscs1024.com/platform/badge//xiaonuobase/snowy.git.svg?size=small"/>
</a>
</p>
</p>
### 快速启动
## 快速链接
您的开发电脑需要安装NodeJs最新版、npm或yarn最新版建议使用yarn、Mysql5.7、Jdk1.8、Maven3.6.3配置阿里仓库地址、开发工具推荐idea
gitee下载地址[https://gitee.com/xiaonuobase/snowy](https://gitee.com/xiaonuobase/snowy)
* 启动前端打开_web文件夹进行依赖下载运行npm install或yarn命令再运行npm run serve或 yarn run serve
* 启动后端打开application-local中配置数据库信息运行XiaoNuoApplication类即可启动
* 浏览器访问http://localhost:81 默认前端端口为81后端端口为82
github下载地址镜像[https://github.com/xiaonuobase/Snowy](https://github.com/xiaonuobase/Snowy)
### 其他版本
演示地址:[https://snowy.xiaonuo.vip](https://snowy.xiaonuo.vip)
* layui单体版本https://gitee.com/xiaonuobase/xiaonuo-layui
* vue前后分离版本https://gitee.com/xiaonuobase/xiaonuo-vue
* cloud微服务前后分离版本https://gitee.com/xiaonuobase/xiaonuo-cloud
* 我们的其他产品线同样开源如需关注最新动态可加入QQ群聊探讨[732230670](https://wpa.qq.com/msgrd?v=3&uin=732230670&_blank)
* 如果我们的产品能满足您的需求,很期待您给我们右上角点个 star
文档地址:[https://xiaonuo.vip/doc](https://xiaonuo.vip/doc)
### 在线演示
## 快速启动
* 账号密码superAdmin/123456地址https://vue.xiaonuo.vip
全栈工程师推荐idea
### 在线文档
### 前端支撑
| 插件 | 版本 | 用途 |
|--- | ----- | ----- |
| node.js | 最新版 | JavaScript运行环境 |
* https://doc.xiaonuo.vip
### 框架亮点及优势
1. 模块化架构设计,层次清晰,业务层推荐写到单独模块,框架升级不影响业务。
```
模块树
├─xiaonuo ->项目工程
│ ├─xiaonuo-base ->框架基础模块
│ ├─xiaonuo-core ->核心模块
│ ├─xiaonuo-gen ->代码生成
│ ├─xiaonuo-system ->基础业务
│ ├─xiaonuo-main ->业务开始模块
│ ├─业务 ->您的业务
```
2、独创前端字典翻译
全部字典数据储存前端store后端接口数据统一过滤器翻译
下拉框多选框等取值只需1行代码'dictData'为过滤器名称,'sex'为字典类型code返回数组字典
```
this.$options.filters['dictData']('sex')
或直接给值
{{ code | dictData }}
```
列表数据中字典翻译:('code'为字典类型唯一code'value'为待翻译的值返回name
```
{{ code | dictType(value) }}
```
3、独创的数据权限范围机制
数据范围的分配也来自于给用户单独分配的数据范围,最终决定用户有几个公司的数据范围的是,用户拥有的角色的数据范围 + 用户直接分配的数据范围
若一个用户有多个角色,系统最终判定用户有哪些数据范围是以多个角色和用户数据范围的 并集 为准。
仅通过注解就可以获取当前用户的数据范围不强制联查sql可根据业务需求极其灵活的使用
```
@DataScope
```
param类继承baseparam使用param.getDadaScope即可获取到数据权限列表
### 启动前端
```
@EqualsAndHashCode(callSuper = true)
@Data
public class SysUserParam extends BaseParam {
npm install
```
```
npm run dev
```
### 后端支撑
| 插件 | 版本 | 用途 |
| --- | ----- | ----- |
| jdk | 11 / 1.8 |java环境 |
| lombok | idea内 |代码简化插件 |
| maven | 最新版 |包管理工具 |
| redis | 最新版 | 缓存库 |
| mysql | 8.0 / 5.7 | 数据库 |
4、独创的文件预览系统
### 启动后端
开发工具内配置好maven并在代码中配置数据库即可启动
支持txt.doc.docx.ppt.pptx.xls.xlsx.pdf.png.jpg.jpeg.bmp.gif等
## 代码结构
预览速度快,兼容性好,支持常见文本格式.只需在运行环境一键安装libreoffice即可运行简单操作方便。
Snowy2.0框架对代码以插件化的模式进行分包使得包层级结构更加清晰合理同时降低了耦合度关于插件模块化开发的规范请查阅文档【SNOWY开源文档——前端手册or后端手册——开发规范】板块。
```
#libreoffice文档在线预览配置
# CentOS 下安装 libreoffice
# 安装yum -y install libreoffice
# Linux 中文字体乱码解决:
# 1、上传 C:\Windows\Fonts 下的字体到 /usr/share/fonts/windows 目录
# 2、执行命令 chmod 644 /usr/share/fonts/windows/* && fc-cache -fv
jodconverter:
local:
#暂时关闭预览,启动时会有点慢
enabled: false
#设置libreoffice主目录 linux地址如/usr/lib64/libreoffice
office-home: C:\Program Files\LibreOffice
#开启多个libreoffice进程,每个端口对应一个进程
port-numbers: 8100
#libreoffice进程重启前的最大进程数
max-tasks-per-process: 100
snowy
|-snowy-admin-web == 前端
|-public == 基础静态文件
|-src == 前端源代码
|-api == API接口转发
|-assets == 静态文件
|-components == VUE组件
|-config == 基础配置
|-layout == 基础布局
|-locales == 多语言配置
|-router == 基础路由配置
|-store == Pinia缓存配置
|-style == 样式风格配置
|-utils == 工具类
|-views == 所有视图界面
|-snowy-common == 基础通用模块
|-snowy-plugin == 插件包
|-snowy-plugin-auth == 登录鉴权插件
|-snowy-plugin-biz == 业务功能插件
|-snowy-plugin-client == C端功能插件
|-snowy-plugin-dev == 开发工具插件
|-snowy-plugin-gen == 代码生成插件
|-snowy-plugin-mobile == 移动端管理插件
|-snowy-plugin-sys == 系统功能插件
|-snowy-plugin-api == 插件api包
|-snowy-plugin-auth-api == 登录鉴权插件api接口
|-snowy-plugin-biz-api == 业务功能插件api接口
|-snowy-plugin-client-api == C端功能插件api接口
|-snowy-plugin-dev-api == 开发工具插件api接口
|-snowy-plugin-gen == 代码生成插件api接口
|-snowy-plugin-mobile == 移动端管理插件api接口
|-snowy-plugin-sys-api == 系统功能插件api接口
|-snowy-web-app == 主启动模块
```
5、其他优势
前后端分离架构,分离开发,分离部署,前后端互不影响。
前端技术采用vue + antdvPro + axios。
## 分支说明
后端采用spring boot + mybatis-plus + hutool等开源可靠。
- master
基于spring security(jwt) + 用户UUID双重认证。
正式稳定版本,具体版本升级内容看更新标签
基于AOP实现的接口粒度的鉴权最细粒度过滤权限资源。
- dev
基于hibernate validator实现的校验框架支持自定义校验注解。
团队开发的分支(代码可能随时会推,不保证运行和使用)
提供Request-No的响应header快速定位线上异常问题。
- snowy1.8
在线用户可查,可在线踢人,同账号登录可同时在线,可单独在线(通过系统参数配置)。
1.x分支目前已停止新增功能只限于bug的维护推荐使用2x版本
支持前端 + 后端在线代码生成。
## 视频教程
文件,短信,缓存,邮件等,利用接口封装,方便拓展。
教程地址(免费开放):[https://space.bilibili.com/50101698/channel/collectiondetail?sid=739071](https://space.bilibili.com/50101698/channel/collectiondetail?sid=739071)
短信默认使用阿里云sms缓存默认使用内存缓存。
<img src="https://pan.xiaonuo.vip/?explorer/share/fileOut&shareID=8nOccuKg&path=%7BshareItemLink%3A8nOccuKg%7D%2F"/>
### 框架说明及后续补充
作者也在上班工作,所以在利用休息时间为大家创作,录制视频的目的也是为各位小伙伴提供文档跟技术交流群聊之外的上手学习资料
* 纯手研发搭建框架脚手架,在自己用的时候,也为各位小伙伴打下坚固的接私活利器。
* 后续我们会行发多个版本,将适配多个数据库环境,国产化环境,并且根据多年经验会出相关系统中用到的案例,提供给大家使用!
* 如需了解我们更多请移步官网https://xiaonuo.vip
* 当然有问题讨论的小伙伴还可以加入我们的QQ技术群[732230670](https://wpa.qq.com/msgrd?v=3&uin=732230670&_blank),一起学习讨论。
> 视频由小诺开源技术团队王同学(每天一点)进行录制
### 效果图
## 效果图:fire:
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-62d4b535dadbfa8ff343cb290d58be43ef0.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-98b3e79f8008b6319ce6394d80172ff02a3.png"/></td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=a938SjhgZ5ayRmNxjyvqNeG4piLbdyB39rdXaFyKsqCVrkmwLRyBcBc&name=/%E7%99%BB%E5%BD%95%E9%A1%B5%E9%9D%A2.png"/></td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=b5e9VS9CKAeez01eHUfUdGyzm9eRSvtPrw9AF90mt_vPImvieiU9BR0&name=/%E7%B3%BB%E7%BB%9F%E9%A6%96%E9%A1%B5.png"/></td>
</tr>
<tr>
<td><img src="https://images.gitee.com/uploads/images/2020/1208/133142_37420daa_1980003.jpeg"/></td>
<td><img src="https://images.gitee.com/uploads/images/2020/1208/133250_3749a395_1980003.jpeg"/></td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=d173c7qJ7dgrK3vN1ovs55qtuDGW6bFOdiYglAsDNCJbI1LDifNuu_E&name=/%E7%94%A8%E6%88%B7%E7%AE%A1%E7%90%86.png"/></td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=0086BVQAINW_1mFSSz3Of4gsyreG3fX-6BZqiqLb0kWSXA-6ff6dD4Y&name=/%E6%9C%8D%E5%8A%A1%E7%9B%91%E6%8E%A7.png"/></td>
</tr>
<tr>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=1b72cVKHNtArl1A7qTeaAMicO1Pcv99U9PrPn4ESfwgk1VqCRmEIVqc&name=/%E6%8E%88%E6%9D%83%E6%9D%83%E9%99%90.png"/></td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=1cc4CdKq2y5-hjuCfBLe5QiydnJMJfHWiM25mbobRsDBD7LK2Czkl3g&name=/%E6%93%8D%E4%BD%9C%E6%97%A5%E5%BF%97.png"/></td>
</tr>
<tr>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=f923EqvOkfbhNtN2pXA0Z55I5fRX4-_XWTmiGA8QBM_JJyIELv7ugLM&name=/EC%E6%95%A3%E7%82%B9%E5%9B%BE.png"/></td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=e43fxc4TEVvJCZNuBNcueFAh5Mi9CDwnc25v25krItJ0iKj1wKBnqfY&name=/%E8%8F%9C%E5%8D%95%E7%AE%A1%E7%90%86.png"/></td>
</tr>
</table>
### 详细功能
1. 主控面板、控制台页面,可进行工作台,分析页,统计等功能的展示。
2. 用户管理、对企业用户和系统管理员用户的维护,可绑定用户职务,机构,角色,数据权限等。
3. 应用管理、通过应用来控制不同维度的菜单展示。
4. 机构管理、公司组织架构维护,支持多层级结构的树形结构。
5. 职位管理、用户职务管理,职务可作为用户的一个标签,职务目前没有和权限等其他功能挂钩。
6. 菜单管理、菜单目录,菜单,和按钮的维护是权限控制的基本单位。
7. 角色管理、角色绑定菜单后,可限制相关角色的人员登录系统的功能范围。角色也可以绑定数据授权范围。
8. 字典管理、系统内各种枚举类型的维护。
9. 访问日志、用户的登录和退出日志的查看和管理。
10. 操作日志、用户的操作业务的日志的查看和管理。
11. 服务监控、服务器的运行状态Java虚拟机信息jvm等数据的查看。
12. 在线用户、当前系统在线用户的查看。
13. 数据监控、druid控制台功能可查看sql的运行信息。
14. 公告管理、系统的公告的管理。
15. 文件管理、文件的上传下载查看等操作文件可使用本地存储阿里云oss腾讯cos接入支持拓展。
16. 定时任务、定时任务的维护通过cron表达式控制任务的执行频率。
17. 系统配置、系统运行的参数的维护,参数的配置与系统运行机制息息相关。
18. 邮件发送、发送邮件功能。
19. 短信发送、短信发送功能可使用阿里云sms腾讯云sms支持拓展。
## 密码分步:fire:
### 参与贡献
| 功能 | 算法类型 |
| ---------------------- | ------------- |
| 登录 | SM2前端加密后端解密 |
| 登录登出日志 | SM2对登录登出日志做签名完整性保护存储 |
| 操作日志 | SM2对操作日志做签名完整性保护存储 |
| 用户密码 | SM3完整性保护存储登录时做完整性校验 |
| 用户手机号 | SM4cbc模式加解密使用字段脱敏 |
- 欢迎各路英雄好汉参与xiaonuo全系版本代码贡献期待您的加入
- 1. Fork 本仓库
- 2. 新建 Feat_xxx 分支
- 3. 提交代码
- 4. 新建 Pull Request
## 官方技术群
### 更新日志:
#### v1.2.5
- 1、【修复】修复用户生日更新失败的bug
- 2、【更新】优化代码pdf文件预览无需转换
- 3、【更新】MappingCache常量字段名称更正
- 4、【更新】升级验证码请求限制
QQ技术群732230670已满、685395081
#### v1.2.4
- 1、更换登录界面图片及细节调整
- 2、更新前端布局多处细节更协调
- 3、设置顶部导航栏由64px为55px及其他细节
- 4、设置菜单栏由255px为230px及其他细节
微信技术群因群达到200人以上需加微信拉群
#### v1.2.3
- 1、修复打war包出现的注入失败导致无法启动的问题
- 2、升级多个插件版本为最新
<table>
<tr>
<td>微信群</td>
<td><img src="https://pan.xiaonuo.vip/?explorer/share/fileOut&shareID=7qwFVcdA&path=%7BshareItemLink%3A7qwFVcdA%7D%2F" width="120"/></td>
</tr>
</table>
#### v1.2.2
- 1、界面列表组件新增快捷操作刷新、列设置、密度、全屏功能实时响应
- 2、列表组件新增slot列表头按钮放入插槽界面更协调
- 3、功能列表代码统一调整规范
## 代码贡献
#### v1.2.1
- 1、集成 AJ-Captcha 验证码功能
- 2、调整日志统一打印格式
- 3、修复代码生成详情实现类主键问题
近期有很多热心开源的小伙伴陆续为咱们Snowy框架提交PR或者提出好的建议基本合格的PR我们都接受这样您的头像就列入到咱们Snowy仓库的贡献者列表啦
#### v1.2.0
- 1、适配Oracle数据库
- 2、日志列表增加时间段查询
- 3、修正邮箱数据问题
如何贡献:
#### v1.1.1
- 1、代码生成中查询条件增加为全部字段可根据不同程序删减代码
1、fork一份代码至自己的账号下本地修改您要提的代码提交至您fork的仓库
#### v1.1
- 1、新增代码生成器以独立的模块存在更加方便维护
- 2、修复多处细节问题
2、登录gitee后到Snowy仓库下创建Pull Requests,选择您的仓库到Snowy的dev分支提交即可
### 版权说明
因为dev分支是团队开发分支并不是统一发版本的测试过的所以我们建议提代码至dev即可
- xiaonuo生态技术框架全系版本采用 Apache License2.0协议
- 代码可用于个人项目等接私活或企业项目脚手架使用xiaonuo全系开源版完全免费
- 二次开发请不要删除和修改根目录下的LICENSE文件及代码头部作者声明。
- 请不要删除和修改xiaonuo源码头部的版权声明及出处。
## 团队成员
### XiaoNuo技术团队荣誉作品
| 成员 | 技术 | 昵称 |
| :---: | :---: | :---: |
| 俞宝山 | 全栈 | 俞宝山 |
| 徐玉祥 | 全栈 | 就是那个锅 |
| 董夏雨 | 全栈 | 阿董 |
| 王鹏 | 全栈 | 每天一点 |
| 成员组成 | 负责内容 |
| :---: | :---: |
| 俞宝山 | 全栈 |
| 徐玉祥 | 全栈 |
| 董夏雨 | 全栈 |
## 曾获荣誉
<p align="center">
<img src="https://pan.xiaonuo.vip/?explorer/share/file&hash=ec54DtG4v8DfcUEPF0ACAHWW-urCcymI_0fSSaqMmMXKLsTWdHpQqH0e&name=/%E8%8D%A3%E8%AA%892021%E4%B8%8E2022.jpg"/>
</p>
## 版权说明
- Snowy生态技术框架全系版本采用 Apache License2.0协议
- 代码可用于个人项目等接私活或企业项目脚手架使用Snowy全系开源版完全免费
- 二次开发如用于开源竞品请先联系群主沟通,未经审核视为侵权
- 请不要删除和修改Snowy源码头部的版权与作者声明及出处

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
> 1%
last 2 versions
not ie <= 10

View File

@ -1,39 +0,0 @@
[*]
charset=utf-8
end_of_line=lf
insert_final_newline=false
indent_style=space
indent_size=2
[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}]
indent_style=space
indent_size=2
[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}]
indent_style=space
indent_size=2
[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}]
indent_style=space
indent_size=2
[*.svg]
indent_style=space
indent_size=2
[*.js.map]
indent_style=space
indent_size=2
[*.less]
indent_style=space
indent_size=2
[*.vue]
indent_style=space
indent_size=2
[{.analysis_options,*.yml,*.yaml}]
indent_style=space
indent_size=2

View File

@ -1,3 +0,0 @@
NODE_ENV=production
VUE_APP_PREVIEW=true
VUE_APP_API_BASE_URL=http://localhost:82

View File

@ -1,3 +0,0 @@
NODE_ENV=development
VUE_APP_PREVIEW=true
VUE_APP_API_BASE_URL=http://localhost:82

View File

@ -1,3 +0,0 @@
NODE_ENV=production
VUE_APP_PREVIEW=false
VUE_APP_API_BASE_URL=http://localhost:82

View File

@ -1,77 +0,0 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/strongly-recommended',
'@vue/standard'
],
rules: {
'no-console': 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'generator-star-spacing': 'off',
'no-mixed-operators': 0,
'vue/max-attributes-per-line': [
2,
{
'singleline': 5,
'multiline': {
'max': 1,
'allowFirstLine': false
}
}
],
'vue/attribute-hyphenation': 0,
'vue/html-self-closing': 0,
'vue/component-name-in-template-casing': 0,
'vue/html-closing-bracket-spacing': 0,
'vue/singleline-html-element-content-newline': 0,
'vue/no-unused-components': 0,
'vue/multiline-html-element-content-newline': 0,
'vue/no-use-v-if-with-v-for': 0,
'vue/html-closing-bracket-newline': 0,
'vue/no-parsing-error': 0,
'no-tabs': 0,
'quotes': [
2,
'single',
{
'avoidEscape': true,
'allowTemplateLiterals': true
}
],
'semi': [
2,
'never',
{
'beforeStatementContinuationChars': 'never'
}
],
'no-delete-var': 2,
'prefer-const': [
2,
{
'ignoreReadBeforeAssign': false
}
],
'template-curly-spacing': 'off',
'indent': 'off',
"space-before-function-paren": 0,
'no-multi-spaces': 2, //不能用多余的空格
},
parserOptions: {
parser: 'babel-eslint'
},
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)'
],
env: {
jest: true
}
}
]
}

3
_web/.gitignore vendored
View File

@ -1,3 +0,0 @@
node_modules/
dist/
.idea/

View File

@ -1,5 +0,0 @@
{
"printWidth": 120,
"semi": false,
"singleQuote": true
}

View File

@ -1,7 +0,0 @@
language: node_js
node_js:
- 10.15.0
cache: yarn
script:
- yarn
- yarn run lint --no-fix && yarn run build

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2018 Anan Yang
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,28 +0,0 @@
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV)
const plugins = []
if (IS_PROD) {
plugins.push('transform-remove-console')
}
// lazy load ant-design-vue
// if your use import on Demand, Use this code
plugins.push(['import', {
'libraryName': 'ant-design-vue',
'libraryDirectory': 'es',
'style': true // `style: true` 会加载 less 文件
}])
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
[
'@babel/preset-env',
{
'useBuiltIns': 'entry',
'corejs': 3
}
]
],
plugins
}

View File

@ -1,46 +0,0 @@
const ThemeColorReplacer = require('webpack-theme-color-replacer')
const generate = require('@ant-design/colors/lib/generate').default
const getAntdSerials = (color) => {
// 淡化即less的tint
const lightens = new Array(9).fill().map((t, i) => {
return ThemeColorReplacer.varyColor.lighten(color, i / 10)
})
const colorPalettes = generate(color)
const rgb = ThemeColorReplacer.varyColor.toNum3(color.replace('#', '')).join(',')
return lightens.concat(colorPalettes).concat(rgb)
}
const themePluginOption = {
fileName: 'css/theme-colors-[contenthash:8].css',
matchColors: getAntdSerials('#1890ff'), // 主色系列
// 改变样式选择器,解决样式覆盖问题
changeSelector (selector) {
switch (selector) {
case '.ant-calendar-today .ant-calendar-date':
return ':not(.ant-calendar-selected-date):not(.ant-calendar-selected-day)' + selector
case '.ant-btn:focus,.ant-btn:hover':
return '.ant-btn:focus:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:hover:not(.ant-btn-primary):not(.ant-btn-danger)'
case '.ant-btn.active,.ant-btn:active':
return '.ant-btn.active:not(.ant-btn-primary):not(.ant-btn-danger),.ant-btn:active:not(.ant-btn-primary):not(.ant-btn-danger)'
case '.ant-steps-item-process .ant-steps-item-icon > .ant-steps-icon':
case '.ant-steps-item-process .ant-steps-item-icon>.ant-steps-icon':
return ':not(.ant-steps-item-process)' + selector
case '.ant-menu-horizontal>.ant-menu-item-active,.ant-menu-horizontal>.ant-menu-item-open,.ant-menu-horizontal>.ant-menu-item-selected,.ant-menu-horizontal>.ant-menu-item:hover,.ant-menu-horizontal>.ant-menu-submenu-active,.ant-menu-horizontal>.ant-menu-submenu-open,.ant-menu-horizontal>.ant-menu-submenu-selected,.ant-menu-horizontal>.ant-menu-submenu:hover':
case '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal > .ant-menu-submenu-selected,.ant-menu-horizontal > .ant-menu-submenu:hover':
return '.ant-menu-horizontal > .ant-menu-item-active,.ant-menu-horizontal > .ant-menu-item-open,.ant-menu-horizontal > .ant-menu-item-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-item:hover,.ant-menu-horizontal > .ant-menu-submenu-active,.ant-menu-horizontal > .ant-menu-submenu-open,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu-selected,.ant-menu-horizontal:not(.ant-menu-dark) > .ant-menu-submenu:hover'
case '.ant-menu-horizontal > .ant-menu-item-selected > a':
case '.ant-menu-horizontal>.ant-menu-item-selected>a':
return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item-selected > a'
case '.ant-menu-horizontal > .ant-menu-item > a:hover':
case '.ant-menu-horizontal>.ant-menu-item>a:hover':
return '.ant-menu-horizontal:not(ant-menu-light):not(.ant-menu-dark) > .ant-menu-item > a:hover'
default :
return selector
}
}
}
const createThemeColorReplacerPlugin = () => new ThemeColorReplacer(themePluginOption)
module.exports = createThemeColorReplacerPlugin

View File

@ -1,23 +0,0 @@
module.exports = {
moduleFileExtensions: [
'js',
'jsx',
'json',
'vue'
],
transform: {
'^.+\\.vue$': 'vue-jest',
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
'^.+\\.jsx?$': 'babel-jest'
},
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1'
},
snapshotSerializers: [
'jest-serializer-vue'
],
testMatch: [
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
],
testURL: 'http://localhost/'
}

View File

@ -1,86 +0,0 @@
{
"name": "vue-antd-pro",
"version": "2.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"build:preview": "vue-cli-service build --mode preview",
"postinstall": "opencollective-postinstall"
},
"dependencies": {
"@antv/data-set": "^0.10.2",
"ant-design-vue": "1.5.0-rc.6",
"axios": "^0.19.0",
"babel-polyfill": "^6.26.0",
"clipboard": "^2.0.6",
"core-js": "^3.1.2",
"crypto-js": "^4.0.0",
"default-passive-events": "^1.0.10",
"enquire.js": "^2.1.6",
"font-awesome": "^4.7.0",
"jquery": "^3.5.1",
"lodash.clonedeep": "^4.5.0",
"lodash.get": "^4.4.2",
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"mockjs2": "1.0.8",
"moment": "^2.24.0",
"nprogress": "^0.2.0",
"print-js": "^1.0.63",
"raphael": "^2.3.0",
"screenfull": "^5.1.0",
"viser-vue": "^2.4.6",
"vue": "^2.6.10",
"vue-clipboard2": "^0.2.1",
"vue-codemirror-lite": "^1.0.4",
"vue-cropper": "0.4.9",
"vue-ls": "^3.2.1",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.1.2",
"vue-svg-component-runtime": "^1.0.1",
"vuedraggable": "^2.23.2",
"vuex": "^3.1.1",
"wangeditor": "^3.1.1"
},
"devDependencies": {
"@ant-design/colors": "^3.2.1",
"@vue/cli-plugin-babel": "^4.0.4",
"@vue/cli-plugin-eslint": "^4.0.4",
"@vue/cli-plugin-router": "^4.0.4",
"@vue/cli-plugin-unit-jest": "^4.0.4",
"@vue/cli-plugin-vuex": "^4.0.4",
"@vue/cli-service": "^4.0.4",
"@vue/eslint-config-prettier": "^5.0.0",
"@vue/eslint-config-standard": "^4.0.0",
"@vue/test-utils": "^1.0.0-beta.29",
"babel-eslint": "^10.0.1",
"babel-plugin-import": "^1.13.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"eslint": "^6.8.0",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-vue": "^5.2.3",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2",
"prettier": "^1.18.2",
"vue-svg-icon-loader": "^2.1.1",
"vue-template-compiler": "^2.6.10",
"webpack-theme-color-replacer": "^1.2.17"
},
"collective": {
"type": "opencollective",
"url": "https://opencollective.com/ant-design-pro-vue"
},
"main": ".eslintrc.js",
"directories": {
"test": "tests"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}

View File

@ -1,5 +0,0 @@
module.exports = {
plugins: {
autoprefixer: {}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

View File

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>logo.png">
<title>XiaoNuo快速开发平台</title>
<style>.first-loading-wrp{display:flex;justify-content:center;align-items:center;flex-direction:column;min-height:420px;height:100%}.first-loading-wrp>h1{font-size:128px}.first-loading-wrp .loading-wrp{padding:98px;display:flex;justify-content:center;align-items:center}.dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:32px;width:32px;height:32px;box-sizing:border-box}.dot i{width:14px;height:14px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.dot i:nth-child(1){top:0;left:0}.dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style>
<!-- require cdn assets css -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but vue-antd-pro doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app">
<div class="first-loading-wrp">
<h1>XiaoNuo</h1>
<div class="loading-wrp">
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
</div>
<div style="display: flex; justify-content: center; align-items: center;">XiaoNuo快速开发平台</div>
</div>
</div>
<!-- require cdn assets js -->
<% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -1 +0,0 @@
#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}}

View File

@ -1 +0,0 @@
<div id="preloadingAnimation"><div class=lds-roller><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div class=load-tips>Loading</div></div>

View File

@ -1,5 +0,0 @@
<div class="preloading-animate">
<div class="preloading-wrapper">
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
</div>
</div>

View File

@ -1 +0,0 @@
.preloading-animate{background:#ffffff;width:100%;height:100%;position:fixed;left:0;top:0;z-index:299;}.preloading-animate .preloading-wrapper{position:absolute;width:5rem;height:5rem;left:50%;top:50%;transform:translate(-50%,-50%);}.preloading-animate .preloading-wrapper .preloading-balls{font-size:5rem;}

View File

@ -1 +0,0 @@
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,47 +0,0 @@
<template>
<a-config-provider :locale="locale">
<div id="app" class="app app1">
<router-view class="scrollbar"/>
</div>
</a-config-provider>
</template>
<script>
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import { AppDeviceEnquire } from '@/utils/mixin'
export default {
mixins: [AppDeviceEnquire],
data () {
return {
locale: zhCN
}
},
mounted () {
}
}
</script>
<style>
.app {
overflow: auto;
border : none;
}
.scrollbar {
margin: 0 auto;
}
.app1::-webkit-scrollbar {
/*滚动条整体样式*/
width : 8px; /*高宽分别对应横竖滚动条的尺寸*/
}
.app1::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 6px;
background : #aaa;
}
.app1::-webkit-scrollbar-track {
/*滚动条里面轨道*/
border-radius: 8px;
background : #FFFFFF;
}
</style>

View File

@ -1,106 +0,0 @@
/**
* 代码生成
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
import { axios } from '@/utils/request'
/**
* 查询列表
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGeneratePage (parameter) {
return axios({
url: '/codeGenerate/page',
method: 'get',
params: parameter
})
}
/**
* 增加
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateAdd (parameter) {
return axios({
url: '/codeGenerate/add',
method: 'post',
data: parameter
})
}
/**
* 编辑
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateEdit (parameter) {
return axios({
url: '/codeGenerate/edit',
method: 'post',
data: parameter
})
}
/**
* 删除
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateDelete (parameter) {
return axios({
url: '/codeGenerate/delete',
method: 'post',
data: parameter
})
}
/**
* 查询当前数据库用户下的所有表
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateInformationList (parameter) {
return axios({
url: '/codeGenerate/InformationList',
method: 'get',
params: parameter
})
}
/**
* 本地生成
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateRunLocal (parameter) {
return axios({
url: '/codeGenerate/runLocal',
method: 'post',
data: parameter
})
}
/**
* 压缩包方式下载
*
* @author yubaoshan
* @date 2020/12/23 15:00
*/
export function codeGenerateRunDown (parameter) {
return axios({
url: '/codeGenerate/runDown',
method: 'get',
params: parameter,
responseType: 'blob'
})
}

View File

@ -1 +0,0 @@
/** 您的业务接口文件全写在此文件夹下面,升级底座直接迁移代码即可 **/

View File

@ -1 +0,0 @@
/** 此文件夹下代码尽量不要动,底座升级直接覆盖替换 **/

View File

@ -1,92 +0,0 @@
/**
* 系统应用
*
* @author yubaoshan
* @date 2020年4月23日12:10:57
*/
import { axios } from '@/utils/request'
/**
* 系统应用列表
*
* @author yubaoshan
* @date 2020年7月9日15:05:01
*/
export function getAppPage (parameter) {
return axios({
url: '/sysApp/page',
method: 'get',
params: parameter
})
}
/**
* 系统应用列表
*
* @author yubaoshan
* @date 2020年7月9日15:05:01
*/
export function getAppList (parameter) {
return axios({
url: '/sysApp/list',
method: 'get',
params: parameter
})
}
/**
* 新增系统应用
*
* @author yubaoshan
* @date 2020年7月9日15:05:01
*/
export function sysAppAdd (parameter) {
return axios({
url: '/sysApp/add',
method: 'post',
data: parameter
})
}
/**
* 编辑系统应用
*
* @author yubaoshan
* @param parameter
* @returns {*}
*/
export function sysAppEdit (parameter) {
return axios({
url: '/sysApp/edit',
method: 'post',
data: parameter
})
}
/**
* 删除系统应用
*
* @author yubaoshan
* @date 2020年7月9日15:05:01
*/
export function sysAppDelete (parameter) {
return axios({
url: '/sysApp/delete',
method: 'post',
data: parameter
})
}
/**
* 设为默认应用
*
* @author yubaoshan
* @date 2020年7月9日15:05:01
*/
export function sysAppSetAsDefault (parameter) {
return axios({
url: '/sysApp/setAsDefault',
method: 'post',
data: parameter
})
}

View File

@ -1,85 +0,0 @@
import { axios } from '@/utils/request'
/**
* 分页查询配置列表
*
* @author yubaoshan
* @date 2020/5/25 01:57
*/
export function sysConfigPage (parameter) {
return axios({
url: '/sysConfig/page',
method: 'get',
params: parameter
})
}
/**
* 添加系统参数配置
*
* @author yubaoshan
* @date 2020/5/25 01:57
*/
export function sysConfigAdd (parameter) {
return axios({
url: '/sysConfig/add',
method: 'post',
data: parameter
})
}
/**
* 编辑系统参数配置
*
* @author yubaoshan
* @date 2020/5/25 01:57
*/
export function sysConfigEdit (parameter) {
return axios({
url: '/sysConfig/edit',
method: 'post',
data: parameter
})
}
/**
* 删除系统参数配置
*
* @author yubaoshan
* @date 2020/5/25 01:57
*/
export function sysConfigDelete (parameter) {
return axios({
url: '/sysConfig/delete',
method: 'post',
data: parameter
})
}
/**
* 获取字典类型下所有字典举例返回格式为[{code:"M",value:"男"},{code:"F",value:"女"}]
*
* @author yubaoshan
* @date 2020/5/25 02:06
*/
export function sysDictTypeDropDown (parameter) {
return axios({
url: '/sysDictType/dropDown',
method: 'get',
params: parameter
})
}
/**
* 获取系统的所有任务列表
*
* @author yubaoshan
* @date 2020/7/8 20:46
*/
export function sysTimersGetActionClasses (parameter) {
return axios({
url: '/sysTimers/getActionClasses',
method: 'get',
params: parameter
})
}

View File

@ -1,57 +0,0 @@
import { axios } from '@/utils/request'
/**
* 查询系统字典值
*
* @author yubaoshan
* @date 2020/5/17 02:24
*/
export function sysDictDataPage (parameter) {
return axios({
url: '/sysDictData/page',
method: 'get',
params: parameter
})
}
/**
* 添加系统字典值
*
* @author yubaoshan
* @date 2020/5/17 02:24
*/
export function sysDictDataAdd (parameter) {
return axios({
url: '/sysDictData/add',
method: 'post',
data: parameter
})
}
/**
* 编辑系统字典值
*
* @author yubaoshan
* @date 2020/5/17 02:25
*/
export function sysDictDataEdit (parameter) {
return axios({
url: '/sysDictData/edit',
method: 'post',
data: parameter
})
}
/**
* 删除系统字典值
*
* @author yubaoshan
* @date 2020/5/17 02:25
*/
export function sysDictDataDelete (parameter) {
return axios({
url: '/sysDictData/delete',
method: 'post',
data: parameter
})
}

View File

@ -1,85 +0,0 @@
import { axios } from '@/utils/request'
/**
* 分页查询系统字典类型
*
* @author yubaoshan
* @date 2020/5/17 01:46
*/
export function sysDictTypePage (parameter) {
return axios({
url: '/sysDictType/page',
method: 'get',
params: parameter
})
}
/**
* 添加系统字典类型
*
* @author yubaoshan
* @date 2020/5/17 01:46
*/
export function sysDictTypeAdd (parameter) {
return axios({
url: '/sysDictType/add',
method: 'post',
data: parameter
})
}
/**
* 编辑系统字典类型
*
* @author yubaoshan
* @date 2020/5/17 01:50
*/
export function sysDictTypeEdit (parameter) {
return axios({
url: '/sysDictType/edit',
method: 'post',
data: parameter
})
}
/**
* 删除系统字典类型
*
* @author yubaoshan
* @date 2020/5/17 01:50
*/
export function sysDictTypeDelete (parameter) {
return axios({
url: '/sysDictType/delete',
method: 'post',
data: parameter
})
}
/**
* 获取字典类型下所有字典举例返回格式为[{code:"M",value:"男"},{code:"F",value:"女"}]
*
* @author yubaoshan
* @date 2020/6/10 00:10
*/
export function sysDictTypeDropDown (parameter) {
return axios({
url: '/sysDictType/dropDown',
method: 'get',
params: parameter
})
}
/**
* 获取所有字典启动时加入缓存使用
*
* @author yubaoshan
* @date 2020/6/10 00:10
*/
export function sysDictTypeTree (parameter) {
return axios({
url: '/sysDictType/tree',
method: 'get',
params: parameter
})
}

View File

@ -1,29 +0,0 @@
import { axios } from '@/utils/request'
/**
* 发送邮件
*
* @author yubaoshan
* @date 2020/7/3 23:22
*/
export function emailSendEmail (parameter) {
return axios({
url: '/email/sendEmail',
method: 'post',
data: parameter
})
}
/**
* 发送html邮件
*
* @author yubaoshan
* @date 2020/7/3 23:23
*/
export function emailSendEmailHtml (parameter) {
return axios({
url: '/email/sendEmailHtml',
method: 'post',
data: parameter
})
}

View File

@ -1,101 +0,0 @@
import { axios } from '@/utils/request'
/**
* 分页查询文件信息表
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoPage (parameter) {
return axios({
url: '/sysFileInfo/page',
method: 'get',
params: parameter
})
}
/**
* 获取全部文件信息表
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoList (parameter) {
return axios({
url: '/sysFileInfo/list',
method: 'get',
params: parameter
})
}
/**
* 上传文件
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoUpload (parameter) {
return axios({
url: '/sysFileInfo/upload',
method: 'post',
data: parameter
})
}
/**
* 下载文件
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoDownload (parameter) {
return axios({
url: '/sysFileInfo/download',
method: 'get',
params: parameter,
responseType: 'blob'
})
}
/**
* 查看图片
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoPreview (parameter) {
return axios({
url: '/sysFileInfo/preview',
method: 'get',
params: parameter,
responseType: 'arraybuffer'
})
}
/**
* 查看详情文件信息表
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoDetail (parameter) {
return axios({
url: '/sysFileInfo/detail',
method: 'get',
params: parameter
})
}
/**
* 删除文件信息表
*
* @author yubaoshan
* @date 2020/6/30 00:20
*/
export function sysFileInfoDelete (parameter) {
return axios({
url: '/sysFileInfo/delete',
method: 'post',
data: parameter
})
}

View File

@ -1,57 +0,0 @@
import { axios } from '@/utils/request'
/**
* 查询访问日志
*
* @author yubaoshan
* @date 2020/5/19 11:57
*/
export function sysVisLogPage (parameter) {
return axios({
url: '/sysVisLog/page',
method: 'get',
params: parameter
})
}
/**
* 查询操作日志
*
* @author yubaoshan
* @date 2020/5/19 11:57
*/
export function sysOpLogPage (parameter) {
return axios({
url: '/sysOpLog/page',
method: 'get',
params: parameter
})
}
/**
* 清空访问日志
*
* @author yubaoshan
* @date 2020/6/23 23:09
*/
export function sysVisLogDelete (parameter) {
return axios({
url: '/sysVisLog/delete',
method: 'post',
data: parameter
})
}
/**
* 清空登录日志
*
* @author yubaoshan
* @date 2020/6/23 23:09
*/
export function sysOpLogDelete (parameter) {
return axios({
url: '/sysOpLog/delete',
method: 'post',
data: parameter
})
}

View File

@ -1,119 +0,0 @@
/**
* 系统应用
*
* @author yubaoshan
* @date 2020/5/26 19:06
*/
import { axios } from '@/utils/request'
/**
* 登录
*
* @author yubaoshan
* @date 2020/5/26 19:06
*/
export function login (parameter) {
return axios({
url: '/login',
method: 'post',
data: parameter
})
}
/**
* 登出
*
* @author yubaoshan
* @date 2020/5/26 19:07
*/
export function logout (parameter) {
return axios({
url: '/logout',
method: 'get',
params: parameter
})
}
/**
* 获取登录用户信息
*
* @author yubaoshan
* @date 2020/5/26 19:08
*/
export function getLoginUser (parameter) {
return axios({
url: '/getLoginUser',
method: 'get',
params: parameter
})
}
/**
* 获取租户开关
*
* @author yubaoshan
* @date 2020/9/5 1:24
*/
export function getTenantOpen (parameter) {
return axios({
url: '/getTenantOpen',
method: 'get',
params: parameter
})
}
/**
* 获取短信验证码
*
* @author yubaoshan
* @date 2020/5/26 19:29
*/
export function getSmsCaptcha (parameter) {
return axios({
url: '/getSmsCaptcha',
method: 'get',
params: parameter
})
}
/**
* 获取验证码开关
*
* @author Jax
* @date 2021/1/22 00:00
*/
export function getCaptchaOpen (parameter) {
return axios({
url: '/getCaptchaOpen',
method: 'get',
params: parameter
})
}
/**
* 获取验证图片 以及token
*
* @author Jax
* @date 2021/1/22 00:00
*/
export function reqGet(data) {
return axios({
url: '/captcha/get',
method: 'post',
data
})
}
/**
* 滑动或者点选验证
*
* @author Jax
* @date 2021/1/22 00:00
*/
export function reqCheck(data) {
return axios({
url: '/captcha/check',
method: 'post',
data
})
}

View File

@ -1,15 +0,0 @@
import { axios } from '@/utils/request'
/**
* 系统属性监控
*
* @author yubaoshan
* @date 2020/6/8 19:47
*/
export function sysMachineQuery (parameter) {
return axios({
url: '/sysMachine/query',
method: 'get',
params: parameter
})
}

View File

@ -1,114 +0,0 @@
import { axios } from '@/utils/request'
/**
* 获取菜单列表
*
* @author yubaoshan
* @param parameter
* @returns {*}
*/
export function getMenuList (parameter) {
return axios({
url: '/sysMenu/list',
method: 'get',
params: parameter
})
}
/**
* 获取系统菜单树用于新增编辑时选择上级节点
*
* @author yubaoshan
* @date 2020/4/23 12:22
*/
export function getMenuTree (parameter) {
return axios({
url: '/sysMenu/tree',
method: 'get',
params: parameter
})
}
/**
* 增加菜单
*
* @author yubaoshan
* @date 2020/4/24 23:23
*/
export function sysMenuAdd (parameter) {
return axios({
url: '/sysMenu/add',
method: 'post',
data: parameter
})
}
/**
* 增加菜单
*
* @author yubaoshan
* @date 2020/4/24 23:23
*/
export function sysMenuDelete (parameter) {
return axios({
url: '/sysMenu/delete',
method: 'post',
data: parameter
})
}
/**
* 查看菜单详情
*
* @author yubaoshan
* @date 2020/4/25 01:11
*/
export function sysMenuDetail (parameter) {
return axios({
url: '/sysMenu/detail',
method: 'post',
data: parameter
})
}
/**
* 编辑系统菜单
*
* @author yubaoshan
* @date 2020/4/25 01:11
*/
export function sysMenuEdit (parameter) {
return axios({
url: '/sysMenu/edit',
method: 'post',
data: parameter
})
}
/**
* 获取系统菜单树用于给角色授权时选择
*
* @author yubaoshan
* @date 2020/6/2 17:30
*/
export function SysMenuTreeForGrant (parameter) {
return axios({
url: '/sysMenu/treeForGrant',
method: 'get',
params: parameter
})
}
/**
* 根据系统切换菜单
*
* @author yubaoshan
* @date 2020/6/28 15:25
*/
export function sysMenuChange (parameter) {
return axios({
url: '/sysMenu/change',
method: 'post',
data: parameter
})
}

View File

@ -1,85 +0,0 @@
import { axios } from '@/utils/request'
/**
* 查询系统通知公告
*
* @author yubaoshan
* @date 2020/6/30 01:56
*/
export function sysNoticePage (parameter) {
return axios({
url: '/sysNotice/page',
method: 'get',
params: parameter
})
}
/**
* 添加系统通知公告
*
* @author yubaoshan
* @date 2020/6/30 01:56
*/
export function sysNoticeAdd (parameter) {
return axios({
url: '/sysNotice/add',
method: 'post',
data: parameter
})
}
/**
* 编辑系统通知公告
*
* @author yubaoshan
* @date 2020/6/30 01:56
*/
export function sysNoticeEdit (parameter) {
return axios({
url: '/sysNotice/edit',
method: 'post',
data: parameter
})
}
/**
* 删除系统通知公告
*
* @author yubaoshan
* @date 2020/6/30 01:56
*/
export function sysNoticeDelete (parameter) {
return axios({
url: '/sysNotice/delete',
method: 'post',
data: parameter
})
}
/**
* 通知公告详情
*
* @author yubaoshan
* @date 2020/6/30 01:56
*/
export function sysNoticeDetail (parameter) {
return axios({
url: '/sysNotice/detail',
method: 'get',
params: parameter
})
}
/**
* 修改状态
*
* @author yubaoshan
* @date 2020/7/30 02:23
*/
export function sysNoticeChangeStatus (parameter) {
return axios({
url: '/sysNotice/changeStatus',
method: 'post',
data: parameter
})
}

View File

@ -1,15 +0,0 @@
import { axios } from '@/utils/request'
/**
* 查询我收到的系统通知公告
*
* @author yubaoshan
* @date 2020/7/3 03:02
*/
export function sysNoticeReceived (parameter) {
return axios({
url: '/sysNotice/received',
method: 'get',
params: parameter
})
}

View File

@ -1,29 +0,0 @@
import { axios } from '@/utils/request'
/**
* 在线用户列表
*
* @author yubaoshan
* @date 2020/6/8 11:11
*/
export function sysOnlineUserList (parameter) {
return axios({
url: '/sysOnlineUser/list',
method: 'get',
params: parameter
})
}
/**
* 强制下线
*
* @author yubaoshan
* @date 2020/6/8 11:11
*/
export function sysOnlineUserForceExist (parameter) {
return axios({
url: '/sysOnlineUser/forceExist',
method: 'post',
data: parameter
})
}

View File

@ -1,85 +0,0 @@
import { axios } from '@/utils/request'
/**
* 获取机构树
*
* @author yubaoshan
* @date 2020/4/26 12:08
*/
export function getOrgTree (parameter) {
return axios({
url: '/sysOrg/tree',
method: 'get',
params: parameter
})
}
/**
* 获取机构列表
*
* @author yubaoshan
* @date 2020/5/11 12:59
*/
export function getOrgList (parameter) {
return axios({
url: '/sysOrg/list',
method: 'get',
params: parameter
})
}
/**
* 获取机构列表
*
* @author yubaoshan
* @date 2020/5/11 16:17
*/
export function getOrgPage (parameter) {
return axios({
url: '/sysOrg/page',
method: 'get',
params: parameter
})
}
/**
* 新增机构
*
* @author yubaoshan
* @date 2020/5/11 13:56
*/
export function sysOrgAdd (parameter) {
return axios({
url: '/sysOrg/add',
method: 'post',
data: parameter
})
}
/**
* 编辑机构
*
* @author yubaoshan
* @date 2020/5/11 13:56
*/
export function sysOrgEdit (parameter) {
return axios({
url: '/sysOrg/edit',
method: 'post',
data: parameter
})
}
/**
* 删除机构
*
* @author yubaoshan
* @date 2020/5/11 12:59
*/
export function sysOrgDelete (parameter) {
return axios({
url: '/sysOrg/delete',
method: 'post',
data: parameter
})
}

View File

@ -1,71 +0,0 @@
import { axios } from '@/utils/request'
/**
* 查询系统职位
*
* @author yubaoshan
* @date 2020/5/25 01:31
*/
export function sysPosPage (parameter) {
return axios({
url: '/sysPos/page',
method: 'get',
params: parameter
})
}
/**
* 系统职位列表
*
* @author yubaoshan
* @date 2020/6/21 23:50
*/
export function sysPosList (parameter) {
return axios({
url: '/sysPos/list',
method: 'get',
params: parameter
})
}
/**
* 添加系统职位
*
* @author yubaoshan
* @date 2020/5/25 01:31
*/
export function sysPosAdd (parameter) {
return axios({
url: '/sysPos/add',
method: 'post',
data: parameter
})
}
/**
* 编辑系统职位
*
* @author yubaoshan
* @date 2020/5/25 01:31
*/
export function sysPosEdit (parameter) {
return axios({
url: '/sysPos/edit',
method: 'post',
data: parameter
})
}
/**
* 删除系统职位
*
* @author yubaoshan
* @date 2020/5/25 01:31
*/
export function sysPosDelete (parameter) {
return axios({
url: '/sysPos/delete',
method: 'post',
data: parameter
})
}

View File

@ -1,141 +0,0 @@
import { axios } from '@/utils/request'
/**
* 获取角色列表
*
* @author yubaoshan
* @date 2020/5/6 11:44
*/
export function getRolePage (parameter) {
return axios({
url: '/sysRole/page',
method: 'get',
params: parameter
})
}
/**
* 增加角色
*
* @author yubaoshan
* @date 2020/5/6 11:44
*/
export function sysRoleAdd (parameter) {
return axios({
url: '/sysRole/add',
method: 'post',
data: parameter
})
}
/**
* 编辑角色
*
* @author yubaoshan
* @date 2020/5/6 11:44
*/
export function sysRoleEdit (parameter) {
return axios({
url: '/sysRole/edit',
method: 'post',
data: parameter
})
}
/**
* 删除角色
*
* @author yubaoshan
* @date 2020/5/6 17:51
*/
export function sysRoleDelete (parameter) {
return axios({
url: '/sysRole/delete',
method: 'post',
data: parameter
})
}
/**
* 删除角色
*
* @author yubaoshan
* @date 2020/5/7 11:28
*/
export function sysRoleDeteil (parameter) {
return axios({
url: '/sysRole/detail',
method: 'get',
params: parameter
})
}
/**
* 获取授权角色列表
*
* @author yubaoshan
* @date 2020/5/26 23:59
*/
export function sysRoleDropDown (parameter) {
return axios({
url: '/sysRole/dropDown',
method: 'get',
params: parameter
})
}
/**
* 拥有菜单
*
* @author yubaoshan
* @date 2020/6/02 19:02
*/
export function sysRoleOwnMenu (parameter) {
return axios({
url: '/sysRole/ownMenu',
method: 'get',
params: parameter
})
}
/**
* 授权菜单
*
* @author yubaoshan
* @date 2020/6/2 21:10
*/
export function sysRoleGrantMenu (parameter) {
return axios({
url: '/sysRole/grantMenu',
method: 'post',
data: parameter
})
}
/**
* 拥有数据
*
* @author yubaoshan
* @date 2020/6/02 21:40
*/
export function sysRoleOwnData (parameter) {
return axios({
url: '/sysRole/ownData',
method: 'get',
params: parameter
})
}
/**
* 授权数据
*
* @author yubaoshan
* @date 2020/6/2 21:50
*/
export function sysRoleGrantData (parameter) {
return axios({
url: '/sysRole/grantData',
method: 'post',
data: parameter
})
}

View File

@ -1,43 +0,0 @@
import { axios } from '@/utils/request'
/**
* 发送记录查询
*
* @author yubaoshan
* @date 2020/7/3 22:11
*/
export function smsPage (parameter) {
return axios({
url: '/sms/page',
method: 'get',
params: parameter
})
}
/**
* 验证短信验证码
*
* @author yubaoshan
* @date 2020/7/3 22:12
*/
export function sysSendLoginMessage (parameter) {
return axios({
url: '/sms/sendLoginMessage',
method: 'post',
data: parameter
})
}
/**
* 验证短信验证码
*
* @author yubaoshan
* @date 2020/7/3 22:12
*/
export function sysValidateMessage (parameter) {
return axios({
url: '/sms/validateMessage',
method: 'post',
data: parameter
})
}

View File

@ -1,127 +0,0 @@
import { axios } from '@/utils/request'
/**
* 分页查询定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:13
*/
export function sysTimersPage (parameter) {
return axios({
url: '/sysTimers/page',
method: 'get',
params: parameter
})
}
/**
* 获取全部定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersList (parameter) {
return axios({
url: '/sysTimers/list',
method: 'get',
params: parameter
})
}
/**
* 查看详情定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersDetail (parameter) {
return axios({
url: '/sysTimers/detail',
method: 'get',
params: parameter
})
}
/**
* 添加定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersAdd (parameter) {
return axios({
url: '/sysTimers/add',
method: 'post',
data: parameter
})
}
/**
* 删除定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersDelete (parameter) {
return axios({
url: '/sysTimers/delete',
method: 'post',
data: parameter
})
}
/**
* 编辑定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersEdit (parameter) {
return axios({
url: '/sysTimers/edit',
method: 'post',
data: parameter
})
}
/**
* 获取系统的所有任务列表
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersGetActionClasses (parameter) {
return axios({
url: '/sysTimers/getActionClasses',
method: 'post',
data: parameter
})
}
/**
* 启动定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersStart (parameter) {
return axios({
url: '/sysTimers/start',
method: 'post',
data: parameter
})
}
/**
* 停止定时任务
*
* @author yubaoshan
* @date 2020/7/3 03:23
*/
export function sysTimersStop (parameter) {
return axios({
url: '/sysTimers/stop',
method: 'post',
data: parameter
})
}

View File

@ -1,211 +0,0 @@
import { axios } from '@/utils/request'
/**
* 获取用户列表
*
* @author yubaoshan
* @date 2020/4/26 12:08
*/
export function getUserPage (parameter) {
return axios({
url: '/sysUser/page',
method: 'get',
params: parameter
})
}
/**
* 增加用户
*
* @author yubaoshan
* @date 2020/5/5 02:08
*/
export function sysUserAdd (parameter) {
return axios({
url: '/sysUser/add',
method: 'post',
data: parameter
})
}
/**
* 编辑用户
*
* @author yubaoshan
* @date 2020/5/5 02:08
*/
export function sysUserEdit (parameter) {
return axios({
url: '/sysUser/edit',
method: 'post',
data: parameter
})
}
/**
* 获取用户详情
*
* @author yubaoshan
* @date 2020/5/5 19:55
*/
export function sysUserDetail (parameter) {
return axios({
url: '/sysUser/detail',
method: 'get',
params: parameter
})
}
/**
* 删除用户
*
* @author yubaoshan
* @date 2020/5/7 19:31
*/
export function sysUserDelete (parameter) {
return axios({
url: '/sysUser/delete',
method: 'post',
data: parameter
})
}
/**
* 拥有角色
*
* @author yubaoshan
* @date 2020/6/3 11:58
*/
export function sysUserOwnRole (parameter) {
return axios({
url: '/sysUser/ownRole',
method: 'get',
params: parameter
})
}
/**
* 授权角色
*
* @author yubaoshan
* @date 2020/5/26 23:59
*/
export function sysUserGrantRole (parameter) {
return axios({
url: '/sysUser/grantRole',
method: 'post',
data: parameter
})
}
/**
* 拥有数据
*
* @author yubaoshan
* @date 2020/6/2 23:14
*/
export function sysUserOwnData (parameter) {
return axios({
url: '/sysUser/ownData',
method: 'get',
params: parameter
})
}
/**
* 授权数据
*
* @author yubaoshan
* @date 2020/6/2 23:15
*/
export function sysUserGrantData (parameter) {
return axios({
url: '/sysUser/grantData',
method: 'post',
data: parameter
})
}
/**
* 修改状态
*
* @author yubaoshan
* @date 2020/6/23 21:36
*/
export function sysUserChangeStatus (parameter) {
return axios({
url: '/sysUser/changeStatus',
method: 'post',
data: parameter
})
}
/**
* 重置密码
*
* @author yubaoshan
* @date 2020/6/23 22:04
*/
export function sysUserResetPwd (parameter) {
return axios({
url: '/sysUser/resetPwd',
method: 'post',
data: parameter
})
}
/**
* 修改密码
*
* @author yubaoshan
* @date 2020/6/25 00:25
*/
export function sysUserUpdatePwd (parameter) {
return axios({
url: '/sysUser/updatePwd',
method: 'post',
data: parameter
})
}
/**
* 用户选择器
*
* @author yubaoshan
* @date 2020/6/25 00:25
*/
export function sysUserSelector (parameter) {
return axios({
url: '/sysUser/selector',
method: 'get',
params: parameter
})
}
/**
* 修改头像
*
* @author yubaoshan
* @date 2020/9/20 2:21
*/
export function sysUserUpdateAvatar (parameter) {
return axios({
url: '/sysUser/updateAvatar',
method: 'post',
data: parameter
})
}
/**
* 更新基本信息
*
* @author yubaoshan
* @date 2020/9/20 03:12
*/
export function sysUserUpdateInfo (parameter) {
return axios({
url: '/sysUser/updateInfo',
method: 'post',
data: parameter
})
}

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1551058675966" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7872" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M85.333333 512h85.333334a340.736 340.736 0 0 1 99.712-241.621333 337.493333 337.493333 0 0 1 108.458666-72.96 346.453333 346.453333 0 0 1 261.546667-1.749334A106.154667 106.154667 0 0 0 746.666667 298.666667C805.802667 298.666667 853.333333 251.136 853.333333 192S805.802667 85.333333 746.666667 85.333333c-29.397333 0-55.978667 11.776-75.221334 30.933334-103.722667-41.514667-222.848-40.874667-325.76 2.517333a423.594667 423.594667 0 0 0-135.68 91.264 423.253333 423.253333 0 0 0-91.306666 135.637333A426.88 426.88 0 0 0 85.333333 512z m741.248 133.205333c-17.109333 40.618667-41.685333 77.141333-72.96 108.416s-67.797333 55.850667-108.458666 72.96a346.453333 346.453333 0 0 1-261.546667 1.749334A106.154667 106.154667 0 0 0 277.333333 725.333333C218.197333 725.333333 170.666667 772.864 170.666667 832S218.197333 938.666667 277.333333 938.666667c29.397333 0 55.978667-11.776 75.221334-30.933334A425.173333 425.173333 0 0 0 512 938.666667a425.941333 425.941333 0 0 0 393.258667-260.352A426.325333 426.325333 0 0 0 938.666667 512h-85.333334a341.034667 341.034667 0 0 1-26.752 133.205333z" p-id="7873"></path><path d="M512 318.378667c-106.752 0-193.621333 86.869333-193.621333 193.621333S405.248 705.621333 512 705.621333s193.621333-86.869333 193.621333-193.621333S618.752 318.378667 512 318.378667z m0 301.909333c-59.690667 0-108.288-48.597333-108.288-108.288S452.309333 403.712 512 403.712s108.288 48.597333 108.288 108.288-48.597333 108.288-108.288 108.288z" p-id="7874"></path></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,376 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="244px" height="180px" viewBox="0 0 244 180" enable-background="new 0 0 244 180" xml:space="preserve"> <image id="image0" width="244" height="180" x="0" y="0"
href="data:image/png;base64,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
zx/BE51u1AgMe7gEwwWQZ8rplbIFzPufwBVnf334+G774BD0l39NlwiriFCJsdOAf7bwKLATcMLz
R/BOpxs0AsMfJq3ATITTRHjE+VB0bljt+W8Mo62SIfA59KoQHwTYgH92jwgXANs9fwTXPH/E8J31
RmDwweQVeRI4FRImElrKwnm2wM0Y3ut03fsTXIIWNhJh0Rwhp89khP0/4Ahg9xeOHH7+sCMwNEDg
0qrlcqPF7GJD2VvAdWcvN7wZT0bQXzqG2QV1bhiF2x8fBHZ+4UiOfeFIPux0A0bgkwvnrcz7tspp
1R6e9E8DJf/4Igz/20hrHFoYL8JqhaeJWARhCrDdC0dyXacrPgIjAIDw8KxZnNrby/v6oniPwAW4
iJhLD2vICFpgJYQFAidvIvAfYF/gJy8cOTRvth+B4Qnnr4ZYy/kff8SVtgqVEKc2VIHbh7u4DQlB
L/VL5hFh9YKzwO5H2OGFozjlhSP5oNMVHoER8OGStfigdxYnzvqQpyTgvw3cAbzS6XoOBEQAIiyH
sE76MlmqmgmcDnz3xaO4udMVHYERKIM/r8fDMz/klI8/pupcNRvDpWcvxxudruNAQCpyLwPMqY4K
eo1YxN77xaNGjtIdgaEB1nLx+29zRbUXoppT80fAY52u20BBtOTRzA1spRxI/gps++JRnPniUfR2
uoIjMAKNwhUb8s6smRzz3pu8qpawpgJPdbpuAwWRxDdirJ1w5xOB77549MhRuiMwNOG6TXnsw/c4
7oP3oBL7O/71T1/75HgwdiF8V+KDxvd66WimdLpCIzACrYIVznrjdb49egyrdHV/sk7IiUSYB1h3
hJhHYLjA9Zvz8axZHPPqS9z4/js80On6DCT8P9ednZxrfdkhAAAAJXRFWHRkYXRlOmNyZWF0ZQAy
MDIwLTEyLTAxVDIwOjA2OjE3KzA4OjAwk+5owQAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMC0xMi0w
MVQyMDowNjoxNyswODowMOKz0H0AAAAgdEVYdHNvZnR3YXJlAGh0dHBzOi8vaW1hZ2VtYWdpY2su
b3JnvM8dnQAAABh0RVh0VGh1bWI6OkRvY3VtZW50OjpQYWdlcwAxp/+7LwAAABh0RVh0VGh1bWI6
OkltYWdlOjpIZWlnaHQAMTgwt0ghOAAAABd0RVh0VGh1bWI6OkltYWdlOjpXaWR0aAAyNDSNJ0Qp
AAAAGXRFWHRUaHVtYjo6TWltZXR5cGUAaW1hZ2UvcG5nP7JWTgAAABd0RVh0VGh1bWI6Ok1UaW1l
ADE2MDY4MjQzNzerTbE+AAAAE3RFWHRUaHVtYjo6U2l6ZQAyMjY0NUJCb9B/YQAAAEZ0RVh0VGh1
bWI6OlVSSQBmaWxlOi8vL2FwcC90bXAvaW1hZ2VsYy9pbWd2aWV3Ml85XzE2MDY3MjkwNjAzODUx
ODcxXzI4X1swXV5WmREAAAAASUVORK5CYII=" ></image>
</svg>

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

View File

@ -1,89 +0,0 @@
<template>
<div class="antd-pro-components-article-list-content-index-listContent">
<div class="description">
<slot>
{{ description }}
</slot>
</div>
<div class="extra">
<a-avatar :src="avatar" size="small" />
<a :href="href">{{ owner }}</a> 发布在 <a :href="href">{{ href }}</a>
<em>{{ updateAt | moment }}</em>
</div>
</div>
</template>
<script>
export default {
name: 'ArticleListContent',
props: {
prefixCls: {
type: String,
default: 'antd-pro-components-article-list-content-index-listContent'
},
description: {
type: String,
default: ''
},
owner: {
type: String,
required: true
},
avatar: {
type: String,
required: true
},
href: {
type: String,
required: true
},
updateAt: {
type: String,
required: true
}
}
}
</script>
<style lang="less" scoped>
@import '../index.less';
.antd-pro-components-article-list-content-index-listContent {
.description {
max-width: 720px;
line-height: 22px;
}
.extra {
margin-top: 16px;
color: @text-color-secondary;
line-height: 22px;
& /deep/ .ant-avatar {
position: relative;
top: 1px;
width: 20px;
height: 20px;
margin-right: 8px;
vertical-align: top;
}
& > em {
margin-left: 16px;
color: @disabled-color;
font-style: normal;
}
}
}
@media screen and (max-width: @screen-xs) {
.antd-pro-components-article-list-content-index-listContent {
.extra {
& > em {
display: block;
margin-top: 8px;
margin-left: 0;
}
}
}
}
</style>

View File

@ -1,3 +0,0 @@
import ArticleListContent from './ArticleListContent'
export default ArticleListContent

View File

@ -1,46 +0,0 @@
<template>
<tooltip v-if="tips !== ''">
<template slot="title">{{ tips }}</template>
<avatar :size="avatarSize" :src="src" />
</tooltip>
<avatar v-else :size="avatarSize" :src="src" />
</template>
<script>
import Avatar from 'ant-design-vue/es/avatar'
import Tooltip from 'ant-design-vue/es/tooltip'
export default {
name: 'AvatarItem',
components: {
Avatar,
Tooltip
},
props: {
tips: {
type: String,
default: '',
required: false
},
src: {
type: String,
default: ''
}
},
data () {
return {
size: this.$parent.size
}
},
computed: {
avatarSize () {
return this.size !== 'mini' && this.size || 20
}
},
watch: {
'$parent.size' (val) {
this.size = val
}
}
}
</script>

View File

@ -1,99 +0,0 @@
<!--
<template>
<div :class="[prefixCls]">
<ul>
<slot></slot>
<template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
<template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
<avatar-item :size="size">
<avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
</avatar-item>
</template>
</ul>
</div>
</template>
-->
<script>
import Avatar from 'ant-design-vue/es/avatar'
import AvatarItem from './Item'
import { filterEmpty } from '@/components/_util/util'
export default {
AvatarItem,
name: 'AvatarList',
components: {
Avatar,
AvatarItem
},
props: {
prefixCls: {
type: String,
default: 'ant-pro-avatar-list'
},
/**
* 头像大小 类型: largesmall mini, default
* 默认值: default
*/
size: {
type: [String, Number],
default: 'default'
},
/**
* 要显示的最大项目
*/
maxLength: {
type: Number,
default: 0
},
/**
* 多余的项目风格
*/
excessItemsStyle: {
type: Object,
default: () => {
return {
color: '#f56a00',
backgroundColor: '#fde3cf'
}
}
}
},
data () {
return {}
},
methods: {
getItems (items) {
const classString = {
[`${this.prefixCls}-item`]: true,
[`${this.size}`]: true
}
if (this.maxLength > 0) {
items = items.slice(0, this.maxLength)
items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>))
}
const itemList = items.map((item) => (
<li class={ classString }>{ item }</li>
))
return itemList
}
},
render () {
const { prefixCls, size } = this.$props
const classString = {
[`${prefixCls}`]: true,
[`${size}`]: true
}
const items = filterEmpty(this.$slots.default)
const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null
return (
<div class={ classString }>
{ itemsDom }
</div>
)
}
}
</script>

View File

@ -1,4 +0,0 @@
import AvatarList from './List'
import './index.less'
export default AvatarList

View File

@ -1,60 +0,0 @@
@import "../index";
@avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list";
@avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item";
.@{avatar-list-prefix-cls} {
display: inline-block;
ul {
list-style: none;
display: inline-block;
padding: 0;
margin: 0 0 0 8px;
font-size: 0;
}
}
.@{avatar-list-item-prefix-cls} {
display: inline-block;
font-size: @font-size-base;
margin-left: -8px;
width: @avatar-size-base;
height: @avatar-size-base;
:global {
.ant-avatar {
border: 1px solid #fff;
cursor: pointer;
}
}
&.large {
width: @avatar-size-lg;
height: @avatar-size-lg;
}
&.small {
width: @avatar-size-sm;
height: @avatar-size-sm;
}
&.mini {
width: 20px;
height: 20px;
:global {
.ant-avatar {
width: 20px;
height: 20px;
line-height: 20px;
.ant-avatar-string {
font-size: 12px;
line-height: 18px;
}
}
}
}
}

View File

@ -1,64 +0,0 @@
# AvatarList 用户头像列表
一组用户头像,常用在项目/团队成员列表。可通过设置 `size` 属性来指定头像大小。
引用方式:
```javascript
import AvatarList from '@/components/AvatarList'
const AvatarListItem = AvatarList.AvatarItem
export default {
components: {
AvatarList,
AvatarListItem
}
}
```
## 代码演示 [demo](https://pro.loacg.com/test/home)
```html
<avatar-list size="mini">
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
</avatar-list>
```
```html
<avatar-list :max-length="3">
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
</avatar-list>
```
## API
### AvatarList
| 参数 | 说明 | 类型 | 默认值 |
| ---------------- | -------- | ---------------------------------- | --------- |
| size | 头像大小 | `large``small``mini`, `default` | `default` |
| maxLength | 要显示的最大项目 | number | - |
| excessItemsStyle | 多余的项目风格 | CSSProperties | - |
### AvatarList.Item
| 参数 | 说明 | 类型 | 默认值 |
| ---- | ------ | --------- | --- |
| tips | 头像展示文案 | string | - |
| src | 头像图片连接 | string | - |

View File

@ -1,62 +0,0 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart
height="254"
:data="data"
:forceFit="true"
:padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
export default {
name: 'Bar',
props: {
title: {
type: String,
default: ''
},
data: {
type: Array,
default: () => {
return []
}
},
scale: {
type: Array,
default: () => {
return [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 22
}]
}
},
tooltip: {
type: Array,
default: () => {
return [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
}
}
},
data () {
return {
}
}
}
</script>

View File

@ -1,120 +0,0 @@
<template>
<a-card :loading="loading" :body-style="{ padding: '20px 24px 8px' }" :bordered="false">
<div class="chart-card-header">
<div class="meta">
<span class="chart-card-title">
<slot name="title">
{{ title }}
</slot>
</span>
<span class="chart-card-action">
<slot name="action"></slot>
</span>
</div>
<div class="total">
<slot name="total">
<span>{{ typeof total === 'function' && total() || total }}</span>
</slot>
</div>
</div>
<div class="chart-card-content">
<div class="content-fix">
<slot></slot>
</div>
</div>
<div class="chart-card-footer">
<div class="field">
<slot name="footer"></slot>
</div>
</div>
</a-card>
</template>
<script>
export default {
name: 'ChartCard',
props: {
title: {
type: String,
default: ''
},
total: {
type: [Function, Number, String],
required: false,
default: null
},
loading: {
type: Boolean,
default: false
}
}
}
</script>
<style lang="less" scoped>
.chart-card-header {
position: relative;
overflow: hidden;
width: 100%;
.meta {
position: relative;
overflow: hidden;
width: 100%;
color: rgba(0, 0, 0, .45);
font-size: 14px;
line-height: 22px;
}
}
.chart-card-action {
cursor: pointer;
position: absolute;
top: 0;
right: 0;
}
.chart-card-footer {
border-top: 1px solid #e8e8e8;
padding-top: 9px;
margin-top: 8px;
> * {
position: relative;
}
.field {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin: 0;
}
}
.chart-card-content {
margin-bottom: 12px;
position: relative;
height: 46px;
width: 100%;
.content-fix {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
}
}
.total {
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
white-space: nowrap;
color: #000;
margin-top: 4px;
margin-bottom: 0;
font-size: 30px;
line-height: 38px;
height: 38px;
}
</style>

View File

@ -1,67 +0,0 @@
<template>
<div>
<v-chart
:forceFit="true"
:height="height"
:width="width"
:data="data"
:scale="scale"
:padding="0">
<v-tooltip />
<v-interval
:shape="['liquid-fill-gauge']"
position="transfer*value"
color=""
:v-style="{
lineWidth: 10,
opacity: 0.75
}"
:tooltip="[
'transfer*value',
(transfer, value) => {
return {
name: transfer,
value,
};
},
]"
></v-interval>
<v-guide
v-for="(row, index) in data"
:key="index"
type="text"
:top="true"
:position="{
gender: row.transfer,
value: 45
}"
:content="row.value + '%'"
:v-style="{
fontSize: 100,
textAlign: 'center',
opacity: 0.75,
}"
/>
</v-chart>
</div>
</template>
<script>
export default {
name: 'Liquid',
props: {
height: {
type: Number,
default: 0
},
width: {
type: Number,
default: 0
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,56 +0,0 @@
<template>
<div class="antv-chart-mini">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 0, 18, 0]">
<v-tooltip />
<v-smooth-area position="x*y" />
</v-chart>
</div>
</div>
</template>
<script>
import moment from 'moment'
const data = []
const beginDay = new Date().getTime()
for (let i = 0; i < 10; i++) {
data.push({
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: Math.round(Math.random() * 10)
})
}
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 22
}]
export default {
name: 'MiniArea',
data () {
return {
data,
tooltip,
scale,
height: 100
}
}
}
</script>
<style lang="less" scoped>
@import "chart";
</style>

View File

@ -1,57 +0,0 @@
<template>
<div class="antv-chart-mini">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]">
<v-tooltip />
<v-bar position="x*y" />
</v-chart>
</div>
</div>
</template>
<script>
import moment from 'moment'
const data = []
const beginDay = new Date().getTime()
for (let i = 0; i < 10; i++) {
data.push({
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: Math.round(Math.random() * 10)
})
}
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '时间',
min: 1,
max: 30
}]
export default {
name: 'MiniBar',
data () {
return {
data,
tooltip,
scale,
height: 100
}
}
}
</script>
<style lang="less" scoped>
@import "chart";
</style>

View File

@ -1,75 +0,0 @@
<template>
<div class="chart-mini-progress">
<div class="target" :style="{ left: target + '%'}">
<span :style="{ backgroundColor: color }" />
<span :style="{ backgroundColor: color }"/>
</div>
<div class="progress-wrapper">
<div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height }"></div>
</div>
</div>
</template>
<script>
export default {
name: 'MiniProgress',
props: {
target: {
type: Number,
default: 0
},
height: {
type: String,
default: '10px'
},
color: {
type: String,
default: '#13C2C2'
},
percentage: {
type: Number,
default: 0
}
}
}
</script>
<style lang="less" scoped>
.chart-mini-progress {
padding: 5px 0;
position: relative;
width: 100%;
.target {
position: absolute;
top: 0;
bottom: 0;
span {
border-radius: 100px;
position: absolute;
top: 0;
left: 0;
height: 4px;
width: 2px;
&:last-child {
top: auto;
bottom: 0;
}
}
}
.progress-wrapper {
background-color: #f5f5f5;
position: relative;
.progress {
transition: all .4s cubic-bezier(.08,.82,.17,1) 0s;
border-radius: 1px 0 0 1px;
background-color: #1890ff;
width: 0;
height: 100%;
}
}
}
</style>

View File

@ -1,40 +0,0 @@
<template>
<div :class="prefixCls">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="100" :data="dataSource" :scale="scale" :padding="[36, 0, 18, 0]">
<v-tooltip />
<v-smooth-line position="x*y" :size="2" />
<v-smooth-area position="x*y" />
</v-chart>
</div>
</div>
</template>
<script>
export default {
name: 'MiniSmoothArea',
props: {
prefixCls: {
type: String,
default: 'ant-pro-smooth-area'
},
scale: {
type: [Object, Array],
required: true
},
dataSource: {
type: Array,
required: true
}
},
data () {
return {
height: 100
}
}
}
</script>
<style lang="less" scoped>
@import "smooth.area.less";
</style>

View File

@ -1,68 +0,0 @@
<template>
<v-chart :forceFit="true" height="400" :data="data" :padding="[20, 20, 95, 20]" :scale="scale">
<v-tooltip></v-tooltip>
<v-axis :dataKey="axis1Opts.dataKey" :line="axis1Opts.line" :tickLine="axis1Opts.tickLine" :grid="axis1Opts.grid" />
<v-axis :dataKey="axis2Opts.dataKey" :line="axis2Opts.line" :tickLine="axis2Opts.tickLine" :grid="axis2Opts.grid" />
<v-legend dataKey="user" marker="circle" :offset="30" />
<v-coord type="polar" radius="0.8" />
<v-line position="item*score" color="user" :size="2" />
<v-point position="item*score" color="user" :size="4" shape="circle" />
</v-chart>
</template>
<script>
const axis1Opts = {
dataKey: 'item',
line: null,
tickLine: null,
grid: {
lineStyle: {
lineDash: null
},
hideFirstLine: false
}
}
const axis2Opts = {
dataKey: 'score',
line: null,
tickLine: null,
grid: {
type: 'polygon',
lineStyle: {
lineDash: null
}
}
}
const scale = [
{
dataKey: 'score',
min: 0,
max: 80
}, {
dataKey: 'user',
alias: '类型'
}
]
export default {
name: 'Radar',
props: {
data: {
type: Array,
default: null
}
},
data () {
return {
axis1Opts,
axis2Opts,
scale
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,77 +0,0 @@
<template>
<div class="rank">
<h4 class="title">{{ title }}</h4>
<ul class="list">
<li :key="index" v-for="(item, index) in list">
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
<span>{{ item.name }}</span>
<span>{{ item.total }}</span>
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'RankList',
// ['title', 'list']
props: {
title: {
type: String,
default: ''
},
list: {
type: Array,
default: null
}
}
}
</script>
<style lang="less" scoped>
.rank {
padding: 0 32px 32px 72px;
.list {
margin: 25px 0 0;
padding: 0;
list-style: none;
li {
margin-top: 16px;
span {
color: rgba(0, 0, 0, .65);
font-size: 14px;
line-height: 22px;
&:first-child {
background-color: #f5f5f5;
border-radius: 20px;
display: inline-block;
font-size: 12px;
font-weight: 600;
margin-right: 24px;
height: 20px;
line-height: 20px;
width: 20px;
text-align: center;
}
&.active {
background-color: #314659;
color: #fff;
}
&:last-child {
float: right;
}
}
}
}
}
.mobile .rank {
padding: 0 32px 32px 32px;
}
</style>

View File

@ -1,113 +0,0 @@
<template>
<v-chart :width="width" :height="height" :padding="[0]" :data="data" :scale="scale">
<v-tooltip :show-title="false" />
<v-coord type="rect" direction="TL" />
<v-point position="x*y" color="category" shape="cloud" tooltip="value*category" />
</v-chart>
</template>
<script>
import { registerShape } from 'viser-vue'
const DataSet = require('@antv/data-set')
const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png'
const scale = [
{ dataKey: 'x', nice: false },
{ dataKey: 'y', nice: false }
]
registerShape('point', 'cloud', {
draw (cfg, container) {
return container.addShape('text', {
attrs: {
fillOpacity: cfg.opacity,
fontSize: cfg.origin._origin.size,
rotate: cfg.origin._origin.rotate,
text: cfg.origin._origin.text,
textAlign: 'center',
fontFamily: cfg.origin._origin.font,
fill: cfg.color,
textBaseline: 'Alphabetic',
...cfg.style,
x: cfg.x,
y: cfg.y
}
})
}
})
export default {
name: 'TagCloud',
props: {
tagList: {
type: Array,
required: true
},
height: {
type: Number,
default: 400
},
width: {
type: Number,
default: 640
}
},
data () {
return {
data: [],
scale
}
},
watch: {
tagList: function (val) {
if (val.length > 0) {
this.initTagCloud(val)
}
}
},
mounted () {
if (this.tagList.length > 0) {
this.initTagCloud(this.tagList)
}
},
methods: {
initTagCloud (dataSource) {
const { height, width } = this
const dv = new DataSet.View().source(dataSource)
const range = dv.range('value')
const min = range[0]
const max = range[1]
const imageMask = new Image()
imageMask.crossOrigin = ''
imageMask.src = imgUrl
imageMask.onload = () => {
dv.transform({
type: 'tag-cloud',
fields: ['name', 'value'],
size: [width, height],
imageMask,
font: 'Verdana',
padding: 0,
timeInterval: 5000, // max execute time
rotate () {
let random = ~~(Math.random() * 4) % 4
if (random === 2) {
random = 0
}
return random * 90 // 0, 90, 270
},
fontSize (d) {
if (d.value) {
return ((d.value - min) / (max - min)) * (32 - 8) + 8
}
return 0
}
})
this.data = dv.rows
}
}
}
}
</script>

View File

@ -1,64 +0,0 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart
height="254"
:data="data"
:scale="scale"
:forceFit="true"
:padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
title: '日期(天)',
alias: '日期(天)',
min: 2
}, {
dataKey: 'y',
title: '流量(Gb)',
alias: '流量(Gb)',
min: 1
}]
export default {
name: 'Bar',
props: {
title: {
type: String,
default: ''
}
},
data () {
return {
data: [],
scale,
tooltip
}
},
created () {
this.getMonthBar()
},
methods: {
getMonthBar () {
this.$http.get('/analysis/month-bar')
.then(res => {
this.data = res.result
})
}
}
}
</script>

View File

@ -1,82 +0,0 @@
<template>
<div class="chart-trend">
{{ term }}
<span>{{ rate }}%</span>
<span :class="['trend-icon', trend]"><a-icon :type="'caret-' + trend"/></span>
</div>
</template>
<script>
export default {
name: 'Trend',
props: {
term: {
type: String,
default: '',
required: true
},
percentage: {
type: Number,
default: null
},
type: {
type: Boolean,
default: null
},
target: {
type: Number,
default: 0
},
value: {
type: Number,
default: 0
},
fixed: {
type: Number,
default: 2
}
},
data () {
return {
trend: this.type && 'up' || 'down',
rate: this.percentage
}
},
created () {
const type = this.type === null ? this.value >= this.target : this.type
this.trend = type ? 'up' : 'down'
this.rate = (this.percentage === null ? Math.abs(this.value - this.target) * 100 / this.target : this.percentage).toFixed(this.fixed)
}
}
</script>
<style lang="less" scoped>
.chart-trend {
display: inline-block;
font-size: 14px;
line-height: 22px;
.trend-icon {
font-size: 12px;
&.up, &.down {
margin-left: 4px;
position: relative;
top: 1px;
i {
font-size: 12px;
transform: scale(.83);
}
}
&.up {
color: #f5222d;
}
&.down {
color: #52c41a;
top: -1px;
}
}
}
</style>

View File

@ -1,13 +0,0 @@
.antv-chart-mini {
position: relative;
width: 100%;
.chart-wrapper {
position: absolute;
bottom: -28px;
width: 100%;
/* margin: 0 -5px;
overflow: hidden;*/
}
}

View File

@ -1,14 +0,0 @@
@import "../index";
@smoothArea-prefix-cls: ~"@{ant-pro-prefix}-smooth-area";
.@{smoothArea-prefix-cls} {
position: relative;
width: 100%;
.chart-wrapper {
position: absolute;
bottom: -28px;
width: 100%;
}
}

View File

@ -1,102 +0,0 @@
<template>
<span>
{{ lastTime | format }}
</span>
</template>
<script>
function fixedZero (val) {
return val * 1 < 10 ? `0${val}` : val
}
export default {
name: 'CountDown',
props: {
format: {
type: Function,
default: undefined
},
target: {
type: [Date, Number],
required: true
},
onEnd: {
type: Function,
default: () => ({})
}
},
data () {
return {
dateTime: '0',
originTargetTime: 0,
lastTime: 0,
timer: 0,
interval: 1000
}
},
filters: {
format (time) {
const hours = 60 * 60 * 1000
const minutes = 60 * 1000
const h = Math.floor(time / hours)
const m = Math.floor((time - h * hours) / minutes)
const s = Math.floor((time - h * hours - m * minutes) / 1000)
return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
}
},
created () {
this.initTime()
this.tick()
},
methods: {
initTime () {
let lastTime = 0
let targetTime = 0
this.originTargetTime = this.target
try {
if (Object.prototype.toString.call(this.target) === '[object Date]') {
targetTime = this.target
} else {
targetTime = new Date(this.target).getTime()
}
} catch (e) {
throw new Error('invalid target prop')
}
lastTime = targetTime - new Date().getTime()
this.lastTime = lastTime < 0 ? 0 : lastTime
},
tick () {
const { onEnd } = this
this.timer = setTimeout(() => {
if (this.lastTime < this.interval) {
clearTimeout(this.timer)
this.lastTime = 0
if (typeof onEnd === 'function') {
onEnd()
}
} else {
this.lastTime -= this.interval
this.tick()
}
}, this.interval)
}
},
beforeUpdate () {
if (this.originTargetTime !== this.target) {
this.initTime()
}
},
beforeDestroy () {
clearTimeout(this.timer)
}
}
</script>
<style scoped>
</style>

View File

@ -1,3 +0,0 @@
import CountDown from './CountDown'
export default CountDown

View File

@ -1,34 +0,0 @@
# CountDown 倒计时
倒计时组件。
引用方式:
```javascript
import CountDown from '@/components/CountDown/CountDown'
export default {
components: {
CountDown
}
}
```
## 代码演示 [demo](https://pro.loacg.com/test/home)
```html
<count-down :target="new Date().getTime() + 3000000" :on-end="onEndHandle" />
```
## API
| 参数 | 说明 | 类型 | 默认值 |
|----------|------------------------------------------|-------------|-------|
| target | 目标时间 | Date | - |
| onEnd | 倒计时结束回调 | funtion | -|

View File

@ -1,153 +0,0 @@
<template>
<div :class="['description-list', size, layout === 'vertical' ? 'vertical': 'horizontal']">
<div v-if="title" class="title">{{ title }}</div>
<a-row>
<slot></slot>
</a-row>
</div>
</template>
<script>
import { Col } from 'ant-design-vue/es/grid/'
const Item = {
name: 'DetailListItem',
props: {
term: {
type: String,
default: '',
required: false
}
},
inject: {
col: {
type: Number
}
},
render () {
return (
<Col {...{ props: responsive[this.col] }}>
<div class="term">{this.$props.term}</div>
<div class="content">{this.$slots.default}</div>
</Col>
)
}
}
const responsive = {
1: { xs: 24 },
2: { xs: 24, sm: 12 },
3: { xs: 24, sm: 12, md: 8 },
4: { xs: 24, sm: 12, md: 6 }
}
export default {
name: 'DetailList',
Item: Item,
components: {
Col
},
props: {
title: {
type: String,
default: '',
required: false
},
col: {
type: Number,
required: false,
default: 3
},
size: {
type: String,
required: false,
default: 'large'
},
layout: {
type: String,
required: false,
default: 'horizontal'
}
},
provide () {
return {
col: this.col > 4 ? 4 : this.col
}
}
}
</script>
<style lang="less" scoped>
.description-list {
.title {
color: rgba(0,0,0,.85);
font-size: 14px;
font-weight: 500;
margin-bottom: 16px;
}
/deep/ .term {
color: rgba(0,0,0,.85);
display: table-cell;
line-height: 20px;
margin-right: 8px;
padding-bottom: 16px;
white-space: nowrap;
&:not(:empty):after {
content: ":";
margin: 0 8px 0 2px;
position: relative;
top: -.5px;
}
}
/deep/ .content {
color: rgba(0,0,0,.65);
display: table-cell;
min-height: 22px;
line-height: 22px;
padding-bottom: 16px;
width: 100%;
&:empty {
content: ' ';
height: 38px;
padding-bottom: 16px;
}
}
&.small {
.title {
font-size: 14px;
color: rgba(0, 0, 0, .65);
font-weight: normal;
margin-bottom: 12px;
}
/deep/ .term, .content {
padding-bottom: 8px;
}
}
&.large {
/deep/ .term, .content {
padding-bottom: 16px;
}
.title {
font-size: 16px;
}
}
&.vertical {
.term {
padding-bottom: 8px;
}
/deep/ .term, .content {
display: block;
}
}
}
</style>

View File

@ -1,2 +0,0 @@
import DescriptionList from './DescriptionList'
export default DescriptionList

View File

@ -1,113 +0,0 @@
import Modal from 'ant-design-vue/es/modal'
export default (Vue) => {
function dialog (component, componentProps, modalProps) {
const _vm = this
modalProps = modalProps || {}
if (!_vm || !_vm._isVue) {
return
}
let dialogDiv = document.querySelector('body>div[type=dialog]')
if (!dialogDiv) {
dialogDiv = document.createElement('div')
dialogDiv.setAttribute('type', 'dialog')
document.body.appendChild(dialogDiv)
}
const handle = function (checkFunction, afterHandel) {
if (checkFunction instanceof Function) {
const res = checkFunction()
if (res instanceof Promise) {
res.then(c => {
c && afterHandel()
})
} else {
res && afterHandel()
}
} else {
// checkFunction && afterHandel()
checkFunction || afterHandel()
}
}
const dialogInstance = new Vue({
data () {
return {
visible: true
}
},
router: _vm.$router,
store: _vm.$store,
mounted () {
this.$on('close', (v) => {
this.handleClose()
})
},
methods: {
handleClose () {
handle(this.$refs._component.onCancel, () => {
this.visible = false
this.$refs._component.$emit('close')
this.$refs._component.$emit('cancel')
dialogInstance.$destroy()
})
},
handleOk () {
handle(this.$refs._component.onOK || this.$refs._component.onOk, () => {
this.visible = false
this.$refs._component.$emit('close')
this.$refs._component.$emit('ok')
dialogInstance.$destroy()
})
}
},
render: function (h) {
const that = this
const modalModel = modalProps && modalProps.model
if (modalModel) {
delete modalProps.model
}
const ModalProps = Object.assign({}, modalModel && { model: modalModel } || {}, {
attrs: Object.assign({}, {
...(modalProps.attrs || modalProps)
}, {
visible: this.visible
}),
on: Object.assign({}, {
...(modalProps.on || modalProps)
}, {
ok: () => {
that.handleOk()
},
cancel: () => {
that.handleClose()
}
})
})
const componentModel = componentProps && componentProps.model
if (componentModel) {
delete componentProps.model
}
const ComponentProps = Object.assign({}, componentModel && { model: componentModel } || {}, {
ref: '_component',
attrs: Object.assign({}, {
...((componentProps && componentProps.attrs) || componentProps)
}),
on: Object.assign({}, {
...((componentProps && componentProps.on) || componentProps)
})
})
return h(Modal, ModalProps, [h(component, ComponentProps)])
}
}).$mount(dialogDiv)
}
Object.defineProperty(Vue.prototype, '$dialog', {
get: () => {
return function () {
dialog.apply(this, arguments)
}
}
})
}

View File

@ -1,82 +0,0 @@
<template>
<div :class="prefixCls">
<quill-editor
v-model="content"
ref="myQuillEditor"
:options="editorOption"
@blur="onEditorBlur($event)"
@focus="onEditorFocus($event)"
@ready="onEditorReady($event)"
@change="onEditorChange($event)">
</quill-editor>
</div>
</template>
<script>
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
import { quillEditor } from 'vue-quill-editor'
export default {
name: 'QuillEditor',
components: {
quillEditor
},
props: {
prefixCls: {
type: String,
default: 'ant-editor-quill'
},
//
// eslint-disable-next-line
value: {
type: String
}
},
data () {
return {
content: null,
editorOption: {
// some quill options
}
}
},
methods: {
onEditorBlur (quill) {
console.log('editor blur!', quill)
},
onEditorFocus (quill) {
console.log('editor focus!', quill)
},
onEditorReady (quill) {
console.log('editor ready!', quill)
},
onEditorChange ({ quill, html, text }) {
console.log('editor change!', quill, html, text)
this.$emit('change', html)
}
},
watch: {
value (val) {
this.content = val
}
}
}
</script>
<style lang="less" scoped>
@import url('../index.less');
/* 覆盖 quill 默认边框圆角为 ant 默认圆角,用于统一 ant 组件风格 */
.ant-editor-quill {
/deep/ .ql-toolbar.ql-snow {
border-radius: @border-radius-base @border-radius-base 0 0;
}
/deep/ .ql-container.ql-snow {
border-radius: 0 0 @border-radius-base @border-radius-base;
}
}
</style>

View File

@ -1,126 +0,0 @@
<template>
<div>
<div id="editor" ref="myEditor"></div>
<slot></slot>
</div>
</template>
<script>
import WangEditor from 'wangeditor'
export default {
name: 'ComponentWangeditor',
data () {
return {
edit: ''
}
},
props: {
value: {
type: String,
default: ''
},
config: {
type: Object,
default: () => {
return {}
}
},
uploadConfig: {
type: Object,
default: () => {
return {
method: 'http', // custom(objurl)http()base64
url: '/'
}
}
}
},
computed: {
customConfig () {
return {
pasteFilterStyle: false, //
pasteIgnoreImg: false, //
...this.config
}
}
},
watch: {
},
components: {
},
methods: {
readBlobAsDataURL (blob, callback) {
var a = new FileReader()
a.onload = function (e) { callback(e.target.result) }
a.readAsDataURL(blob)
},
initEditor () {
var self = this
this.editor = new WangEditor(this.$refs.myEditor)
// onchange
this.editor.customConfig = this.customConfig
this.editor.customConfig.uploadImgMaxLength = 5
this.editor.change = function () { //
self.$emit('input', this.txt.html())
self.$emit('onchange', this.txt.html(), this.txt)
// editor.txt.html('.....') //
// editor.txt.clear() //
// editor.txt.append('<p></p>')//
// editor.txt.text() // text
// editor.txt.getJSON() // JSON
}
this.editor.customConfig.customUploadImg = function (files, insert) {
if (self.uploadConfig.method === 'custom') {
files.forEach(file => {
var fileUrl = URL.createObjectURL(file)
insert(fileUrl)
})
}
if (self.uploadConfig.method === 'base64') {
files.forEach(file => {
self.readBlobAsDataURL(file, function (dataurl) {
insert(dataurl)
})
})
}
if (self.uploadConfig.method === 'http') {
if (self.uploadConfig.callback) {
self.uploadConfig.callback(files, insert)
} else {
var formData = new FormData()
files.forEach(file => {
formData.append('file', file)
})
self.$axios.post(self.uploadConfig.url, formData).then(({ data }) => {
if (data.status === 'success') {
insert(data.url)
}
})
}
}
}
this.editor.create() //
this.editor.txt.text(this.value) //
this.$emit('oninit', this.editor)
}
},
beforeCreate () {
},
created () {
},
beforeMount () {
},
mounted () {
this.initEditor()
}
}
</script>
<style >
.w-e-toolbar{
flex-wrap:wrap;
}
</style>

View File

@ -1,64 +0,0 @@
<script>
import Tooltip from 'ant-design-vue/es/tooltip'
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/util'
/*
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
const TooltipOverlayStyle = {
overflowWrap: 'break-word',
wordWrap: 'break-word',
};
*/
export default {
name: 'Ellipsis',
components: {
Tooltip
},
props: {
prefixCls: {
type: String,
default: 'ant-pro-ellipsis'
},
tooltip: {
type: Boolean
},
length: {
type: Number,
required: true
},
lines: {
type: Number,
default: 1
},
fullWidthRecognition: {
type: Boolean,
default: false
}
},
methods: {
getStrDom (str, fullLength) {
return (
<span>{ cutStrByFullLength(str, this.length) + (fullLength > this.length ? '...' : '') }</span>
)
},
getTooltip (fullStr, fullLength) {
return (
<Tooltip>
<template slot="title">{ fullStr }</template>
{ this.getStrDom(fullStr, fullLength) }
</Tooltip>
)
}
},
render () {
const { tooltip, length } = this.$props
const str = this.$slots.default.map(vNode => vNode.text).join('')
const fullLength = getStrFullLength(str)
const strDom = tooltip && fullLength > length ? this.getTooltip(str, fullLength) : this.getStrDom(str, fullLength)
return (
strDom
)
}
}
</script>

View File

@ -1,3 +0,0 @@
import Ellipsis from './Ellipsis'
export default Ellipsis

View File

@ -1,130 +0,0 @@
<template>
<div class="exception">
<div class="imgBlock">
<div class="imgEle" :style="{backgroundImage: `url(${config[type].img})`}">
</div>
</div>
<div class="content">
<h1>{{ config[type].title }}</h1>
<div class="desc">{{ config[type].desc }}</div>
<div class="actions">
<a-button type="primary" @click="handleToHome">返回首页</a-button>
</div>
</div>
</div>
</template>
<script>
import types from './type'
export default {
name: 'Exception',
props: {
type: {
type: String,
default: '404'
}
},
data () {
return {
config: types
}
},
methods: {
handleToHome () {
this.$router.push({ name: 'Console' })
}
}
}
</script>
<style lang="less">
@import "~ant-design-vue/lib/style/index";
.exception {
display: flex;
align-items: center;
height: 80%;
min-height: 500px;
.imgBlock {
flex: 0 0 62.5%;
width: 62.5%;
padding-right: 152px;
zoom: 1;
&::before,
&::after {
content: ' ';
display: table;
}
&::after {
clear: both;
height: 0;
font-size: 0;
visibility: hidden;
}
}
.imgEle {
float: right;
width: 100%;
max-width: 430px;
height: 360px;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: contain;
}
.content {
flex: auto;
h1 {
margin-bottom: 24px;
color: #434e59;
font-weight: 600;
font-size: 72px;
line-height: 72px;
}
.desc {
margin-bottom: 16px;
color: @text-color-secondary;
font-size: 20px;
line-height: 28px;
}
.actions {
button:not(:last-child) {
margin-right: 8px;
}
}
}
}
@media screen and (max-width: @screen-xl) {
.exception {
.imgBlock {
padding-right: 88px;
}
}
}
@media screen and (max-width: @screen-sm) {
.exception {
display: block;
text-align: center;
.imgBlock {
margin: 0 auto 24px;
padding-right: 0;
}
}
}
@media screen and (max-width: @screen-xs) {
.exception {
.imgBlock {
margin-bottom: -24px;
overflow: hidden;
}
}
}
</style>

View File

@ -1,2 +0,0 @@
import ExceptionPage from './ExceptionPage.vue'
export default ExceptionPage

View File

@ -1,19 +0,0 @@
const types = {
403: {
img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg',
title: '403',
desc: '抱歉,你无权访问该页面'
},
404: {
img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg',
title: '404',
desc: '抱歉,你访问的页面不存在或仍在开发中'
},
500: {
img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg',
title: '500',
desc: '抱歉,服务器出错了'
}
}
export default types

View File

@ -1,30 +0,0 @@
<template>
<div :class="prefixCls">
<div style="float: left">
<slot name="extra">{{ extra }}</slot>
</div>
<div style="float: right">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'FooterToolBar',
props: {
prefixCls: {
type: String,
default: 'ant-pro-footer-toolbar'
},
extra: {
type: [String, Object],
default: ''
}
}
}
</script>
<style lang="less" scoped>
</style>

View File

@ -1,4 +0,0 @@
import FooterToolBar from './FooterToolBar'
import './index.less'
export default FooterToolBar

View File

@ -1,23 +0,0 @@
@import "../index";
@footer-toolbar-prefix-cls: ~"@{ant-pro-prefix}-footer-toolbar";
.@{footer-toolbar-prefix-cls} {
position: fixed;
width: 100%;
bottom: 0;
right: 0;
height: 56px;
line-height: 56px;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03);
background: #fff;
border-top: 1px solid #e8e8e8;
padding: 0 24px;
z-index: 9;
&:after {
content: "";
display: block;
clear: both;
}
}

View File

@ -1,48 +0,0 @@
# FooterToolbar 底部工具栏
固定在底部的工具栏。
## 何时使用
固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。
引用方式:
```javascript
import FooterToolBar from '@/components/FooterToolbar'
export default {
components: {
FooterToolBar
}
}
```
## 代码演示
```html
<footer-tool-bar>
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
</footer-tool-bar>
```
```html
<footer-tool-bar extra="扩展信息提示">
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
</footer-tool-bar>
```
## API
参数 | 说明 | 类型 | 默认值
----|------|-----|------
children (slot) | 工具栏内容,向右对齐 | - | -
extra | 额外信息,向左对齐 | String, Object | -

View File

@ -1,46 +0,0 @@
<template>
<div class="footer">
<div class="links">
</div>
<div class="copyright">
Copyright © 2020 <a target="_blank" href="https://www.xiaonuo.vip/">XiaoNuo</a> All rights reserved. xiaonuo-vue 1.2.0
</div>
</div>
</template>
<script>
export default {
name: 'GlobalFooter',
data () {
return {}
}
}
</script>
<style lang="less" scoped>
.footer {
padding: 0 16px;
margin: 48px 0 24px;
text-align: center;
.links {
margin-bottom: 8px;
a {
color: rgba(0, 0, 0, 0.45);
&:hover {
color: rgba(0, 0, 0, 0.65);
}
&:not(:last-child) {
margin-right: 40px;
}
}
}
.copyright {
color: rgba(0, 0, 0, 0.45);
font-size: 14px;
}
}
</style>

View File

@ -1,2 +0,0 @@
import GlobalFooter from './GlobalFooter'
export default GlobalFooter

View File

@ -1,165 +0,0 @@
<template>
<transition name="showHeader">
<div v-if="visible" class="header-animat">
<a-layout-header
v-if="visible"
:class="[fixedHeader && 'ant-header-fixedHeader', sidebarOpened ? 'ant-header-side-opened' : 'ant-header-side-closed', ]"
:style="{ padding: '0', height: '55px' }">
<div v-if="mode === 'sidemenu'" class="header">
<a-menu
style="height: 55px"
mode="horizontal"
:default-selected-keys="this.defApp"
>
<a-icon v-if="device==='mobile'" class="trigger" :type="collapsed ? 'menu-fold' : 'menu-unfold'" @click="toggle"/>
<a-icon v-else class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggle"/>
<a-menu-item v-for="(item) in userInfo.apps" :key="item.code" style="top:0px; line-height: 55px; padding-left: 10px; padding-right: 10px" @click="switchApp(item.code)">
{{ item.name }}
</a-menu-item>
<user-menu></user-menu>
</a-menu>
</div>
<div v-else :class="['top-nav-header-index', theme]">
<div class="header-index-wide">
<div class="header-index-left">
<logo class="top-nav-header" :show-title="device !== 'mobile'"/>
<s-menu v-if="device !== 'mobile'" mode="horizontal" :menu="menus" :theme="theme" />
<a-icon v-else class="trigger" :type="collapsed ? 'menu-fold' : 'menu-unfold'" @click="toggle" />
</div>
<user-menu class="header-index-right"></user-menu>
</div>
</div>
</a-layout-header>
</div>
</transition>
</template>
<script>
import UserMenu from '../tools/UserMenu'
import SMenu from '../Menu/'
import Logo from '../tools/Logo'
import { mixin } from '@/utils/mixin'
import { mapActions, mapGetters } from 'vuex'
import { ALL_APPS_MENU } from '@/store/mutation-types'
import Vue from 'vue'
import { message } from 'ant-design-vue/es'
export default {
name: 'GlobalHeader',
components: {
UserMenu,
SMenu,
Logo
},
computed: {
...mapGetters(['userInfo'])
},
created () {
this.defApp.push(Vue.ls.get(ALL_APPS_MENU)[0].code)
},
mixins: [mixin],
props: {
mode: {
type: String,
// sidemenu, topmenu
default: 'sidemenu'
},
menus: {
type: Array,
required: true
},
theme: {
type: String,
required: false,
default: 'dark'
},
collapsed: {
type: Boolean,
required: false,
default: false
},
device: {
type: String,
required: false,
default: 'desktop'
}
},
data () {
return {
visible: true,
oldScrollTop: 0,
defApp: []
}
},
mounted () {
document.addEventListener('scroll', this.handleScroll, { passive: true })
},
methods: {
...mapActions(['MenuChange']),
/**
* 应用切换
*/
switchApp (appCode) {
this.defApp = []
const applicationData = this.userInfo.apps.filter(item => item.code === appCode)
const hideMessage = message.loading('正在切换应用!', 0)
this.MenuChange(applicationData[0]).then((res) => {
hideMessage()
// eslint-disable-next-line handle-callback-err
}).catch((err) => {
message.error('应用切换异常')
})
},
handleScroll () {
if (!this.autoHideHeader) {
return
}
const scrollTop = document.body.scrollTop + document.documentElement.scrollTop
if (!this.ticking) {
this.ticking = true
requestAnimationFrame(() => {
if (this.oldScrollTop > scrollTop) {
this.visible = true
} else if (scrollTop > 300 && this.visible) {
this.visible = false
} else if (scrollTop < 300 && !this.visible) {
this.visible = true
}
this.oldScrollTop = scrollTop
this.ticking = false
})
}
},
toggle () {
this.$emit('toggle')
}
},
beforeDestroy () {
document.body.removeEventListener('scroll', this.handleScroll, true)
}
}
</script>
<style lang="less">
@import '../index.less';
.header-animat{
position: relative;
z-index: @ant-global-header-zindex;
}
.showHeader-enter-active {
transition: all 0.25s ease;
}
.showHeader-leave-active {
transition: all 0.5s ease;
}
.showHeader-enter, .showHeader-leave-to {
opacity: 0;
}
</style>

View File

@ -1,2 +0,0 @@
import GlobalHeader from './GlobalHeader'
export default GlobalHeader

View File

@ -1,86 +0,0 @@
<template>
<div :class="prefixCls">
<a-tabs v-model="currentTab" @change="handleTabChange">
<a-tab-pane v-for="v in icons" :tab="v.title" :key="v.key">
<ul>
<li v-for="(icon, key) in v.icons" :key="`${v.key}-${key}`" :class="{ 'active': selectedIcon==icon }" @click="handleSelectedIcon(icon)" >
<a-icon :type="icon" :style="{ fontSize: '36px' }" />
</li>
</ul>
</a-tab-pane>
</a-tabs>
</div>
</template>
<script>
import icons from './icons'
export default {
name: 'IconSelect',
props: {
prefixCls: {
type: String,
default: 'ant-pro-icon-selector'
},
// eslint-disable-next-line
value: {
type: String
}
},
data () {
return {
selectedIcon: this.value || '',
currentTab: 'directional',
icons
}
},
watch: {
value (val) {
this.selectedIcon = val
this.autoSwitchTab()
}
},
created () {
if (this.value) {
this.autoSwitchTab()
}
},
methods: {
handleSelectedIcon (icon) {
this.selectedIcon = icon
this.$emit('change', icon)
},
handleTabChange (activeKey) {
this.currentTab = activeKey
},
autoSwitchTab () {
icons.some(item => item.icons.some(icon => icon === this.value) && (this.currentTab = item.key))
}
}
}
</script>
<style lang="less" scoped>
@import "../index.less";
ul{
list-style: none;
padding: 0;
overflow-y: scroll;
height: 250px;
li{
display: inline-block;
padding: @padding-sm;
margin: 3px 0;
border-radius: @border-radius-base;
&:hover, &.active{
// box-shadow: 0px 0px 5px 2px @primary-color;
cursor: pointer;
color: @white;
background-color: @primary-color;
}
}
}
</style>

View File

@ -1,48 +0,0 @@
IconSelector
====
> 图标选择组件,常用于为某一个数据设定一个图标时使用
> eg: 设定菜单列表时,为每个菜单设定一个图标
该组件由 [@Saraka](https://github.com/saraka-tsukai) 封装
### 使用方式
```vue
<template>
<div>
<icon-selector @change="handleIconChange"/>
</div>
</template>
<script>
import IconSelector from '@/components/IconSelector'
export default {
name: 'YourView',
components: {
IconSelector
},
data () {
return {
}
},
methods: {
handleIconChange (icon) {
console.log('change Icon', icon)
}
}
}
</script>
```
### 事件
| 名称 | 说明 | 类型 | 默认值 |
| ------ | -------------------------- | ------ | ------ |
| change | 当改变了 `icon` 选中项触发 | String | - |

Some files were not shown because too many files have changed in this diff Show More