jeecg-boot 1.1 稳定版本发布

pull/47/head
zhangdaihao 2019-04-14 16:20:04 +08:00
parent 1511c46f9c
commit d8e70b7f90
375 changed files with 48784 additions and 7523 deletions

101
README.md
View File

@ -1,7 +1,7 @@
Jeecg-Boot 快速开发平台(前后端分离版本)
===============
当前最新版本: 1.0发布日期20190304
当前最新版本: 1.1发布日期20190415
项目介绍:
-----------------------------------
@ -79,28 +79,85 @@ JeecgBoot的宗旨是降低前后端分离的开发成本提高UI能力的同
├─系统管理
│ ├─用户管理
│ ├─角色管理
│ ├─菜单管理(权限设置)
│ ├─菜单管理
│ ├─权限设置(支持按钮权限、数据权限)
│ ├─部门管理
│ └─字典管理
├─智能化功能
│ ├─代码生成器功能(一键生成,包括前端页面也可以生成,绝对是后端开发福音)
│ ├─代码生成器功能(一键生成前后端代码,生成后无需修改直接用,绝对是后端开发福音)
│ ├─代码生成器模板提供4套模板分别支持单表和一对多模型不同风格选择
│ ├─代码生成器模板生成代码自带excel导入导出
│ ├─查询过滤器(查询逻辑无需编码,系统根据页面配置自动生成)
│ ├─高级查询器(弹窗自动组合查询条件)
│ ├─Excel导入导出工具集成支持单表一对多 导入导出)
│ ├─平台移动自适应支持
├─Online在线开发
│ ├─Online在线表单
│ ├─Online在线图表
│ ├─Online在线报表
│ ├─消息中心(支持短信、邮件、微信推送等等)
├─系统监控
│ ├─性能扫描监控
│ │ ├─监控 Redis
│ │ ├─Tomcat
│ │ ├─jvm
│ │ ├─服务器信息
│ │ ├─请求追踪
│ ├─定时任务
│ ├─系统日志
│ ├─数据日志(记录数据变更情况,可进行版本对比查看数据变更记录)
│ ├─系统通知
│ ├─SQL监控
│ ├─swagger-ui(在线接口文档)
│─报表示例
│ ├─曲线图
│ └─饼状图
│ └─柱状图
│ └─折线图
│ └─面积图
│ └─雷达图
│ └─仪表图
│ └─进度条
│ └─排名列表
│ └─等等
│─常用示例
│ ├─单表模型例子
│ └─一对多模型例子
│ └─打印例子
│ └─一对多TAB例子
│ └─内嵌table例子
│ └─常用选择组件
│ └─一对多JEditable
│ └─接口模拟测试
│ └─一对多JEditable
│─封装通用组件
│ ├─行编辑表格JEditableTable
│ └─省略显示组件
│ └─时间控件
│ └─高级查询
│ └─通用选择用户组件
│ └─通过组织机构选择用户组件
│ └─报表组件封装
│ └─等等组件
│─更多页面模板
│ ├─各种高级表单
│ ├─各种列表效果
│ └─结果页面
│ └─异常页面
│ └─个人页面
│─流程模块功能
│ ├─在线流程设计
│ ├─在线表单设计
│ └─我的任务
│ └─历史流程
│ └─历史流程
│ └─流程实例管理
│ └─流程监听管理
│ └─流程表达式
│ └─我发起的流程
│ └─我的抄送
│ └─流程委派、抄送、跳转
│ └─。。。
└─其他模块
└─其他
@ -110,19 +167,31 @@ JeecgBoot的宗旨是降低前后端分离的开发成本提高UI能力的同
系统效果
----
![输入图片说明](https://static.oschina.net/uploads/img/201902/25154007_icdX.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25153956_Q752.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201901/07154149_555Q.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25154209_qlCg.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25154251_XoW9.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25154331_0ndT.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25154414_ckFS.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25155155_Hm6H.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25155213_T04n.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25155224_MRLU.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25155234_7zCP.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25155242_K7Sw.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201902/25154007_icdX.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14155402_AmlV.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160623_8fwk.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160633_u59G.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160643_kCJ7.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160650_fcgw.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160657_cHwb.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160705_NAJn.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160751_bsO9.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160801_2AhS.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160813_KmXS.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160828_pkFr.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160834_Lo23.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160842_QK7B.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160849_GBm5.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160858_6RAM.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160905_RGJ5.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160917_9Ftz.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160926_PUDV.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160935_Nibs.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160947_gfoN.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14160957_hN3X.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14161004_bxQ4.png "在这里输入图片标题")
![输入图片说明](https://static.oschina.net/uploads/img/201904/14161013_zW5n.png "在这里输入图片标题")
@ -134,7 +203,7 @@ JeecgBoot的宗旨是降低前后端分离的开发成本提高UI能力的同
- jdk8
- mysql
- redis
- 数据库脚步jeecg-boot\docs\dbsys-init-20190225.sql
- 数据库脚步jeecg-boot\docs\jeecg-boot_1.1.0-20190415.sql
- 默认登录账号: admin/123456

View File

@ -1,11 +1,13 @@
Jeecg-Boot 快速开发平台(前后端分离版本)
===============
Ant Design Jeecg Vue
====
当前最新版本: 1.0发布日期20190225
当前最新版本: 1.1发布日期20190415
项目介绍:
-----------------------------------
Jeecg-boot 一个全新的版本,采用前后端分离方案,提供强大代码生成器的快速开发平台。
Overview
----
基于 [Ant Design of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 实现的 Ant Design Pro Vue 版
Jeecg-boot 的前段UI框架采用前后端分离方案提供强大代码生成器的快速开发平台。
前端页面代码和后端功能代码一键生成不需要写任何代码保持jeecg一贯的强大

View File

@ -1,6 +1,6 @@
{
"name": "vue-antd-pro",
"version": "1.1.0",
"name": "vue-antd-jeecg",
"version": "1.0.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --open",
@ -11,7 +11,9 @@
},
"dependencies": {
"@antv/data-set": "^0.10.1",
"@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "^1.3.1",
"apexcharts": "^3.6.5",
"axios": "^0.18.0",
"dayjs": "^1.8.0",
"enquire.js": "^2.1.6",
@ -20,13 +22,15 @@
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"nprogress": "^0.2.0",
"tinymce": "^5.0.2",
"viser-vue": "^2.4.4",
"vue": "^2.5.22",
"vue-apexcharts": "^1.3.2",
"vue-class-component": "^6.0.0",
"vue-cropper": "^0.4.8",
"vue-i18n": "^8.7.0",
"vue-ls": "^3.2.0",
"vue-print-nb": "^1.0.3",
"vue-print-nb-jeecg": "^1.0.5",
"vue-property-decorator": "^7.3.0",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",

View File

@ -2175,9 +2175,8 @@ this.tinycolor = tinycolor;
.globalFooter .copyright {
color: rgba(0, 0, 0, 0.45);
}
.header {
background: #fff;
box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
.layout .header {
background-color: @primary-color !important;
}
i.trigger:hover {
background: rgba(0, 0, 0, 0.025);
@ -2342,24 +2341,22 @@ i.trigger:hover {
border-radius: 2px;
color: #fff;
}
.logo {
}
.logo h1 {
color: white;
}
.sider {
box-shadow: 2px 0 6px rgba(0, 21, 41, 0.35);
box-shadow: 2px 116px 6px rgba(0, 21, 41, 0.35);
}
.sider.light {
box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
box-shadow: 2px 116px 8px 0 rgba(29, 35, 41, 0.05);
background-color: white;
}
.sider.light .logo {
background: white;
background-color: @primary-color !important;
box-shadow: 1px 1px 0 0 #e8e8e8;
}
.sider.light .logo h1 {
color: @primary-color;
color: white;
}
.sider.light :global(.ant-menu-light) {
border-right-color: transparent;
@ -6808,7 +6805,7 @@ tr.ant-table-expanded-row:hover {
}
.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
background: #fff;
border-color: #e8e8e8;
border-color: @primary-color !important;
color: @primary-color;
}
.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-tab .ant-tabs-close-x {

BIN
ant-design-jeecg-vue/public/goright.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -5,7 +5,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Jeecg-Boot Ant Design Vue</title>
<title>Jeecg-Boot </title>
<link rel="icon" href="<%= BASE_URL %>logo.png">
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.2.5/polyfill.js"></script>
<style>
@ -219,6 +219,12 @@
opacity: 0.5;
}
</style>
<!-- -->
<script>
window._CONFIG = {};
window._CONFIG['domianURL'] = 'http://localhost:8080/jeecg-boot';
window._CONFIG['imgDomainURL'] = 'http://localhost:8080/jeecg-boot/sys/common/view';
</script>
</head>
<body>
@ -228,7 +234,7 @@
<div id="loader"></div>
<div class="loader-section section-left"></div>
<div class="loader-section section-right"></div>
<div class="load_title"> Jeecg-Boot Ant Design Vue,
<div class="load_title"> Jeecg-Boot ,
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,261 @@
tinymce.addI18n('zh_CN',{
"Redo": "\u91cd\u590d",
"Undo": "\u64a4\u6d88",
"Cut": "\u526a\u5207",
"Copy": "\u590d\u5236",
"Paste": "\u7c98\u8d34",
"Select all": "\u5168\u9009",
"New document": "\u65b0\u6587\u6863",
"Ok": "\u786e\u5b9a",
"Cancel": "\u53d6\u6d88",
"Visual aids": "\u7f51\u683c\u7ebf",
"Bold": "\u7c97\u4f53",
"Italic": "\u659c\u4f53",
"Underline": "\u4e0b\u5212\u7ebf",
"Strikethrough": "\u5220\u9664\u7ebf",
"Superscript": "\u4e0a\u6807",
"Subscript": "\u4e0b\u6807",
"Clear formatting": "\u6e05\u9664\u683c\u5f0f",
"Align left": "\u5de6\u5bf9\u9f50",
"Align center": "\u5c45\u4e2d",
"Align right": "\u53f3\u5bf9\u9f50",
"Justify": "\u4e24\u7aef\u5bf9\u9f50",
"Bullet list": "\u9879\u76ee\u7b26\u53f7",
"Numbered list": "\u7f16\u53f7\u5217\u8868",
"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb",
"Increase indent": "\u589e\u52a0\u7f29\u8fdb",
"Close": "\u5173\u95ed",
"Formats": "\u683c\u5f0f",
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u5bf9\u526a\u8d34\u677f\u7684\u8bbf\u95ee\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u952e\u8fdb\u884c\u590d\u5236\u7c98\u8d34\u3002",
"Headers": "\u6807\u9898",
"Header 1": "\u6807\u98981",
"Header 2": "\u6807\u98982",
"Header 3": "\u6807\u98983",
"Header 4": "\u6807\u98984",
"Header 5": "\u6807\u98985",
"Header 6": "\u6807\u98986",
"Headings": "\u6807\u9898",
"Heading 1": "\u6807\u98981",
"Heading 2": "\u6807\u98982",
"Heading 3": "\u6807\u98983",
"Heading 4": "\u6807\u98984",
"Heading 5": "\u6807\u98985",
"Heading 6": "\u6807\u98986",
"Preformatted": "\u9884\u683c\u5f0f\u5316",
"Div": "Div\u533a\u5757",
"Pre": "\u9884\u683c\u5f0f\u6587\u672c",
"Code": "\u4ee3\u7801",
"Paragraph": "\u6bb5\u843d",
"Blockquote": "\u5f15\u7528",
"Inline": "\u6587\u672c",
"Blocks": "\u533a\u5757",
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002",
"Font Family": "\u5b57\u4f53",
"Font Sizes": "\u5b57\u53f7",
"Class": "Class",
"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf",
"OR": "\u6216",
"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64",
"Upload": "\u4e0a\u4f20",
"Block": "\u5757",
"Align": "\u5bf9\u9f50",
"Default": "\u9ed8\u8ba4",
"Circle": "\u7a7a\u5fc3\u5706",
"Disc": "\u5b9e\u5fc3\u5706",
"Square": "\u65b9\u5757",
"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd",
"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd",
"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd",
"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd",
"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd",
"Anchor": "\u951a\u70b9",
"Name": "\u540d\u79f0",
"Id": "\u6807\u8bc6\u7b26",
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002",
"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f",
"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f",
"Special character": "\u7279\u6b8a\u7b26\u53f7",
"Source code": "\u6e90\u4ee3\u7801",
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b",
"Language": "\u8bed\u8a00",
"Code sample": "\u4ee3\u7801\u793a\u4f8b",
"Color": "\u989c\u8272",
"R": "R",
"G": "G",
"B": "B",
"Left to right": "\u4ece\u5de6\u5230\u53f3",
"Right to left": "\u4ece\u53f3\u5230\u5de6",
"Emoticons": "\u8868\u60c5",
"Document properties": "\u6587\u6863\u5c5e\u6027",
"Title": "\u6807\u9898",
"Keywords": "\u5173\u952e\u8bcd",
"Description": "\u63cf\u8ff0",
"Robots": "\u673a\u5668\u4eba",
"Author": "\u4f5c\u8005",
"Encoding": "\u7f16\u7801",
"Fullscreen": "\u5168\u5c4f",
"Action": "\u64cd\u4f5c",
"Shortcut": "\u5feb\u6377\u952e",
"Help": "\u5e2e\u52a9",
"Address": "\u5730\u5740",
"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f",
"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f",
"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84",
"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355",
"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)",
"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):",
"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a",
"Learn more...": "\u4e86\u89e3\u66f4\u591a...",
"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}",
"Plugins": "\u63d2\u4ef6",
"Handy Shortcuts": "\u5feb\u6377\u952e",
"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf",
"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247",
"Image description": "\u56fe\u7247\u63cf\u8ff0",
"Source": "\u5730\u5740",
"Dimensions": "\u5927\u5c0f",
"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4",
"General": "\u666e\u901a",
"Advanced": "\u9ad8\u7ea7",
"Style": "\u6837\u5f0f",
"Vertical space": "\u5782\u76f4\u8fb9\u8ddd",
"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd",
"Border": "\u8fb9\u6846",
"Insert image": "\u63d2\u5165\u56fe\u7247",
"Image": "\u56fe\u7247",
"Image list": "\u56fe\u7247\u5217\u8868",
"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c",
"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c",
"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c",
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c",
"Edit image": "\u7f16\u8f91\u56fe\u7247",
"Image options": "\u56fe\u7247\u9009\u9879",
"Zoom in": "\u653e\u5927",
"Zoom out": "\u7f29\u5c0f",
"Crop": "\u88c1\u526a",
"Resize": "\u8c03\u6574\u5927\u5c0f",
"Orientation": "\u65b9\u5411",
"Brightness": "\u4eae\u5ea6",
"Sharpen": "\u9510\u5316",
"Contrast": "\u5bf9\u6bd4\u5ea6",
"Color levels": "\u989c\u8272\u5c42\u6b21",
"Gamma": "\u4f3d\u9a6c\u503c",
"Invert": "\u53cd\u8f6c",
"Apply": "\u5e94\u7528",
"Back": "\u540e\u9000",
"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4",
"Date\/time": "\u65e5\u671f\/\u65f6\u95f4",
"Insert link": "\u63d2\u5165\u94fe\u63a5",
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5",
"Text to display": "\u663e\u793a\u6587\u5b57",
"Url": "\u5730\u5740",
"Target": "\u6253\u5f00\u65b9\u5f0f",
"None": "\u65e0",
"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00",
"Remove link": "\u5220\u9664\u94fe\u63a5",
"Anchors": "\u951a\u70b9",
"Link": "\u94fe\u63a5",
"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5",
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f",
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f",
"Link list": "\u94fe\u63a5\u5217\u8868",
"Insert video": "\u63d2\u5165\u89c6\u9891",
"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891",
"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53",
"Alternative source": "\u955c\u50cf",
"Poster": "\u5c01\u9762",
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:",
"Embed": "\u5185\u5d4c",
"Media": "\u5a92\u4f53",
"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c",
"Page break": "\u5206\u9875\u7b26",
"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c",
"Preview": "\u9884\u89c8",
"Print": "\u6253\u5370",
"Save": "\u4fdd\u5b58",
"Find": "\u67e5\u627e",
"Replace with": "\u66ff\u6362\u4e3a",
"Replace": "\u66ff\u6362",
"Replace all": "\u5168\u90e8\u66ff\u6362",
"Prev": "\u4e0a\u4e00\u4e2a",
"Next": "\u4e0b\u4e00\u4e2a",
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362",
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.",
"Match case": "\u533a\u5206\u5927\u5c0f\u5199",
"Whole words": "\u5168\u5b57\u5339\u914d",
"Spellcheck": "\u62fc\u5199\u68c0\u67e5",
"Ignore": "\u5ffd\u7565",
"Ignore all": "\u5168\u90e8\u5ffd\u7565",
"Finish": "\u5b8c\u6210",
"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178",
"Insert table": "\u63d2\u5165\u8868\u683c",
"Table properties": "\u8868\u683c\u5c5e\u6027",
"Delete table": "\u5220\u9664\u8868\u683c",
"Cell": "\u5355\u5143\u683c",
"Row": "\u884c",
"Column": "\u5217",
"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027",
"Merge cells": "\u5408\u5e76\u5355\u5143\u683c",
"Split cell": "\u62c6\u5206\u5355\u5143\u683c",
"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165",
"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165",
"Delete row": "\u5220\u9664\u884c",
"Row properties": "\u884c\u5c5e\u6027",
"Cut row": "\u526a\u5207\u884c",
"Copy row": "\u590d\u5236\u884c",
"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9",
"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9",
"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165",
"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165",
"Delete column": "\u5220\u9664\u5217",
"Cols": "\u5217",
"Rows": "\u884c",
"Width": "\u5bbd",
"Height": "\u9ad8",
"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd",
"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd",
"Caption": "\u6807\u9898",
"Left": "\u5de6\u5bf9\u9f50",
"Center": "\u5c45\u4e2d",
"Right": "\u53f3\u5bf9\u9f50",
"Cell type": "\u5355\u5143\u683c\u7c7b\u578b",
"Scope": "\u8303\u56f4",
"Alignment": "\u5bf9\u9f50\u65b9\u5f0f",
"H Align": "\u6c34\u5e73\u5bf9\u9f50",
"V Align": "\u5782\u76f4\u5bf9\u9f50",
"Top": "\u9876\u90e8\u5bf9\u9f50",
"Middle": "\u5782\u76f4\u5c45\u4e2d",
"Bottom": "\u5e95\u90e8\u5bf9\u9f50",
"Header cell": "\u8868\u5934\u5355\u5143\u683c",
"Row group": "\u884c\u7ec4",
"Column group": "\u5217\u7ec4",
"Row type": "\u884c\u7c7b\u578b",
"Header": "\u8868\u5934",
"Body": "\u8868\u4f53",
"Footer": "\u8868\u5c3e",
"Border color": "\u8fb9\u6846\u989c\u8272",
"Insert template": "\u63d2\u5165\u6a21\u677f",
"Templates": "\u6a21\u677f",
"Template": "\u6a21\u677f",
"Text color": "\u6587\u5b57\u989c\u8272",
"Background color": "\u80cc\u666f\u8272",
"Custom...": "\u81ea\u5b9a\u4e49...",
"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272",
"No color": "\u65e0",
"Table of Contents": "\u5185\u5bb9\u5217\u8868",
"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846",
"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26",
"Words: {0}": "\u5b57\u6570\uff1a{0}",
"{0} words": "{0} \u5b57",
"File": "\u6587\u4ef6",
"Edit": "\u7f16\u8f91",
"Insert": "\u63d2\u5165",
"View": "\u89c6\u56fe",
"Format": "\u683c\u5f0f",
"Table": "\u8868\u683c",
"Tools": "\u5de5\u5177",
"Powered by {0}": "\u7531{0}\u9a71\u52a8",
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9"
});

View File

@ -0,0 +1,554 @@
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
.mce-content-body .mce-item-anchor {
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'8'%20height%3D'12'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20d%3D'M0%200L8%200%208%2012%204.09117821%209%200%2012z'%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
cursor: default;
display: inline-block;
height: 12px !important;
padding: 0 2px;
-webkit-user-modify: read-only;
-moz-user-modify: read-only;
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
user-select: all;
width: 8px !important;
}
.mce-content-body .mce-item-anchor[data-mce-selected] {
outline-offset: 1px;
}
.tox-comments-visible .tox-comment {
background-color: #fff0b7;
}
.tox-comments-visible .tox-comment--active {
background-color: #ffe168;
}
.tox-checklist > li:not(.tox-checklist--hidden) {
list-style: none;
margin: .25em 0;
position: relative;
}
.tox-checklist > li:not(.tox-checklist--hidden)::before {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-unchecked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2215%22%20height%3D%2215%22%20x%3D%22.5%22%20y%3D%22.5%22%20fill-rule%3D%22nonzero%22%20stroke%3D%22%234C4C4C%22%20rx%3D%222%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
background-size: 100%;
content: '';
cursor: pointer;
height: 1em;
left: -1.5em;
position: absolute;
top: .125em;
width: 1em;
}
.tox-checklist li:not(.tox-checklist--hidden).tox-checklist--checked::before {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2216%22%20height%3D%2216%22%20viewBox%3D%220%200%2016%2016%22%3E%3Cg%20id%3D%22checklist-checked%22%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%3Crect%20id%3D%22Rectangle%22%20width%3D%2216%22%20height%3D%2216%22%20fill%3D%22%234099FF%22%20fill-rule%3D%22nonzero%22%20rx%3D%222%22%2F%3E%3Cpath%20id%3D%22Path%22%20fill%3D%22%23FFF%22%20fill-rule%3D%22nonzero%22%20d%3D%22M11.5703186%2C3.14417309%20C11.8516238%2C2.73724603%2012.4164781%2C2.62829933%2012.83558%2C2.89774797%20C13.260121%2C3.17069355%2013.3759736%2C3.72932262%2013.0909105%2C4.14168582%20L7.7580587%2C11.8560195%20C7.43776896%2C12.3193404%206.76483983%2C12.3852142%206.35607322%2C11.9948725%20L3.02491697%2C8.8138662%20C2.66090143%2C8.46625845%202.65798871%2C7.89594698%203.01850234%2C7.54483354%20C3.373942%2C7.19866177%203.94940006%2C7.19592841%204.30829608%2C7.5386474%20L6.85276923%2C9.9684299%20L11.5703186%2C3.14417309%20Z%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E%0A");
}
/* stylelint-disable */
/* http://prismjs.com/ */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
font-size: .875rem;
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: transparent !important;
border: 1px solid #ccc;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #a67f59;
background: rgba(255, 255, 255, 0.5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
/* stylelint-enable */
.mce-content-body .mce-visual-caret {
background-color: black;
background-color: currentcolor;
position: absolute;
}
.mce-content-body .mce-visual-caret-hidden {
display: none;
}
.mce-content-body *[data-mce-caret] {
left: -1000px;
margin: 0;
padding: 0;
position: absolute;
right: auto;
top: 0;
}
.mce-content-body .mce-offscreen-selection {
left: -9999999999px;
max-width: 1000000px;
position: absolute;
}
.mce-content-body *[contentEditable=false] {
cursor: default;
}
.mce-content-body *[contentEditable=true] {
cursor: text;
}
.tox-cursor-format-painter {
cursor: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%20viewBox%3D%220%200%2024%2024%22%3E%0A%20%20%3Cg%20fill%3D%22none%22%20fill-rule%3D%22evenodd%22%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M15%2C6%20C15%2C5.45%2014.55%2C5%2014%2C5%20L6%2C5%20C5.45%2C5%205%2C5.45%205%2C6%20L5%2C10%20C5%2C10.55%205.45%2C11%206%2C11%20L14%2C11%20C14.55%2C11%2015%2C10.55%2015%2C10%20L15%2C9%20L16%2C9%20L16%2C12%20L9%2C12%20L9%2C19%20C9%2C19.55%209.45%2C20%2010%2C20%20L11%2C20%20C11.55%2C20%2012%2C19.55%2012%2C19%20L12%2C14%20L18%2C14%20L18%2C7%20L15%2C7%20L15%2C6%20Z%22%2F%3E%0A%20%20%20%20%3Cpath%20fill%3D%22%23000%22%20fill-rule%3D%22nonzero%22%20d%3D%22M1%2C1%20L8.25%2C1%20C8.66421356%2C1%209%2C1.33578644%209%2C1.75%20L9%2C1.75%20C9%2C2.16421356%208.66421356%2C2.5%208.25%2C2.5%20L2.5%2C2.5%20L2.5%2C8.25%20C2.5%2C8.66421356%202.16421356%2C9%201.75%2C9%20L1.75%2C9%20C1.33578644%2C9%201%2C8.66421356%201%2C8.25%20L1%2C1%20Z%22%2F%3E%0A%20%20%3C%2Fg%3E%0A%3C%2Fsvg%3E%0A"), default;
}
.mce-content-body figure.align-left {
float: left;
}
.mce-content-body figure.align-right {
float: right;
}
.mce-content-body figure.image.align-center {
display: table;
margin-left: auto;
margin-right: auto;
}
.mce-preview-object {
border: 1px solid gray;
display: inline-block;
line-height: 0;
margin: 0 2px 0 2px;
position: relative;
}
.mce-preview-object .mce-shim {
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.mce-preview-object[data-mce-selected="2"] .mce-shim {
display: none;
}
.mce-object {
background: transparent url("data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2224%22%20height%3D%2224%22%3E%3Cpath%20d%3D%22M4%203h16a1%201%200%200%201%201%201v16a1%201%200%200%201-1%201H4a1%201%200%200%201-1-1V4a1%201%200%200%201%201-1zm1%202v14h14V5H5zm4.79%202.565l5.64%204.028a.5.5%200%200%201%200%20.814l-5.64%204.028a.5.5%200%200%201-.79-.407V7.972a.5.5%200%200%201%20.79-.407z%22%2F%3E%3C%2Fsvg%3E%0A") no-repeat center;
border: 1px dashed #aaa;
}
.mce-pagebreak {
border: 1px dashed #aaa;
cursor: default;
display: block;
height: 5px;
margin-top: 15px;
page-break-before: always;
width: 100%;
}
@media print {
.mce-pagebreak {
border: 0;
}
}
.tiny-pageembed .mce-shim {
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.tiny-pageembed[data-mce-selected="2"] .mce-shim {
display: none;
}
.tiny-pageembed {
display: inline-block;
position: relative;
}
.tiny-pageembed--21by9,
.tiny-pageembed--16by9,
.tiny-pageembed--4by3,
.tiny-pageembed--1by1 {
display: block;
overflow: hidden;
padding: 0;
position: relative;
width: 100%;
}
.tiny-pageembed--21by9::before,
.tiny-pageembed--16by9::before,
.tiny-pageembed--4by3::before,
.tiny-pageembed--1by1::before {
content: "";
display: block;
}
.tiny-pageembed--21by9::before {
padding-top: 42.857143%;
}
.tiny-pageembed--16by9::before {
padding-top: 56.25%;
}
.tiny-pageembed--4by3::before {
padding-top: 75%;
}
.tiny-pageembed--1by1::before {
padding-top: 100%;
}
.tiny-pageembed--21by9 iframe,
.tiny-pageembed--16by9 iframe,
.tiny-pageembed--4by3 iframe,
.tiny-pageembed--1by1 iframe {
border: 0;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.mce-content-body div.mce-resizehandle {
background-color: #4099ff;
border-color: #4099ff;
border-style: solid;
border-width: 1px;
box-sizing: border-box;
height: 10px;
position: absolute;
width: 10px;
z-index: 10000;
}
.mce-content-body div.mce-resizehandle:hover {
background-color: #4099ff;
}
.mce-content-body div.mce-resizehandle:nth-of-type(1) {
cursor: nwse-resize;
}
.mce-content-body div.mce-resizehandle:nth-of-type(2) {
cursor: nesw-resize;
}
.mce-content-body div.mce-resizehandle:nth-of-type(3) {
cursor: nwse-resize;
}
.mce-content-body div.mce-resizehandle:nth-of-type(4) {
cursor: nesw-resize;
}
.mce-content-body .mce-clonedresizable {
opacity: .5;
outline: 1px dashed black;
position: absolute;
z-index: 10000;
}
.mce-content-body .mce-resize-helper {
background: #555;
background: rgba(0, 0, 0, 0.75);
border: 1px;
border-radius: 3px;
color: white;
display: none;
font-family: sans-serif;
font-size: 12px;
line-height: 14px;
margin: 5px 10px;
padding: 5px;
position: absolute;
white-space: nowrap;
z-index: 10001;
}
.mce-match-marker {
background: #aaa;
color: #fff;
}
.mce-match-marker-selected {
background: #39f;
color: #fff;
}
.mce-content-body img[data-mce-selected],
.mce-content-body table[data-mce-selected] {
outline: 3px solid #b4d7ff;
}
.mce-content-body hr[data-mce-selected] {
outline: 3px solid #b4d7ff;
outline-offset: 1px;
}
.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus {
outline: 3px solid #b4d7ff;
}
.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover {
outline: 3px solid #b4d7ff;
}
.mce-content-body *[contentEditable=false][data-mce-selected] {
cursor: not-allowed;
outline: 3px solid #b4d7ff;
}
.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,
.mce-content-body.mce-content-readonly *[contentEditable=true]:hover {
outline: none;
}
.mce-content-body *[data-mce-selected="inline-boundary"] {
background-color: #b4d7ff;
}
.mce-content-body .mce-edit-focus {
outline: 3px solid #b4d7ff;
}
.mce-content-body td[data-mce-selected],
.mce-content-body th[data-mce-selected] {
background-color: #b4d7ff !important;
}
.mce-content-body td[data-mce-selected]::-moz-selection,
.mce-content-body th[data-mce-selected]::-moz-selection {
background: none;
}
.mce-content-body td[data-mce-selected]::selection,
.mce-content-body th[data-mce-selected]::selection {
background: none;
}
.mce-content-body td[data-mce-selected] *,
.mce-content-body th[data-mce-selected] * {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.mce-content-body img::-moz-selection {
background: none;
}
.mce-content-body img::selection {
background: none;
}
.ephox-snooker-resizer-bar {
background-color: #b4d7ff;
opacity: 0;
}
.ephox-snooker-resizer-cols {
cursor: col-resize;
}
.ephox-snooker-resizer-rows {
cursor: row-resize;
}
.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging {
opacity: 1;
}
.mce-spellchecker-word {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23ff0000'%20fill%3D'none'%20stroke-linecap%3D'round'%20stroke-opacity%3D'.5'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
background-position: 0 calc(100% + 1px);
background-repeat: repeat-x;
background-size: auto 6px;
cursor: default;
height: 2rem;
}
.mce-spellchecker-grammar {
background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D'4'%20height%3D'4'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%3E%3Cpath%20stroke%3D'%23008800'%20fill%3D'none'%20stroke-linecap%3D'round'%20d%3D'M0%203L2%201%204%203'%2F%3E%3C%2Fsvg%3E%0A");
background-position: 0 calc(100% + 1px);
background-repeat: repeat-x;
background-size: auto 6px;
cursor: default;
}
.mce-toc {
border: 1px solid gray;
}
.mce-toc h2 {
margin: 4px;
}
.mce-toc li {
list-style-type: none;
}
.mce-item-table,
.mce-item-table td,
.mce-item-table th,
.mce-item-table caption {
border: 1px dashed #bbb;
}
.mce-visualblocks p,
.mce-visualblocks h1,
.mce-visualblocks h2,
.mce-visualblocks h3,
.mce-visualblocks h4,
.mce-visualblocks h5,
.mce-visualblocks h6,
.mce-visualblocks div:not([data-mce-bogus]),
.mce-visualblocks section,
.mce-visualblocks article,
.mce-visualblocks blockquote,
.mce-visualblocks address,
.mce-visualblocks pre,
.mce-visualblocks figure,
.mce-visualblocks figcaption,
.mce-visualblocks hgroup,
.mce-visualblocks aside,
.mce-visualblocks ul,
.mce-visualblocks ol,
.mce-visualblocks dl {
background-repeat: no-repeat;
border: 1px dashed #bbb;
margin-left: 3px;
padding-top: 10px;
}
.mce-visualblocks p {
background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7);
}
.mce-visualblocks h1 {
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==);
}
.mce-visualblocks h2 {
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==);
}
.mce-visualblocks h3 {
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7);
}
.mce-visualblocks h4 {
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==);
}
.mce-visualblocks h5 {
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==);
}
.mce-visualblocks h6 {
background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==);
}
.mce-visualblocks div:not([data-mce-bogus]) {
background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7);
}
.mce-visualblocks section {
background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=);
}
.mce-visualblocks article {
background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7);
}
.mce-visualblocks blockquote {
background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7);
}
.mce-visualblocks address {
background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=);
}
.mce-visualblocks pre {
background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==);
}
.mce-visualblocks figure {
background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7);
}
.mce-visualblocks figcaption {
border: 1px dashed #bbb;
}
.mce-visualblocks hgroup {
background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7);
}
.mce-visualblocks aside {
background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=);
}
.mce-visualblocks ul {
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIAAALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGuYnqUVSjvw26DzzXiqIDlVwAAOw==);
}
.mce-visualblocks ol {
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybH6HHt0qourxC6CvzXieHyeWQAAOw==);
}
.mce-visualblocks dl {
background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybEOnmOvUoWznTqeuEjNSCqeGRUAOw==);
}
.mce-nbsp,
.mce-shy {
background: #aaa;
}
.mce-shy::after {
content: '-';
}
body {
font-family: sans-serif;
}
table {
border-collapse: collapse;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,17 @@
import { getAction,deleteAction,putAction,postAction} from '@/api/manage'
//根路径
const doMian = "/jeecg-boot/";
//图片预览请求地址
const imgView = "http://127.0.0.1:8080/jeecg-boot/sys/common/view/";
////根路径
// const doMian = "/jeecg-boot/";
////图片预览请求地址
// const imgView = "http://localhost:8080/jeecg-boot/sys/common/view/";
//角色管理
const addRole = (params)=>postAction("/sys/role/add",params);
const editRole = (params)=>putAction("/sys/role/edit",params);
const getRoleList = (params)=>getAction("/sys/role/list",params);
const deleteRole = (params)=>deleteAction("/sys/role/delete",params);
const deleteRoleList = (params)=>deleteAction("/sys/role/deleteBatch",params);
// const getRoleList = (params)=>getAction("/sys/role/list",params);
// const deleteRole = (params)=>deleteAction("/sys/role/delete",params);
// const deleteRoleList = (params)=>deleteAction("/sys/role/deleteBatch",params);
const checkRoleCode = (params)=>getAction("/sys/role/checkRoleCode",params);
const queryall = (params)=>getAction("/sys/role/queryall",params);
@ -20,8 +20,8 @@ const addUser = (params)=>postAction("/sys/user/add",params);
const editUser = (params)=>putAction("/sys/user/edit",params);
const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params);
const getUserList = (params)=>getAction("/sys/user/list",params);
const deleteUser = (params)=>deleteAction("/sys/user/delete",params);
const deleteUserList = (params)=>deleteAction("/sys/user/deleteBatch",params);
// const deleteUser = (params)=>deleteAction("/sys/user/delete",params);
// const deleteUserList = (params)=>deleteAction("/sys/user/deleteBatch",params);
const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
//验证用户账号是否唯一
const checkUsername = (params)=>getAction("/sys/user/checkOnlyUser",params);
@ -32,37 +32,41 @@ const changPassword = (params)=>putAction("/sys/user/changPassword",params);
const addPermission= (params)=>postAction("/sys/permission/add",params);
const editPermission= (params)=>putAction("/sys/permission/edit",params);
const getPermissionList = (params)=>getAction("/sys/permission/list",params);
const deletePermission = (params)=>deleteAction("/sys/permission/delete",params);
const deletePermissionList = (params)=>deleteAction("/sys/permission/deleteBatch",params);
// const deletePermission = (params)=>deleteAction("/sys/permission/delete",params);
// const deletePermissionList = (params)=>deleteAction("/sys/permission/deleteBatch",params);
const queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params);
const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params);
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params);
const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params);
const queryPermissionsByUser = (params)=>getAction("/sys/permission/queryByUser",params);
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermissionRule",params);
// 部门管理
const queryDepartTreeList = (params)=>getAction("/sysdepart/sysDepart/queryTreeList",params);
const queryIdTree = (params)=>getAction("/sysdepart/sysDepart/queryIdTree",params);
const queryParentName = (params)=>getAction("/sysdepart/sysDepart/queryParentName",params);
const searchByKeywords = (params)=>getAction("/sysdepart/sysDepart/searchBy",params);
const deleteByDepartId = (params)=>deleteAction("/sysdepart/sysDepart/delete",params);
//日志管理
const getLogList = (params)=>getAction("/sys/log/list",params);
//const getLogList = (params)=>getAction("/sys/log/list",params);
const deleteLog = (params)=>deleteAction("/sys/log/delete",params);
const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params);
//数据字典
const addDict = (params)=>postAction("/sys/dict/add",params);
const editDict = (params)=>putAction("/sys/dict/edit",params);
const getDictList = (params)=>getAction("/sys/dict/list",params);
//const getDictList = (params)=>getAction("/sys/dict/list",params);
const treeList = (params)=>getAction("/sys/dict/treeList",params);
const delDict = (params)=>deleteAction("/sys/dict/delete",params);
const getDictItemList = (params)=>getAction("/sys/dictItem/list",params);
// const delDict = (params)=>deleteAction("/sys/dict/delete",params);
//const getDictItemList = (params)=>getAction("/sys/dictItem/list",params);
const addDictItem = (params)=>postAction("/sys/dictItem/add",params);
const editDictItem = (params)=>putAction("/sys/dictItem/edit",params);
const delDictItem = (params)=>deleteAction("/sys/dictItem/delete",params);
const delDictItemList = (params)=>deleteAction("/sys/dictItem/deleteBatch",params);
//const delDictItem = (params)=>deleteAction("/sys/dictItem/delete",params);
//const delDictItemList = (params)=>deleteAction("/sys/dictItem/deleteBatch",params);
//字典标签专用通过code获取字典数组
export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params);
@ -72,29 +76,32 @@ const doReleaseData = (params)=>getAction("/sys/annountCement/doReleaseData",par
const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",params);
//获取系统访问量
const getLoginfo = (params)=>getAction("/sys/loginfo",params);
//数据日志访问
// const getDataLogList = (params)=>getAction("/sys/dataLog/list",params);
// 根据部门主键查询用户信息
const queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params);
// 查询用户角色表里的所有信息
const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params);
// 重复校验
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
export {
imgView,
doMian,
// imgView,
// doMian,
addRole,
editRole,
getRoleList,
deleteRole,
deleteRoleList,
checkRoleCode,
addUser,
editUser,
queryUserRole,
queryall,
getUserList,
deleteUser,
deleteUserList,
queryall,
frozenBatch,
checkUsername,
changPassword,
getPermissionList,
deletePermission,
deletePermissionList,
addPermission,
editPermission,
queryTreeList,
@ -103,26 +110,27 @@ export {
saveRolePermission,
queryPermissionsByUser,
loadAllRoleIds,
getPermissionRuleList,
queryPermissionRule,
queryDepartTreeList,
queryIdTree,
queryParentName,
searchByKeywords,
getLogList,
deleteByDepartId,
deleteLog,
deleteLogList,
getDictList,
addDict,
editDict,
delDict,
treeList,
getDictItemList,
addDictItem,
editDictItem,
delDictItem,
delDictItemList,
doReleaseData,
doReovkeData,
getLoginfo
getLoginfo,
queryUserByDepId,
queryUserRoleMap,
duplicateCheck,
queryTreeListForRole
}

View File

@ -1,6 +1,6 @@
const api = {
Login: '/sys/login',
Logout: '/auth/logout',
Logout: '/sys/logout',
ForgePassword: '/auth/forge-password',
Register: '/auth/register',
SendSms: '/account/sms',

View File

@ -38,12 +38,13 @@ export function getInfo() {
})
}
export function logout() {
export function logout(logoutToken) {
return axios({
url: '/api/auth/logout',
url: '/sys/logout',
method: 'post',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
'Content-Type': 'application/json;charset=UTF-8',
'X-Access-Token': logoutToken
}
})
}

View File

@ -97,3 +97,18 @@ export function saveService(parameter) {
})
}
/**
* excel
* @param url
* @param parameter
* @returns {*}
*/
export function downFile(url,parameter){
return axios({
url: url,
params: parameter,
method:'get' ,
responseType: 'blob'
})
}

View File

@ -0,0 +1,29 @@
/*列表上方操作按钮*/
.ant-card-body .table-operator {
margin-bottom: 18px;
}
/*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
/*列表页面弹出modal*/
.ant-modal-cust-warp {
height: 100%
}
/*弹出modal Y轴滚动条*/
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
/*弹出modal 先有content后有body 故滚动条控制在body上*/
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}

View File

@ -1,3 +1,6 @@
/**
* 列表查询通用样式,移动端自适应
*/
.search{
margin-bottom: 54px;
}
@ -19,3 +22,7 @@
i {
cursor: pointer;
}
.trcolor{
background-color: rgba(255, 192, 203, 0.31);
color:red;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,41 @@
####1._util包:存放自定义函数 详细见代码注释
####2.AvatarList:显示头像群并支持tip用法参考src\views\Home.vue如下图
![输入图片说明](https://static.oschina.net/uploads/img/201904/12181253_O0Xi.png "在这里输入图片标题")
####3.chart包:存放各种图表相关的组件,条形图柱形图折线图等等 具体用法参考首页
####4.countDown包:一个倒计时组件用法参考home页,简单描述,该组件有3个属性,
target(时间/毫秒数)必填,
format(function,该方法接收一个毫秒数的参数,用于格式化显示当前倒计时时间)非必填,
onEnd倒计时结束触发函数
![输入图片说明](https://static.oschina.net/uploads/img/201904/12182046_mwqJ.png "在这里输入图片标题")
####5.dict包数据字典专用用法参考文件夹下readme文件
####6.Ellipsis包字符串截取组件,可以指定字符串的显示长度,并将全部内容显示到tip中,简单使用参考src\views\system\PermissionList.vue
####7.jeecg包该包下自定义了很多列表/表单中用到的组件 参考包下readme文件
####8.jeecgbiz包该包下定义了一些业务相关的组件比如选择用户弹框,根据部门选择用户等等
####9.layouts+page包系统页面布局相关组件比如登陆进去之后页面顶部显示什么底部显示什么菜单点击触发多个tab的布局等等 一般情况不需要修改
####10.menun包菜单组件俩个一个折叠菜单一个正常显示的菜单
####11.NumberInfo:数字信息显示组件 如下图
![输入图片说明](https://static.oschina.net/uploads/img/201904/12185858_uvJ5.png "在这里输入图片标题")
####12.online包该包下封装了online表单的相关组件,用于展示表单各种控件,验证表单等等,相关用法参考readme
####13.setting包该包下封装了首页风格切换等功能如下图
![输入图片说明](https://static.oschina.net/uploads/img/201904/12190520_jySG.png "在这里输入图片标题")
####14.table包一个二次封装的table组件,用于展示列表参考readme
####15.tools包
Breadcrumb.vue面包屑二次封装,支持路由跳转
DetailList.vue详情展示用法参考src\views\profile\advanced\Advanced.vue(效果如下图)
![输入图片说明](https://static.oschina.net/uploads/img/201904/12193954_Uar6.png "在这里输入图片标题")
````
个人认为该页面代码有两点值得学习:
1.vue provide/inject的使用
2.该页面css定义方式,只定义一个顶层class,其余样式都定义在其下,这样只要顶层class不和别的页面冲突,整个页面的样式都是唯一生效的
````
FooterToolBar.vue:fixed定位的底部通过是否定义内部控件的属性slot="extra"决定是左浮动或是右浮动
HeaderNotice.vue:首页通知(如下图)
![输入图片说明](https://static.oschina.net/uploads/img/201904/12195340_fPe0.png "在这里输入图片标题")
HeaderInfo.vue:上下文字布局(如下图)
![输入图片说明](https://static.oschina.net/uploads/img/201904/12195638_dG5o.png "在这里输入图片标题")
Logo.vue:首页左上侧的log图
![输入图片说明](https://static.oschina.net/uploads/img/201904/12200908_ihv3.png "在这里输入图片标题")
UserMenu.vue:首页右上侧的内容
![输入图片说明](https://static.oschina.net/uploads/img/201904/12201226_laQK.png "在这里输入图片标题")
####16.trend包 趋势显示组件(如下图)
![输入图片说明](https://static.oschina.net/uploads/img/201904/12201600_Wo8K.png "在这里输入图片标题")

View File

@ -1,4 +1,8 @@
/**
* ascii1 2
* @param str
* @returns {number}
*/
export const getStrFullLength = (str = '') =>
str.split('').reduce((pre, cur) => {
const charCode = cur.charCodeAt(0)
@ -8,6 +12,12 @@ export const getStrFullLength = (str = '') =>
return pre + 2
}, 0)
/**
* ,
* @param str
* @param maxLength
* @returns {string}
*/
export const cutStrByFullLength = (str = '', maxLength) => {
let showLength = 0
return str.split('').reduce((pre, cur) => {

View File

@ -0,0 +1,68 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart ref="chart" :forceFit="true" :height="height" :data="dataSource" :scale="scale">
<v-tooltip/>
<v-axis/>
<v-line position="x*y" :size="lineSize"/>
<v-area position="x*y"/>
</v-chart>
</div>
</template>
<script>
import { triggerWindowResizeEvent } from '@/utils/util'
export default {
name: 'AreaChartTy',
props: {
// 图表数据
dataSource: {
type: Array,
required: true
},
// 图表标题
title: {
type: String,
default: ''
},
// x 轴别名
x: {
type: String,
default: 'x'
},
// y 轴别名
y: {
type: String,
default: 'y'
},
// 图表高度
height: {
type: Number,
default: 254
},
// 线的粗细
lineSize: {
type: Number,
default: 2
}
},
computed: {
scale() {
return [
{ dataKey: 'x', title: this.x, alias: this.x },
{ dataKey: 'y', title: this.y, alias: this.y }
]
}
},
mounted() {
triggerWindowResizeEvent()
}
}
</script>
<style lang="scss" scoped>
@import "chart";
</style>

View File

@ -1,57 +1,38 @@
<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-chart :forceFit="true" :height="height" :data="dataSource" :padding="padding">
<v-tooltip/>
<v-axis/>
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
const data = []
for (let i = 0; i < 12; i += 1) {
data.push({
x: `${i + 1}`,
y: Math.floor(Math.random() * 1000) + 200
})
}
const tooltip = [
'x*y',
(x, y) => ({
name: x,
value: y
})
]
const scale = [{
dataKey: 'x',
min: 2
}, {
dataKey: 'y',
title: '',
min: 1,
max: 22
}]
import { triggerWindowResizeEvent } from '@/utils/util'
export default {
name: "Bar",
name: 'Bar',
props: {
dataSource: {
type: Array,
required: true
},
title: {
type: String,
default: ''
},
height: {
type: Number,
default: 254
}
},
data () {
return {
data,
scale,
tooltip
}
data() {
return { padding: ['auto', 'auto', '40', '50'] }
},
mounted() {
triggerWindowResizeEvent()
}
}
</script>

View File

@ -0,0 +1,79 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :forceFit="true" :height="height" :data="data" :padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-legend />
<v-bar position="x*y" color="type" :adjust="adjust" />
</v-chart>
</div>
</template>
<script>
import { DataSet } from '@antv/data-set'
const sourceDataConst = [
{ type: 'Jeecg', 'Jan.': 18.9, 'Feb.': 28.8, 'Mar.': 39.3, 'Apr.': 81.4, 'May': 47, 'Jun.': 20.3, 'Jul.': 24, 'Aug.': 35.6 },
{ type: 'Jeebt', 'Jan.': 12.4, 'Feb.': 23.2, 'Mar.': 34.5, 'Apr.': 99.7, 'May': 52.6, 'Jun.': 35.5, 'Jul.': 37.4, 'Aug.': 42.4 }
];
const fieldsConst = ['Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'Jun.', 'Jul.', 'Aug.'];
export default {
name: 'BarMultid',
props: {
title: {
type: String,
default: ''
},
dataSource:{
type:Array,
default:()=>[]
},
fields:{
type:Array,
default:()=>[]
},
height: {
type: Number,
default: 254
}
},
data() {
return {
data:"",
adjust: [{
type: 'dodge',
marginRatio: 1 / 32,
}],
};
},
watch: {
'dataSource': function () {
this.drawChart();
}
},
mounted(){
this.drawChart()
},
methods:{
drawChart(){
let temp = sourceDataConst;
if(this.dataSource && this.dataSource.length>0){
temp = this.dataSource
}
const dv = new DataSet.View().source(temp);
dv.transform({
type: 'fold',
fields:(!this.fields||this.fields.length==0)?fieldsConst:this.fields,
key: 'x',
value: 'y',
});
this.data=dv.rows;
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,190 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
<v-coord type="polar" :startAngle="-202.5" :endAngle="22.5" :radius="0.75"></v-coord>
<v-axis
dataKey="value"
:zIndex="2"
:line="null"
:label="axisLabel"
:subTickCount="4"
:subTickLine="axisSubTickLine"
:tickLine="axisTickLine"
:grid="null"
></v-axis>
<v-axis dataKey="1" :show="false"></v-axis>
<v-series
gemo="point"
position="value*1"
shape="pointer"
color="#1890FF"
:active="false"
></v-series>
<v-guide
type="arc"
:zIndex="0"
:top="false"
:start="arcGuide1Start"
:end="arcGuide1End"
:vStyle="arcGuide1Style"
></v-guide>
<v-guide
type="arc"
:zIndex="1"
:start="arcGuide2Start"
:end="getArcGuide2End"
:vStyle="arcGuide2Style"
></v-guide>
<v-guide
type="html"
:position="htmlGuidePosition"
:html="getHtmlGuideHtml()"
></v-guide>
</v-chart>
</div>
</template>
<script>
import {registerShape} from 'viser-vue';
registerShape('point', 'pointer', {
draw(cfg, container) {
let point = cfg.points[0];
point = this.parsePoint(point);
const center = this.parsePoint({
x: 0,
y: 0,
});
container.addShape('line', {
attrs: {
x1: center.x,
y1: center.y,
x2: point.x,
y2: point.y + 15,
stroke: cfg.color,
lineWidth: 5,
lineCap: 'round',
}
});
return container.addShape('circle', {
attrs: {
x: center.x,
y: center.y,
r: 9.75,
stroke: cfg.color,
lineWidth: 4.5,
fill: '#fff',
}
});
}
});
const scale = [{
dataKey: 'value',
min: 0,
max: 9,
tickInterval: 1,
nice: false,
}];
const sourceData = [
{value: 6.7},
];
export default {
name: "DashChartDemo",
props: {
value: {
type: Number,
default: 6.7
},
title: {
type: String,
default: ''
},
height: {
type: Number,
default: 254
}
},
created() {
if (!this.value) {
this.data = sourceData;
} else {
this.data = [
{value: this.value},
];
}
this.getData()
},
watch: {
'value': function (val) {
this.data = [
{value: val},
];
this.getData();
}
},
methods: {
getData() {
if (this.data && this.data.length > 0) {
this.abcd = this.data[0].value * 10
} else {
this.abcd = 70
}
},
getHtmlGuideHtml() {
return '<div style="width: 300px;text-align: center;">\n' +
'<p style="font-size: 14px;color: #545454;margin: 0;">' + this.title + '</p>\n' +
'<p style="font-size: 36px;color: #545454;margin: 0;">' + this.abcd + '%</p>\n' +
'</div>'
},
getArcGuide2End() {
return [this.data[0].value, 0.945]
}
},
data() {
return {
data: [],
scale: scale,
abcd: 70,
axisLabel: {
offset: -16,
textStyle: {
fontSize: 18,
textAlign: 'center',
textBaseline: 'middle'
}
},
axisSubTickLine: {
length: -8,
stroke: '#fff',
strokeOpacity: 1,
},
axisTickLine: {
length: -17,
stroke: '#fff',
strokeOpacity: 1,
},
arcGuide1Start: [0, 0.945],
arcGuide1End: [9, 0.945],
arcGuide1Style: {
stroke: '#CBCBCB',
lineWidth: 18,
},
arcGuide2Start: [0, 0.945],
arcGuide2Style: {
stroke: '#1890FF',
lineWidth: 18,
},
htmlGuidePosition: ['50%', '100%'],
htmlGuideHtml: `
<div style="width: 300px;text-align: center;">
<p style="font-size: 14px;color: #545454;margin: 0;">${this.title}</p>
<p style="font-size: 36px;color: #545454;margin: 0;">${this.abcd}%</p>
</div>
`,
};
},
};
</script>

View File

@ -0,0 +1,100 @@
<template>
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<v-legend />
<v-line position="type*y" color="x" />
<v-point position="type*y" color="x" :size="4" :v-style="style" :shape="'circle'" />
</v-chart>
</div>
</template>
<script>
import { DataSet } from '@antv/data-set'
const sourceDataConst = [
{ type: 'Jan', jeecg: 7.0, jeebt: 3.9 },
{ type: 'Feb', jeecg: 6.9, jeebt: 4.2 },
{ type: 'Mar', jeecg: 9.5, jeebt: 5.7 },
{ type: 'Apr', jeecg: 14.5, jeebt: 8.5 },
{ type: 'May', jeecg: 18.4, jeebt: 11.9 },
{ type: 'Jun', jeecg: 21.5, jeebt: 15.2 },
{ type: 'Jul', jeecg: 25.2, jeebt: 17.0 },
{ type: 'Aug', jeecg: 26.5, jeebt: 16.6 },
{ type: 'Sep', jeecg: 23.3, jeebt: 14.2 },
{ type: 'Oct', jeecg: 18.3, jeebt: 10.3 },
{ type: 'Nov', jeecg: 13.9, jeebt: 6.6 },
{ type: 'Dec', jeecg: 9.6, jeebt: 4.8 }
];
export default {
name: 'LineChartMultid',
props: {
title: {
type: String,
default: ''
},
dataSource:{
type:Array,
default:()=>[]
},
fields:{
type:Array,
default: () => ['jeecg', 'jeebt']
},
height:{
type:Number,
default:254
}
},
data() {
return {
data:"",
scale: [{
dataKey: 'x',
min: 0,
max: 1
}],
style: { stroke: '#fff', lineWidth: 1 },
};
},
watch: {
'dataSource': function () {
this.drawChart();
}
},
mounted(){
this.drawChart()
},
methods:{
drawChart(){
let temp = sourceDataConst;
if (this.dataSource && this.dataSource.length > 0) {
temp = this.dataSource.map(item => {
// 为了防止直接修改源数据导致报错
let obj = Object.assign({}, item)
obj.type = obj.x
return obj
})
}
const dv = new DataSet.View().source(temp);
dv.transform({
type: 'fold',
fields: this.fields,
key: 'x',
value: 'y',
});
this.data=dv.rows;
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,19 +1,19 @@
<template>
<div>
<v-chart
:forceFit="true"
:height="height"
:width="width"
:data="data"
:scale="scale"
<v-chart
:forceFit="true"
:height="height"
:width="width"
:data="data"
:scale="scale"
:padding="0">
<v-tooltip />
<v-tooltip/>
<v-interval
:shape="['liquid-fill-gauge']"
position="transfer*value"
color=""
:v-style="{
lineWidth: 10,
lineWidth: 8,
opacity: 0.75
}"
:tooltip="[
@ -47,8 +47,15 @@
</template>
<script>
const sourceDataConst = [
{ transfer: '', value: 813 },
{ transfer: '', value: 233 },
{ transfer: '', value: 561 }
]
export default {
name: "Liquid",
name: 'Liquid',
props: {
height: {
type: Number,
@ -58,6 +65,12 @@
type: Number,
default: 0
}
},
data() {
return {
data: sourceDataConst,
scale: []
}
}
}
</script>

View File

@ -1,9 +1,9 @@
<template>
<div class="antv-chart-mini">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="height" :data="datasource" :padding="[36, 0, 18, 0]">
<v-tooltip />
<v-smooth-area position="x*y" />
<v-chart :force-fit="true" :height="height" :data="data" :scale="scale" :padding="[36, 0, 18, 0]">
<v-tooltip/>
<v-smooth-area position="x*y"/>
</v-chart>
</div>
</div>
@ -11,53 +11,55 @@
<script>
import moment from 'dayjs'
const data = []
const sourceData = []
const beginDay = new Date().getTime()
for (let i = 0; i < 10; i++) {
data.push({
sourceData.push({
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: Math.round(Math.random() * 10)
})
}
console.log("123321",data)
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",
props:{
datasource:{
name: 'MiniArea',
props: {
dataSource: {
type: Array,
default:()=>[]
default: () => []
},
// x 轴别名
x: {
type: String,
default: 'x'
},
// y 轴别名
y: {
type: String,
default: 'y'
}
},
created(){
if(this.datasource.length==0){
this.datasource = data;
}
},
data () {
data() {
return {
tooltip,
scale,
data: [],
height: 100
}
},
computed: {
scale() {
return [
{ dataKey: 'x', title: this.x, alias: this.x },
{ dataKey: 'y', title: this.y, alias: this.y }
]
}
},
created() {
if (this.dataSource.length === 0) {
this.data = sourceData
} else {
this.data = this.dataSource
}
}
}
</script>

View File

@ -1,21 +1,20 @@
<template>
<div class="antv-chart-mini">
<div class="chart-wrapper" :style="{ height: 46 }">
<v-chart :force-fit="true" :height="height" :data="datasource" :padding="[36, 5, 18, 5]">
<v-tooltip />
<v-bar position="x*y" />
</v-chart>
</div>
<div :style="{'width':width==null?'auto':width+'px'}">
<v-chart :forceFit="width==null" :height="height" :data="data" padding="0">
<v-tooltip/>
<v-bar position="x*y"/>
</v-chart>
</div>
</template>
<script>
import moment from 'dayjs'
const data = []
const sourceData = []
const beginDay = new Date().getTime()
for (let i = 0; i < 10; i++) {
data.push({
sourceData.push({
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
y: Math.round(Math.random() * 10)
})
@ -40,24 +39,33 @@
}]
export default {
name: "MiniBar",
props:{
datasource:{
name: 'MiniBar',
props: {
dataSource: {
type: Array,
default:()=>[]
default: () => []
},
width: {
type: Number,
default: null
},
height: {
type: Number,
default: 200
}
},
created(){
if(this.datasource.length==0){
this.datasource = data;
created() {
if (this.dataSource.length === 0) {
this.data = sourceData
} else {
this.data = this.dataSource
}
},
data () {
data() {
return {
data,
tooltip,
scale,
height: 100
data: [],
scale
}
}
}

View File

@ -1,26 +1,26 @@
<template>
<div class="chart-mini-progress">
<div class="target" :style="{ left: target + '%'}">
<span :style="{ backgroundColor: color }" />
<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 class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height+'px' }"></div>
</div>
</div>
</template>
<script>
export default {
name: "MiniProgress",
name: 'MiniProgress',
props: {
target: {
type: Number,
default: 0
},
height: {
type: String,
default: '10px'
type: Number,
default: 10
},
color: {
type: String,
@ -64,7 +64,7 @@
position: relative;
.progress {
transition: all .4s cubic-bezier(.08,.82,.17,1) 0s;
transition: all .4s cubic-bezier(.08, .82, .17, 1) 0s;
border-radius: 1px 0 0 1px;
background-color: #1890ff;
width: 0;

View File

@ -0,0 +1,83 @@
<template>
<v-chart :forceFit="true" :height="height" :data="data" :scale="scale">
<v-tooltip :showTitle="false" dataKey="item*percent"/>
<v-axis/>
<v-legend dataKey="item"/>
<v-pie position="percent" color="item" :v-style="pieStyle" :label="labelConfig"/>
<v-coord type="theta"/>
</v-chart>
</template>
<script>
const DataSet = require('@antv/data-set')
const sourceData = [
{ item: '', percent: 40 },
{ item: '', percent: 21 },
{ item: '', percent: 17 },
{ item: '', percent: 13 },
{ item: '', percent: 9 }
]
const scale = [{
dataKey: 'percent',
min: 0,
formatter: '.0%'
}]
export default {
props: {
title: {
type: String,
default: ''
},
height: {
type: Number,
default: 254
},
dataSource: {
type: Array,
default: () => []
}
},
created() {
this.change()
},
watch: {
'dataSource': function() {
this.change()
}
},
methods: {
change() {
if (this.dataSource.length === 0) {
this.data = sourceData
} else {
const dv = new DataSet.View().source(this.dataSource)
dv.transform({
type: 'percent',
field: 'count',
dimension: 'item',
as: 'percent'
})
this.data = dv.rows
}
}
},
data() {
return {
data: '',
scale,
pieStyle: {
stroke: '#fff',
lineWidth: 1
},
labelConfig: ['percent', {
formatter: (val, item) => {
return item.point.item + ': ' + val
}
}]
}
}
}
</script>

View File

@ -0,0 +1,328 @@
# 报表组件文档
## 柱状图
##### 引用方式
```js
import Bar from '@/components/chart/Bar'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|------------|
| title | string | | 报表标题 |
| dataSource | array | ✔️ | 报表数据源 |
| height | number | | 报表高度默认254 |
##### dataSource 示例
```json
[
{
"x": "1月",
"y": 320
},
{
"x": "2月",
"y": 457
},
{
"x": "3月",
"y": 182
}
]
```
## 多列柱状图
##### 引用方式
```js
import BarMultid from '@/components/chart/BarMultid'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|------------|
| title | string | | 报表标题 |
| fields | array | | 主列字段列表 |
| dataSource | array | | 报表数据源 |
| height | number | | 报表高度默认254 |
##### fields 示例
```json
["Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug."]
```
##### dataSource 示例
```json
[
{
"type": "Jeecg", // 列名
"Jan.": 18.9,
"Feb.": 28.8,
"Mar.": 39.3,
"Apr.": 81.4,
"May": 47,
"Jun.": 20.3,
"Jul.": 24,
"Aug.": 35.6
},
{
"type": "Jeebt",
"Jan.": 12.4,
"Feb.": 23.2,
"Mar.": 34.5,
"Apr.": 99.7,
"May": 52.6,
"Jun.": 35.5,
"Jul.": 37.4,
"Aug.": 42.4
}
]
```
## 迷你柱状图
不带标题和数据轴的柱状图
##### 引用方式
```js
import MiniBar from '@/components/chart/MiniBar'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|---------------|
| width | number | | 报表宽度度,默认自适应宽度 |
| height | number | | 报表高度默认200 |
| dataSource | array | | 报表数据源 |
##### dataSource 示例
```json
[
{
"x": "1月",
"y": 320
},
{
"x": "2月",
"y": 457
},
{
"x": "3月",
"y": 182
}
]
```
## 面积图
##### 引用方式
```js
import AreaChartTy from '@/components/chart/AreaChartTy'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|------------|
| title | string | | 报表标题 |
| dataSource | array | ✔️ | 报表数据源 |
| height | number | | 报表高度默认254 |
| lineSize | number | | 线的粗细默认2 |
##### dataSource 示例
```json
[
{
"x": "1月",
"y": 320
},
{
"x": "2月",
"y": 457
},
{
"x": "3月",
"y": 182
}
]
```
## 多行折线图
##### 引用方式
```js
import LineChartMultid from '@/components/chart/LineChartMultid'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|------------|
| title | string | | 报表标题 |
| fields | array | | 主列字段列表 |
| dataSource | array | | 报表数据源 |
| height | number | | 报表高度默认254 |
##### fields 示例
```json
["jeecg", "jeebt"]
```
##### dataSource 示例
```json
[
{
"type": "Jan", // 列名
"jeecg": 7,
"jeebt": 3.9
},
{ "type": "Feb", "jeecg": 6.9, "jeebt": 4.2 },
{ "type": "Mar", "jeecg": 9.5, "jeebt": 5.7 },
{ "type": "Apr", "jeecg": 14.5, "jeebt": 8.5 },
{ "type": "May", "jeecg": 18.4, "jeebt": 11.9 },
{ "type": "Jun", "jeecg": 21.5, "jeebt": 15.2 },
{ "type": "Jul", "jeecg": 25.2, "jeebt": 17 },
{ "type": "Aug", "jeecg": 26.5, "jeebt": 16.6 },
{ "type": "Sep", "jeecg": 23.3, "jeebt": 14.2 },
{ "type": "Oct", "jeecg": 18.3, "jeebt": 10.3 },
{ "type": "Nov", "jeecg": 13.9, "jeebt": 6.6 },
{ "type": "Dec", "jeecg": 9.6, "jeebt": 4.8 }
]
```
## 饼状图
##### 引用方式
```js
import Pie from '@/components/chart/Pie'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|------------|
| dataSource | array | | 报表数据源 |
| height | number | | 报表高度默认254 |
##### dataSource 示例
```json
[
// 所有的 percent 相加等于 100
{ "item": "一月", "percent": 40 },
{ "item": "二月", "percent": 21 },
{ "item": "三月", "percent": 17 },
{ "item": "四月", "percent": 13 },
{ "item": "五月", "percent": 9 }
]
```
## 雷达图
##### 引用方式
```js
import Radar from '@/components/chart/Radar'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|------------|
| dataSource | array | | 报表数据源 |
| height | number | | 报表高度默认254 |
##### dataSource 示例
```json
[
// score 最小值为 0最大值为 100
{ "item": "一月", "score": 40 },
{ "item": "二月", "score": 20 },
{ "item": "三月", "score": 67 },
{ "item": "四月", "score": 43 },
{ "item": "五月", "score": 90 }
]
```
## 进度条
##### 引用方式
```js
import MiniProgress from '@/components/chart/MiniProgress'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|------------|--------|----|-------------------|
| percentage | number | | 当前进度百分比默认0最高100 |
| target | number | | 目标值默认10 |
| height | number | | 进度条高度默认10 |
| color | string | | 进度条颜色,默认 #13C2C2 |
## 仪表盘
##### 引用方式
```js
import DashChartDemo from '@/components/chart/DashChartDemo'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|--------|--------|----|----------------|
| title | string | | 报表标题 |
| value | number | | 当前值默认6.7最大为9 |
| height | number | | 报表高度默认254 |
## 排名列表
##### 引用方式
```js
import RankList from '@/components/chart/RankList'
```
##### 参数列表
| 参数名 | 类型 | 必填 | 说明 |
|--------|--------|----|--------------|
| title | string | | 报表标题 |
| list | array | | 排名列表数据 |
| height | number | | 报表高度,默认自适应高度 |
##### list 示例
```json
[
{
"name": "北京朝阳 1 号店",
"total": 1981
},
{ "name": "北京朝阳 2 号店", "total": 1359 },
{ "name": "北京朝阳 3 号店", "total": 1354 },
{ "name": "北京朝阳 4 号店", "total": 263 },
{ "name": "北京朝阳 5 号店", "total": 446 },
{ "name": "北京朝阳 6 号店", "total": 796 }
]
```

View File

@ -1,12 +1,12 @@
<template>
<v-chart :forceFit="true" height="400" :data="data" :padding="[20, 20, 95, 20]" :scale="scale">
<v-chart :forceFit="true" :height="height" :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-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>
@ -38,26 +38,48 @@
{
dataKey: 'score',
min: 0,
max: 80
max: 100
}, {
dataKey: 'user',
alias: ''
}
]
const sourceData = [
{ item: '', score: 40 },
{ item: '', score: 20 },
{ item: '', score: 67 },
{ item: '', score: 43 },
{ item: '', score: 90 }
]
export default {
name: 'Radar',
props: {
data: {
height: {
type: Number,
default: 254
},
dataSource: {
type: Array,
default: null,
default: () => []
}
},
data () {
data() {
return {
axis1Opts,
axis2Opts,
scale
scale,
data: sourceData
}
},
watch: {
dataSource(newVal) {
if (newVal.length === 0) {
this.data = sourceData
} else {
this.data = newVal
}
}
}
}

View File

@ -1,7 +1,7 @@
<template>
<div class="rank">
<h4 class="title">{{ title }}</h4>
<ul class="list">
<ul class="list" :style="{height:height?`${height}px`:'auto',overflow:'auto'}">
<li :key="index" v-for="(item, index) in list">
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
<span>{{ item.name }}</span>
@ -23,6 +23,10 @@
list: {
type: Array,
default: null
},
height: {
type: Number,
default: null
}
}
}

View File

@ -2,63 +2,65 @@
<div :style="{ padding: '0 0 32px 32px' }">
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
<v-chart
height="254"
:height="height"
:data="data"
:scale="scale"
:forceFit="true"
:padding="['auto', 'auto', '40', '50']">
<v-tooltip />
<v-axis />
<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",
name: 'Bar',
props: {
title: {
type: String,
default: ''
},
x: {
type: String,
default: 'x'
},
y: {
type: String,
default: 'y'
},
data: {
type: Array,
default: () => []
},
height: {
type: Number,
default: 254
}
},
data () {
return {
data: [],
scale,
tooltip
data() {
return {}
},
computed: {
scale() {
return [
{ dataKey: 'x', title: this.x, alias: this.x },
{ dataKey: 'y', title: this.y, alias: this.y }
]
}
},
created () {
this.getMonthBar()
created() {
// this.getMonthBar()
},
methods: {
getMonthBar() {
this.$http.get('/analysis/month-bar')
.then(res => {
this.data = res.result
})
}
// getMonthBar() {
// this.$http.get('/analysis/month-bar')
// .then(res => {
// this.data = res.result
// })
// }
}
}
</script>

View File

@ -10,11 +10,13 @@
export default {
name: "Trend",
props: {
// 同title
term: {
type: String,
default: '',
required: true
},
// 百分比
percentage: {
type: Number,
default: null

View File

@ -9,10 +9,11 @@
import {ajaxGetDictItems} from '@/api/api'
export default {
name: "DictSelectTag",
name: "JDictSelectTag",
props: {
dictCode: String,
placeholder: String,
triggerChange: Boolean,
value: String,// 1.接收一个 value prop
},
data() {
@ -37,7 +38,11 @@
},
handleInput(val) {
console.log(val);
this.$emit('input', val); // 2.触发 input 事件,并传入新值
if(this.triggerChange){
this.$emit('change', val);
}else{
this.$emit('input', val);
}
}
}
}

View File

@ -37,6 +37,32 @@ export function filterDictText(dictOptions, text) {
return re;
}
/**
* ()
* @param dictOptions
* @param text
* @return String
*/
export function filterMultiDictText(dictOptions, text) {
if(!text){
return ""
}
let re = "";
let arr = text.split(",")
dictOptions.forEach(function (option) {
for(let i=0;i<arr.length;i++){
if (arr[i] === option.value) {
re += option.text+",";
break;
}
}
});
if(re==""){
return "";
}
return re.substring(0,re.length-1);
}
/**
*
* @param children

View File

@ -1,26 +1,42 @@
DictSelectTag 组件说明
===
例子
# JDictSelectTag 组件用法
----
<DictSelectTag v-model="queryParam.sex" placeholder="请输入用户性别" dictCode="sex"/>
- 从字典表获取数据,dictCode格式说明: 字典code
```html
<j-dict-select-tag v-model="queryParam.sex" placeholder="请输入用户性别"
dictCode="sex"/>
```
v-decorator用法
```html
<j-dict-select-tag v-decorator="['sex', {}]" :triggerChange="true" placeholder="请输入用户性别"
dictCode="sex"/>
```
- 从数据库表获取字典数据dictCode格式说明: 表名,文本字段,取值字段
```html
<j-dict-select-tag v-model="queryParam.username" placeholder="请选择用户名称"
dictCode="sys_user,realname,id"/>
```
DictSelectUtil.js 列表字典函数用法说明
===
例子
# JDictSelectUtil.js 列表字典函数用法
----
第一步: 引入依赖方法
import {initDictOptions, filterDictText} from '@/components/dict/DictSelectUtil'
- 第一步: 引入依赖方法
```html
import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil'
```
第二步: 在created()初始化方法执行字典配置方法
- 第二步: 在created()初始化方法执行字典配置方法
```html
//初始化字典配置
this.initDictConfig();
第三步: 实现initDictConfig方法加载列表所需要的字典(列表上有多个字典项就执行多次initDictOptions方法)
//sexDictOptions 自行定义
this.initDictConfig();
```
- 第三步: 实现initDictConfig方法加载列表所需要的字典(列表上有多个字典项就执行多次initDictOptions方法)
```html
initDictConfig() {
//初始化字典 - 性别
initDictOptions('sex').then((res) => {
@ -29,8 +45,12 @@ DictSelectUtil.js 列表字典函数用法说明
}
});
},
第四步实现字段的customRender方法
```
- 第四步: 实现字段的customRender方法
```html
customRender: (text, record, index) => {
//字典值替换通用方法
return filterDictText(this.sexDictOptions, text);
}
}
```

View File

@ -1,22 +0,0 @@
<template>
<span>
<!--// 1、当有数据输入时触发了该组件的input事件-->
<!--<input type="text" :value="value" @input="updateVal($event.target.value)">-->
<a-input :placeholder="placeholder" :value="value" @input="updateVal($event.target.value)"></a-input>
</span>
</template>
<script>
export default {
props: {
value: String,
placeholder: String
},
methods: {
updateVal: function(val) {
// 2、手动触发父组件的input事件并将值传给父组件
this.$emit('input', val);
}
}
}
</script>

View File

@ -1,7 +1,7 @@
import T from './DictSelectTag.vue'
const DictSelectTag = {
import T from './JDictSelectTag.vue'
const JDictSelectTag = {
install: function (Vue) {
Vue.component('DictSelectTag',T);
Vue.component('JDictSelectTag',T);
}
}
export default DictSelectTag;
export default JDictSelectTag;

View File

@ -0,0 +1,52 @@
<template>
<a-checkbox-group :options="options" :value="checkboxArray" @change="onChange" />
</template>
<script>
export default {
name: 'JCheckbox',
props: {
value:{
type: String,
required: false
},
readOnly:{
type: Boolean,
required: false,
default: false
},
options:{
type: Array,
required: true
},
triggerChange:{
type: Boolean,
required: false,
default: false
}
},
data(){
return {
checkboxArray:!this.value?[]:this.value.split(",")
}
},
watch:{
value (val) {
if(!val){
this.checkboxArray = []
}else{
this.checkboxArray = this.value.split(",")
}
}
},
methods:{
onChange (checkedValues) {
if(this.triggerChange){
this.$emit('change', checkedValues.join(","));
}else{
this.$emit('input', checkedValues.join(","));
}
},
}
}
</script>

View File

@ -20,7 +20,6 @@
},
value:{
type: String,
default: '',
required: false
},
dateFormat:{
@ -71,4 +70,5 @@
}
}
}
//note: do not set the prop value one default property
</script>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
<template>
<div class="tinymce-editor">
<editor
v-model="myValue"
:init="init"
:disabled="disabled"
@onClick="onClick">
</editor>
</div>
</template>
<script>
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver/theme'
import 'tinymce/plugins/image'
import 'tinymce/plugins/media'
import 'tinymce/plugins/table'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
export default {
components: {
Editor
},
props: {
value: {
type: String,
required:false
},
disabled: {
type: Boolean,
default: false
},
plugins: {
type: [String, Array],
default: 'lists image media table textcolor wordcount contextmenu'
},
toolbar: {
type: [String, Array],
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat'
}
},
data() {
return {
//初始化配置
init: {
language_url: '/tinymce/langs/zh_CN.js',
language: 'zh_CN',
skin_url: '/tinymce/skins/lightgray',
height: 300,
plugins: this.plugins,
toolbar: this.toolbar,
branding: false,
menubar: false,
images_upload_handler: (blobInfo, success) => {
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
success(img)
}
},
myValue: this.value
}
},
mounted() {
tinymce.init({})
},
methods: {
onClick(e) {
this.$emit('onClick', e, tinymce)
},
//可以添加一些自己的自定义事件,如清空内容
clear() {
this.myValue = ''
}
},
watch: {
value(newValue) {
this.myValue = newValue
},
myValue(newValue) {
console.log(newValue)
this.$emit('input', newValue)
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,29 @@
<template>
<a-tooltip placement="topLeft">
<template slot="title">
<span>{{value}}</span>
</template>
{{ value | ellipsis(length) }}
</a-tooltip>
</template>
<script>
export default {
name: 'JEllipsis',
props: {
value: {
type: String,
required: false,
},
length: {
type: Number,
required: false,
default: 25,
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,110 @@
<template>
<a-modal
title="导入EXCEL"
:width="600"
:visible="visible"
:confirmLoading="uploading"
@cancel="handleClose">
<a-upload
name="file"
:multiple="true"
accept=".xls,.xlsx"
:fileList="fileList"
:remove="handleRemove"
:beforeUpload="beforeUpload">
<a-button>
<a-icon type="upload" />
</a-button>
</a-upload>
<template slot="footer">
<a-button @click="handleClose"></a-button>
<a-button
type="primary"
@click="handleImport"
:disabled="fileList.length === 0"
:loading="uploading">
{{ uploading ? '...' : '' }}
</a-button>
</template>
</a-modal>
</template>
<script>
import { postAction } from '@/api/manage'
export default {
name: 'JImportModal',
props:{
url:{
type: String,
default: '',
required: false
}
},
data(){
return {
visible:false,
uploading:false,
fileList:[],
uploadAction:''
}
},
watch: {
url (val) {
if(val){
this.uploadAction = window._CONFIG['domianURL']+val
}
}
},
created () {
this.uploadAction = window._CONFIG['domianURL']+this.url
},
methods:{
handleClose(){
this.visible=false
},
show(){
this.fileList = []
this.uploading = false
this.visible = true
},
handleRemove(file) {
const index = this.fileList.indexOf(file);
const newFileList = this.fileList.slice();
newFileList.splice(index, 1);
this.fileList = newFileList
},
beforeUpload(file) {
this.fileList = [...this.fileList, file]
return false;
},
handleImport() {
const { fileList } = this;
const formData = new FormData();
fileList.forEach((file) => {
formData.append('files[]', file);
});
this.uploading = true
postAction(this.uploadAction, formData).then((res) => {
this.uploading = false
if(res.success){
this.$message.success(res.message)
this.visible=false
this.$emit('ok')
}else{
this.$message.warning(res.message)
}
})
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,65 @@
<template>
<a-select :value="arrayValue" @change="onChange" mode="multiple" :placeholder="placeholder">
<a-select-option
v-for="(item,index) in options"
:key="index"
:value="item.value">
{{ item.text }}
</a-select-option>
</a-select>
</template>
<script>
//option {label:,value:}
export default {
name: 'JSelectMultiple',
props: {
placeholder:{
type: String,
default:'',
required: false
},
value:{
type: String,
required: false
},
readOnly:{
type: Boolean,
required: false,
default: false
},
options:{
type: Array,
required: true
},
triggerChange:{
type: Boolean,
required: false,
default: false
}
},
data(){
return {
arrayValue:!this.value?[]:this.value.split(",")
}
},
watch:{
value (val) {
if(!val){
this.arrayValue = []
}else{
this.arrayValue = this.value.split(",")
}
}
},
methods:{
onChange (selectedValue) {
if(this.triggerChange){
this.$emit('change', selectedValue.join(","));
}else{
this.$emit('input', selectedValue.join(","));
}
},
}
}
</script>

View File

@ -0,0 +1,152 @@
<template>
<a-modal
title="高级查询构造器"
:width="800"
:visible="visible"
:confirmLoading="confirmLoading"
@cancel="handleCancel"
:mask="false"
wrapClassName="ant-modal-cust-warp"
style="top:5%;max-height: 95%;">
<template slot="footer">
<a-button @click="handleCancel"> </a-button>
<a-button @click="handleReset" style="float: left"> </a-button>
<a-button type="primary" @click="handleOk"> </a-button>
</template>
<a-spin :spinning="confirmLoading">
<a-form>
<div>
<a-row type="flex" style="margin-bottom:10px" :gutter="16" v-for="(item, index) in queryParamsModel" :key="index">
<a-col :span="6">
<a-select placeholder="选择查询字段" v-model="item.field" @select="(val,option)=>handleSelected(option,item)">
<a-select-option v-for="(f,fIndex) in fieldList" :key=" 'field'+fIndex" :value="f.value" :data-type="f.type">{{ f.text }}</a-select-option>
</a-select>
</a-col>
<a-col :span="6">
<a-select placeholder="选择匹配规则" v-model="item.rule">
<a-select-option value="eq"></a-select-option>
<a-select-option value="ne"></a-select-option>
<a-select-option value="gt"></a-select-option>
<a-select-option value="ge"></a-select-option>
<a-select-option value="lt"></a-select-option>
<a-select-option value="le"></a-select-option>
<a-select-option value="right_like">..</a-select-option>
<a-select-option value="left_like">..</a-select-option>
<a-select-option value="like"></a-select-option>
<a-select-option value="in">...</a-select-option>
</a-select>
</a-col>
<a-col :span="6">
<j-date v-if=" item.type=='date' " v-model="item.val" placeholder="请选择日期"></j-date>
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss"></j-date>
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
<a-input v-else v-model="item.val" placeholder="请输入值" />
</a-col>
<a-col :span="6">
<a-button @click="handleAdd" icon="plus"></a-button>&nbsp;
<a-button @click="handleDel( index )" icon="minus"></a-button>
</a-col>
</a-row>
</div>
</a-form>
</a-spin>
</a-modal>
</template>
<script>
import ACol from 'ant-design-vue/es/grid/Col'
import JDate from '@/components/jeecg/JDate.vue';
export default {
name: 'JSuperQuery',
components: {
ACol,
JDate
},
data(){
return {
visible:false,
confirmLoading:false,
queryParamsModel:[{}]
}
},
props:{
/* fieldList:[{value:'',text:'',type:''}]
* type:date datetime int number string
* */
fieldList:{
type:Array,
required:true
},
/*
*
* */
callback:{
type:String,
required:false,
default:'handleSuperQuery'
}
},
methods:{
show(){
if(!this.queryParamsModel ||this.queryParamsModel.length==0){
this.queryParamsModel = [{}]
}
this.visible = true;
},
handleOk(){
console.log("---高级查询参数--->",this.queryParamsModel)
if(!this.isNullArray()){
this.$emit(this.callback, this.queryParamsModel)
}else{
this.$emit(this.callback)
}
},
handleCancel(){
this.close()
},
close () {
this.$emit('close');
this.visible = false;
},
handleAdd () {
this.queryParamsModel.push({});
},
handleDel (index) {
this.queryParamsModel.splice(index,1);
this.$message.warning("请关闭后重新打开")
},
handleSelected(option,item){
item['type'] = option.data.attrs['data-type']
},
handleReset(){
this.queryParamsModel=[{}]
this.$emit(this.callback)
},
isNullArray(){
//判断是不是空数组对象
if(!this.queryParamsModel || this.queryParamsModel.length==0){
return true
}
if(this.queryParamsModel.length==1){
let obj = this.queryParamsModel[0]
if(!obj.field || !obj.val || !obj.rule){
return true
}
}
return false;
}
}
}
</script>
<style >
</style>

View File

@ -1,43 +1,198 @@
日期组件
说明antd-vue日期组件需要用moment中转一下用起来不是很方便特二次封装使用时只需要传字符串即可
====
参数说明
----
placeholderplaceholder
readOnlytrue/false
value绑定v-model或是v-decorator后不需要设置
showTime是否展示时间true/false
dateFormat日期格式 默认'YYYY-MM-DD' 若showTime设置为true则需要将其设置成对应的时间格式(如YYYY-MM-DD HH:mm:ss)
triggerChange触发组件值改变的事件是否是change,当使用v-decorator时且没有设置decorator的option.trigger为input需要设置该值为true
# JDate 日期组件 使用文档
###### 说明: antd-vue日期组件需要用moment中转一下用起来不是很方便特二次封装使用时只需要传字符串即可
## 参数配置
| 参数 | 类型 | 必填 |说明|
|--------------|---------|----|---------|
| placeholder |string | | placeholder |
| readOnly | boolean | | true/false 默认false |
| value | string | | 绑定v-model或是v-decorator后不需要设置 |
| showTime | boolean | | 是否展示时间true/false 默认false |
| dateFormat | string | |日期格式 默认'YYYY-MM-DD' 若showTime设置为true则需要将其设置成对应的时间格式(如:YYYY-MM-DD HH:mm:ss) |
| triggerChange | string | |触发组件值改变的事件是否是change,当使用v-decorator时且没有设置decorator的option.trigger为input需要设置该值为true |
使用示例
----
1.组件带有v-model的使用方法
```vue
<j-date v-model="dateStr"></j-date>
```
2.组件带有v-decorator的使用方法
2.组件带有v-decorator的使用方法
a).设置trigger-change属性为true
```vue
<j-date :trigger-change="true" v-decorator="['dateStr',{}]"></j-date>
```
b).设置decorator的option.trigger为input
```vue
<j-date v-decorator="['dateStr',{trigger:'input'}]"></j-date>
```
3.其他使用
添加style
<j-date v-model="dateStr" style="width:100%"></j-date>
```vue
<j-date v-model="dateStr" style="width:100%"></j-date>
```
添加placeholder
<j-date v-model="dateStr" placeholder="请输入dateStr"></j-date>
```vue
<j-date v-model="dateStr" placeholder="请输入dateStr"></j-date>
```
添加readOnly
<j-date v-model="dateStr" :read-only="true"></j-date>
```vue
<j-date v-model="dateStr" :read-only="true"></j-date>
```
备注:
script内需引入jdate
```vue
<script>
import JDate from '@/components/jeecg/JDate'
export default {
name: "demo",
components: {
JDate
}
//...
}
</script>
```
---
# JSuperQuery 高级查询 使用文档
## 参数配置
| 参数 | 类型 | 必填 | 说明 |
|--------------|---------|----|----------------------|
| fieldList | array |✔| 需要查询的列集合示例如下type类型有:date/datetime/string/int/number |
| callback | array | | 回调函数名称(非必须)默认handleSuperQuery |
fieldList结构示例
```vue
const superQueryFieldList=[{
type:"date",
value:"birthday",
text:"生日"
},{
type:"string",
value:"name",
text:"用户名"
},{
type:"int",
value:"age",
text:"年龄"
}]
```
页面代码概述:
----
1.import之后再components之内声明
```vue
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
export default {
name: "JeecgDemoList",
components: {
JSuperQuery
},
....
</script>
```
2.页面引用
```vue
<!-- 高级查询区域 -->
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
```
3.list页面data中需要定义三个属性
```vue
fieldList:superQueryFieldList,
superQueryFlag:false,
superQueryParams:""
```
4.list页面声明回调事件handleSuperQuery(与组件的callback对应即可)
```vue
//高级查询方法
handleSuperQuery(arg) {
if(!arg){
this.superQueryParams=''
this.superQueryFlag = false
}else{
this.superQueryFlag = true
this.superQueryParams=JSON.stringify(arg)
}
this.loadData()
},
```
5.改造list页面方法
```vue
// 获取查询条件
getQueryParams() {
let sqp = {}
if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams)
}
var param = Object.assign(sqp, this.queryParam, this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
```
6.打开弹框调用show方法
```vue
this.$refs.superQueryModal.show();
```
# JEllipsis 字符串超长截取省略号显示
###### 说明: 遇到超长文本展示,通过此标签可以截取省略号显示,鼠标放置会提示全文本
## 参数配置
| 参数 | 类型 | 必填 | 说明 |
|--------|---------|----|----------------|
| value |string | 必填 | 字符串文本|
| length | number | 非必填 | 默认25 |
使用示例
----
1.组件带有v-model的使用方法
```vue
<j-ellipsis :value="text"/>
# Modal弹框实现最大化功能
1.定义modal的宽度
```vue
<a-modal
:width="modalWidth"
/>
```
2.自定义modal的title,居右显示切换图标
```vue
<template slot="title">
<div style="width: 100%;">
<span>{{ title }}</span>
<span style="display:inline-block;width:calc(100% - 51px);padding-right:10px;text-align: right">
<a-button @click="toggleScreen" icon="appstore" style="height:20px;width:20px;border:0px"></a-button>
</span>
</div>
</template>
```
3.定义toggleScreen事件,用于切换modal宽度
```vue
toggleScreen(){
if(this.modaltoggleFlag){
this.modalWidth = window.innerWidth;
}else{
this.modalWidth = 800;
}
this.modaltoggleFlag = !this.modaltoggleFlag;
},
```
4.data中声明上述用到的属性
```vue
data () {
return {
modalWidth:800,
modaltoggleFlag:true,
```

View File

@ -0,0 +1,396 @@
# JEditableTable 帮助文档
## 参数配置
| 参数 | 类型 | 必填 | 说明 |
|--------------|---------|----|---------------------------------|
| columns | array | ✔️ | 表格列的配置描述,具体项见下表 |
| dataSource | array | ✔️ | 表格数据 |
| loading | boolean | | 是否正在加载加载中不会显示任何行默认false |
| actionButton | boolean | | 是否显示操作按钮,包括"新增"、"删除"默认false |
| rowNumber | boolean | | 是否显示行号默认false |
| rowSelection | boolean | | 是否可选择行默认false |
| maxHeight | number | | 设定最大高度(px)默认400 |
| disabledRows | object | | 设定禁用的行,被禁用的行无法被选择和编辑,配置方法可以查看示例 |
### columns 参数详解
| 参数 | 类型 | 必填 | 说明 |
|---------------|--------|----|----------------------------------------------------------------------|
| title | string | ✔️ | 表格列头显示的问题 |
| key | string | ✔️ | 列数据在数据项中对应的 key必须是唯一的 |
| type | string | ✔️ | 表单的类型,可以通过`JEditableTableUtil.FormTypes`赋值 |
| width | string | | 列的宽度,可以是百分比,也可以是`px`或其他单位建议设置为百分比且每一列的宽度加起来不应超过100%,否则可能会不能达到预期的效果。留空会自动计算百分比 |
| placeholder | string | | 表单预期值的提示信息,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式` |
| defaultValue | string | | 默认值,在新增一行时生效 |
| validateRules | array | | 表单验证规则,配置方式见[validateRules 配置规则](#validaterules-配置规则) |
| props | object | | 设置添加给表单元素的自定义属性,例如:`props:{title: 'show title'}` |
#### 当 type=checkbox 时所需的参数
| 参数 | 类型 | 必填 | 说明 |
|----------------|---------|----|------------------------------------------------------------------------------------------------------------------------------------------|
| defaultChecked | boolean | | 默认值是否选中 |
| customValue | array | | 自定义值checkbox需要的是boolean值如果数据是其他值例如`'Y' or 'N'`)时,就会导致错误,所以提供了该属性进行转换,例:`customValue: ['Y','N']`,会将`true`转换为`'Y'``false`转换为`'N'`,反之亦然 |
#### 当 type=select 时所需的参数
| 参数 | 类型 | 必填 | 说明 |
|---------|-------|----|-------------|
| options | array | ✔️ | 下拉选项列表,详见下表 |
##### options 所需参数
| 参数 | 类型 | 必填 | 说明 |
|-------|--------|----|------|
| title | string | ✔️ | 显示标题 |
| value | string | ✔️ | 真实值 |
### validateRules 配置规则
`validateRules` 需要的是一个数组数组里每项都是一个规则规则是object类型规则的各个参数如下
- `required` 是否必填,可选值为`true`or`false`
- `pattern` 正则表达式验证,只有成功匹配该正则的值才能成功通过验证
- `message` 当验证未通过时显示的提示文本,可以使用`${...}`变量替换文本(详见`${...} 变量使用方式`
- 配置示例请看[示例二](#示例二)
## 事件
| 事件名 | 触发时机 | 参数 |
|-----------------|---------------------------|--------------------------|
| added | 当添加行操作完成后触发 | |
| deleted | 当删除行操作完成后触发(批量删除操作只会触发一次) | `deleteIds` 被逻辑删除的id |
| selectRowChange | 当行被选中或取消选中时触发 | `selectedRowIds` 被选中行的id |
## 方法
关于方法的如何调用的问题,请在**FAQ**中查看[方法如何调用](#方法如何调用)
### initialize
用于初始化表格(清空表格)
- `参数:`
- `返回值:`
### resetScrollTop
重置滚动条Top位置
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|-----|--------|----|--------------------------------------------------------|
| top | number | | 新top位置留空则滚动到上次记录的位置用于解决切换tab选项卡时导致白屏以及自动将滚动条滚动到顶部的问题 |
- `返回值:`
### add
主动添加行,默认情况下,当用户的滚动条已经在底部的时候,会将滚动条固定在底部,即添加后无需用户手动滚动,而会自动滚动到底部
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|---------------------|---------|----|--------------------------------------|
| num | number | | 添加几行默认为1 |
| forceScrollToBottom | boolean | | 是否在添加后无论用户的滚动条在什么位置都强制滚动到底部默认为false |
- `返回值:`
### removeRows
主动删除一行或多行
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|-----|----------------|----|--------------------------------------------------|
| id | string 或 array | ✔️ | 被删除行的id。如果要删除一个可以直接传id如果要删除多个需要将多个id封装成一个数组传入 |
- `返回值:`
### removeSelectedRows
主动删除被选中的行
- `参数:`
- `返回值:`
### getValues
用于获取表格里所有表单的值,可进行表单验证
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|----------|----------|----|-----------------------------------------------------------------------------------------------|
| callback | function | ✔️ | 获取值的回调方法,会传入`error`和`values`两个参数。`error`:未通过验证的数量,当等于`0`时代表验证通过;`values`:获取的值(即使未通过验证该字段也有数据) |
| validate | boolean | | 是否进行表单验证,默认为`true`,设为`false`则代表忽略表单验证 |
- `返回值:`
### getValuesPromise
`getValues`的promise版会在`resolve`中传入获取到的值,会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|----------|---------|----|---------------------------|
| validate | boolean | | 同`getValues`的`validate`参数 |
- `返回值:` Promise
### getDeleteIds
用于获取被逻辑删除的行的id返回一个数组用户可将该数组传入后台并进行批量删除
- `参数:`
- `返回值:` array
### getAll
获取所有的数据包括values、deleteIds
会在`resolve`中传入获取到的值:`{values, deleteIds}`
会在`reject`中传入失败原因,例如`VALIDATE_NO_PASSED`
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|----------|---------|----|---------------------------|
| validate | boolean | | 同`getValues`的`validate`参数 |
- `返回值:` Promise
### setValues
主动设置表格中某行某列的值
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|--------|-------|----|-------------------------------|
| values | array | | 传入一个数组,数组中的每项都是一行的新值,具体见下面的示例 |
- `返回值:`
- `示例:`
```js
setValues([
{
rowKey: id1, // 行的id
values: { // 在这里 values 中的 name 是你 columns 中配置的 key
'name': 'zhangsan',
'age': '20'
}
},
{
rowKey: id2,
values: {
'name': 'lisi',
'age': '23'
}
}
])
```
## ${...} 变量使用方式
在`placeholder`和`message`这两个属性中可以使用`${...}`变量来替换文本
在[示例二](#示例二)中,配置了`title`为`名称`的一列,而`placeholder`配置成了`请输入${title}`,那么最终显示效果为`请输入名称`
这就是`${...}`变量的使用方式,在`${}`中可以使用的变量有`title`、`key`、`defaultValue`这三个属性的值
## JEditableTableUtil 使用说明
在之前配置`columns`时提到过`JEditableTableUtil`这个工具类,那么如果想要知道详细的使用说明就请看这里
### export 的常量
#### FormTypes
这是配置`columns.type`时用到的常量值,其中包括
- `normal` 默认,直接显示值,不渲染表单
- `input` 显示输入框
- `inputNumber` 显示数字输入框
- `checkbox` 显示多选框
- `select` 显示选择器(下拉框)
- `date` 日期选择器
- `datetime` 日期时间选择器
### VALIDATE_NO_PASSED
在判断表单验证是否通过时使用,如果 reject 的值 === VALIDATE_NO_PASSED 则代表表单验证未通过,你可以做相应的其他处理,反之则可能是发生了报错,可以使用 `console.error` 输出
### 封装的方法
#### validateTables
当你的页面中存在多个JEditableTable实例的时候如果要获取每个实例的值、判断表单验证是否通过就会让代码变得极其冗余、繁琐于是我们就将该操作封装成了一个函数供你调用它可以同时获取并验证多个JEditableTable实例的值只有当所有实例的表单验证都通过后才会返回值否则将会告诉你具体哪个实例没有通过验证。具体使用方法请看下面的示例
- `参数:`
| 参数名 | 类型 | 必填 | 说明 |
|-------|-------|----|------------------------------------|
| cases | array | | 传入一个数组数组中的每项都是一个JEditableTable的实例 |
- `返回值:` Promise
- `示例:`
```js
import { validateTables, VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
// 封装cases
let cases = []
cases.push(this.$refs.editableTable1)
cases.push(this.$refs.editableTable2)
cases.push(this.$refs.editableTable3)
cases.push(this.$refs.editableTable4)
cases.push(this.$refs.editableTable5)
// 同时验证并获取多个实例的值
validateTables(cases).then((all) => {
// all 是一个数组每项都对应传入cases的下标包含values和deleteIds
console.log('所有实例的值:', all)
}).catch((e = {}) => {
// 判断表单验证是否未通过
if (e.error === VALIDATE_NO_PASSED) {
console.log('未通过验证的实例下标:', e.index)
} else {
console.error('发生异常:', e)
}
})
```
## FAQ
### 方法如何调用?
在[示例一](#示例一)中,设定了一个 `ref="editableTable"` 的属性那么在vue中就可以使用`this.$refs.editableTable`获取到该表格的实例,并调取其中的方法。
假如我要调取`initialize`方法,就可以这么写:`this.$refs.editableTable.initialize()`
### 如何获取表单的值?
使用`getValue`方法进行获取,详见[示例三](#示例三)
### 如何进行表单验证?
在获取值的时候默认会进行表单验证操作,用户在输入的时候也会对正在输入的表单进行验证,只要配置好规则就可以了
### 如何添加或删除一行?
该功能已封装到组件中,你只需要将 `actionButton` 设置为 `true` 即可,当然你也可以在代码中主动调用新增方法或修改,具体见上方的方法介绍。
### 为什么使用了ATab组件后切换选项卡会导致白屏或滚动条位置会归零
在ATab组件中确实会导致滚动条位置归零且不会触发`onscroll`方法,所以无法动态加载行,导致白屏的问题出现。
解决方法是在ATab组件的`onChange`事件触发时执行`resetScrollTop()`即可但是需要注意的是代码主动改变ATab的`activeKey`不会触发`onChange`事件,还需要你手动调用下
- `示例`
```html
<template>
<a-tabs @change="handleChangeTab">
<a-tab-pane tab="表格1" :forceRender="true" key="1">
<j-editable-table
ref="editableTable1"
:loading="tab1.loading"
:columns="tab1.columns"
:dataSource="tab1.dataSource"/>
</a-tab-pane>
<a-tab-pane tab="表格2" :forceRender="true" key="2">
<j-editable-table
ref="editableTable2"
:loading="tab2.loading"
:columns="tab2.columns"
:dataSource="tab2.dataSource"/>
</a-tab-pane>
</a-tabs>
</template>
```
```js
/*--- 忽略部分代码片段 ---*/
methods: {
/** 切换tab选项卡的时候重置editableTable的滚动条状态 */
handleChangeTab(key) {
this.$refs[`editableTable${key}`].resetScrollTop()
}
}
/*--- 忽略部分代码片段 ---*/
```
----
## 示例一
```html
<j-editable-table
ref="editableTable"
:loading="loading"
:columns="columns"
:dataSource="dataSource"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"
style="margin-top: 8px;"
@selectRowChange="handleSelectRowChange"/>
```
## 示例二
```js
import { FormTypes } from '@/utils/JEditableTableUtil'
/*--- 忽略部分代码片断 ---*/
columns: [
{
title: '名称',
key: 'name',
type: FormTypes.input,
placeholder: '请输入${title}',
defaultValue: '称名',
// 表单验证规则
validateRules: [
{
required: true, // 必填
message: '${title}不能为空' // 提示的文本
},
{
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
message: '${title}必须以字母开头,可包含数字、下划线、横杠'
}
]
},
{
title: '年龄',
key: 'age',
type: FormTypes.inputNumber,
placeholder: '请输入${title}',
defaultValue: 18,
validateRules: [{required: true, message: '${title}不能为空'}]
}
]
/*--- 忽略部分代码片断 ---*/
```
## 示例三
```js
// 获取被逻辑删除的字段id
let deleteIds = this.$refs.editableTable.getDeleteIds();
// 获取所有表单的值,并进行验证
this.$refs.editableTable.getValues((error, values) => {
// 错误数 = 0 则代表验证通过
if (error === 0) {
this.$message.success('验证通过')
// 将通过后的数组提交到后台或自行进行其他处理
console.log(deleteIds, values)
} else {
this.$message.error('验证未通过')
}
})
```

View File

@ -0,0 +1,309 @@
<template>
<a-modal
:width="modalWidth"
:visible="visible"
:title="title"
@ok="handleSubmit"
@cancel="close"
cancelText="关闭"
style="margin-top: -70px"
wrapClassName="ant-modal-cust-warp"
>
<a-row :gutter="10" style="background-color: #ececec; padding: 10px; margin: -10px">
<a-col :md="6" :sm="24">
<a-card :bordered="false">
<!---->
<a-directory-tree
selectable
:selectedKeys="selectedKeys"
:checkStrictly="true"
@select="this.onSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
/>
</a-card>
</a-col>
<a-col :md="18" :sm="24">
<a-card :bordered="false">
:
<a-input-search
:style="{width:'150px',marginBottom:'15px'}"
placeholder="请输入用户名搜索"
v-model="queryParam.username"
@search="onSearch"
></a-input-search>
<a-button @click="searchReset(1)" style="margin-left: 20px" icon="redo"></a-button>
<!---->
<a-table
ref="table"
:scroll="scrollTrigger"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
</a-table>
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
import { filterObj } from '@/utils/util'
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
export default {
name: 'JSearchUserByDep',
components: {},
data() {
return {
queryParam: {
username:"",
},
columns: [
{
title: '',
align: 'center',
dataIndex: 'username'
},
{
title: '',
align: 'center',
dataIndex: 'realname'
},
{
title: '',
align: 'center',
dataIndex: 'roleName'
},
{
title: '',
align: 'center',
dataIndex: 'sex',
customRender: function(text) {
if (text === 1) {
return '男'
} else if (text === 2) {
return '女'
} else {
return text
}
}
},
{
title: '',
align: 'center',
dataIndex: 'phone'
},
{
title: '',
align: 'center',
dataIndex: 'email'
}
],
scrollTrigger: {},
dataSource: [],
selectedKeys: [],
userNameArr: [],
departName: '',
userRolesMap: {},
title: '',
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' ' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter: {
column: 'createTime',
order: 'desc'
},
selectedRowKeys: [],
selectedRows: [],
modalWidth: 1250,
departTree: [],
visible: false,
form: this.$form.createForm(this)
}
},
created() {
// 该方法触发屏幕自适应
this.resetScreenSize();
this.queryUserRoleMap();
},
methods: {
loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
let params = this.getQueryParams();//查询条件
getUserList(params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.assignRoleName(this.dataSource);
this.ipagination.total = res.result.total;
}
})
},
queryUserRoleMap(){
queryUserRoleMap().then((res) => {
if (res.success) {
this.userRolesMap = res.result;
this.loadData();
}
})
},
// 触发屏幕自适应
resetScreenSize() {
let screenWidth = document.body.clientWidth;
if (screenWidth < 500) {
this.scrollTrigger = { x: 800 };
} else {
this.scrollTrigger = {};
}
},
showModal() {
this.visible = true;
this.assignRoleName(this.dataSource);
this.queryDepartTree();
this.form.resetFields();
},
getQueryParams() {
let param = Object.assign({}, this.queryParam, this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
let str = 'id,';
for (let a = 0; a < this.columns.length; a++) {
str += ',' + this.columns[a].dataIndex;
}
return str;
},
searchReset(num) {
let that = this;
that.selectedRowKeys = [];
that.userNameArr = [];
that.queryParam = {};
that.selectedKeys = [];
if(num !== 0){
that.loadData();
}
},
close() {
this.searchReset(0);
this.visible = false;
},
handleTableChange(pagination, filters, sorter) {
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
}
this.ipagination = pagination;
this.loadData();
},
handleSubmit() {
let that = this;
for (let i = 0, len = this.selectedRowKeys.length; i < len; i++) {
this.getUserNames(this.selectedRowKeys[i]);
}
that.$emit('ok', that.userNameArr.join(','));
that.close();
},
// 遍历匹配,获取用户真实姓名
getUserNames(rowId) {
let dataSource = this.dataSource;
for (let i = 0, len = dataSource.length; i < len; i++) {
if (rowId === dataSource[i].id) {
this.userNameArr.push(dataSource[i].realname);
}
}
},
// 点击树节点,筛选出对应的用户
onSelect(selectedKeys) {
if (selectedKeys[0] != null) {
this.queryUserByDepId(selectedKeys); // 调用方法根据选选择的id查询用户信息
if (this.selectedKeys[0] !== selectedKeys[0]) {
this.selectedKeys = [selectedKeys[0]];
}
}
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onSearch() {
this.loadData(1);
},
// 根据选择的id来查询用户信息
queryUserByDepId(selectedKeys) {
queryUserByDepId({ id: selectedKeys.toString() }).then((res) => {
if (res.success) {
this.dataSource = res.result;
this.ipagination.total = res.result.length;
this.assignRoleName(this.dataSource);
}
})
},
// 传入用户id,找到匹配的角色名称
queryUserRole(userId) {
let map = this.userRolesMap;
let roleName = [];
for (var key in map) {
if (userId === key) {
roleName.push(map[key]);
}
}
return roleName.join(',');
},
queryDepartTree() {
queryDepartTreeList().then((res) => {
if (res.success) {
this.departTree = res.result;
}
})
},
// 为角色名称赋值
assignRoleName(data) {
let userId = '';
let role = '';
for (let i = 0, length = data.length; i < length; i++) {
userId = this.dataSource[i].id;
role = this.queryUserRole(userId);
this.dataSource[i].roleName = role;
}
},
modalFormOk() {
this.loadData();
}
}
}
</script>
<style scoped>
.ant-table-tbody .ant-table-row td {
padding-top: 10px;
padding-bottom: 10px;
}
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color .3s;
}
</style>

View File

@ -0,0 +1,309 @@
<template>
<a-modal
:width="modalWidth"
:visible="visible"
:title="title"
@ok="handleSubmit"
@cancel="close"
cancelText="关闭"
style="margin-top: -70px"
wrapClassName="ant-modal-cust-warp"
>
<a-row :gutter="10" style="background-color: #ececec; padding: 10px; margin: -10px">
<a-col :md="6" :sm="24">
<a-card :bordered="false">
<!---->
<a-directory-tree
selectable
:selectedKeys="selectedKeys"
:checkStrictly="true"
@select="this.onSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
/>
</a-card>
</a-col>
<a-col :md="18" :sm="24">
<a-card :bordered="false">
:
<a-input-search
:style="{width:'150px',marginBottom:'15px'}"
placeholder="请输入用户名搜索"
v-model="queryParam.username"
@search="onSearch"
/>
<a-button @click="searchReset" style="margin-left: 20px" icon="redo"></a-button>
<!---->
<a-table
ref="table"
:scroll="scrollTrigger"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
</a-table>
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
import { filterObj } from '@/utils/util'
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
export default {
name: 'JSearchUserByDepModal',
components: {},
data() {
return {
queryParam: {},
columns: [
{
title: '',
align: 'center',
dataIndex: 'username'
},
{
title: '',
align: 'center',
dataIndex: 'realname'
},
{
title: '',
align: 'center',
dataIndex: 'roleName'
},
{
title: '',
align: 'center',
dataIndex: 'sex',
customRender: function(text) {
if (text === 1) {
return '男'
} else if (text === 2) {
return '女'
} else {
return text
}
}
},
{
title: '',
align: 'center',
dataIndex: 'phone'
},
{
title: '',
align: 'center',
dataIndex: 'email'
}
],
scrollTrigger: {},
dataSource: [],
userDataSource:[],
selectedKeys: [],
userNameArr: [],
departName: '',
userRolesMap: {},
title: '',
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' ' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter: {
column: 'createTime',
order: 'desc'
},
selectedRowKeys: [],
selectedRows: [],
modalWidth: 1250,
departTree: [],
visible: false,
form: this.$form.createForm(this)
}
},
created() {
// 该方法触发屏幕自适应
this.resetScreenSize();
this.queryUserRoleMap();
},
methods: {
loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
let params = this.getQueryParams();//查询条件
getUserList(params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.userDataSource = res.result.records;
this.assignRoleName(this.dataSource);
this.ipagination.total = res.result.total;
}
})
},
queryUserRoleMap(){
queryUserRoleMap().then((res) => {
if (res.success) {
this.userRolesMap = res.result;
this.loadData();
}
})
},
// 触发屏幕自适应
resetScreenSize() {
let screenWidth = document.body.clientWidth;
if (screenWidth < 500) {
this.scrollTrigger = { x: 800 };
} else {
this.scrollTrigger = {};
}
},
showModal() {
this.visible = true;
this.assignRoleName(this.dataSource);
this.queryDepartTree();
this.form.resetFields();
},
getQueryParams() {
let param = Object.assign({}, this.queryParam, this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
let str = 'id,';
for (let a = 0; a < this.columns.length; a++) {
str += ',' + this.columns[a].dataIndex;
}
return str;
},
searchReset(num) {
let that = this;
if (num !== 0) {
that.dataSource = that.userDataSource;
}
that.selectedRowKeys = [];
that.userNameArr = [];
that.queryParam = {};
that.selectedKeys = [];
},
close() {
this.searchReset(0);
this.visible = false;
},
handleTableChange(pagination, filters, sorter) {
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
}
this.ipagination = pagination;
this.loadData();
},
handleSubmit() {
let that = this;
for (let i = 0, len = this.selectedRowKeys.length; i < len; i++) {
this.getUserNames(this.selectedRowKeys[i]);
}
that.$emit('ok', that.userNameArr.join(','));
that.close();
},
// 遍历匹配,获取用户真实姓名
getUserNames(rowId) {
let dataSource = this.dataSource;
for (let i = 0, len = dataSource.length; i < len; i++) {
if (rowId === dataSource[i].id) {
this.userNameArr.push(dataSource[i].realname);
}
}
},
// 点击树节点,筛选出对应的用户
onSelect(selectedKeys) {
if (selectedKeys[0] != null) {
this.queryUserByDepId(selectedKeys); // 调用方法根据选选择的id查询用户信息
if (this.selectedKeys[0] !== selectedKeys[0]) {
this.selectedKeys = [selectedKeys[0]];
}
}
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onSearch() {
this.loadData(1);
},
// 根据选择的id来查询用户信息
queryUserByDepId(selectedKeys) {
queryUserByDepId({ id: selectedKeys.toString() }).then((res) => {
if (res.success) {
this.dataSource = res.result;
this.ipagination.total = res.result.length;
this.assignRoleName(this.dataSource);
}
})
},
// 传入用户id,找到匹配的角色名称
queryUserRole(userId) {
let map = this.userRolesMap;
let roleName = [];
for (var key in map) {
if (userId === key) {
roleName.push(map[key]);
}
}
return roleName.join(',');
},
queryDepartTree() {
queryDepartTreeList().then((res) => {
if (res.success) {
this.departTree = res.result;
}
})
},
// 为角色名称赋值
assignRoleName(data) {
let userId = '';
let role = '';
for (let i = 0, length = data.length; i < length; i++) {
userId = this.dataSource[i].id;
role = this.queryUserRole(userId);
this.dataSource[i].roleName = role;
}
},
modalFormOk() {
this.loadData();
}
}
}
</script>
<style scoped>
.ant-table-tbody .ant-table-row td {
padding-top: 10px;
padding-bottom: 10px;
}
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color .3s;
}
</style>

View File

@ -0,0 +1,87 @@
<template>
<div>
<a-modal
:title="title"
:width="800"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel">
<div>
<a-form-item label="用户名:" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
<a-input-search placeholder="点击右侧按钮选择用户" disabled @search="onSearch" v-model="userNames">
<a-button slot="enterButton" icon="search"></a-button>
</a-input-search>
</a-form-item>
</div>
</a-modal>
<!-- -->
<select-user-list-modal ref="selectUserListModal" @ok="getUserCallBack"></select-user-list-modal>
</div>
</template>
<script>
import {getUserList} from '@/api/api'
import SelectUserListModal from './modal/SelectUserListModal'
export default {
name: "SelectUserModal",
components: {
SelectUserListModal,
},
props: ['taskId'],
data() {
return {
title: "操作",
visible: false,
selectUserListVisible: false,
model: {},
confirmLoading: false,
userNames: '',
userKeys: '',
}
},
created() {
},
methods: {
open() {
this.userNames = ''
this.userKeys = ''
this.visible = true;
},
close() {
this.$emit('close');
this.visible = false;
},
handleCancel() {
this.close()
},
onSearch() {
this.$refs.selectUserListModal.open();
},
getUserCallBack(selectionRows) {
console.log(selectionRows)
let names = ''
let keys = ''
for (let row of selectionRows) {
names = row.realname + "," + names
keys = row.username + "," + keys
}
this.userNames = names
this.userKeys = keys
console.log('--userkeys--' + this.userKeys)
},
handleSubmit() {
console.log("taskId: "+ this.taskId)
this.$emit('ok', this.userKeys,this.taskId);
this.close()
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,308 @@
<template>
<a-modal
:width="modalWidth"
:visible="visible"
:title="title"
@ok="handleSubmit"
@cancel="close"
cancelText="关闭"
style="margin-top: -70px"
wrapClassName="ant-modal-cust-warp"
>
<a-row :gutter="10" style="background-color: #ececec; padding: 10px; margin: -10px">
<a-col :md="6" :sm="24">
<a-card :bordered="false">
<!---->
<a-directory-tree
selectable
:selectedKeys="selectedKeys"
:checkStrictly="true"
@select="this.onSelect"
:dropdownStyle="{maxHeight:'200px',overflow:'auto'}"
:treeData="departTree"
/>
</a-card>
</a-col>
<a-col :md="18" :sm="24">
<a-card :bordered="false">
:
<a-input-search
:style="{width:'150px',marginBottom:'15px'}"
placeholder=""
v-model="queryParam.username"
@search="onSearch"
/>
<a-button @click="searchReset" style="margin-left: 10px" icon="redo"></a-button>
<!---->
<a-table
ref="table"
:scroll="scrollTrigger"
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
style="background-color: white"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
</a-table>
</a-card>
</a-col>
</a-row>
</a-modal>
</template>
<script>
import { filterObj } from '@/utils/util'
import { queryDepartTreeList, getUserList, queryUserByDepId, queryUserRoleMap } from '@/api/api'
export default {
name: 'SearchUserByDepModal',
components: {
},
data() {
return {
queryParam: {},
columns: [
{
title: '',
align: 'center',
dataIndex: 'username'
},
{
title: '',
align: 'center',
dataIndex: 'realname'
},
{
title: '',
align: 'center',
dataIndex: 'roleName'
},
{
title: '',
align: 'center',
dataIndex: 'sex',
customRender: function(text) {
if (text === 1) {
return '男'
} else if (text === 2) {
return '女'
} else {
return text
}
}
},
{
title: '',
align: 'center',
dataIndex: 'phone'
},
{
title: '',
align: 'center',
dataIndex: 'email'
}
],
scrollTrigger:{},
dataSource: [],
selectedKeys: [],
userNames: [],
departName: '',
userRolesMap: {},
title: '',
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + ' ' + total + '条'
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter: {
column: 'createTime',
order: 'desc'
},
selectedRowKeys: [],
selectedRows: [],
userData: [],
modalWidth: 1250,
departTree: [],
visible: false,
form: this.$form.createForm(this),
}
},
created() {
// 该方法触发屏幕自适应
this.resetScreenSize();
},
methods: {
loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
let params = this.getQueryParams();//查询条件
getUserList(params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.assignRoleName(this.dataSource);
this.userData = res.result.records;
this.ipagination.total = res.result.total;
}
})
queryUserRoleMap().then((res) => {
if (res.success) {
this.userRolesMap = res.result;
}
})
},
// 触发屏幕自适应
resetScreenSize(){
let screenWidth = document.body.clientWidth;
if(screenWidth < 500){
this.scrollTrigger = {x : 800};
}else{
this.scrollTrigger = {};
}
},
showModal() {
this.visible = true;
this.assignRoleName(this.dataSource);
this.queryDepartTree();
this.form.resetFields();
this.loadData(1);
},
getQueryParams() {
let param = Object.assign({}, this.queryParam, this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
let str = 'id,';
for (let a = 0; a < this.columns.length; a++) {
str += ',' + this.columns[a].dataIndex;
}
return str;
},
searchReset(num) {
let that = this;
if(num !== 0){
that.loadData(1);
}
that.selectedRowKeys = [];
that.userNames = [];
that.queryParam = {};
that.selectedKeys = [];
that.userNames = [];
},
close() {
this.$emit('close');
this.searchReset(0);
this.visible = false;
},
handleTableChange(pagination, filters, sorter) {
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = 'ascend' === sorter.order ? 'asc' : 'desc';
}
this.ipagination = pagination;
this.loadData();
},
handleSubmit() {
const that = this;
for (let i = 0, len = this.selectedRowKeys.length; i < len; i++) {
this.getUserNames(this.selectedRowKeys[i]);
}
that.$emit('ok', that.userNames.join(','));
that.close();
},
// 遍历匹配,获取用户真实姓名
getUserNames(rowId) {
let dataSource = this.dataSource;
for (let i = 0, len = dataSource.length; i < len; i++) {
if (rowId === dataSource[i].id) {
this.userNames.push(dataSource[i].realname);
}
}
},
// 点击树节点,筛选出对应的用户
onSelect(selectedKeys) {
if (selectedKeys[0] != null) {
this.queryUser(selectedKeys) // 调用方法根据选选择的id查询用户信息
if (this.selectedKeys[0] !== selectedKeys[0]) {
this.selectedKeys = [selectedKeys[0]];
}
}
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onSearch() {
this.loadData(1);
},
// 根据选择的id来查询用户信息
queryUser(selectedKeys) {
queryUserByDepId({ id: selectedKeys.toString() }).then((res) => {
if (res.success) {
this.ipagination.total = res.result.length;
this.dataSource = res.result;
this.assignRoleName(this.dataSource);
}
})
},
// 传入用户id,找到匹配的角色名称
queryUserRole(userId) {
let map = this.userRolesMap;
let roleName = [];
for (var key in map) {
if (userId === key) {
roleName.push(map[key]);
}
}
return roleName.join(',');
},
queryDepartTree() {
queryDepartTreeList().then((res) => {
if (res.success) {
this.departTree = res.result;
}
})
},
// 为角色名称赋值
assignRoleName(data) {
let userId = '';
let role = '';
for (let i = 0, length = data.length; i < length; i++) {
userId = this.dataSource[i].id;
role = this.queryUserRole(userId);
this.dataSource[i].roleName = role;
}
},
modalFormOk() {
this.loadData();
}
}
}
</script>
<style scoped>
.ant-table-tbody .ant-table-row td {
padding-top: 10px;
padding-bottom: 10px;
}
#components-layout-demo-custom-trigger .trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
cursor: pointer;
transition: color .3s;
}
</style>

View File

@ -0,0 +1,276 @@
<template>
<div>
<a-modal
centered
:title="title"
:width="1000"
:visible="visible"
@ok="handleOk"
@cancel="handleCancel"
cancelText="关闭">
<a-row :gutter="18">
<a-col :span="16">
<a-card title="选择人员" :bordered=true>
<!-- -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="10">
<a-form-item label="姓名">
<a-input placeholder="请输入姓名" v-model="queryParam.name"></a-input>
</a-form-item>
</a-col>
<a-col :span="8" >
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- table-begin -->
<div>
<a-table
size="small"
bordered
rowKey="id"
:columns="columns1"
:dataSource="dataSource1"
:pagination="ipagination"
:loading="loading"
:scroll="{ y: 240 }"
:rowSelection="{selectedRowKeys: selectedRowKeys,onSelectAll:onSelectAll,onSelect:onSelect,onChange: onSelectChange}"
@change="handleTableChange">
</a-table>
</div>
<!-- table-end -->
</a-card>
</a-col>
<a-col :span="8">
<a-card title="用户选择" :bordered=true>
<!-- table-begin -->
<div>
<a-table
size="small"
bordered
rowKey="id"
:columns="columns2"
:dataSource="dataSource2"
:loading="loading"
:scroll="{ y: 240 }"
>
<span slot="action" slot-scope="text, record">
<a-button type="primary" size="small" @click="handleDelete(record)" icon="delete"></a-button>
</span>
</a-table>
</div>
<!-- table-end -->
</a-card>
</a-col>
</a-row>
</a-modal>
</div>
</template>
<script>
import { filterObj } from '@/utils/util'
import { getAction } from '@/api/manage'
export default {
name: "SelectDemoModal",
data () {
return {
title: "用户列表",
names: [],
visible: false,
placement: 'right',
description: '',
// 查询条件
queryParam: {},
// 表头
columns1: [
{
title: '#',
dataIndex: '',
key:'rowIndex',
width:50,
align:"center",
customRender:function (t,r,index) {
return parseInt(index)+1;
}
},
{
title: '',
align:"center",
width:113,
dataIndex: 'name'
},
{
title: '',
align:"center",
width:100,
dataIndex: 'age'
},
{
title: '',
align:"center",
width:100,
dataIndex: 'birthday'
}
],
columns2: [
{
title: '',
align:"center",
width:100,
dataIndex: 'name'
},
{
title: '',
dataIndex: 'action',
align:"center",
width:100,
scopedSlots: { customRender: 'action' },
}
],
//数据集
dataSource1:[],
dataSource2:[],
// 分页参数
ipagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter:{
column: 'createTime',
order: 'desc',
},
loading:false,
selectedRowKeys: [],
selectedRows: [],
url: {
list: "/test/jeecgDemo/list",
},
}
},
created() {
this.loadData();
},
methods: {
searchQuery(){
this.loadData(1);
},
searchReset(){
this.queryParam={};
this.loadData(1);
},
handleCancel() {
this.visible = false;
},
handleOk() {
this.$emit("selectFinished",this.dataSource2);
this.visible = false;
},
add() {
this.visible = true;
},
loadData (arg){
//加载数据 若传入参数1则加载第一页的内容
if(arg===1){
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list,params).then((res)=>{
if(res.success){
this.dataSource1 = res.result.records;
this.ipagination.total = res.result.total;
}
})
},
getQueryParams(){
var param = Object.assign({}, this.queryParam,this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField(){
//TODO 字段权限控制
},
onSelectAll (selected, selectedRows, changeRows) {
if(selected===true){
for(var a = 0;a<changeRows.length;a++){
this.dataSource2.push(changeRows[a]);
}
}else{
for(var b = 0;b<changeRows.length;b++){
this.dataSource2.splice(this.dataSource2.indexOf(changeRows[b]),1);
}
}
// console.log(selected, selectedRows, changeRows);
},
onSelect (record,selected) {
if(selected===true){
this.dataSource2.push(record);
}else{
var index = this.dataSource2.indexOf(record);
//console.log();
if(index >=0 ){
this.dataSource2.splice(this.dataSource2.indexOf(record),1);
}
}
},
onSelectChange (selectedRowKeys,selectedRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectedRows;
},
onClearSelected(){
this.selectedRowKeys = [];
this.selectionRows = [];
},
handleDelete: function(record){
this.dataSource2.splice(this.dataSource2.indexOf(record),1);
},
handleTableChange(pagination, filters, sorter){
//分页、排序、筛选变化时触发
console.log(sorter);
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.ipagination = pagination;
this.loadData();
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body .table-operator{
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td{
padding-top:15px;
padding-bottom:15px;
}
.anty-row-operator button{margin: 0 5px}
.ant-btn-danger{background-color: #ffffff}
.ant-modal-cust-warp{height: 100%}
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}
.ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden}
</style>

View File

@ -0,0 +1,122 @@
<template>
<a-modal
title="用户列表"
:width="1000"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel">
<a-table
ref="table"
bordered
size="middle"
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"></a-table>
</a-modal>
</template>
<script>
import {getUserList} from '@/api/api'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
export default {
name: "SelectUserListModal",
mixins: [JeecgListMixin],
data() {
return {
title: "操作",
visible: false,
model: {},
confirmLoading: false,
url: {
add: "/act/model/create",
list: "/sys/user/list"
},
columns: [
{
title: '',
align: "center",
dataIndex: 'username',
fixed: 'left',
width: 200
},
{
title: '',
align: "center",
dataIndex: 'realname',
},
{
title: '',
align: "center",
dataIndex: 'sex_dictText'
},
{
title: '',
align: "center",
dataIndex: 'phone'
},
{
title: '',
align: "center",
dataIndex: 'email'
},
{
title: '',
align: "center",
dataIndex: 'status_dictText'
}
]
}
},
created() {
//Step.2 加载用户数据
getUserList().then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
})
},
methods: {
open() {
this.visible = true;
//Step.1 清空选中用户
this.selectedRowKeys = []
this.selectedRows = []
},
close() {
this.$emit('close');
this.visible = false;
},
handleChange(info) {
let file = info.file;
if (file.response.success) {
this.$message.success(file.response.message);
this.$emit('ok');
this.close()
} else {
this.$message.warn(file.response.message);
this.close()
}
},
handleCancel() {
this.close()
},
handleSubmit() {
this.$emit('ok', this.selectionRows);
this.close()
},
}
}
</script>
<style>
</style>

View File

@ -1,11 +1,12 @@
<template>
<global-layout>
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect" />
<contextmenu :itemList="menuItemList" :visible.sync="menuVisible" @select="onMenuSelect"/>
<a-tabs
@contextmenu.native="e => onContextmenu(e)"
v-if="multipage"
:active-key="activePage"
style="margin-top: -8px; margin-bottom: -10px"
class="tab-layout-tabs"
style="height:52px"
:hide-add="true"
type="editable-card"
@change="changePage"
@ -14,26 +15,33 @@
<span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
</a-tab-pane>
</a-tabs>
<transition name="page-toggle">
<keep-alive v-if="multipage">
<router-view />
</keep-alive>
<router-view v-else />
</transition>
<div style="margin: 24px 24px 0;">
<transition name="page-toggle">
<keep-alive v-if="multipage">
<router-view/>
</keep-alive>
<router-view v-else/>
</transition>
</div>
</global-layout>
</template>
<script>
import GlobalLayout from '@/components/page/GlobalLayout'
import Contextmenu from '@/components/menu/Contextmenu'
const indexKey="/dashboard/analysis"
import { mixin, mixinDevice } from '@/utils/mixin.js'
import { topNavScrollToSelectItem } from '@/utils/util'
const indexKey = '/dashboard/analysis'
export default {
name: "TabLayout",
name: 'TabLayout',
components: {
GlobalLayout,
Contextmenu
},
data () {
mixins: [mixin, mixinDevice],
data() {
return {
pageList: [],
linkList: [],
@ -47,17 +55,34 @@
}
},
computed: {
multipage () {
return this.$store.state.app.multipage
multipage() {
//判断如果是手机模式,自动切换为单页面模式
if (this.isMobile()) {
return false
} else {
return this.$store.state.app.multipage
}
}
},
created () {
created() {
if (this.$route.path != indexKey) {
this.pageList.push({
name: 'dashboard-analysis',
path: indexKey,
fullPath: indexKey,
meta: {
icon: 'dashboard',
title: ''
}
})
this.linkList.push(indexKey)
}
this.pageList.push(this.$route)
this.linkList.push(this.$route.fullPath)
this.activePage = this.$route.fullPath
},
watch: {
'$route': function (newRoute) {
'$route': function(newRoute) {
this.activePage = newRoute.fullPath
if (!this.multipage) {
this.linkList = [newRoute.fullPath]
@ -65,21 +90,21 @@
} else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
this.linkList.push(newRoute.fullPath)
this.pageList.push(newRoute)
}else if(this.linkList.indexOf(newRoute.fullPath) >= 0){
let oldIndex = this.linkList.indexOf(newRoute.fullPath);
this.pageList.splice(oldIndex,1,newRoute);
} else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
let oldIndex = this.linkList.indexOf(newRoute.fullPath)
this.pageList.splice(oldIndex, 1, newRoute)
}
},
'activePage': function (key) {
let index = this.linkList.lastIndexOf(key);
var waitRouter = this.pageList[index];
'activePage': function(key) {
let index = this.linkList.lastIndexOf(key)
var waitRouter = this.pageList[index]
this.$router.push({
path: waitRouter.path,
name: waitRouter.name,
params: waitRouter.params
});
})
},
'multipage': function (newVal) {
'multipage': function(newVal) {
if (!newVal) {
this.linkList = [this.$route.fullPath]
this.pageList = [this.$route]
@ -87,14 +112,20 @@
}
},
methods: {
changePage (key) {
changePage(key) {
this.activePage = key
// 只有当前模式是顶部菜单时才执行定位
if (this.layoutMode === 'topmenu') {
setTimeout(() => {
topNavScrollToSelectItem(document)
}, 100)
}
},
editPage (key, action) {
editPage(key, action) {
this[action](key)
},
remove (key) {
if(key==indexKey){
remove(key) {
if (key == indexKey) {
this.$message.warning('!')
return
}
@ -108,14 +139,14 @@
index = index >= this.linkList.length ? this.linkList.length - 1 : index
this.activePage = this.linkList[index]
},
onContextmenu (e) {
onContextmenu(e) {
const pagekey = this.getPageKey(e.target)
if (pagekey !== null) {
e.preventDefault()
this.menuVisible = true
}
},
getPageKey (target, depth) {
getPageKey(target, depth) {
depth = depth || 0
if (depth > 2) {
return null
@ -124,7 +155,7 @@
pageKey = pageKey || (target.previousElementSibling ? target.previousElementSibling.getAttribute('pagekey') : null)
return pageKey || (target.firstElementChild ? this.getPageKey(target.firstElementChild, ++depth) : null)
},
onMenuSelect (key, target) {
onMenuSelect(key, target) {
let pageKey = this.getPageKey(target)
switch (key) {
case '1':
@ -140,14 +171,14 @@
break
}
},
closeOthers (pageKey) {
closeOthers(pageKey) {
let index = this.linkList.indexOf(pageKey)
if(pageKey==indexKey){
if (pageKey == indexKey) {
this.linkList = this.linkList.slice(index, index + 1)
this.pageList = this.pageList.slice(index, index + 1)
this.activePage = this.linkList[0]
}else{
let indexContent = this.pageList.slice(0,1)[0]
} else {
let indexContent = this.pageList.slice(0, 1)[0]
this.linkList = this.linkList.slice(index, index + 1)
this.pageList = this.pageList.slice(index, index + 1)
this.linkList.unshift(indexKey)
@ -155,12 +186,12 @@
this.activePage = this.linkList[1]
}
},
closeLeft (pageKey) {
if(pageKey==indexKey){
closeLeft(pageKey) {
if (pageKey == indexKey) {
return
}
let tempList = [...this.pageList];
let indexContent = tempList.slice(0,1)[0]
let tempList = [...this.pageList]
let indexContent = tempList.slice(0, 1)[0]
let index = this.linkList.indexOf(pageKey)
this.linkList = this.linkList.slice(index)
this.pageList = this.pageList.slice(index)
@ -170,7 +201,7 @@
this.activePage = this.linkList[0]
}
},
closeRight (pageKey) {
closeRight(pageKey) {
let index = this.linkList.indexOf(pageKey)
this.linkList = this.linkList.slice(0, index + 1)
this.pageList = this.pageList.slice(0, index + 1)
@ -178,7 +209,7 @@
this.activePage = this.linkList[this.linkList.length - 1]
}
}
},
}
}
</script>
@ -206,8 +237,63 @@
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
/*美化弹出Tab样式*/
.ant-tabs-nav-container {
margin-top: 4px;
}
/* 修改 ant-tabs 样式 */
.tab-layout-tabs.ant-tabs {
border-bottom: 1px solid #ccc;
border-left: 1px solid #ccc;
background-color: white;
padding: 0 20px;
.ant-tabs-bar {
margin: 4px 0 0;
border: none;
}
}
.ant-tabs {
&.ant-tabs-card .ant-tabs-tab {
padding: 0 24px !important;
background-color: white !important;
margin-right: 10px !important;
.ant-tabs-close-x {
width: 12px !important;
height: 12px !important;
opacity: 0 !important;
cursor: pointer !important;
font-size: 12px !important;
margin: 0 !important;
position: absolute;
top: 36%;
right: 6px;
}
&:hover .ant-tabs-close-x {
opacity: 1 !important;
}
}
}
.ant-tabs.ant-tabs-card > .ant-tabs-bar {
.ant-tabs-tab {
border: none !important;
border-bottom: 1px solid transparent !important;
}
.ant-tabs-tab-active {
border-color: #1890ff !important;
}
}
</style>

View File

@ -17,9 +17,9 @@
<div class="footer">
<div class="links">
<a href="_self"></a>
<a href="_self"></a>
<a href="_self"></a>
<a href="http://jeecg-boot.mydoc.io" target="_blank"></a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"></a>
<a href="https://github.com/zhangdaiscott/jeecg-boot" target="_blank"></a>
</div>
<div class="copyright">
Copyright &copy; 2019 <a href="http://www.jeecg.org" target="_blank">JEECG</a>

View File

@ -1,7 +1,7 @@
<template>
<a-layout-sider
:class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null ]"
width="248px"
width="200px"
:collapsible="collapsible"
v-model="collapsed"
:trigger="null">
@ -12,7 +12,7 @@
:theme="theme"
@select="onSelect"
:mode="mode"
style="padding: 16px 0px;"></s-menu>
style="padding: 0;"></s-menu>
</a-layout-sider>
</template>

View File

@ -62,18 +62,38 @@ export default {
: h(Icon, { props: { type: icon !== undefined ? icon : '' } })
},
renderMenuItem: function (h, menu, pIndex, index) {
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
[
h(
'router-link',
{ attrs: { to: { name: menu.name } } },
[
this.renderIcon(h, menu.meta.icon),
h('span', [ menu.meta.title ])
]
)
]
)
// 判断是否带参数路由URL,是的话采用path跳转方式
if(menu.route && menu.route === '0'){
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
[
h(
'router-link',
//--update-begin----author:scott---date:20190320------for:改造菜单路由跳转规则原来是跳转到组件现在改造成跳转URL为了支持参数URL菜单------
{ attrs: { to: { path: menu.path } } },
//--update-end----author:scott---date:20190320------for:改造菜单路由跳转规则原来是跳转到组件现在改造成跳转URL为了支持参数URL菜单------
[
this.renderIcon(h, menu.meta.icon),
h('span', [ menu.meta.title ])
]
)
]
)
}else{
// 默认采用组件跳转方式
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index },
[
h(
'router-link',
{ attrs: { to: { name: menu.name } } },
[
this.renderIcon(h, menu.meta.icon),
h('span', [ menu.meta.title ])
]
)
]
)
}
},
renderSubMenu: function (h, menu, pIndex, index) {
const this2_ = this;

View File

@ -1,7 +1,11 @@
<template>
<!-- , width: fixedHeader ? `calc(100% - ${sidebarOpened ? 256 : 80}px)` : '100%' -->
<a-layout-header v-if="!headerBarFixed" :class="[fixedHeader && 'ant-header-fixedHeader', sidebarOpened ? 'ant-header-side-opened' : 'ant-header-side-closed', ]" :style="{ padding: '0' }">
<div v-if="mode === 'sidemenu'" class="header">
<a-layout-header
v-if="!headerBarFixed"
:class="[fixedHeader && 'ant-header-fixedHeader', sidebarOpened ? 'ant-header-side-opened' : 'ant-header-side-closed', ]"
:style="{ padding: '0' }">
<div v-if="mode === 'sidemenu'" class="header" :class="theme">
<a-icon
v-if="device==='mobile'"
class="trigger"
@ -12,26 +16,32 @@
class="trigger"
:type="collapsed ? 'menu-unfold' : 'menu-fold'"
@click.native="toggle"/>
<span> Jeecg-Boot </span>
<user-menu></user-menu>
<span v-if="device === 'desktop'"> Jeecg-Boot </span>
<span v-else>Jeecg-Boot</span>
<user-menu :theme="theme"/>
</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"
></s-menu>
<div class="header-index-left" :style="topMenuStyle.headerIndexLeft">
<logo class="top-nav-header" :show-title="device !== 'mobile'" :style="topMenuStyle.topNavHeader"/>
<div v-if="device !== 'mobile'" id="top-nav-scroll-view" :style="topMenuStyle.scrollView">
<div id="top-nav-scroll-width" :style="topMenuStyle.scrollWidth">
<s-menu
mode="horizontal"
:menu="menus"
:theme="theme"></s-menu>
</div>
</div>
<a-icon
v-else
class="trigger"
:type="collapsed ? 'menu-fold' : 'menu-unfold'"
@click.native="toggle"></a-icon>
</div>
<user-menu class="header-index-right"></user-menu>
<user-menu class="header-index-right" :theme="theme" :style="topMenuStyle.headerIndexRight"/>
</div>
</div>
@ -44,9 +54,10 @@
import Logo from '../tools/Logo'
import { mixin } from '@/utils/mixin.js'
import { topNavScrollToSelectItem } from '@/utils/util'
export default {
name: "GlobalHeader",
name: 'GlobalHeader',
components: {
UserMenu,
SMenu,
@ -82,13 +93,48 @@
data() {
return {
headerBarFixed: false,
//update-begin--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
topMenuStyle: {
headerIndexLeft: {},
topNavHeader: {},
headerIndexRight: {},
scrollView: {
'overflow-x': 'auto',
'overflow-y': 'hidden'
},
scrollWidth: {
// 设置这么宽是为了让顶部菜单首次加载时充分展开,方便计算真实宽度
'width': '10000px'
}
}
}
},
mounted () {
watch: {
/** 监听设备变化 */
device() {
if (this.mode === 'topmenu') {
this.buildTopMenuStyle()
}
},
/** 监听导航栏模式变化 */
mode(newVal) {
if (newVal === 'topmenu') {
this.calcTopMenuScrollWidth()
}
}
},
//update-end--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
mounted() {
window.addEventListener('scroll', this.handleScroll)
//update-begin--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
if (this.mode === 'topmenu') {
this.buildTopMenuStyle()
this.calcTopMenuScrollWidth()
}
//update-end--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
},
methods: {
handleScroll () {
handleScroll() {
if (this.autoHideHeader) {
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop > 100) {
@ -102,26 +148,172 @@
},
toggle() {
this.$emit('toggle')
},
//update-begin--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
buildTopMenuStyle() {
if (this.mode === 'topmenu') {
if (this.device === 'mobile') {
// 手机端需要清空样式,否则显示会错乱
this.topMenuStyle.topNavHeader = {}
this.topMenuStyle.headerIndexRight = {}
this.topMenuStyle.headerIndexLeft = {}
} else {
let rightWidth = '360px'
this.topMenuStyle.topNavHeader = { 'min-width': '165px' }
this.topMenuStyle.headerIndexRight = { 'min-width': rightWidth }
this.topMenuStyle.headerIndexLeft = { 'width': `calc(100% - ${rightWidth})` }
// 由于首次从mobile设备下切换到desktop设备没有初始化TopMenuScrollWidth所以这里需要计算一下
if (this.topMenuStyle.scrollWidth['width'] === '10000px') {
this.calcTopMenuScrollWidth()
}
}
}
},
/** 计算滚动条的宽度 */
calcTopMenuScrollWidth() {
// 非顶部菜单时不计算宽度
if (this.mode !== 'topmenu') return
let count = 0
let timer = setInterval(() => {
count++
let scrollWidth = document.getElementById('top-nav-scroll-width')
if (scrollWidth == null) {
clearInterval(timer)
return
}
let menu = scrollWidth.getElementsByClassName('ant-menu')[0]
if (menu) {
let widthCount = 0
let menuItems = menu.getElementsByTagName('li')
for (let item of menuItems) {
if (item.className.indexOf('ant-menu-overflowed-submenu') === -1) {
widthCount += item.offsetWidth
}
}
// 由于首次从侧边菜单模式下切换到顶部菜单模式下没有buildTopMenuStyle所以这里需要build一下
if (this.topMenuStyle.scrollWidth['width'] === '10000px') {
// 防止递归调用
this.$nextTick(() => {
this.buildTopMenuStyle()
})
}
this.topMenuStyle.scrollWidth['width'] = `${widthCount + 10}px`
// 将滚动条位置滚动到当前选中的菜单处
if (count === 1) {
topNavScrollToSelectItem(document)
}
}
// 校准数据三次再关闭定时器
if (count === 3) {
clearInterval(timer)
}
}, 100)
}
//update-end--author:sunjianlei---date:20190408------for: 顶部导航栏增加横向滚动条-----
}
}
</script>
<style lang="scss" scoped>
/* update_begin author:scott date:20190220 for: 缩小首页布局顶部的高度*/
.layout .top-nav-header-index .header-index-wide {
margin-left: 20px
}
.layout .header {
height: 59px;
$height: 59px;
.layout {
.top-nav-header-index {
.header-index-wide {
margin-left: 10px;
.ant-menu.ant-menu-horizontal {
height: $height;
line-height: $height;
}
}
.trigger {
line-height: 64px;
&:hover {
background: rgba(0, 0, 0, 0.05);
}
}
}
.header {
z-index: 2;
color: white;
height: $height;
background-color: #1890ff;
transition: background 300ms;
/* dark 样式 */
&.dark {
color: #000000;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
background-color: white !important;
}
}
.header, .top-nav-header-index {
&.dark .trigger:hover {
background: rgba(0, 0, 0, 0.05);
}
}
}
.ant-layout-header {
height: 59px;
line-height: 59px;
}
.layout .top-nav-header-index .header-index-wide .ant-menu.ant-menu-horizontal {
height: 59px;
line-height: 59px;
height: $height;
line-height: $height;
}
/* update_end author:scott date:20190220 for: 缩小首页布局顶部的高度*/
/* update_begin author:sunjianlei date:20190408 for: 修改顶部导航栏滚动条的样式 */
#top-nav-scroll-view {
$scrollBarSize: 8px;
/* 定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/
&::-webkit-scrollbar {
width: $scrollBarSize;
height: $scrollBarSize;
background-color: transparent;
}
/* 定义滚动条轨道 */
&::-webkit-scrollbar-track {
background-color: transparent;
}
/* 定义滑块 */
&::-webkit-scrollbar-thumb {
border-radius: $scrollBarSize;
background-color: #eee;
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
&:hover {
background-color: #dddddd;
}
&:active {
background-color: #bbbbbb;
}
}
}
/** 暗色系滚动条样式 */
.dark #top-nav-scroll-view {
&::-webkit-scrollbar-thumb {
background-color: #666666;
&:hover {
background-color: #808080;
}
&:active {
background-color: #999999;
}
}
}
/* update_end author:sunjianlei date:20190408 for: 修改顶部导航栏滚动条的样式 */
</style>

View File

@ -9,6 +9,7 @@
@close="() => this.collapsed = false"
:closable="false"
:visible="collapsed"
width="200px"
>
<side-menu
mode="inline"
@ -36,6 +37,7 @@
@close="() => this.collapsed = false"
:closable="false"
:visible="collapsed"
width="200px"
>
<side-menu
mode="inline"
@ -47,25 +49,27 @@
</a-drawer>
</template>
<a-layout :class="[layoutMode, `content-width-${contentWidth}`]" :style="{ paddingLeft: fixSiderbar && isDesktop() ? `${sidebarOpened ? 256 : 80}px` : '0' }">
<a-layout
:class="[layoutMode, `content-width-${contentWidth}`]"
:style="{ paddingLeft: fixSiderbar && isDesktop() ? `${sidebarOpened ? 200 : 80}px` : '0' }">
<!-- layout header -->
<global-header
:mode="layoutMode"
:menus="menus"
:theme="navTheme"
:collapsed="collapsed"
:device="device"
<global-header
:mode="layoutMode"
:menus="menus"
:theme="navTheme"
:collapsed="collapsed"
:device="device"
@toggle="toggle"
/>
<!-- layout content -->
<a-layout-content :style="{ margin: '10px 24px 0', height: '100%', paddingTop: fixedHeader ? '64px' : '0' }">
<a-layout-content :style="{ height: '100%', paddingTop: fixedHeader ? '59px' : '0' }">
<slot></slot>
</a-layout-content>
<!-- layout footer -->
<a-layout-footer style="padding: 0px">
<global-footer />
<global-footer/>
</a-layout-footer>
</a-layout>
@ -83,7 +87,7 @@
import { mixin, mixinDevice } from '@/utils/mixin.js'
export default {
name: "GlobalLayout",
name: 'GlobalLayout',
components: {
SideMenu,
GlobalHeader,
@ -91,7 +95,7 @@
SettingDrawer
},
mixins: [mixin, mixinDevice],
data () {
data() {
return {
collapsed: false,
menus: []
@ -100,16 +104,26 @@
computed: {
...mapState({
// 主路由
mainMenu: state => state.permission.addRouters,
mainRouters: state => state.permission.addRouters,
// 后台菜单
permissionMenuList: state => state.user.permissionList
})
},
watch: {
sidebarOpened(val) {
this.collapsed = !val
},
}
},
created() {
this.menus = this.mainMenu.find((item) => item.path === '/').children
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置判断是否路由菜单字段动态选择是否生成路由为了支持参数URL菜单------
//this.menus = this.mainRouters.find((item) => item.path === '/').children;
this.menus = this.permissionMenuList
// 根据后台配置菜单,重新排序加载路由信息
console.log('--------')
console.log(this.mainRouters)
console.log(this.permissionMenuList)
console.log('----navTheme------'+this.navTheme)
//--update-end----author:scott---date:20190320------for:根据后台菜单配置判断是否路由菜单字段动态选择是否生成路由为了支持参数URL菜单------
},
methods: {
...mapActions(['setSidebar']),
@ -123,7 +137,7 @@
this.collapsed = false
}
}
},
}
}
</script>
@ -138,7 +152,7 @@
}
.layout {
min-height: 100vh;
min-height: 100vh !important;
overflow-x: hidden;
&.mobile {
@ -165,7 +179,7 @@
.sidemenu {
.ant-header-fixedHeader {
&.ant-header-side-opened, &.ant-header-side-closed {
&.ant-header-side-opened, &.ant-header-side-closed {
width: 100%
}
}
@ -179,6 +193,11 @@
}
}
}
.header, .top-nav-header-index {
.user-wrapper .action {
padding: 0 12px;
}
}
}
&.ant-layout-has-sider {
@ -186,13 +205,14 @@
}
.trigger {
font-size: 20px;
line-height: 64px;
padding: 0 24px;
font-size: 22px;
line-height: 42px;
padding: 0 18px;
cursor: pointer;
transition: color .3s;
transition: color 300ms, background 300ms;
&:hover {
background: rgba(0, 0, 0, 0.025);
background: rgba(255, 255, 255, 0.3);
}
}
@ -237,7 +257,7 @@
transition: width .2s;
&.ant-header-side-opened {
width: calc(100% - 256px)
width: calc(100% - 200px)
}
&.ant-header-side-closed {
@ -246,8 +266,6 @@
}
}
.header {
height: 64px;
padding: 0 12px 0 0;
@ -264,23 +282,28 @@
.action {
cursor: pointer;
padding: 0 12px;
padding: 0 14px;
display: inline-block;
transition: all .3s;
height: 100%;
height: 70%;
line-height: 46px;
&.action-full {
height: 100%;
}
&:hover {
background: rgba(0, 0, 0, 0.025);
background: rgba(255, 255, 255, 0.3);
}
.avatar {
margin: 20px 8px 20px 0;
margin: 20px 10px 20px 0;
color: #1890ff;
background: hsla(0, 0%, 100%, .85);
vertical-align: middle;
}
.icon {
font-size: 16px;
padding: 4px;
@ -292,10 +315,10 @@
.user-wrapper {
.action {
color: rgba(255, 255, 255, 0.85);
color: black;
&:hover {
background: rgba(255, 255, 255, 0.16);
background: rgba(0, 0, 0, 0.05);
}
}
}
@ -322,6 +345,10 @@
}
}
.user-wrapper .action .avatar {
margin: 20px 0;
}
&.light {
.header-index-wide {
@ -346,7 +373,7 @@
.header-index-left {
.logo > a {
overflow: hidden;
text-overflow:ellipsis;
text-overflow: ellipsis;
white-space: nowrap;
}
}
@ -355,18 +382,17 @@
}
.top-nav-header-index {
box-shadow: 0 1px 4px rgba(0,21,41,.08);
box-shadow: 0 1px 4px rgba(0, 21, 41, .08);
position: relative;
transition: background .3s,width .2s;
transition: background .3s, width .2s;
.header-index-wide {
max-width: 1200px;
width: 100%;
margin: auto;
padding-left: 0;
padding: 0 20px 0 0;
display: flex;
height: 64px;
height: 59px;
.ant-menu.ant-menu-horizontal {
border: none;
@ -405,8 +431,11 @@
.header-index-right {
float: right;
height: 64px;
height: 59px;
overflow: hidden;
.action:hover {
background-color: rgba(0, 0, 0, 0.05);
}
}
}
@ -423,13 +452,29 @@
}
}
}
}
&.dark {
.user-wrapper {
.action {
color: white;
&:hover {
background: rgba(255, 255, 255, 0.3);
}
}
}
.header-index-wide .header-index-left .trigger:hover {
background: rgba(255, 255, 255, 0.3);
}
}
}
// 内容区
.layout-content {
margin: 24px 24px 0px;
height: 100%;
height: 64px;
padding: 0 12px 0 0;
}
@ -438,8 +483,8 @@
.topmenu {
.page-header-index-wide {
max-width: 1200px;
margin: 0 auto;
width: 100%;
}
}
@ -468,7 +513,7 @@
// 菜单样式
.sider {
box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
box-shadow: 2px 116px 6px 0 rgba(0, 21, 41, .35);
position: relative;
z-index: 10;
@ -498,8 +543,8 @@
h1 {
color: #fff;
font-size: 20px;
margin: 0 0 0 12px;
font-size: 18px;
margin: 0 0 0 8px;
font-family: "Chinese Quote", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-weight: 600;
}
@ -507,11 +552,11 @@
&.light {
background-color: #fff;
box-shadow: 2px 0px 8px 0px rgba(29, 35, 41, 0.05);
box-shadow: 2px 116px 8px 0 rgba(29, 35, 41, 0.05);
.logo {
background: #fff;
box-shadow: 1px 1px 0px 0px #e8e8e8;
box-shadow: 1px 1px 0 0 #e8e8e8;
h1 {
color: unset;
@ -563,7 +608,7 @@
vertical-align: middle;
}
>.ant-form-item-label {
> .ant-form-item-label {
line-height: 32px;
padding-right: 8px;
width: auto;

View File

@ -1,5 +1,5 @@
<template>
<div :style="!$route.meta.pageHeader ? 'margin: -16px -24px 0px;' : null">
<div :style="!$route.meta.pageHeader ? 'margin: -10px -24px 0;' : null">
<!-- pageHeader , route meta hideHeader:true on hide -->
<page-header v-if="!$route.meta.pageHeader" :title="title" :logo="logo" :avatar="avatar">
<slot slot="action" name="action"></slot>

View File

@ -134,6 +134,12 @@
<div slot="title"></div>
</a-list-item-meta>
</a-list-item>
<a-list-item>
<a-switch slot="actions" size="small" :defaultChecked="multipage" @change="onMultipageWeak" />
<a-list-item-meta>
<div slot="title"></div>
</a-list-item-meta>
</a-list-item>
</a-list>
</div>
</div>
@ -161,6 +167,7 @@
import config from '@/defaultSettings'
import { updateTheme, updateColorWeak, colorList } from '@/components/tools/setting'
import { mixin, mixinDevice } from '@/utils/mixin.js'
import { triggerWindowResizeEvent } from '@/utils/util'
export default {
components: {
@ -189,6 +196,9 @@
if (this.colorWeak !== config.colorWeak) {
updateColorWeak(this.colorWeak)
}
if (this.multipage !== config.multipage) {
this.$store.dispatch('ToggleMultipage', this.multipage)
}
},
methods: {
showDrawer() {
@ -204,14 +214,18 @@
this.$store.dispatch('ToggleWeak', checked)
updateColorWeak(checked)
},
onMultipageWeak (checked) {
this.$store.dispatch('ToggleMultipage', checked)
},
handleMenuTheme (theme) {
this.$store.dispatch('ToggleTheme', theme)
},
handleLayout (mode) {
this.$store.dispatch('ToggleLayoutMode', mode)
// 因为顶部菜单不能固定左侧菜单栏,所以强制关闭
//
this.handleFixSiderbar(false);
this.handleFixSiderbar(false)
// 触发窗口resize事件
triggerWindowResizeEvent()
},
handleContentWidthChange (type) {
this.$store.dispatch('ToggleContentWidth', type)

View File

@ -9,7 +9,7 @@
<script>
export default {
name: "Logo",
name: 'Logo',
props: {
title: {
type: String,
@ -26,8 +26,26 @@
</script>
<style lang="scss" scoped>
/*缩小首页布 局顶部的高度*/
.sider .logo {
height: 59px!important;
line-height: 59px!important;
$height: 59px;
.sider {
box-shadow: none !important;
.logo {
height: $height !important;
line-height: $height !important;
box-shadow: none !important;
transition: background 300ms;
a {
color: white;
&:hover {
color: rgba(255, 255, 255, 0.8);
}
}
}
&.light .logo {
background-color: #1890ff;
}
}
</style>

View File

@ -1,13 +1,13 @@
<template>
<div class="user-wrapper">
<div class="user-wrapper" :class="theme">
<span class="action">
<a-icon type="question-circle-o"></a-icon>
</span>
<header-notice class="action"/>
<a-dropdown>
<span class="action ant-dropdown-link user-dropdown-menu">
<span class="action action-full ant-dropdown-link user-dropdown-menu">
<a-avatar class="avatar" size="small" :src="getAvatar()"/>
<span>{{ nickname() }}</span>
<span v-if="isDesktop()">{{ nickname() }}</span>
</span>
<a-menu slot="overlay" class="user-dropdown-menu-wrapper">
<a-menu-item key="0">
@ -38,7 +38,7 @@
<span class="action">
<a class="logout_title" href="javascript:;" @click="handleLogout">
<a-icon type="logout"/>
<span> 退</span>
<span v-if="isDesktop()">&nbsp;退</span>
</a>
</span>
</div>
@ -47,19 +47,26 @@
<script>
import HeaderNotice from './HeaderNotice'
import { mapActions, mapGetters } from 'vuex'
import {imgView} from '@/api/api'
import { mixinDevice } from '@/utils/mixin.js'
export default {
name: "UserMenu",
mixins: [mixinDevice],
components: {
HeaderNotice
},
props: {
theme: {
type: String,
required: false,
default: 'dark'
}
},
methods: {
...mapActions(["Logout"]),
...mapGetters(["nickname", "avatar"]),
getAvatar(){
console.log('url = '+ imgView+this.avatar())
return imgView+this.avatar()
console.log('url = '+ window._CONFIG['imgDomainURL']+"/"+this.avatar())
return window._CONFIG['imgDomainURL']+"/"+this.avatar()
},
handleLogout() {
const that = this
@ -69,7 +76,8 @@
content: ' ?',
onOk() {
return that.Logout({}).then(() => {
window.location.reload()
window.location.href="/";
//window.location.reload()
}).catch(err => {
that.$message.error({
title: '',
@ -86,8 +94,8 @@
</script>
<style scoped>
.logout_title{
color: rgba(0, 0, 0, 0.65);
text-decoration:none;
.logout_title {
color: inherit;
text-decoration: none;
}
</style>

View File

@ -8,43 +8,258 @@ export const asyncRouterMap = [
{
path: '/',
name: 'index',
name: 'dashboard',
component: TabLayout,
meta: { title: '' },
redirect: '/dashboard/workplace',
children: [
//系统管理
{
path: '/system',
name: 'system',
redirect: '/isystem/user',
component: RouteView,
meta: { title: '', icon: 'dashboard', permission: [ 'dashboard' ] },
children: [
{
path: '/system/user',
name: 'user',
component: () => import('@/views/system/UserList'),
meta: { title: '', permission: [ 'dashboard' ] }
},
{
path: '/system/role',
name: 'role',
component: () => import('@/views/system/RoleList'),
meta: { title: '', permission: [ 'dashboard' ] }
},
{
path: '/system/log',
name: 'log',
component: () => import('@/views/system/LogList'),
meta: { title: '', permission: [ 'dashboard' ] }
},
]
},
// //流程管理
// {
// path: '/process',
// name: 'process',
// redirect: '/process',
// component: RouteView,
// meta: { title: '流程管理', icon: 'dashboard', permission: [ 'dashboard' ] },
// children: [
// {
// path: '/process/ExtActExpressionList',
// name: 'ExtActExpressionList',
// component: () => import('@/views/modules/extbpm/process/ExtActExpressionList'),
// meta: { title: '流程表达式', permission: [ 'dashboard' ] }
// },
// {
// path: '/process/ExtActListenerList',
// name: 'ExtActListenerList',
// component: () => import('@/views/modules/extbpm/process/ExtActListenerList'),
// meta: { title: '流程监听', permission: [ 'dashboard' ] }
// },
// {
// path: '/process/ExtActProcessList',
// name: 'ExtActProcessList',
// component: () => import('@/views/modules/extbpm/process/ExtActProcessList'),
// meta: { title: '流程设计', permission: [ 'dashboard' ] }
// },
// ]
// },
//
//
// //工作流程
// {
// path: '/bpm',
// name: 'bpm',
// redirect: '/bpm',
// component: RouteView,
// meta: { title: '工作流程', icon: 'dashboard', permission: [ 'dashboard' ] },
// children: [
// {
// path: '/modules/bpm/ModelList',
// name: 'ModelList',
// component: () => import('@/views/modules/bpm/ModelList'),
// meta: { title: '在线流程设计', permission: [ 'dashboard' ] }
// },
// {
// path: '/modules/bpm/ProcessList',
// name: 'ProcessList',
// component: () => import('@/views/modules/bpm/ProcessList'),
// meta: { title: '流程发布管理', permission: [ 'dashboard' ] }
// },
// {
// path: '/modules/bpm/task/MyTaskList',
// name: 'MyTaskList',
// component: () => import('@/views/modules/bpm/task/MyTaskList'),
// meta: { title: '我的任务', permission: [ 'dashboard' ] }
// },
// {
// path: '/modules/bpm/ProcessInstanceList',
// name: 'ProcessInstanceList',
// component: () => import('@/views/modules/bpm/ProcessInstanceList'),
// meta: { title: '流程实例管理', permission: [ 'dashboard' ] }
// },
// ]
// },
//
// //系统管理
// {
// path: '/isystem',
// name: 'system',
// redirect: '/isystem/user',
// component: RouteView,
// meta: { title: '系统管理', icon: 'dashboard', permission: [ 'dashboard' ] },
// children: [
// {
// path: '/isystem/user',
// name: 'user',
// component: () => import('@/views/system/UserList'),
// meta: { title: '用户管理', permission: [ 'dashboard' ] }
// },
// {
// path: '/isystem/permission',
// name: 'permission',
// component: () => import('@/views/system/PermissionList'),
// meta: { title: '菜单管理', permission: [ 'dashboard' ] }
// },
// {
// path: '/isystem/dict',
// name: 'dict',
// component: () => import('@/views/system/DictList'),
// meta: { title: '字典管理', permission: [ 'dashboard' ] }
// },
// {
// path: '/isystem/annountCement',
// name: 'annountCement',
// component: () => import('@/views/system/SysAnnouncementList'),
// meta: { title: '系统通知', permission: [ 'dashboard' ] }
// },
// {
// path: '/isystem/depart',
// name: 'depart',
// component: () => import('@/views/system/DepartList'),
// meta: { title: '部门管理', permission: [ 'dashboard' ] }
// },
//
// {
// path: '/isystem/role',
// name: 'role',
// component: () => import('@/views/system/RoleList'),
// meta: { title: '角色管理', permission: [ 'dashboard' ] }
// },
// {
// path: '/isystem/log',
// name: 'log',
// component: () => import('@/views/system/LogList'),
// meta: { title: '日志管理', permission: [ 'dashboard' ] }
// },
// ]
// },
//
//
// //Online开发
// {
// path: '/online',
// name: 'online',
// redirect: '/online',
// component: RouteView,
// meta: { title: '在线开发', icon: 'dashboard', permission: [ 'dashboard' ] },
// children: [
// {
// path: '/online/cgreport',
// name: 'OnlCgreportHeadList',
// component: () => import('@/views/modules/online/cgreport/OnlCgreportHeadList'),
// meta: { title: 'Online报表配置', permission: [ 'dashboard' ] }
// },
// {
// path: '/online/cgform',
// name: 'OnlCgformHeadList',
// component: () => import('@/views/modules/online/cgform/OnlCgformHeadList'),
// meta: { title: 'Online表单开发', permission: [ 'dashboard' ] }
// },
// {
// path: '/jeecg/jeecgOnlineTest',
// name: 'JeecgOnlineTest',
// component: () => import('@/views/jeecg/JeecgOnlineTest'),
// meta: { title: '动态表单页面', permission: [ 'dashboard' ] }
// },
// {
// path: '/online/auto/:code',
// name: 'onlineAutoList',
// hidden : true,
// component: () => import('@/views/modules/online/cgreport/auto/OnlCgreportAutoList'),
// meta: { title: 'Auto报表', permission: [ 'cgreport' ] }
// }
// ]
// },
//
//
// //系统监控
// {
// path: '/sysmonitor',
// name: 'sysmonitor',
// redirect: '/sysmonitor',
// component: RouteView,
// meta: { title: '系统监控', icon: 'dashboard', permission: [ 'dashboard' ] },
// children: [
// {
// path: '/sys/dataLog-list',
// name: 'DataLogList',
// component: () => import('@/views/system/DataLogList'),
// meta: { title: '数据日志', permission: [ 'dashboard' ] }
// },
// {
// path: 'http://localhost:8080/jeecg-boot/druid/',
// name: 'druid',
// component: () => import('@/views/jeecg/tablist/JeecgOrderDMainList'),
// meta: { title: 'SQL监控', permission: [ 'dashboard' ] }
// },
// {
// path: '/isystem/QuartzJobList',
// name: 'QuartzJobList',
// component: () => import('@/views/system/QuartzJobList'),
// meta: { title: '定时任务', permission: [ 'dashboard' ] }
// },
// ]
// },
//
//
// //jeecg demo
// {
// path: '/jeecg',
// name: 'jeecg',
// redirect: '/jeecg',
// component: RouteView,
// meta: { title: 'JEECG案例', icon: 'dashboard', permission: [ 'dashboard' ] },
// children: [
// {
// path: '/jeecg/JeecgDemoList',
// name: 'DemoList',
// component: () => import('@/views/jeecg/JeecgDemoList'),
// meta: { title: '单表模型示例', permission: [ 'dashboard' ] }
// },
// {
// path: '/jeecg/tablist/JeecgOrderDMainList',
// name: 'JeecgOrderDMainList',
// component: () => import('@/views/jeecg/tablist/JeecgOrderDMainList'),
// meta: { title: '一对多Tab示例', permission: [ 'dashboard' ] }
// },
// {
// path: '/jeecg/FlowTest',
// name: 'FlowTest',
// component: () => import('@/views/jeecg/FlowTest'),
// meta: { title: '数据回执模拟', permission: [ 'dashboard' ] }
// },
// {
// path: '/jeecg/PrintDemo',
// name: 'PrintDemo',
// component: () => import('@/views/jeecg/PrintDemo'),
// meta: { title: '打印测试', permission: [ 'dashboard' ] }
// },
// {
// path: '/jeecg/JeecgOrderMainList',
// name: 'JeecgOrderMainList',
// component: () => import('@/views/jeecg/JeecgOrderMainList'),
// meta: { title: '一对多示例', permission: [ 'dashboard' ] }
// },
// {
// path: 'http://www.baidu.com',
// name: 'baidu',
// component: () => import('@/components/layouts/IframePageView'),
// meta: { title: '百度', permission: [ 'dashboard' ] }
// },
// {
// path: 'http://localhost:8080/jeecg-boot/auto/cgform/list',
// name: 'cgformtest',
// component: () => import('@/components/layouts/IframePageView'),
// meta: { title: 'online表单测试', permission: [ 'dashboard' ] }
// },
// {
// path: '/jeecg/helloworld',
// name: 'helloworld',
// hidden : true,
// component: () => import('@/views/jeecg/helloworld'),
// meta: { title: 'helloworld', permission: [ 'dashboard' ] }
// },
// ]
// },
// dashboard
{
@ -76,29 +291,6 @@ export const asyncRouterMap = [
]
},
//jeecg
{
path: '/jeecg',
name: 'jeecg',
redirect: '/jeecg',
component: RouteView,
meta: { title: 'JEECG', icon: 'dashboard', permission: [ 'dashboard' ] },
children: [
{
path: '/jeecg/JeecgDemoList',
name: 'DemoList',
component: () => import('@/views/jeecg/JeecgDemoList'),
meta: { title: '', permission: [ 'dashboard' ] }
},
{
path: '/jeecg/helloworld',
name: 'helloworld',
hidden : true,
component: () => import('@/views/jeecg/helloworld'),
meta: { title: 'helloworld', permission: [ 'dashboard' ] }
}
]
},
// forms
{
path: '/form',
@ -369,10 +561,34 @@ export const constantRouterMap = [
path: 'register-result',
name: 'registerResult',
component: () => import(/* webpackChunkName: "user" */ '@/views/user/RegisterResult')
}
},
]
},
// {
// path: '/',
// name: 'index',
// component: TabLayout,
// meta: {title: '首页'},
// redirect: '/dashboard/workplace',
// children: [
// {
// path: '/online',
// name: 'online',
// redirect: '/online',
// component: RouteView,
// meta: {title: '在线开发', icon: 'dashboard', permission: ['dashboard']},
// children: [
// {
// path: '/online/auto/:code',
// name: 'report',
// component: () => import('@/views/modules/online/cgreport/OnlCgreportAutoList')
// },
// ]
// },
// ]
// },
{
path: '/test',
component: BlankLayout,
@ -385,7 +601,6 @@ export const constantRouterMap = [
}
]
},
{
path: '/404',
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')

View File

@ -22,6 +22,7 @@ export default {
fixSiderbar: false, // sticky siderbar
autoHideHeader: false, // auto hide header
colorWeak: false,
multipage: false, //默认多页签模式
// vue-ls options
storageOptions: {
namespace: 'pro__', // key prefix

View File

@ -12,9 +12,9 @@ import 'ant-design-vue/dist/antd.less'; // or 'ant-design-vue/dist/antd.less'
import '@/permission' // permission control
import '@/utils/filter' // base filter
import DictSelectTag from './components/dict/index.js'
import Print from 'vue-print-nb'
import Print from 'vue-print-nb-jeecg'
/*import '@babel/polyfill'*/
import VueApexCharts from 'vue-apexcharts'
import {
ACCESS_TOKEN,
@ -30,17 +30,19 @@ import {
} from "@/store/mutation-types"
import config from '@/defaultSettings'
import JDictSelectTag from './components/dict/index.js'
import hasPermission from '@/utils/hasPermission'
Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions)
Vue.use(Antd)
Vue.use(VueAxios, router)
Vue.use(Viser)
Vue.use(hasPermission)
Vue.use(DictSelectTag)
Vue.use(JDictSelectTag)
Vue.use(Print)
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)
new Vue({
router,

View File

@ -0,0 +1,160 @@
import JEditableTable from '@/components/jeecg/JEditableTable'
import { VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables } from '@/utils/JEditableTableUtil'
import { httpAction, getAction } from '@/api/manage'
export const JEditableTableOneToManyMixin = {
components: {
JEditableTable
},
data() {
return {
title: '',
visible: false,
form: this.$form.createForm(this),
confirmLoading: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 18 }
}
}
},
methods: {
/** 获取所有的editableTable实例 */
getAllTable() {
if (!(this.refKeys instanceof Array)) {
throw this.throwNotArray('refKeys')
}
let values = this.refKeys.map(key => getRefPromise(this, key))
return Promise.all(values)
},
/** 遍历所有的JEditableTable实例 */
eachAllTable(callback) {
// 开始遍历
this.getAllTable().then(tables => {
tables.forEach((item, index) => {
if (typeof callback === 'function') {
callback(item, index)
}
})
})
},
/** 当点击新增按钮时调用此方法 */
add() {
// 默认新增空数据
let rowNum = this.addDefaultRowNum
if (typeof rowNum !== 'number') {
rowNum = 1
console.warn(' data addDefaultRowNum addDefaultRowNum addDefaultRowNum 0')
}
this.eachAllTable((item) => {
item.add(rowNum)
})
this.edit({})
},
/** 当点击了编辑(修改)按钮时调用此方法 */
edit(record) {
if (typeof this.editBefore === 'function') this.editBefore(record)
this.visible = true
this.activeKey = this.refKeys[0]
this.form.resetFields()
this.model = Object.assign({}, record)
if (typeof this.editAfter === 'function') this.editAfter(this.model)
},
/** 关闭弹窗并将所有JEditableTable实例回归到初始状态 */
close() {
this.visible = false
this.eachAllTable((item) => {
item.initialize()
})
this.$emit('close')
},
/** 查询某个tab的数据 */
requestSubTableData(url, params, tab) {
tab.loading = true
getAction(url, params).then(res => {
tab.dataSource = res.result || []
}).finally(() => {
tab.loading = false
})
},
/** 发起请求,自动判断是执行新增还是修改操作 */
request(formData) {
let url = this.url.add, method = 'post'
if (this.model.id) {
url = this.url.edit
method = 'put'
}
this.confirmLoading = true
httpAction(url, formData, method).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
},
/* --- handle 事件 --- */
/** ATab 选项卡切换事件 */
handleChangeTabs(key) {
// 自动重置scrollTop状态防止出现白屏
getRefPromise(this, key).then(editableTable => {
editableTable.resetScrollTop()
})
},
/** 关闭按钮点击事件 */
handleCancel() {
this.close()
},
/** 确定按钮点击事件 */
handleOk() {
/** 触发表单验证 */
this.getAllTable().then(tables => {
/** 一次性验证主表和所有的次表 */
return validateFormAndTables(this.form, tables)
}).then(allValues => {
if (typeof this.classifyIntoFormData !== 'function') {
throw this.throwNotFunction('classifyIntoFormData')
}
let formData = this.classifyIntoFormData(allValues)
// 发起请求
return this.request(formData)
}).catch(e => {
if (e.error === VALIDATE_NO_PASSED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
} else {
console.error(e)
}
})
},
/* --- throw --- */
/** not a function */
throwNotFunction(name) {
return `${name} `
},
/** not a array */
throwNotArray(name) {
return `${name} `
}
}
}

View File

@ -0,0 +1,220 @@
/**
* modalFormOk refmodalForm
* superQuery refsuperQueryModal
* dataurl list delete deleteBatch
*/
import { filterObj } from '@/utils/util';
import { deleteAction, getAction } from '@/api/manage'
export const JeecgListMixin = {
data(){
return {
/* 查询条件 */
queryParam: {},
/* 数据源 */
dataSource:[],
/* 分页参数 */
ipagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
/* 排序参数 */
isorter:{
column: 'createTime',
order: 'desc',
},
/* 筛选参数 */
filters: {},
/* table加载状态 */
loading:false,
/* table选中keys*/
selectedRowKeys: [],
/* table选中records*/
selectionRows: [],
/* 查询折叠 */
toggleSearchStatus:false,
/* 高级查询条件生效状态 */
superQueryFlag:false,
/* 高级查询条件 */
superQueryParams:"",
}
},
created() {
this.loadData();
//初始化字典配置 在自己页面定义
this.initDictConfig();
},
methods:{
loadData(arg) {
if(!this.url.list){
this.$message.error("请设置url.list属性!")
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
})
},
initDictConfig(){
console.log("--这是一个假的方法!")
},
handleSuperQuery(arg) {
//高级查询方法
if(!arg){
this.superQueryParams=''
this.superQueryFlag = false
}else{
this.superQueryFlag = true
this.superQueryParams=JSON.stringify(arg)
}
this.loadData()
},
getQueryParams() {
//获取查询条件
let sqp = {}
if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams)
}
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
//TODO 字段权限控制
var str = "id,";
this.columns.forEach(function (value) {
str += "," + value.dataIndex;
});
return str;
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onClearSelected() {
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery() {
this.loadData(1);
},
superQuery() {
this.$refs.superQueryModal.show();
},
searchReset() {
this.queryParam = {}
this.loadData(1);
},
batchDel: function () {
if(!this.url.deleteBatch){
this.$message.error("请设置url.deleteBatch属性!")
return
}
if (this.selectedRowKeys.length <= 0) {
this.$message.warning('');
return;
} else {
var ids = "";
for (var a = 0; a < this.selectedRowKeys.length; a++) {
ids += this.selectedRowKeys[a] + ",";
}
var that = this;
this.$confirm({
title: "确认删除",
content: "是否删除选中数据?",
onOk: function () {
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
} else {
that.$message.warning(res.message);
}
});
}
});
}
},
handleDelete: function (id) {
if(!this.url.delete){
this.$message.error("请设置url.delete属性!")
return
}
var that = this;
deleteAction(that.url.delete, {id: id}).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.loadData();
} else {
that.$message.warning(res.message);
}
});
},
handleEdit: function (record) {
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title = "编辑";
},
handleAdd: function () {
this.$refs.modalForm.add();
this.$refs.modalForm.title = "新增";
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
}
this.ipagination = pagination;
this.loadData();
},
handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus;
},
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
},
handleDetail:function(record){
this.$refs.modalForm.edit(record);
this.$refs.modalForm.title="详情";
this.$refs.modalForm.disableSubmit = true;
},
/* 导出 */
handleExportXls(){
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
let url = `${window._CONFIG['domianURL']}/${this.url.exportXlsUrl}?paramsStr=${paramsStr}`;
window.location.href = url;
},
/* 导入 */
handleImportExcel(info){
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
this.$message.success(`${info.file.name} `);
this.loadData();
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} .`);
}
},
}
}

View File

@ -26,7 +26,7 @@ const app = {
autoHideHeader: false,
color: null,
weak: false,
multipage: true
multipage: true //默认多页签模式
},
mutations: {
SET_SIDEBAR_TYPE: (state, type) => {
@ -74,8 +74,8 @@ const app = {
Vue.ls.set(DEFAULT_COLOR_WEAK, flag)
state.weak = flag
},
setMultipage (state, multipage) {
state.multipage = multipage
SET_MULTI_PAGE (state, multipageFlag) {
state.multipage = multipageFlag
}
},
actions: {
@ -114,6 +114,9 @@ const app = {
},
ToggleWeak({ commit }, weakFlag) {
commit('TOGGLE_WEAK', weakFlag)
},
ToggleMultipage({ commit }, multipageFlag) {
commit('SET_MULTI_PAGE', multipageFlag)
}
}
}

View File

@ -82,11 +82,12 @@ const user = {
// 登出
Logout({ commit, state }) {
return new Promise((resolve) => {
let logoutToken = state.token;
commit('SET_TOKEN', '')
commit('SET_PERMISSIONLIST', [])
Vue.ls.remove(ACCESS_TOKEN)
logout(state.token).then(() => {
//console.log('logoutToken: '+ logoutToken)
logout(logoutToken).then(() => {
resolve()
}).catch(() => {
resolve()

View File

@ -0,0 +1,97 @@
const FormTypes = {
normal: 'normal',
input: 'input',
inputNumber: 'inputNumber',
checkbox: 'checkbox',
select: 'select',
date: 'date',
datetime: 'datetime'
}
const VALIDATE_NO_PASSED = Symbol()
export { FormTypes, VALIDATE_NO_PASSED }
/**
* $refs
* $refs
* $refs
* @author sunjianlei
**/
export function getRefPromise(vm, name) {
return new Promise((resolve) => {
(function next() {
let ref = vm.$refs[name]
if (ref) {
resolve(ref)
} else {
setTimeout(() => {
next()
}, 10)
}
})()
})
}
/**
*
* @param form form
* @param cases JEditableTable
* @returns {Promise<any>}
* @author sunjianlei
*/
export function validateFormAndTables(form, cases) {
if (!(form && typeof form.validateFields === 'function')) {
throw `form form${typeof form}`
}
let options = {}
return new Promise((resolve, reject) => {
// 验证主表表单
form.validateFields((err, values) => {
err ? reject({ error: VALIDATE_NO_PASSED }) : resolve(values)
})
}).then(values => {
Object.assign(options, { formValue: values })
// 验证所有子表的表单
return validateTables(cases)
}).then(all => {
Object.assign(options, { tablesValue: all })
return Promise.resolve(options)
}).catch(error => {
return Promise.reject(error)
})
}
/**
*
* @param cases JEditableTable
* @author sunjianlei
*/
export function validateTables(cases) {
if (!(cases instanceof Array)) {
throw `'validateTables''cases'${typeof cases}`
}
return new Promise((resolve, reject) => {
let tables = []
let index = 0;
(function next() {
let vm = cases[index]
vm.getAll(true).then(all => {
tables[index] = all
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
if (++index === cases.length) {
resolve(tables)
} else (
next()
)
}, error => {
// 出现未验证通过的表单,不再进行下一步校验,直接返回失败并跳转到该表格
if (error === VALIDATE_NO_PASSED) {
reject({ error: VALIDATE_NO_PASSED, index })
}
reject(error)
})
})()
})
}

View File

@ -33,5 +33,5 @@ const VueAxios = {
export {
VueAxios,
// eslint-disable-next-line no-undef
// instance as axios
//instance as axios
}

View File

@ -15,4 +15,16 @@ Vue.filter('dayjs', function(dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
Vue.filter('moment', function(dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
return dayjs(dataStr).format(pattern)
})
/** 字符串超长截取省略号显示 */
Vue.filter('ellipsis', function (value, vlength = 25) {
if(!value){
return "";
}
console.log('vlength: '+ vlength);
if (value.length > vlength) {
return value.slice(0, vlength) + '...'
}
return value
})

View File

@ -3,10 +3,11 @@ const hasPermission = {
console.log(options);
Vue.directive('has', {
inserted: (el, binding, vnode)=>{
//console.log("页面权限----",el);
console.log("页面权限----",el);
let permissionList = vnode.context.$route.meta.permissionList;
if (permissionList === null || permissionList === "" || permissionList === undefined) {
el.parentNode.removeChild(el)
return
}
let permissions = [];
for (var item of permissionList) {

View File

@ -11,6 +11,7 @@ const mixin = {
navTheme: state => state.app.theme,
primaryColor: state => state.app.color,
colorWeak: state => state.app.weak,
multipage: state => state.app.multipage,//多页签设置
fixedHeader: state => state.app.fixedHeader,
fixSiderbar: state => state.app.fixSiderbar,
contentWidth: state => state.app.contentWidth,

View File

@ -23,7 +23,7 @@ const err = (error) => {
break
case 500:
//notification.error({ message: '系统提示', description:'Token失效请重新登录!',duration: 4})
if(data.message=="Token失效请重新登录"){
if(token && data.message=="Token失效请重新登录"){
// update-begin- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式不直接跳转----
// store.dispatch('Logout').then(() => {
// window.location.reload()
@ -35,6 +35,7 @@ const err = (error) => {
mask: false,
onOk: () => {
store.dispatch('Logout').then(() => {
Vue.ls.remove(ACCESS_TOKEN)
window.location.reload()
})
}
@ -76,6 +77,12 @@ service.interceptors.request.use(config => {
if (token) {
config.headers[ 'X-Access-Token' ] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
}
if(config.method=='get'){
config.params = {
_t: Date.parse(new Date())/1000,
...config.params
}
}
return config
},(error) => {
return Promise.reject(error)

View File

@ -1,3 +1,4 @@
import { isURL } from '@/utils/validate'
export function timeFix() {
const time = new Date()
@ -33,7 +34,7 @@ export function filterObj(obj) {
for ( var key in obj) {
if (obj.hasOwnProperty(key)
&& (obj[key] == null || obj[key] == undefined || obj[key] == '')) {
&& (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
delete obj[key];
}
}
@ -105,6 +106,13 @@ function generateChildRouters (data) {
}else{
component = "views/"+item.component;
}
// eslint-disable-next-line
let URL = (item.meta.url|| '').replace(/{{([^}}]+)?}}/g, (s1, s2) => eval(s2)) // URL支持{{ window.xxx }}占位符变量
if (isURL(URL)) {
item.meta.url = URL;
}
let menu = {
path: item.path,
name: item.name,
@ -125,7 +133,94 @@ function generateChildRouters (data) {
if (item.children && item.children.length > 0) {
menu.children = [...generateChildRouters( item.children)];
}
routers.push(menu);
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置判断是否路由菜单字段动态选择是否生成路由为了支持参数URL菜单------
//判断是否生成路由
if(item.route && item.route === '0'){
console.log(' item.route '+item.route);
console.log(' item.path '+item.path);
}else{
routers.push(menu);
}
//--update-end----author:scott---date:20190320------for:根据后台菜单配置判断是否路由菜单字段动态选择是否生成路由为了支持参数URL菜单------
}
return routers
}
/**
*
* @param obj
* @return
*/
export function cloneObject(obj) {
return JSON.parse(JSON.stringify(obj))
}
/**
*
* @param min
* @param max
* @return int
*/
export function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
/**
*
* @param length
* @param chats
* @return string
*/
export function randomString(length, chats) {
if (!length) length = 1
if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm'
let str = ''
for (let i = 0; i < length; i++) {
let num = randomNumber(0, chats.length - 1)
str += chats[num]
}
return str
}
/**
* uuid
* @return string uuid
*/
export function randomUUID() {
let chats = '0123456789abcdef'
return randomString(32, chats)
}
/**
*
* @date 2019-04-08
*
* @param doc document
*/
export function topNavScrollToSelectItem(doc) {
let scrollWidth = doc.getElementById('top-nav-scroll-width')
if (scrollWidth == null) return
let menu = scrollWidth.getElementsByClassName('ant-menu')[0]
if (menu) {
let menuItems = menu.getElementsByTagName('li')
for (let item of menuItems) {
let index1 = item.className.indexOf('ant-menu-item-selected') !== -1
let index2 = item.className.indexOf('ant-menu-submenu-selected') !== -1
if (index1 || index2) {
// scrollLeft = 选中项left - 选中项width - (第一个隐藏的div的宽度)
let scrollLeft = (item.offsetLeft - item.offsetWidth - (index1 ? 100 : 60))
let scrollView = doc.getElementById('top-nav-scroll-view')
// scrollTo() 方法存在兼容性问题
if (typeof scrollView.scrollTo === 'function') {
scrollView.scrollTo({
left: scrollLeft,
behavior: 'smooth'
})
} else {
scrollView.scrollLeft = scrollLeft
}
break
}
}
}
}

View File

@ -0,0 +1,31 @@
/**
*
* @param {*} s
*/
export function isEmail (s) {
return /^([a-zA-Z0-9._-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s)
}
/**
*
* @param {*} s
*/
export function isMobile (s) {
return /^1[0-9]{10}$/.test(s)
}
/**
*
* @param {*} s
*/
export function isPhone (s) {
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s)
}
/**
* URL
* @param {*} s
*/
export function isURL (s) {
return /^http[s]?:\/\/.*/.test(s)
}

View File

@ -93,8 +93,6 @@
import PageLayout from '@/components/page/PageLayout'
import RouteView from "@/components/layouts/RouteView"
import { AppPage, ArticlePage, ProjectPage } from './page'
import {imgView} from '@/api/api'
import { mapGetters } from 'vuex'
export default {
@ -135,7 +133,7 @@
methods: {
...mapGetters(["nickname", "avatar"]),
getAvatar(){
return imgView+this.avatar();
return window._CONFIG['imgDomainURL']+"/"+this.avatar();
},
getTeams() {
this.$http.get('/api/workplace/teams')

View File

@ -36,7 +36,7 @@
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar />
<mini-bar :height="40" />
</div>
<template slot="footer"> <span>60%</span></template>
</chart-card>
@ -47,7 +47,7 @@
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-progress color="rgb(19, 194, 194)" :target="80" :percentage="78" height="8px" />
<mini-progress color="rgb(19, 194, 194)" :target="80" :percentage="78" :height="8" />
</div>
<template slot="footer">
<trend flag="down" style="margin-right: 16px;">
@ -78,7 +78,7 @@
<a-tab-pane loading="true" tab="销售额" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额排行" />
<bar title="销售额排行" :dataSource="barData"/>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList"/>
@ -88,7 +88,7 @@
<a-tab-pane tab="访问量" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="销售额趋势" />
<bar title="销售额趋势" :dataSource="barData"/>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<rank-list title="门店销售排行榜" :list="rankList"/>
@ -173,7 +173,7 @@
import RankList from '@/components/chart/RankList'
import Bar from '@/components/chart/Bar'
import Trend from '@/components/Trend'
import {getLoginfo} from '@/api/api.js'
import {getLoginfo} from '@/api/api'
const rankList = []
for (let i = 0; i < 7; i++) {
@ -182,7 +182,13 @@
total: 1234.56 - i * 100
})
}
const barData = []
for (let i = 0; i < 12; i += 1) {
barData.push({
x: `${i + 1}`,
y: Math.floor(Math.random() * 1000) + 200
})
}
export default {
name: "Analysis",
components: {
@ -199,7 +205,9 @@
data() {
return {
loading: true,
center: null,
rankList,
barData,
loginfo:{},
}
},

View File

@ -21,11 +21,11 @@
<div>
<a-row :gutter="24">
<a-col :xl="16" :lg="24" :md="24" :sm="24" :xs="24">
<a-card
class="project-list"
:loading="loading"
style="margin-bottom: 24px;"
:bordered="false"
<a-card
class="project-list"
:loading="loading"
style="margin-bottom: 24px;"
:bordered="false"
title="进行中的项目"
:body-style="{ padding: 0 }">
<a slot="extra"></a>
@ -67,12 +67,12 @@
</a-list>
</a-card>
</a-col>
<a-col
style="padding: 0 12px"
:xl="8"
:lg="24"
:md="24"
:sm="24"
<a-col
style="padding: 0 12px"
:xl="8"
:lg="24"
:md="24"
:sm="24"
:xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
@ -116,9 +116,7 @@
import PageLayout from '@/components/page/PageLayout'
import HeadInfo from '@/components/tools/HeadInfo'
import Radar from '@/components/chart/Radar'
import { getRoleList, getServiceList } from "@/api/manage"
import {imgView} from '@/api/api'
const DataSet = require('@antv/data-set')
@ -187,7 +185,8 @@
},
created() {
this.user = this.userInfo
this.avatar = imgView + this.userInfo.avatar
this.avatar = window._CONFIG['imgDomainURL'] +"/"+ this.userInfo.avatar
console.log('this.avatar :'+ this.avatar)
getRoleList().then(res => {
console.log('workplace -> call getRoleList()', res)

View File

@ -1,13 +1,13 @@
<template>
<a-card :bordered="false">
<a-row>
<a-col :span="2">
<a-col :md="2" :sm="4">
<a-select defaultValue="POST" style="width: 90px" @change="handleChange" size="large">
<a-select-option value="POST">POST</a-select-option>
<!--<a-select-option value="GET">GET</a-select-option>-->
</a-select>
</a-col>
<a-col :span="22">
<a-col :md="22" :sm="20">
<a-input-search
placeholder="input send url"
v-model="url"

View File

@ -0,0 +1,43 @@
<template>
<div>
<a-input-search
v-model="this.selectedUserNames"
placeholder="请先选择用户"
disabled
@search="onSearch"
size="large">
<a-button slot="enterButton"></a-button>
</a-input-search>
<j-search-user-by-dep-modal ref="JSearchUserByDepModal" @ok="modalFormOk"></j-search-user-by-dep-modal>
</div>
</template>
<script>
import JSearchUserByDepModal from '@/components/jeecgbiz/JSearchUserByDepModal'
export default {
name: 'JSearchUserByDepList',
components: {
JSearchUserByDepModal,
},
data() {
return {
selectedUserNames: '',
}
},
methods: {
onSearch() {
this.$refs.JSearchUserByDepModal.showModal();
this.selectedUserNames = '';
this.$refs.JSearchUserByDepModal.title = '';
},
modalFormOk(selectedValue) {
this.selectedUserNames = selectedValue;
}
}
}
</script>
<style scoped>
</style>

View File

@ -6,40 +6,65 @@
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="6">
<a-col :md="6" :sm="8">
<a-form-item label="名称">
<a-input placeholder="请输入名称查询" v-model="queryParam.name"></a-input>
</a-form-item>
</a-col>
<a-col :span="6">
<a-col :md="6" :sm="8">
<a-form-item label="年龄">
<a-input placeholder="请输入名称查询" v-model="queryParam.age"></a-input>
</a-form-item>
</a-col>
<a-col :span="6">
<a-form-item label="性别">
<DictSelectTag v-model="queryParam.sex" placeholder="请输入用户性别" dictCode="sex"/>
</a-form-item>
</a-col>
<template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8">
<a-form-item label="字典下拉">
<j-dict-select-tag v-model="queryParam.sex" placeholder="请选择用户名称" dictCode="sex"/>
</a-form-item>
</a-col>
<a-col :span="6" >
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="8">
<a-form-item label="字典表下拉">
<j-dict-select-tag v-model="queryParam.realname" placeholder="请选择用户" dictCode="sys_user,realname,id"/>
</a-form-item>
</a-col>
</template>
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
<a-button type="primary" @click="superQuery" icon="filter" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-col>
</span>
<a-col :md="6" :sm="24">
<template v-if="superQueryFlag">
<a-tooltip title="已有高级查询条件生效!">
<button :disabled="false" class="ant-btn ant-btn-primary" @click="superQuery">
<a-icon type="appstore" theme="twoTone" spin="true"></a-icon>
<span></span>
</button>
</a-tooltip>
</template>
<a-button v-else type="primary" @click="superQuery" icon="filter"></a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '' : '' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator">
<div class="table-operator" style="margin-top: 5px">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button type="primary" icon="plus" @click="jump"></a-button>
<a-button type="primary" icon="plus" @click="onetomany"></a-button>
<a-button type="primary" icon="download" @click="exportXls"></a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import"></a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
@ -94,38 +119,51 @@
<!-- table-end -->
<!-- -->
<jeecgDemo-modal ref="jeecgDemoModal" @ok="modalFormOk"></jeecgDemo-modal>
<jeecgDemo-modal ref="modalForm" @ok="modalFormOk"></jeecgDemo-modal>
<!-- -->
<JeecgDemoTabsModal ref="jeecgDemoTabsModal" @ok="modalFormOk"></JeecgDemoTabsModal>
<!-- -->
<superQueryModal ref="superQueryModal" @ok="modalFormOk" @handleSuperQuery="handleSuperQuery"></superQueryModal>
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
</a-card>
</template>
<script>
import JeecgDemoModal from './modules/JeecgDemoModal'
import SuperQueryModal from './modules/SuperQueryModal'
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
import JeecgDemoTabsModal from './modules/JeecgDemoTabsModal'
import {filterObj} from '@/utils/util'
import {deleteAction, getAction, postAction} from '@/api/manage'
import {initDictOptions, filterDictText} from '@/components/dict/DictSelectUtil'
import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
//高级查询modal需要参数
const superQueryFieldList=[{
type:"date",
value:"birthday",
text:"生日"
},{
type:"string",
value:"name",
text:"用户名"
},{
type:"int",
value:"age",
text:"年龄"
}]
export default {
name: "JeecgDemoList",
mixins:[JeecgListMixin],
components: {
JeecgDemoModal,
SuperQueryModal,
JSuperQuery,
JeecgDemoTabsModal,
},
data() {
return {
description: '',
// 查询条件
queryParam: {},
//字典数组缓存
sexDictOptions: [],
importExcelUrl:`${window._CONFIG['domianURL']}/test/jeecgDemo/importExcel`,
// 表头
columns: [
{
@ -157,7 +195,7 @@
title: '',
align: "center",
dataIndex: 'sex',
customRender: (text, record, index) => {
customRender: (text) => {
//字典值替换通用方法
return filterDictText(this.sexDictOptions, text);
}
@ -189,66 +227,34 @@
scopedSlots: {customRender: 'action'},
}
],
//数据集
dataSource: [],
// 分页参数
ipagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter: {
column: 'createTime',
order: 'desc',
},
loading: false,
selectedRowKeys: [],
selectedRows: [],
url: {
list: "/test/jeecgDemo/list",
delete: "/test/jeecgDemo/delete",
deleteBatch: "/test/jeecgDemo/deleteBatch",
},
fieldList:superQueryFieldList
}
},
created() {
this.loadData();
//初始化字典配置
this.initDictConfig();
},
methods: {
loadData(arg) {
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
})
exportXls(){
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
console.log('paramsStr: ' + paramsStr)
let url = `${window._CONFIG['domianURL']}/test/jeecgDemo/exportXls?paramsStr=${paramsStr}`;
window.location.href = url;
},
handleSuperQuery(arg) {//高级查询方法
let params = {'superQueryParams':encodeURI(JSON.stringify(arg))};
getAction(this.url.list, params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}else{
that.$message.warn(res.message);
}
})
handleImportExcel(info){
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
if (info.file.status === 'done') {
this.$message.success(`${info.file.name} `);
this.loadData();
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} .`);
}
},
initDictConfig() {
console.log("--我才是真的方法!--")
//初始化字典 - 性别
initDictOptions('sex').then((res) => {
if (res.success) {
@ -256,105 +262,10 @@
}
});
},
getQueryParams() {
var param = Object.assign({}, this.queryParam, this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
//TODO 字段权限控制
var str = "id,";
this.columns.forEach(function (value, index) {
str += "," + value.dataIndex;
});
return str;
},
onSelectChange(selectedRowKeys, selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onClearSelected() {
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery() {
this.loadData(1);
},
superQuery() {
this.$refs.superQueryModal.show();
},
searchReset() {
var that = this;
that.queryParam = {}
that.loadData(1);
},
batchDel: function () {
if (this.selectedRowKeys.length <= 0) {
this.$message.warning('');
return;
} else {
var ids = "";
for (var a = 0; a < this.selectedRowKeys.length; a++) {
ids += this.selectedRowKeys[a] + ",";
}
var that = this;
this.$confirm({
title: "确认删除",
content: "是否删除选中数据?",
onOk: function () {
deleteAction(that.url.deleteBatch, {ids: ids}).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
} else {
that.$message.warning(res.message);
}
});
}
});
}
},
handleDelete: function (id) {
var that = this;
deleteAction(that.url.delete, {id: id}).then((res) => {
if (res.success) {
that.$message.success(res.message);
that.loadData();
} else {
that.$message.warning(res.message);
}
});
},
handleEdit: function (record) {
this.$refs.jeecgDemoModal.edit(record);
this.$refs.jeecgDemoModal.title = "编辑";
},
onetomany: function (record) {
onetomany: function () {
this.$refs.jeecgDemoTabsModal.add();
this.$refs.jeecgDemoTabsModal.title = "编辑";
},
handleAdd: function () {
this.$refs.jeecgDemoModal.add();
this.$refs.jeecgDemoModal.title = "新增";
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
console.log(sorter);
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
}
this.ipagination = pagination;
this.loadData();
},
modalFormOk() {
// 新增/修改 成功时,重载列表
this.loadData();
},
//跳转单据页面
jump() {
this.$router.push({path: '/jeecg/helloworld'})
@ -367,10 +278,6 @@
margin-bottom: 18px;
}
.ant-layout-content {
margin: 12px 16px 0 !important;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;

View File

@ -0,0 +1,191 @@
<template>
<a-card :borderd="false">
<a-button @click="handleTableCheck" type="primary"></a-button>
<span style="padding-left:8px;"></span>
<a-tooltip placement="top" title="获取值,忽略表单验证" :autoAdjustOverflow="true">
<a-button @click="handleTableGet" type="primary"></a-button>
</a-tooltip>
<span style="padding-left:8px;"></span>
<a-tooltip placement="top" title="模拟加载1000条数据" :autoAdjustOverflow="true">
<a-button @click="handleTableSet" type="primary"></a-button>
</a-tooltip>
<j-editable-table
ref="editableTable"
:loading="loading"
:columns="columns"
:dataSource="dataSource"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"
style="margin-top: 8px;"
@selectRowChange="handleSelectRowChange"/>
</a-card>
</template>
<script>
import JEditableTable from '@/components/jeecg/JEditableTable'
import { FormTypes } from '@/utils/JEditableTableUtil'
import { randomUUID, randomString, randomNumber } from '@/utils/util'
export default {
name: 'JeecgEditableTableExample',
components: {
JEditableTable
},
data() {
return {
loading: false,
columns: [
{
title: '',
key: 'dbFieldName',
width: '19%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [
{
required: true, // 必填
message: '${title}' // 显示的文本
},
{
pattern: /^[a-z|A-Z][a-z|A-Z\d_-]{0,}$/, // 正则
message: '${title}线'
}
]
},
{
title: '',
key: 'dbFieldTxt',
width: '19%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [{ required: true, message: '${title}' }]
},
{
title: '',
key: 'dbFieldType',
width: '18%',
type: FormTypes.select,
options: [ // 下拉选项
{ title: 'String', value: 'string' },
{ title: 'Integer', value: 'int' },
{ title: 'Double', value: 'double' },
{ title: 'Boolean', value: 'boolean' }
],
defaultValue: '',
placeholder: '${title}',
validateRules: [{ required: true, message: '${title}' }]
},
{
title: '',
key: 'dbLength',
width: '8%',
type: FormTypes.inputNumber,
defaultValue: 32,
placeholder: '${title}',
validateRules: [{ required: true, message: '${title}' }]
},
{
title: '',
key: 'dbDefaultVal',
width: '22%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [{ required: true, message: '${title}' }]
},
{
title: '',
key: 'isNull',
width: '8%',
type: FormTypes.checkbox,
customValue: ['Y', 'N'], // true ,false
defaultChecked: false
}
],
dataSource: [],
selectedRowIds: []
}
},
created() {
},
mounted() {
this.randomData(23, false)
},
methods: {
/** 表单验证 */
handleTableCheck() {
this.$refs.editableTable.getValues((error) => {
if (error === 0) {
this.$message.success('')
} else {
this.$message.error('')
}
})
},
/** 获取值,忽略表单验证 */
handleTableGet() {
this.$refs.editableTable.getValues((error, values) => {
console.log('values:', values)
}, false)
console.log('deleteIds:', this.$refs.editableTable.getDeleteIds())
this.$message.info('')
},
/** 模拟加载1000条数据 */
handleTableSet() {
this.randomData(1000, true)
},
handleSelectRowChange(selectedRowIds) {
this.selectedRowIds = selectedRowIds
},
/* 随机生成数据 */
randomData(size, loading = false) {
if (loading) {
this.loading = true
setTimeout(() => {
this.loading = false
}, 3000)
}
let values = []
for (let i = 0; i < size; i++) {
values.push({
id: randomUUID(),
dbFieldName: `name_${i + 1}`,
dbFieldTxt: randomString(10),
dbFieldType: ['string', 'int', 'double', 'boolean'][randomNumber(0, 3)],
dbLength: randomNumber(0, 233),
dbDefaultVal: randomString(8),
isNull: ['Y', 'N'][randomNumber(0, 1)]
})
}
this.dataSource = values
}
}
}
</script>
<style scoped>
</style>

View File

@ -6,12 +6,12 @@
<a-form layout="inline">
<a-row :gutter="24">
<a-col :span="6">
<a-col :md="6" :sm="24">
<a-form-item label="订单号">
<a-input placeholder="请输入订单号" v-model="queryParam.orderCode"></a-input>
</a-form-item>
</a-col>
<a-col :span="6">
<a-col :md="6" :sm="24">
<a-form-item label="订单类型">
<a-select placeholder="请输入订单类型" v-model="queryParam.ctype">
<a-select-option value="1"></a-select-option>
@ -20,7 +20,7 @@
</a-form-item>
</a-col>
<a-col :span="8" >
<a-col :md="6" :sm="24" >
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
@ -34,6 +34,10 @@
<!-- -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-button type="primary" icon="download" @click="exportXls"></a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import"></a-button>
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
@ -83,25 +87,24 @@
<!-- table-end -->
<!-- -->
<jeecgOrderMain-modal ref="jeecgOrderMainModal" @ok="modalFormOk"></jeecgOrderMain-modal>
<jeecgOrderMain-modal ref="modalForm" @ok="modalFormOk"></jeecgOrderMain-modal>
</a-card>
</template>
<script>
import JeecgOrderMainModal from './modules/JeecgOrderMainModal'
import { filterObj } from '@/utils/util'
import { deleteAction,getAction } from '@/api/manage'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
export default {
name: "JeecgOrderMainList",
mixins: [JeecgListMixin],
components: {
JeecgOrderMainModal
},
data () {
return {
description: '',
// 查询条件
queryParam: {},
importExcelUrl:`${window._CONFIG['domianURL']}/test/jeecgOrderMain/importExcel`,
// 表头
columns: [
{
@ -114,12 +117,12 @@
return parseInt(index)+1;
}
},
{
{
title: '',
align:"center",
dataIndex: 'orderCode'
},
{
{
title: '',
align:"center",
dataIndex: 'ctype',
@ -133,17 +136,17 @@
return re;
}
},
{
{
title: '',
align:"center",
dataIndex: 'orderDate'
},
{
{
title: '',
align:"center",
dataIndex: 'orderMoney'
},
{
{
title: '',
align:"center",
dataIndex: 'content'
@ -155,154 +158,43 @@
scopedSlots: { customRender: 'action' },
}
],
//数据集
dataSource:[],
// 分页参数
ipagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter:{
column: 'createTime',
order: 'desc',
},
loading:false,
selectedRowKeys: [],
selectedRows: [],
url: {
list: "/test/jeecgOrderMain/list",
delete: "/test/jeecgOrderMain/delete",
deleteBatch: "/test/jeecgOrderMain/deleteBatch",
},
}
}
},
created() {
this.loadData();
},
methods: {
loadData (arg){
//加载数据 若传入参数1则加载第一页的内容
if(arg===1){
this.ipagination.current = 1;
exportXls(){
let paramsStr = encodeURI(JSON.stringify(this.getQueryParams()));
console.log('paramsStr: ' + paramsStr)
let url = `${window._CONFIG['domianURL']}/test/jeecgOrderMain/exportXls?paramsStr=${paramsStr}`;
window.location.href = url;
},
handleImportExcel(info){
if (info.file.status !== 'uploading') {
console.log(info.file, info.fileList);
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list,params).then((res)=>{
if(res.success){
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
})
},
getQueryParams(){
var param = Object.assign({}, this.queryParam,this.isorter);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField(){
//TODO 字段权限控制
var str = "id,";
for(var a = 0;a<this.columns.length;a++){
str+=","+this.columns[a].dataIndex;
if (info.file.status === 'done') {
this.$message.success(`${info.file.name} `);
this.loadData();
} else if (info.file.status === 'error') {
this.$message.error(`${info.file.name} .`);
}
return str;
},
onSelectChange (selectedRowKeys,selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onClearSelected(){
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery(){
this.loadData(1);
},
searchReset(){
var that = this;
that.queryParam={};
that.loadData(1);
},
batchDel: function(){
if(this.selectedRowKeys.length<=0){
this.$message.warning('');
return ;
}else{
var ids = "";
for(var a =0;a<this.selectedRowKeys.length;a++){
ids+=this.selectedRowKeys[a]+",";
}
var that = this;
this.$confirm({
title:"确认删除",
content:"是否删除选中数据?",
onOk: function(){
deleteAction(that.url.deleteBatch,{ids: ids}).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
}
},
handleDelete: function(id){
var that = this;
deleteAction(that.url.delete,{id: id}).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
}else{
that.$message.warning(res.message);
}
});
},
handleEdit: function(record){
this.$refs.jeecgOrderMainModal.edit(record);
this.$refs.jeecgOrderMainModal.title="编辑";
},
handleAdd: function(){
this.$refs.jeecgOrderMainModal.add();
this.$refs.jeecgOrderMainModal.title="新增";
},
handleTableChange(pagination, filters, sorter){
//分页、排序、筛选变化时触发
console.log(sorter);
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.ipagination = pagination;
this.loadData();
},
modalFormOk () {
// 新增/修改 成功时,重载列表
this.loadData();
}
}
}
</script>
<style scoped>
/** Button按钮间距 */
.ant-btn {
margin-left: 3px
}
.ant-card-body .table-operator{
margin-bottom: 18px;
}
.ant-layout-content{
margin:12px 16px 0 !important;
}
.ant-table-tbody .ant-table-row td{
padding-top:15px;
padding-bottom:15px;

View File

@ -0,0 +1,217 @@
<template>
<a-card :bordered="false">
<!-- -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :md="6" :sm="24">
<a-form-item label="订单号">
<a-input placeholder="请输入订单号" v-model="queryParam.orderCode"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-form-item label="订单类型">
<a-select placeholder="请输入订单类型" v-model="queryParam.ctype">
<a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
<span></span>
<a style="font-weight: 600">
{{ selectedRowKeys.length }}
</a>
<span></span>
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link"> <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a></a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<!-- table-end -->
<!-- -->
<jeecg-order-modal-for-j-editable-table ref="modalForm" @ok="modalFormOk"/>
</a-card>
</template>
<script>
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import JeecgOrderModalForJEditableTable from './modules/JeecgOrderModalForJEditableTable'
export default {
name: 'JeecgOrderMainListForJEditableTable',
mixins: [JeecgListMixin],
components: {
JeecgOrderModalForJEditableTable
},
data() {
return {
description: '',
// 请求参数
url: {
list: '/test/jeecgOrderMain/list',
delete: '/test/jeecgOrderMain/delete',
deleteBatch: '/test/jeecgOrderMain/deleteBatch'
},
// 表头
columns: [
{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: 'center',
customRender: function(t, r, index) {
return parseInt(index) + 1
}
},
{
title: '',
align: 'center',
dataIndex: 'orderCode'
},
{
title: '',
align: 'center',
dataIndex: 'ctype',
customRender: (text) => {
let re = ''
if (text === '1') {
re = ''
} else if (text === '2') {
re = ''
}
return re
}
},
{
title: '',
align: 'center',
dataIndex: 'orderDate'
},
{
title: '',
align: 'center',
dataIndex: 'orderMoney'
},
{
title: '',
align: 'center',
dataIndex: 'content'
},
{
title: '',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
]
}
},
methods: {
initDictConfig() {
}
}
}
</script>
<style scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
</style>

View File

@ -1,32 +1,38 @@
<template>
<a-card :bordered="false" :class="{'abcdefg':true}">
<div class="no-print" style="text-align: right">
<a-button v-print="'#acceptProof'" ghost type="primary"></a-button>
<a-button v-print="'#printContent'" ghost type="primary"></a-button>
</div>
<section ref="print" id="acceptProof" class="abcdefg">
<section ref="print" id="printContent" class="abcdefg">
<div style="text-align: center">
<p style="font-size: 24px;font-weight: 800"></p>
</div>
<!---->
<div class="sign" style="text-align: left">
<a-form-item label="打印员:" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback>
<a-input placeholder="请输入您的名字"/>
</a-form-item>
<a-form-item label="打印日期:" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback>
<a-date-picker></a-date-picker>
</a-form-item>
<a-form-item label="打印内容:" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback>
<a-textarea placeholder="请输入打印内容..."/>
</a-form-item>
<a-form-item label="打印目的:" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback>
<a-textarea placeholder="请输入打印目的..."/>
</a-form-item>
<a-form-item label="打印说明:" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback>
<a-textarea placeholder="请输入打印说明..."/>
</a-form-item>
<a-form-item label="打印图片:" :labelCol="labelCol" :wrapperCol="wrapperCol" hasFeedback>
<a-col :md="24" :sm="24">
<div class="sign" style="text-align: left;height: inherit">
<a-col :span="24">
<span>
:
</span>
<a-input style="width: 30%" v-model="printer"/>
<span style="margin-left: 12.5%">:</span>
<a-input style="width: 30%" v-model="printTime"/>
</a-col>
<a-col :span="24">
</a-col>
<a-col :span="24" style="margin-top: 20px">
<span>:</span>
<a-input style="width: 80%" v-model="printContent"/>
</a-col>
<a-col :span="24" style="margin-top: 20px">
<span>:</span>
<a-input style="width: 80%" v-model="printReason"/>
</a-col>
<a-col style="margin-top: 20px" :span="24">
<span>:</span>
<br/>
<a-upload
action="//jsonplaceholder.typicode.com/posts/"
action="/jsonplaceholder.typicode.com/posts/"
listType="picture-card"
:fileList="fileList"
@preview="handlePreview"
@ -39,8 +45,9 @@
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
<img alt="example" style="width: 100%" :src="previewImage" />
</a-modal>
</a-form-item>
</a-col>
</div>
</a-col>
</section>
</a-card>
<!--</page-layout>-->
@ -48,7 +55,6 @@
<script>
import ACol from "ant-design-vue/es/grid/Col";
import ARow from "ant-design-vue/es/grid/Row";
import {getAction} from '@/api/manage';
import ATextarea from 'ant-design-vue/es/input/TextArea'
export default {
@ -66,25 +72,9 @@
},
data(){
return {
columns: [
/* {
title: '',
dataIndex: 'fileCategoryName',
align:"center",
},
{
title: '',
dataIndex: 'fileNum',
align:"center",
},
{
title: '',
dataIndex: 'fileType',
align:"center",
},*/
columns: [{
}
],
dataSource:[],
applicantName:"",
labelCol: {
xs: { span: 24 },
sm: { span: 2 },
@ -93,15 +83,10 @@
xs: { span: 24 },
sm: { span: 8 },
},
beginYear:"",
beginMonth:"",
beginDay:"",
endYear:"",
endMonth:"",
endDay:"",
ipagination:{
hideOnSinglePage:false,
},
printer:'',
printTime:'2019-02-01 12:00:00',
printContent:',',
printReason:'',
previewVisible: false,
previewImage: '',
fileList: [{
@ -127,34 +112,7 @@
this.getDate();
},
methods: {
loadData(reBizCode){
// 获取材料文件
getAction(this.url.loadRegisterFiles,{reBizCode:reBizCode}).then((res)=>{
if(res.success){
console.log(res.result)
this.dataSource = res.result;
}
});
// 获取申请人信息
getAction(this.url.loadApplicant,{reBizCode:reBizCode}).then((res)=>{
if(res.success){
this.applicant = res.result;
var name ="";
for(var i=0;i<res.result.length;i++){
if(i==res.result.length-1){
name = name+res.result[i].name;
}else{
name = name+res.result[i].name+",";
}
}
if(name=="" || name==null ||name=="null"){
this.applicantName = "";
}else{
this.applicantName = name;
}
}
});
loadData(){
},
getDate(){

View File

@ -0,0 +1,43 @@
<template>
<div>
<a-input-search
v-model="this.selectedUserNames"
placeholder="请先选择用户"
disabled
@search="onSearch"
size="large">
<a-button slot="enterButton"></a-button>
</a-input-search>
<j-search-user-by-dep ref="JSearchUserByDep" @ok="modalFormOk"></j-search-user-by-dep>
</div>
</template>
<script>
import JSearchUserByDep from '@/components/jeecgbiz/JSearchUserByDep'
export default {
name: 'SearchUserByDepList',
components: {
JSearchUserByDep,
},
data() {
return {
selectedUserNames: '',
}
},
methods: {
onSearch() {
this.$refs.JSearchUserByDep.showModal();
this.selectedUserNames = '';
this.$refs.JSearchUserByDep.title = '';
},
modalFormOk(selectedValue) {
this.selectedUserNames = selectedValue;
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,135 @@
<template>
<a-card :bordered="false" style="height:100%">
<div class="table-page-search-wrapper">
<a-form layout="inline">
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="人员列表">
<a-select
mode="multiple"
placeholder="Please select"
:value=nameList
@change="handleChange"
>
</a-select>
</a-form-item>
</a-col>
<a-col :span="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="handleSelect" icon="search"></a-button>
<a-button type="primary" @click="selectReset" icon="reload" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-row>
<!-- -->
<a-row :gutter="24">
<a-col :span="12">
<a-form-item label="人员列表">
<a-input-search
v-model="this.selectedDepUsers"
placeholder="请先选择用户"
disabled
@search="onSearchDepUser"
size="large">
<a-button slot="enterButton"></a-button>
</a-input-search>
</a-form-item>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<select-multiple-user-modal ref="selectDemoModal" @selectFinished="selectOK"></select-multiple-user-modal>
<!-- -->
<search-user-by-dep-modal ref="SearchUserByDepModal" @ok="onSearchDepUserCallBack"></search-user-by-dep-modal>
</a-card>
</template>
<script>
import SelectMultipleUserModal from '@/components/jeecgbiz/SelectMultipleUserModal'
import SearchUserByDepModal from '@/components/jeecgbiz/SearchUserByDepModal'
export default {
name: "SelectDemo",
components: {
SelectMultipleUserModal,
SearchUserByDepModal
},
data() {
return {
selectList: [],
selectedDepUsers: ''
}
},
computed: {
nameList: function () {
var names = [];
for (var a = 0; a < this.selectList.length; a++) {
names.push(this.selectList[a].name);
}
return names;
}
},
methods: {
handleChange() {
},
selectOK: function (data) {
this.selectList = data;
},
handleSelect: function () {
this.$refs.selectDemoModal.add();
},
selectReset() {
this.selectList = [];
},
//通过组织机构筛选选择用户
onSearchDepUser() {
this.$refs.SearchUserByDepModal.showModal()
this.selectedDepUsers = ''
this.$refs.SearchUserByDepModal.selectedKeys = []
this.$refs.SearchUserByDepModal.title = ''
},
onSearchDepUserCallBack(selectedDepUsers) {
this.selectedDepUsers = selectedDepUsers
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
</style>

View File

@ -0,0 +1,270 @@
<template>
<a-card :bordered="false">
<!-- -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :md="6" :sm="24">
<a-form-item label="订单号">
<a-input placeholder="请输入订单号" v-model="queryParam.orderCode"></a-input>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<a-form-item label="订单类型">
<a-select placeholder="请输入订单类型" v-model="queryParam.ctype">
<a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="6" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search"></a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px"></a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected"></a>
</div>
<a-table
ref="table"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="false"
:expandedRowKeys= "expandedRowKeys"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange"
@expand="handleExpand"
>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical"/>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a></a>
</a-popconfirm>
</span>
<a-table
slot="expandedRowRender"
slot-scope="text"
:columns="innerColumns"
:dataSource="innerData"
size="middle"
bordered
rowKey="id"
:pagination="false"
:loading="loading"
>
</a-table>
</a-table>
</div>
<!-- table-end -->
<!-- -->
<jeecgOrderDMain-modal ref="modalForm" @ok="modalFormOk"></jeecgOrderDMain-modal>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
import JeecgOrderDMainModal from '@/views/jeecg/tablist/form/JeecgOrderDMainModal'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
export default {
name: "TableDemo",
mixins: [JeecgListMixin],
components: {
JeecgOrderDMainModal
},
data() {
return {
// 子表表头
innerColumns: [
{
title: '',
align: "center",
width: 100,
dataIndex: 'name',
key: 'name',
},
{
title: '',
align: "center",
dataIndex: 'sex',
customRender: function (text) {
if (text == 1) {
return "男";
} else if (text == 2) {
return "女";
} else {
return text;
}
}
},
{
title: '',
align: "center",
dataIndex: 'idcard',
},
{
title: '',
dataIndex: 'telphone',
align: "center",
},
],
innerData: [],
expandedRowKeys: [],
id: ' ',
description: 'Demo',
// 列表表头
columns: [{
title: '#',
dataIndex: '',
key: 'rowIndex',
width: 60,
align: "center",
customRender: function (t, r, index) {
return parseInt(index) + 1;
}
},
{
title: '',
align: "center",
dataIndex: 'orderCode'
},
{
title: '',
align: "center",
dataIndex: 'ctype',
customRender: (text) => {
let re = "";
if (text === '1') {
re = "国内订单";
} else if (text === '2') {
re = "国际订单";
}
return re;
}
},
{
title: '',
align: "center",
dataIndex: 'orderDate'
},
{
title: '',
align: "center",
dataIndex: 'orderMoney'
},
{
title: '',
align: "center",
dataIndex: 'content'
},
{
title: '',
dataIndex: 'action',
align: "center",
scopedSlots: {customRender: 'action'},
}],
// 分页参数
type: "radio",
url: {
list: "/test/order/orderList",
delete: "/test/order/delete",
deleteBatch: "/test/order/deleteBatch",
customerListByMainId: "/test/order/listOrderCustomerByMainId",
},
}
},
computed: {
currentId(){
return this.id;
}
},
methods: {
handleExpand(expanded, record){
this.expandedRowKeys=[];
this.innerData=[];
if(expanded===true){
this.loading = true;
this.expandedRowKeys.push(record.id);
getAction(this.url.customerListByMainId, {mainId: record.id}).then((res) => {
if (res.success) {
this.loading = false;
this.innerData = res.result;
}
});
}
},
}
}
</script>
<style scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-layout-content {
margin: 12px 16px 0 !important;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
</style>

View File

@ -1,49 +1,41 @@
<template>
<a-form @submit="handleSubmit" :form="form">
<a-form-item
label="Note"
:labelCol="{ span: 5 }"
:wrapperCol="{ span: 12 }"
>
<a-input
v-decorator="[
'note',
{rules: [{ required: true, message: 'Please input your note!' }]}
]"
/>
</a-form-item>
<a-form-item
label="Gender"
:labelCol="{ span: 5 }"
:wrapperCol="{ span: 12 }"
>
<a-select
v-decorator="[
'gender',
{rules: [{ required: true, message: 'Please select your gender!' }]}
]"
placeholder="Select a option and change input text above"
@change="this.handleSelectChange"
>
<a-select-option value="male">male</a-select-option>
<a-select-option value="female">female</a-select-option>
</a-select>
</a-form-item>
<a-form-item
:wrapperCol="{ span: 12, offset: 5 }">
<a-button type="primary" htmlType="submit">
Submit
</a-button>
</a-form-item>
</a-form>
<a-card :bordered="false">
<a-form @submit="handleSubmit" :form="form">
<a-col :md="24" :sm="24">
<a-form-item label="Note" :labelCol="{ span: 7 }" :wrapperCol="{ span: 15 }">
<a-input v-decorator="['note',{rules: [{ required: true, message: 'Please input your note!' }]}]"/>
</a-form-item>
</a-col>
<a-col :md="24" :sm="24">
<a-form-item label="Gender" :labelCol="{ span: 7 }" :wrapperCol="{ span: 15 }">
<a-select v-decorator="['gender',{rules: [{ required: true, message: 'Please select your gender!' }]}]" placeholder="Select a option and change input text above" @change="this.handleSelectChange">
<a-select-option value="male">male</a-select-option>
<a-select-option value="female">female</a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :md="24" :sm="24">
<a-form-item label="Gender" :labelCol="{ span: 7 }" :wrapperCol="{ span: 15 }">
<a-cascader :options="areaOptions" @change="onChange" :showSearch="{filter}" placeholder="Please select" />
</a-form-item>
</a-col>
<a-form-item :wrapperCol="{ span: 12, offset: 5 }">
<a-col :md="24" :sm="24">
<a-button type="primary" htmlType="submit">Submit</a-button>
</a-col>
</a-form-item>
</a-form>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
data () {
return {
formLayout: 'horizontal',
form: this.$form.createForm(this),
areaOptions:[]
}
},
methods: {
@ -61,6 +53,19 @@
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
})
},
onChange(value, selectedOptions) {
console.log(value, selectedOptions);
},
filter(inputValue, path) {
return (path.some(option => (option.label).toLowerCase().indexOf(inputValue.toLowerCase()) > -1));
},
},
created (){
getAction('/api/area').then((res) => {
console.log("------------")
console.log(res)
this.areaOptions = res;
})
}
}
</script>

View File

@ -1,12 +1,12 @@
<template>
<a-modal
:title="title"
:width="1000"
:width="1200"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<!-- -->
@ -35,7 +35,7 @@
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单日期">
<a-date-picker showTime format='YYYY-MM-DD HH:mm:ss' v-decorator="[ 'orderDate',{}]"/>
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" v-decorator="[ 'orderDate',{}]"/>
</a-form-item>
</a-col>
</a-row>
@ -237,9 +237,11 @@
let orderMainData = Object.assign(this.orderMainModel, values);
//时间格式化
orderMainData.orderDate = orderMainData.orderDate?orderMainData.orderDate.format('YYYY-MM-DD HH:mm:ss'):null;
let formData = {jeecgOrderMain:orderMainData,
jeecgOrderCustomerList:orderMainData.jeecgOrderCustomerList,
jeecgOrderTicketList:orderMainData.jeecgOrderTicketList}
let formData = {
...orderMainData,
jeecgOrderCustomerList: orderMainData.jeecgOrderCustomerList,
jeecgOrderTicketList: orderMainData.jeecgOrderTicketList
}
console.log(formData)
httpAction(httpurl,formData,method).then((res)=>{

View File

@ -0,0 +1,340 @@
<template>
<a-modal
:title="title"
:width="1200"
:visible="visible"
:maskClosable="false"
:confirmLoading="confirmLoading"
@ok="handleOk"
@cancel="handleCancel">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
<!-- -->
<a-row class="form-row" :gutter="0">
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单号">
<a-input
placeholder="请输入订单号"
v-decorator="['orderCode', {rules: [{ required: true, message: '请输入订单号!' }]}]"/>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单类型">
<a-select placeholder="请选择订单类型" v-decorator="['ctype',{}]">
<a-select-option value="1"></a-select-option>
<a-select-option value="2"></a-select-option>
</a-select>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单日期">
<a-date-picker showTime format="YYYY-MM-DD HH:mm:ss" style="width: 100%" v-decorator="[ 'orderDate',{}]"/>
</a-form-item>
</a-col>
</a-row>
<a-row class="form-row" :gutter="0">
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单金额">
<a-input-number placeholder="请输入订单金额" style="width: 100%" v-decorator="[ 'orderMoney', {}]"/>
</a-form-item>
</a-col>
<a-col :lg="8">
<a-form-item
:labelCol="labelCol"
:wrapperCol="wrapperCol"
label="订单备注">
<a-input placeholder="请输入订单备注" v-decorator="['content', {}]"/>
</a-form-item>
</a-col>
</a-row>
</a-form>
<!-- -->
<a-tabs v-model="activeKey" @change="handleChangeTabs">
<a-tab-pane tab="客户信息" key="1" :forceRender="true">
<j-editable-table
ref="editableTable1"
:loading="table1.loading"
:columns="table1.columns"
:dataSource="table1.dataSource"
:maxHeight="300"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"/>
</a-tab-pane>
<a-tab-pane tab="机票信息" key="2" :forceRender="true">
<j-editable-table
ref="editableTable2"
:loading="table2.loading"
:columns="table2.columns"
:dataSource="table2.dataSource"
:maxHeight="300"
:rowNumber="true"
:rowSelection="true"
:actionButton="true"/>
</a-tab-pane>
</a-tabs>
</a-spin>
</a-modal>
</template>
<script>
import JEditableTable from '@/components/jeecg/JEditableTable'
import { FormTypes, VALIDATE_NO_PASSED, getRefPromise, validateFormAndTables } from '@/utils/JEditableTableUtil'
import { httpAction, getAction } from '@/api/manage'
import JDate from '@/components/jeecg/JDate'
import pick from 'lodash.pick'
import moment from 'moment'
export default {
name: 'JeecgOrderModalForJEditableTable',
components: {
JDate, JEditableTable
},
data() {
return {
title: '',
visible: false,
form: this.$form.createForm(this),
confirmLoading: false,
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 6 }
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 24 - 6 }
},
activeKey: '1',
// 客户信息
table1: {
loading: false,
dataSource: [],
columns: [
{
title: '',
key: 'name',
width: '24%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [{ required: true, message: '${title}' }]
},
{
title: '',
key: 'sex',
width: '18%',
type: FormTypes.select,
options: [ // 下拉选项
{ title: '男', value: '1' },
{ title: '女', value: '2' }
],
defaultValue: '',
placeholder: '${title}'
},
{
title: '',
key: 'idcard',
width: '24%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [{
pattern: '^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|[xX])$',
message: '${title}'
}]
},
{
title: '',
key: 'telphone',
width: '24%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [{
pattern: '^1(3|4|5|7|8)\\d{9}$',
message: '${title}'
}]
}
]
},
// 机票信息
table2: {
loading: false,
dataSource: [],
columns: [
{
title: '',
key: 'ticketCode',
width: '40%',
type: FormTypes.input,
defaultValue: '',
placeholder: '${title}',
validateRules: [{ required: true, message: '${title}' }]
},
{
title: '',
key: 'tickectDate',
width: '30%',
type: FormTypes.date,
placeholder: '${title}',
defaultValue: ''
}
]
},
url: {
add: '/test/jeecgOrderMain/add',
edit: '/test/jeecgOrderMain/edit',
orderCustomerList: '/test/jeecgOrderMain/queryOrderCustomerListByMainId',
orderTicketList: '/test/jeecgOrderMain/queryOrderTicketListByMainId'
}
}
},
created() {
},
methods: {
// 获取所有的editableTable实例
getAllTable() {
return Promise.all([
getRefPromise(this, 'editableTable1'),
getRefPromise(this, 'editableTable2')
])
},
add() {
// 默认新增一条数据
this.getAllTable().then(editableTables => {
editableTables[0].add()
editableTables[1].add()
})
this.edit({})
},
edit(record) {
this.visible = true
this.activeKey = '1'
this.form.resetFields()
this.model = Object.assign({}, record)
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model, 'orderCode', 'ctype', 'orderMoney', 'content'))
//时间格式化
this.form.setFieldsValue({ orderDate: this.model.orderDate ? moment(this.model.orderDate) : null })
})
// 加载子表数据
if (this.model.id) {
let params = { id: this.model.id }
this.requestTableData(this.url.orderCustomerList, params, this.table1)
this.requestTableData(this.url.orderTicketList, params, this.table2)
}
},
close() {
this.visible = false
this.getAllTable().then(editableTables => {
editableTables[0].initialize()
editableTables[1].initialize()
})
this.$emit('close')
},
/** 查询某个tab的数据 */
requestTableData(url, params, tab) {
tab.loading = true
getAction(url, params).then(res => {
tab.dataSource = res.result || []
}).finally(() => {
tab.loading = false
})
},
handleOk() {
this.validateFields()
},
handleCancel() {
this.close()
},
/** ATab 选项卡切换事件 */
handleChangeTabs(key) {
getRefPromise(this, `editableTable${key}`).then(editableTable => {
editableTable.resetScrollTop()
})
},
/** 触发表单验证 */
validateFields() {
this.getAllTable().then(tables => {
/** 一次性验证主表和所有的次表 */
return validateFormAndTables(this.form, tables)
}).then(allValues => {
let formData = this.classifyIntoFormData(allValues)
// 发起请求
return this.requestAddOrEdit(formData)
}).catch(e => {
if (e.error === VALIDATE_NO_PASSED) {
// 如果有未通过表单验证的子表就自动跳转到它所在的tab
this.activeKey = e.index == null ? this.activeKey : (e.index + 1).toString()
} else {
console.error(e)
}
})
},
/** 整理成formData */
classifyIntoFormData(allValues) {
let orderMain = Object.assign(this.model, allValues.formValue)
//时间格式化
orderMain.orderDate = orderMain.orderDate ? orderMain.orderDate.format('YYYY-MM-DD HH:mm:ss') : null
return {
...orderMain, // 展开
jeecgOrderCustomerList: allValues.tablesValue[0].values,
jeecgOrderTicketList: allValues.tablesValue[1].values
}
},
/** 发起新增或修改的请求 */
requestAddOrEdit(formData) {
let url = this.url.add, method = 'post'
if (this.model.id) {
url = this.url.edit
method = 'put'
}
this.confirmLoading = true
httpAction(url, formData, method).then((res) => {
if (res.success) {
this.$message.success(res.message)
this.$emit('ok')
this.close()
} else {
this.$message.warning(res.message)
}
}).finally(() => {
this.confirmLoading = false
})
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,698 @@
<template>
<div class="page-header-index-wide">
<a-row :gutter="24">
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="受理量" :total="cardCount.sll | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area :dataSource="chartData.sll" />
</div>
<template slot="footer"><span>{{ todaySll }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="办结量" :total="cardCount.bjl | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area :dataSource="chartData.bjl"/>
</div>
<template slot="footer"><span>{{ todayBjl }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="用户受理量" :total="cardCount.isll | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar :dataSource="chartData.isll"/>
</div>
<template slot="footer"><span>{{ todayISll }}</span></template>
</chart-card>
</a-col>
<a-col :sm="24" :md="12" :xl="6" :style="{ marginBottom: '24px' }">
<chart-card :loading="loading" title="用户办结量" :total="cardCount.ibjl | NumberFormat">
<a-tooltip title="指标说明" slot="action">
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-bar :dataSource="chartData.ibjl"/>
</div>
<template slot="footer"><span>{{ todayIBjl }}</span></template>
</chart-card>
</a-col>
</a-row>
<a-card :loading="loading" :bordered="false" :body-style="{padding: '0'}">
<div class="salesCard">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrapper" slot="tabBarExtraContent">
<div class="extra-item">
<a></a>
<a></a>
<a></a>
<a></a>
</div>
<a-range-picker :style="{width: '256px'}" />
</div>
<a-tab-pane loading="true" tab="受理监管" key="1">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar title="受理量统计" />
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="12" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="交互监管" key="2">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<bar-multid :dataSource="jhjgData" :fields="jhjgFields" title="平台与部门交互量统计"></bar-multid>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="12" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="效率监管" key="3">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<line-chart-multid :dataSource="xljgData" :fields="xljgFields" title="平台与部门交互效率统计"></line-chart-multid>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="12" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
<a-tab-pane tab="存储监管" key="4">
<a-row>
<a-col :xl="16" :lg="12" :md="12" :sm="24" :xs="24">
<a-row>
<template v-if="diskInfo && diskInfo.length>0">
<a-col :span="12" v-for="(item,index) in diskInfo" :key=" 'diskInfo'+index ">
<dash-chart-demo :title="item.name" :dataSource="item.restPPT"></dash-chart-demo>
</a-col>
</template>
</a-row>
</a-col>
<a-col :xl="8" :lg="12" :md="12" :sm="24" :xs="24">
<a-card title="快速开始 / 便捷导航" style="margin-bottom: 24px" :bordered="false" :body-style="{padding: 0}">
<div class="item-group">
<a-row>
<a-col :class="'more-btn'" :span="10" v-for="(item,index) in registerTypeList" :key=" 'registerType'+index ">
<a-button @click="goPage(index)" style="margin-bottom:10px" size="small" type="primary" ghost>{{ item.text }}</a-button>
</a-col>
</a-row>
</div>
</a-card>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
</div>
</a-card>
<a-row :gutter="12">
<a-card :loading="loading" :class="{ 'anty-list-cust':true }" :bordered="false" :style="{ marginTop: '24px' }">
<a-tabs default-active-key="1" size="large" :tab-bar-style="{marginBottom: '24px', paddingLeft: '16px'}">
<div class="extra-wrapper" slot="tabBarExtraContent">
<a-radio-group defaultValue="1">
<a-radio-button value="1"></a-radio-button>
<a-radio-button value="2"></a-radio-button>
</a-radio-group>
</div>
<a-tab-pane loading="true" tab="业务流程限时监管" key="1">
<a-table :dataSource="dataSource1" size="default" rowKey="id" :columns="columns" :pagination="ipagination">
<template slot="flowRate" slot-scope="text, record, index">
<a-progress :percent="getFlowRateNumber(record.flowRate)" style="width:80px" />
</template>
</a-table>
</a-tab-pane>
<a-tab-pane loading="true" tab="业务节点限时监管" key="2">
<a-table :dataSource="dataSource2" size="default" rowKey="id" :columns="columns2" :pagination="ipagination">
<template slot="flowRate" slot-scope="text, record, index">
<span style="color: red;">{{ record.flowRate }}</span>
</template>
</a-table>
</a-tab-pane>
</a-tabs>
</a-card>
</a-row>
</div>
</template>
<script>
import ChartCard from '@/components/ChartCard'
import ACol from "ant-design-vue/es/grid/Col"
import ATooltip from "ant-design-vue/es/tooltip/Tooltip"
import MiniArea from '@/components/chart/MiniArea'
import MiniBar from '@/components/chart/MiniBar'
import LineChartMultid from '@/components/chart/LineChartMultid'
import AreaChartTy from '@/components/chart/AreaChartTy'
import DashChartDemo from '@/components/chart/DashChartDemo'
import BarMultid from '@/components/chart/BarMultid'
import MiniProgress from '@/components/chart/MiniProgress'
import RankList from '@/components/chart/RankList'
import Bar from '@/components/chart/Bar'
import Trend from '@/components/Trend'
import { getAction } from '@/api/manage'
import { filterObj } from '@/utils/util'
import moment from 'dayjs'
const rankList = []
for (let i = 0; i < 7; i++) {
rankList.push({
name: ' ' + (i+1) + ' ',
total: 1234.56 - i * 100
})
}
const dataCol1 = [{
title: '',
align:"center",
dataIndex: 'reBizCode'
},{
title: '',
align:"center",
dataIndex: 'droitType'
},{
title: '',
align:"center",
dataIndex: 'registeType'
},{
title: '',
align:"center",
dataIndex: 'beLocated'
},{
title: '',
align:"center",
dataIndex: 'qlr'
},{
title: '',
align:"center",
dataIndex: 'ywr'
},{
title: '',
align:"center",
dataIndex: 'acceptBy'
},{
title: '',
align:"center",
dataIndex: 'acceptDate'
},{
title: '',
align:"center",
dataIndex: 'curNode'
},{
title: '',
align:"center",
dataIndex: 'flowRate',
scopedSlots: { customRender: 'flowRate' }
}];
const dataCol2 = [{
title: '',
align:"center",
dataIndex: 'reBizCode'
},{
title: '',
align:"center",
dataIndex: 'droitType'
},{
title: '',
align:"center",
dataIndex: 'registeType'
},{
title: '',
align:"center",
dataIndex: 'beLocated'
},{
title: '',
align:"center",
dataIndex: 'qlr'
},{
title: '',
align:"center",
dataIndex: 'ywr'
},{
title: '',
align:"center",
dataIndex: 'acceptBy'
},{
title: '',
align:"center",
dataIndex: 'acceptDate'
},{
title: '',
align:"center",
dataIndex: 'curNode'
},{
title: '',
align:"center",
dataIndex: 'flowRate',
scopedSlots: { customRender: 'flowRate' }
}];
const jhjgData = [
{ type: '', '': 900, '': 1120, '': 1380, '': 1480, '': 1450, '': 1100, '':1300, '':900,'':1000 ,'':1200 ,'':600 ,'':900 },
{ type: '', '':1200, '': 1500, '': 1980, '': 2000, '': 1000, '': 600, '':900, '':1100,'':1300 ,'':2000 ,'':900 ,'':1100 },
{ type: '', '':2000, '': 1430, '': 1300, '': 1400, '': 900, '': 500, '':600, '':1000,'':600 ,'':1000 ,'':1500 ,'':1200 }
]
const jhjgFields=[
'','','','','','',
'','','','','',''
]
const xljgData = [
{type:'',"房管":1.12,"税务":1.55,"不动产":1.2},
{type:'',"房管":1.65,"税务":1.32,"不动产":1.42},
{type:'',"房管":1.85,"税务":1.1,"不动产":1.5},
{type:'',"房管":1.33,"税务":1.63,"不动产":1.4},
{type:'',"房管":1.63,"税务":1.8,"不动产":1.7},
{type:'',"房管":1.85,"税务":1.98,"不动产":1.8},
{type:'',"房管":1.98,"税务":1.5,"不动产":1.76},
{type:'',"房管":1.48,"税务":1.2,"不动产":1.3},
{type:'',"房管":1.41,"税务":1.9,"不动产":1.6},
{type:'',"房管":1.1,"税务":1.1,"不动产":1.4},
{type:'',"房管":1.85,"税务":1.6,"不动产":1.5},
{type:'',"房管":1.5,"税务":1.4,"不动产":1.3}
]
const xljgFields=["房管","税务","不动产"]
export default {
name: "Analysis",
components: {
ATooltip,
ACol,
ChartCard,
MiniArea,
MiniBar,
MiniProgress,
RankList,
Bar,
Trend,
LineChartMultid,
AreaChartTy,
DashChartDemo,
BarMultid
},
data() {
return {
xljgData,
xljgFields,
jhjgData,
jhjgFields,
loading: true,
rankList,
zsll:0,
zbjl:0,
todaySll:0,
todayBjl:0,
todayISll:0,
todayIBjl:0,
registerTypeList:[{
text:"业务受理"
},{
text:"业务管理"
},{
text:"文件管理"
},{
text:"信息查询"
}],
// 分页参数
ipagination:{
current: 1,
pageSize: 5,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
//数据集
dataSource:[],
dataSource1:[],
dataSource2:[],
url:{
analysis:"/sps/register/analysis",
list:"sps/register/virtualList",
countSll:"sps/register/sllTenDaysCount",
countBjl:"sps/register/bjlTenDaysCount",
countISll:'sps/register/ISllTenDaysCount',
countIBjl:'sps/register/IBjlTenDaysCount',
queryDiskInfo:'api/queryDiskInfo'
},
chartData:{
sll:[],
bjl:[],
isll:[],
ibjl:[]
},
cardCount:{
sll:0,
bjl:0,
isll:0,
ibjl:0
},
columns:dataCol1,
columns2:dataCol2,
diskInfo:[]
}
},
methods:{
goPage(index){
if(index==0){
this.$router.push({
path: '/isps/registerStepForm',
name: 'isps-registerStepForm',
});
}else if(index==1){
this.$router.push({
path: '/isps/registerList',
name: 'isps-registerList',
});
}else if(index==2){
this.$router.push({
path: '/isps/fileManage',
name: 'isps-fileManage',
});
}else if(index==3){
this.$router.push({
path: '/isps/infoSearch',
name: 'isps-infoSearch',
});
}
},
loadList (arg){
if(arg===1){
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list,params).then((res)=>{
console.log("dsdsd",res.result)
this.dataSource1 = res.result.data1;
this.dataSource2 = res.result.data2;
this.ipagination.total = 5;
});
},
getQueryParams(){
var param = {flowStatus:"-3"};
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
formatRespectiveHoldCert(value){
return (value=="1"||eval(value))?"是":"否"
},
formatCertFormat(value){
if(value=="1"){
return "单一版"
}else if(value=="2"){
return "集成版"
}else{
return value;
}
},
getFlowRateNumber(value){
return Number(value)
},
getFlowPercent(record){
if(record.flowStatus=="3"){
return 100
}else if(record.flowStatus=="0"){
return 0
}else{
return record.flowRate
}
},
getFlowStatus(status){
if(status=="4"){
return "exception";
}else if(status=="0"){
return "normal";
}else if(status=="3"){
return "success";
}else{
return "active";
}
},
queryCount(){
getAction(this.url.analysis).then((res)=>{
if(res.success){
this.cardCount = res.result
}
console.log(res);
});
},
loadDiskInfo(){
getAction(this.url.queryDiskInfo).then((res)=>{
if(res.success){
console.log(res.result)
let one=0,two="";
for(let a in res.result){
let tempNum = Number(res.result[a].max)
if(tempNum>one){
one = tempNum
two = res.result[a].name
}
}
let ontItem = res.result.filter((item)=>{return item.name == two})[0]
ontItem.restPPT = ontItem.restPPT/10
this.diskInfo.push(ontItem);
if(res.result.length>1){
let one2=0,two2="";
for(let a in res.result){
if(res.result[a].name == two){
continue;
}
let tempNum = Number(res.result[a].max)
if(tempNum>one2){
one2 = tempNum
two2 = res.result[a].name
}
}
let one2Item = res.result.filter((item)=>{return item.name == two2})[0]
one2Item.restPPT = one2Item.restPPT/10
this.diskInfo.push(one2Item);
}
}else{
console.log(res.message)
}
})
},
loadChartData(){
getAction(this.url.countSll).then((res)=>{
if(res.success){
let map = res.result;
for(var key in map){
let dataStr = key;
let value = map[key];
let today = moment(new Date()).format('YYYY-MM-DD');
if(dataStr == today){
this.todaySll = map[today];
}
this.chartData.sll.push({
x: dataStr,
y: value
});
}
}
}),
getAction(this.url.countBjl).then((res)=>{
if(res.success){
let map = res.result;
for(var key in map){
let dataStr = key;
let value = map[key];
let today = moment(new Date()).format('YYYY-MM-DD');
if(dataStr == today){
this.todayBjl = map[today];
}
this.chartData.bjl.push({
x: dataStr,
y: value
});
}
}
}),
getAction(this.url.countISll).then((res)=>{
if(res.success){
let map = res.result;
for(var key in map){
let dataStr = key;
let value = map[key];
let today = moment(new Date()).format('YYYY-MM-DD');
if(dataStr == today){
this.todayISll = map[today];
}
this.chartData.isll.push({
x: key,
y: value
});
}
}
}),
getAction(this.url.countIBjl).then((res)=>{
if(res.success){
let map = res.result;
for(var key in map){
let dataStr = key;
let value = map[key];
let today = moment(new Date()).format('YYYY-MM-DD');
if(dataStr == today){
this.todayIBjl = map[today];
}
this.chartData.ibjl.push({
x: key,
y: value
});
}
}
})
}
},
created() {
this.loadDiskInfo()
this.queryCount();
this.loadChartData();
this.loadList(1);
setTimeout(() => {
this.loading = !this.loading
}, 1000)
}
}
</script>
<style lang="scss" scoped>
.extra-wrapper {
line-height: 55px;
padding-right: 24px;
.extra-item {
display: inline-block;
margin-right: 24px;
a {
margin-left: 24px;
}
}
}
.item-group {
padding: 20px 0 8px 24px;
font-size: 0;
a {
color: rgba(0, 0, 0, 0.65);
display: inline-block;
font-size: 14px;
margin-bottom: 13px;
width: 25%;
}
}
.item-group {
.more-btn {
margin-bottom: 13px;
text-align: center;
}
}
.list-content-item {
color: rgba(0, 0, 0, .45);
display: inline-block;
vertical-align: middle;
font-size: 14px;
margin-left: 40px;
}
@media only screen and (min-width: 1600px) {
.list-content-item{
margin-left:60px;
}
}
@media only screen and (max-width: 1300px) {
.list-content-item{
margin-left:20px;
}
.width-hidden4{
display:none
}
}
.list-content-item{
span{line-height: 20px;}
}
.list-content-item{
p{margin-top: 4px;margin-bottom:0;line-height:22px;}
}
.anty-list-cust {
.ant-list-item-meta{flex: 0.3 !important;}
}
.anty-list-cust {
.ant-list-item-content{flex:1 !important; justify-content:flex-start !important;margin-left: 20px;}
}
</style>

View File

@ -0,0 +1,315 @@
<template>
<a-card :bordered="false">
<a-tabs defaultActiveKey="1" @change="callback">
<a-tab-pane tab="柱状图" key="1">
<a-row :gutter="24">
<a-col :span="10">
<a-radio-group :value="barType" @change="statisticst">
<a-radio-button value="year"></a-radio-button>
<a-radio-button value="month"></a-radio-button>
<a-radio-button value="category"></a-radio-button>
<a-radio-button value="cabinet"></a-radio-button>
</a-radio-group>
</a-col>
<a-col :span="14">
<a-form v-if="barType === 'month'" layout="inline" style="margin-top: -4px">
<a-form-item label="月份区间">
<a-range-picker
:placeholder="['开始月份', '结束月份']"
format="YYYY-MM"
:value="barValue"
:mode="barDate"
@panelChange="handleBarDate"/>
</a-form-item>
<a-button style="margin-top: 2px" type="primary" icon="search" @click="queryDatebar"></a-button>
<a-button style="margin-top: 2px;margin-left: 8px" type="primary" icon="reload" @click="searchReset"></a-button>
</a-form>
</a-col>
<bar class="statistic" title="档案统计" :dataSource="countSource"/>
</a-row>
</a-tab-pane>
<a-tab-pane tab="饼状图" key="2">
<a-row :gutter="24">
<a-col :span="10">
<a-radio-group :value="pieType" @change="statisticst">
<a-radio-button value="year"></a-radio-button>
<a-radio-button value="month"></a-radio-button>
<a-radio-button value="category"></a-radio-button>
<a-radio-button value="cabinet"></a-radio-button>
</a-radio-group>
</a-col>
<a-col :span="14">
<a-form v-if="pieType === 'month'" layout="inline" style="margin-top: -4px">
<a-row :gutter="24">
<a-form-item label="月份区间">
<a-range-picker
:placeholder="['开始月份', '结束月份']"
format="YYYY-MM"
:value="pieValue"
:mode="pieDate"
@panelChange="handlePieDate"/>
</a-form-item>
<a-button style="margin-top: 2px" type="primary" icon="search" @click="queryDatepie"></a-button>
<a-button style="margin-top: 2px;margin-left: 8px" type="primary" icon="reload" @click="searchReset"></a-button>
</a-row>
</a-form>
</a-col>
<pie class="statistic" title="档案统计" :dataSource="countSource"/>
</a-row>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script>
import Bar from '@/components/chart/Bar'
import Pie from '@/components/chart/Pie'
import ACol from 'ant-design-vue/es/grid/Col'
import { getAction } from '@/api/manage'
export default {
name: 'ArchivesStatisticst',
components: {
ACol,
Bar,
Pie
},
data() {
return {
description: '',
// 查询条件
queryParam: {},
// 数据集
countSource: [],
// 柱状图
barType: 'year',
barDate: ['month', 'month'],
barValue: [],
// 饼状图
pieType: 'year',
pieDate: ['month', 'month'],
pieValue: [],
// 统计图类型
tabStatus:"bar",
url: {
getYearCountInfo: "/api/report/getYearCountInfo",
getMonthCountInfo:"/api/report/getMonthCountInfo",
getCntrNoCountInfo:"/api/report/getCntrNoCountInfo",
getCabinetCountInfo:"/api/report/getCabinetCountInfo",
},
}
},
created() {
let url = this.url.getYearCountInfo;
this.loadDate(url,'year',{});
},
methods: {
loadDate(url,type,param) {
getAction(url,param,'get').then((res) => {
if (res.success) {
this.countSource = [];
if(type === 'year'){
this.getYearCountSource(res.result);
}
if(type === 'month'){
this.getMonthCountSource(res.result);
}
if(type === 'category'){
this.getCategoryCountSource(res.result);
}
if(type === 'cabinet'){
this.getCabinetCountSource(res.result);
}
}else{
var that=this;
that.$message.warning(res.message);
}
})
},
getYearCountSource(data){
for (let i = 0; i < data.length; i++) {
if(this.tabStatus === "bar"){
this.countSource.push({
x: `${data[i].year}`,
y: data[i].yearcount
})
}else{
this.countSource.push({
item: `${data[i].year}`,
count:data[i].yearcount
})
}
}
},
getMonthCountSource(data){
for (let i = 0; i < data.length; i++) {
if(this.tabStatus === "bar"){
this.countSource.push({
x: data[i].month,
y: data[i].monthcount
})
}else{
this.countSource.push({
item: data[i].month,
count:data[i].monthcount
})
}
}
},
getCategoryCountSource(data){
for (let i = 0; i < data.length; i++) {
if(this.tabStatus ==="bar"){
this.countSource.push({
x: data[i].classifyname,
y: data[i].cntrnocount
})
}else{
this.countSource.push({
item: data[i].classifyname,
count:data[i].cntrnocount
})
}
}
},
getCabinetCountSource(data){
for (let i = 0; i < data.length; i++) {
if(this.tabStatus === "bar"){
this.countSource.push({
x: data[i].cabinetname,
y: data[i].cabinetcocunt
})
}else{
this.countSource.push({
item: data[i].cabinetname,
count:data[i].cabinetcocunt
})
}
}
},
// 选择统计图类别
callback(key) {
if(key === "1"){
this.tabStatus = "bar";
this.queryDatebar();
}else{
this.tabStatus = "pie";
this.queryDatepie();
}
},
// 选择统计类别
statisticst(e) {
if(this.tabStatus === "pie"){
this.pieType = e.target.value;
this.queryDatepie();
}else{
this.barType = e.target.value;
this.queryDatebar();
}
},
// 按月份查询
queryDatebar(){
if(this.barValue.length>0){
this.getUrl(this.barType,{startTime:this.barValue[0]._d,endTime:this.barValue[1]._d});
}else{
this.getUrl(this.barType,{});
}
},
queryDatepie(){
if(this.pieValue.length>0){
this.getUrl(this.pieType,{startTime:this.pieValue[0]._d,endTime:this.pieValue[1]._d});
}else{
this.getUrl(this.pieType,{});
}
},
searchReset(){
console.log(this.tabStatus);
if(this.tabStatus === "pie"){
this.pieValue = [];
}else{
this.barValue = [];
}
this.getUrl(this.barType,{});
},
// 选择请求url
getUrl(type,param){
let url = "";
if(type === 'year'){
url = this.url.getYearCountInfo;
}
if(type === 'month'){
url = this.url.getMonthCountInfo;
}
if(type === 'category'){
url = this.url.getCntrNoCountInfo;
}
if(type === 'cabinet'){
url = this.url.getCabinetCountInfo;
}
this.loadDate(url,type,param);
},
// 选择月份日期
handleBarDate(value, mode) {
this.barValue = value
this.barDate = [
mode[0] === 'date' ? 'month' : mode[0],
mode[1] === 'date' ? 'month' : mode[1]
]
},
handlePieDate(value, mode) {
this.pieValue = value
this.pieDate = [
mode[0] === 'date' ? 'month' : mode[0],
mode[1] === 'date' ? 'month' : mode[1]
]
},
}
}
</script>
<style scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
.statistic {
padding: 0px !important;
margin-top: 50px;
}
.statistic h4 {
margin-bottom: 20px;
text-align: center !important;
font-size: 24px !important;;
}
.statistic #canvas_1 {
width: 100% !important;
}
</style>

View File

@ -0,0 +1,136 @@
<template>
<a-card :bordered="false">
<a-tabs defaultActiveKey="1">
<!-- -->
<a-tab-pane tab="柱状图" key="1">
<bar title="销售额排行" :dataSource="barData" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="多列柱状图" key="2">
<bar-multid title="多列柱状图" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="迷你柱状图" key="3">
<mini-bar :dataSource="barData" :width="400" :height="200"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="面积图" key="4">
<area-chart-ty title="销售额排行" :dataSource="areaData" x="月份" y="销售额" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="迷你面积图" key="5">
<div style="padding-top: 100px;width:600px;height:200px">
<mini-area :dataSource="areaData" x="月份" y="销售额" :height="height"/>
</div>
</a-tab-pane>
<!-- 线 -->
<a-tab-pane tab="多行折线图" key="6">
<line-chart-multid title="多行折线图" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="饼图" key="7">
<pie title="饼图" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="雷达图" key="8">
<radar title="雷达图" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="仪表盘" key="9">
<dash-chart-demo title="仪表盘" :value="9" :height="height"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="进度条" key="10">
<mini-progress :percentage="30" :target="40" :height="30"/>
<mini-progress :percentage="51" :target="60" :height="30" color="#FFA500"/>
<mini-progress :percentage="66" :target="80" :height="30" color="#1E90FF"/>
<mini-progress :percentage="74" :target="70" :height="30" color="#FF4500"/>
<mini-progress :percentage="92" :target="100" :height="30" color="#49CC49"/>
</a-tab-pane>
<!-- -->
<a-tab-pane tab="排名列表" key="11">
<rank-list title="门店销售排行榜" :list="rankList" style="width: 600px;margin: 0 auto;"/>
</a-tab-pane>
<!-- TransferBar -->
<a-tab-pane tab="TransferBar" key="12">
<transfer-bar title="年度消耗流量一览表" :data="barData" x="月份" y="流量(Mb)" :height="height"/>
</a-tab-pane>
<!-- Trend -->
<a-tab-pane tab="Trend" key="13">
<trend title="Trend" term="Trend" :percentage="30"/>
</a-tab-pane>
<!-- Liquid -->
<a-tab-pane tab="Liquid" key="14">
<liquid :height="height"/>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script>
import AreaChartTy from '@/components/chart/AreaChartTy'
import Bar from '@/components/chart/Bar'
import BarMultid from '@/components/chart/BarMultid'
import DashChartDemo from '@/components/chart/DashChartDemo'
import LineChartMultid from '@/components/chart/LineChartMultid'
import Liquid from '@/components/chart/Liquid'
import MiniBar from '@/components/chart/MiniBar'
import MiniArea from '@/components/chart/MiniArea'
import MiniProgress from '@/components/chart/MiniProgress'
import Pie from '@/components/chart/Pie'
import Radar from '@/components/chart/Radar'
import RankList from '@/components/chart/RankList'
import TransferBar from '@/components/chart/TransferBar'
import Trend from '@/components/chart/Trend'
export default {
name: 'ViserChartDemo',
components: {
Bar, MiniBar, BarMultid, AreaChartTy, LineChartMultid,
Pie, Radar, DashChartDemo, MiniProgress, RankList,
TransferBar, Trend, Liquid, MiniArea
},
data() {
return {
height: 420,
rankList: [],
barData: [],
areaData: []
}
},
created() {
setTimeout(() => {
this.loadBarData()
this.loadAreaData()
this.loadRankListData()
}, 100)
},
methods: {
loadData(x, y, max, min, before = '', after = '月') {
let data = []
for (let i = 0; i < 12; i += 1) {
data.push({
[x]: `${before}${i + 1}${after}`,
[y]: Math.floor(Math.random() * max) + min
})
}
return data
},
// 加载柱状图数据
loadBarData() {
this.barData = this.loadData('x', 'y', 1000, 200)
},
// 加载AreaChartTy的数据
loadAreaData() {
this.areaData = this.loadData('x', 'y', 500, 100)
},
loadRankListData() {
this.rankList = this.loadData('name', 'total', 2000, 100, ' ', ' ')
}
}
}
</script>
<style scoped>
</style>

View File

@ -2,14 +2,19 @@
<a-card :bordered="false">
<!-- -->
<div class="table-operator">
<div class="table-operator" :md="24" :sm="24" style="margin: -25px 0px 10px 0px">
<a-button @click="handleAdd" type="primary" icon="plus"></a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/></a-menu-item>
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> <a-icon type="down" /></a-button>
<a-button style="margin-left: 8px">
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
@ -22,7 +27,7 @@
<a-table
ref="table"
size="default"
size="middle"
bordered
rowKey="id"
:columns="columns"
@ -34,13 +39,13 @@
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)"></a>
<a-divider type="vertical" />
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
<a-icon type="down" />
<a-icon type="down"/>
</a>
<a-menu slot="overlay">
<a-menu-item >
<a-menu-item>
<a href="javascript:;" @click="handleDetail(record)"></a>
</a-menu-item>
<a-menu-item>
@ -55,238 +60,101 @@
</div>
<!-- table-end -->
<!-- -->
<jeecgOrderCustomer-modal ref="JeecgOrderCustomerModal" @ok="modalFormOk"></jeecgOrderCustomer-modal>
<jeecgOrderCustomer-modal ref="modalForm" @ok="modalFormOk"></jeecgOrderCustomer-modal>
</a-card>
</template>
<script>
import JeecgOrderCustomerModal from './form/JeecgOrderCustomerModal'
import { filterObj } from '@/utils/util'
import { deleteAction,getAction } from '@/api/manage'
import JeecgOrderDMainList from './JeecgOrderDMainList'
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import {getAction} from '@/api/manage'
export default {
name: "JeecgOrderCustomerList",
mixins: [JeecgListMixin],
components: {
JeecgOrderDMainList,
JeecgOrderCustomerModal
},
data () {
data() {
return {
description: '',
// 查询条件
queryParam: {
orderId:null,
},
// 表头
columns: [
{
title: '',
align:"center",
align: "center",
width: 100,
dataIndex: 'name',
key: 'name',
fixed: 'left'
},
{
title: '',
align:"center",
align: "center",
dataIndex: 'sex',
customRender:function (text) {
if(text==1){
customRender: function (text) {
if (text == 1) {
return "男";
}else if(text==2){
} else if (text == 2) {
return "女";
}else{
} else {
return text;
}
}
},
{
title: '',
align:"center",
align: "center",
dataIndex: 'idcard',
},
{
title: '',
dataIndex: 'telphone',
align:"center",
align: "center",
},
{
title: '',
key: 'operation',
align: 'center',
fixed: 'right',
width: 130,
scopedSlots: { customRender: 'action' },
scopedSlots: {customRender: 'action'},
},
],
//数据集
dataSource:[],
// 分页参数
ipagination:{
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
},
isorter:{
column: 'createTime',
order: 'desc',
},
loading:false,
selectedRowKeys: [],
selectedRows: [],
url: {
list: "/test/order/queryOrderCustomerListByMainId",
list: "/test/order/listOrderCustomerByMainId",
delete: "/test/order/deleteCustomer",
deleteBatch: "/test/order/deleteBatchCustomer",
},
}
}
},
created() {
this.loadData();
},
methods: {
loadData (arg){
//加载数据 若传入参数1则加载第一页的内容
if(arg===1){
loadData(arg) {
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url.list,{id:params.orderId}).then((res)=>{
if(res.success){
var params = this.getQueryParams();
getAction(this.url.list, {mainId: params.mainId}).then((res) => {
if (res.success) {
this.dataSource = res.result;
/*
this.ipagination.total = res.result.total;
*/
}else{
} else {
this.dataSource = null;
/* this.ipagination.total = 0;*/
}
})
},
getQueryParams(){
var param = Object.assign({}, this.queryParam,this.isorter);
param.orderId = this.queryParam.orderId;
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField(){
//TODO 字段权限控制
var str = "id,";
for(var a = 0;a<this.columns.length;a++){
str+=","+this.columns[a].dataIndex;
}
return str;
},
onSelectChange (selectedRowKeys,selectionRows) {
this.selectedRowKeys = selectedRowKeys;
this.selectionRows = selectionRows;
},
onClearSelected(){
this.selectedRowKeys = [];
this.selectionRows = [];
},
searchQuery(){
getOrderMain(orderId) {
this.queryParam.mainId = orderId;
this.loadData(1);
},
searchReset(){
var that = this;
for(var a in that.queryParam){
that.queryParam[a] = '';
}
that.loadData(1);
handleAdd: function () {
this.$refs.modalForm.add(this.queryParam.mainId);
this.$refs.modalForm.title = "添加客户信息";
},
batchDel: function(){
if(this.selectedRowKeys.length<=0){
this.$message.warning('');
return ;
}else{
var ids = "";
for(var a =0;a<this.selectedRowKeys.length;a++){
ids+=this.selectedRowKeys[a]+",";
}
var that = this;
this.$confirm({
title:"确认删除",
content:"是否删除选中数据?",
onOk: function(){
deleteAction(that.url.deleteBatch,{ids: ids}).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
}
},
handleDelete: function(id){
var that = this;
this.$confirm({
title:"确认删除",
content:"是否删除选中数据?",
onOk: function(){
deleteAction(that.url.delete,{id: id}).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
}else{
that.$message.warning(res.message);
}
});
}
});
},
handleEdit: function(record){
this.$refs.JeecgOrderCustomerModal.edit(record,'e');
this.$refs.JeecgOrderCustomerModal.title="编辑";
},
handleAdd: function(){
this.$refs.JeecgOrderCustomerModal.add(this.queryParam.orderId);
this.$refs.JeecgOrderCustomerModal.title="添加客户信息";
},
handleDetail: function(record){
this.$refs.JeecgOrderCustomerModal.detail(record);
this.$refs.JeecgOrderCustomerModal.title="添加客户信息";
},
handleTableChange(pagination, filters, sorter){
//分页、排序、筛选变化时触发
console.log(sorter);
//TODO 筛选
if (Object.keys(sorter).length>0){
this.isorter.column = sorter.field;
this.isorter.order = "ascend"==sorter.order?"asc":"desc"
}
this.ipagination = pagination;
this.loadData();
},
modalFormOk () {
// 新增/修改 成功时,重载列表
this.loadData();
},
getOrderMain(orderId){
this.queryParam.orderId = orderId.toString();
this.loadData(1);
}
}
}
</script>
<style scoped>
.ant-card{
.ant-card {
margin-left: -30px;
margin-right: -30px;
}

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