mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2025-12-08 17:12:28 +08:00
Compare commits
103 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5eb2541834 | |||
| 462b0d17b1 | |||
| 7cc54084dc | |||
| 32297110d9 | |||
| b7717d0461 | |||
| 97c078c46a | |||
| 17019e6261 | |||
| 4a49479985 | |||
| e49d76bc80 | |||
| d6cf2b502b | |||
| c741d779f2 | |||
| 7f847c9721 | |||
| fa2c5ecb73 | |||
| eb1578ada3 | |||
| 90758f3b2a | |||
| 766c48bdbf | |||
| d16520cc59 | |||
| 0252213b6e | |||
| ce44147e6e | |||
| 0ea4ac910a | |||
| 4f61f0ad48 | |||
| 4a5ff61ef7 | |||
| 88a0bb2d2d | |||
| b153669b69 | |||
| 449a7759be | |||
| 337920964d | |||
| 2a7946ae42 | |||
| c233f95f5f | |||
| f87cc2d97f | |||
| 02bb521b8f | |||
| 53e84ae34b | |||
| d6feeef7b5 | |||
| 18fc7b146a | |||
| 3792f46388 | |||
| f35236609c | |||
| e46b653bc4 | |||
| 4437c749ca | |||
| 74ebac4967 | |||
| a9f21795cb | |||
| a5ca8183cd | |||
| e7970e52bc | |||
| 74a9e10ce6 | |||
| df5c106d94 | |||
| ae0f9edb27 | |||
| 3d4bb704f1 | |||
| 85efec3730 | |||
| 8b0ee2d0a2 | |||
| 41c1572ad8 | |||
| 5d555158fe | |||
| 1fd0b5d4db | |||
| 693d86cf00 | |||
| 9a3f872d63 | |||
| 5b82a1aa06 | |||
| 3cb88452dc | |||
| 2fa1c7c17b | |||
| b6a3085083 | |||
| 8a7fc033cd | |||
| e0cf946d18 | |||
| c5b33b6bd1 | |||
| aec00d9ba2 | |||
| 341830c5a0 | |||
| ff45fe4858 | |||
| c13ed675a7 | |||
| 6917e91398 | |||
| 18a5c247d8 | |||
| 51bf9a7c14 | |||
| 8278041aeb | |||
| 39bb7a46fd | |||
| 1c234fbaff | |||
| ca1f5872be | |||
| 2ae3844d5e | |||
| c2db7691d1 | |||
| 543a49fcb6 | |||
| df6cf7137c | |||
| d7450cab04 | |||
| 496d85265b | |||
| b4b1162ea0 | |||
| 33e39941fb | |||
| 1b5ba9f56b | |||
| 0aadc70e74 | |||
| 94aed3ade4 | |||
| 9657eac673 | |||
| 680a8b3c42 | |||
| 6e6f88620a | |||
| 14f4f92d84 | |||
| 2c4597c0a9 | |||
| 757f1cd5a8 | |||
| 3c62a58d64 | |||
| bec39867a9 | |||
| dca8713a2e | |||
| a004acee4b | |||
| 35ef0eff90 | |||
| c70fd3383e | |||
| 3e2f640b68 | |||
| bf6c5f4623 | |||
| df259385ec | |||
| c5f51a17da | |||
| 94c0610496 | |||
| ccf4946b70 | |||
| 3b4a65ba04 | |||
| 3a8ae4c089 | |||
| 63048d8c64 | |||
| 8775472470 |
71
README.md
71
README.md
@ -7,12 +7,12 @@
|
||||
JEECG BOOT 低代码开发平台(前后端分离版本)
|
||||
===============
|
||||
|
||||
当前最新版本: 2.3(发布日期:2020-09-14)
|
||||
当前最新版本: 2.4.2(发布日期:2021-01-26)
|
||||
|
||||
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
|
||||
[](http://www.jeecg.com)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
[](https://github.com/zhangdaiscott/jeecg-boot)
|
||||
|
||||
@ -23,11 +23,14 @@ JEECG BOOT 低代码开发平台(前后端分离版本)
|
||||
|
||||
<h3 align="center">Java Low Code Platform for Enterprise web applications</h3>
|
||||
|
||||
JeecgBoot 是一款基于代码生成器的`低代码`开发平台,零代码开发!采用前后端分离架构:SpringBoot2.x,Ant Design&Vue,Mybatis-plus,Shiro,JWT。强大的代码生成器让前后端代码一键生成,无需写任何代码! JeecgBoot引领新的开发模式(Online Coding模式-> 代码生成器模式-> 手工MERGE智能开发), 帮助解决Java项目70%的重复工作,让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省成本,同时又不失灵活性!JeecgBoot还独创在线开发模式(No代码概念):在线表单配置(表单设计器)、移动配置能力、工作流配置(在线设计流程)、报表配置能力、在线图表配置、插件能力(可插拔)等等!
|
||||
JeecgBoot 是一款基于代码生成器的`低代码`开发平台!前后端分离架构 SpringBoot2.x,SpringCloud,Ant Design&Vue,Mybatis-plus,Shiro,JWT,支持微服务。强大的代码生成器让前后端代码一键生成,实现低代码开发! JeecgBoot 引领新的低代码开发模式(OnlineCoding-> 代码生成器-> 手工MERGE), 帮助解决Java项目70%的重复工作,让开发更多关注业务。既能快速提高效率,节省研发成本,同时又不失灵活性!
|
||||
|
||||
JeecgBoot 提供了一系列`低代码模块`,实现在线开发`真正的零代码`:Online表单开发、Online报表、报表配置能力、在线图表设计、大屏设计、移动配置能力、表单设计器、在线设计流程、流程自动化配置、插件能力(可插拔)等等!
|
||||
|
||||
|
||||
`JEECG宗旨是:` 简单功能由Online Coding配置实现既`零代码开发`(在线配置表单、在线配置报表、在线图表设计、在线设计流程、在线设计表单),复杂功能由代码生成器生成进行手工Merge,既保证了`智能`又兼顾了`灵活`;
|
||||
业务流程采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。
|
||||
`JEECG宗旨是:` 简单功能由OnlineCoding配置实现,做到`零代码开发`;复杂功能由代码生成器生成进行手工Merge 实现`低代码开发`,既保证了`智能`又兼顾`灵活`;实现了低代码开发的同时又支持灵活编码,解决了当前低代码产品普遍不灵活的弊端!
|
||||
|
||||
`JEECG业务流程:` 采用工作流来实现、扩展出任务接口,供开发编写业务逻辑,表单提供多种解决方案: 表单设计器、online配置表单、编码表单。同时实现了流程与表单的分离设计(松耦合)、并支持任务节点灵活配置,既保证了公司流程的保密性,又减少了开发人员的工作量。
|
||||
|
||||
|
||||
适用项目
|
||||
@ -41,13 +44,15 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
|
||||
- 技术官网: [http://www.jeecg.com](http://www.jeecg.com)
|
||||
|
||||
- 开发文档: [http://doc.jeecg.com](http://doc.jeecg.com/1273753)
|
||||
- 开发文档: [http://doc.jeecg.com](http://doc.jeecg.com)
|
||||
|
||||
- 微服务启动: [单体升级为微服务启动文档2.4+](http://doc.jeecg.com/2043906)
|
||||
|
||||
- 在线演示 : [http://boot.jeecg.com](http://boot.jeecg.com)
|
||||
|
||||
- 视频教程 :[JeecgBoot入门视频教程](http://www.jeecg.com/doc/video)
|
||||
- 视频教程 :[JeecgBoot入门视频](http://www.jeecg.com/doc/video)
|
||||
|
||||
- 常见问题: [入门常见问题大全](http://bbs.jeecg.com/forum.php?mod=viewthread&tid=7816&extra=page%3D1)
|
||||
- 常见问题: [入门常见问题Q&A](http://jeecg.com/doc/qa)
|
||||
|
||||
- 更新日志: [版本日志](http://www.jeecg.com/doc/log)
|
||||
|
||||
@ -130,15 +135,17 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
|
||||
|
||||
#### 后端
|
||||
- 基础框架:Spring Boot 2.1.3.RELEASE \ Spring Cloud Alibaba 2.1.0.RELEASE
|
||||
- 基础框架:Spring Boot 2.3.5.RELEASE
|
||||
|
||||
- 持久层框架:Mybatis-plus_3.1.2
|
||||
- 微服务框架: Spring Cloud Alibaba 2.2.3.RELEASE
|
||||
|
||||
- 安全框架:Apache Shiro 1.4.0,Jwt_3.7.0
|
||||
- 持久层框架:Mybatis-plus 3.4.1
|
||||
|
||||
- 微服务技术:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywarking
|
||||
- 安全框架:Apache Shiro 1.7.0,Jwt 3.11.0
|
||||
|
||||
- 数据库连接池:阿里巴巴Druid 1.1.10
|
||||
- 微服务技术栈:Spring Cloud Alibaba、Nacos、Gateway、Sentinel、Skywarking
|
||||
|
||||
- 数据库连接池:阿里巴巴Druid 1.1.22
|
||||
|
||||
- 缓存框架:redis
|
||||
|
||||
@ -182,7 +189,7 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
├─消息中心
|
||||
│ ├─消息管理
|
||||
│ ├─模板管理
|
||||
├─智能化功能
|
||||
├─代码生成器(低代码)
|
||||
│ ├─代码生成器功能(一键生成前后端代码,生成后无需修改直接用,绝对是后端开发福音)
|
||||
│ ├─代码生成器模板(提供4套模板,分别支持单表和一对多模型,不同风格选择)
|
||||
│ ├─代码生成器模板(生成代码,自带excel导入导出)
|
||||
@ -271,14 +278,19 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
│ ├─提供单点登录CAS集成方案
|
||||
│ ├─提供APP发布方案
|
||||
│ ├─集成Websocket消息通知机制
|
||||
├─Online在线低代码开发(暂未开源)
|
||||
├─Online在线开发(低代码)
|
||||
│ ├─Online在线表单 - 功能已开放
|
||||
│ ├─在线代码生成器 - 功能已开放
|
||||
│ ├─Online代码生成器 - 功能已开放
|
||||
│ ├─Online在线报表 - 功能已开放
|
||||
│ ├─多数据源管理
|
||||
│ ├─Online在线图表
|
||||
│ ├─Online图表模板配置
|
||||
│ ├─高级表单设计器
|
||||
│ ├─Online在线图表(暂不开源)
|
||||
│ ├─Online图表模板配置(暂不开源)
|
||||
│ ├─Online布局设计(暂不开源)
|
||||
│ ├─多数据源管理 - 功能已开放
|
||||
├─积木报表设计器(低代码)
|
||||
│ ├─打印设计器
|
||||
│ ├─数据报表设计
|
||||
│ ├─图形报表设计(支持echart)
|
||||
│ ├─大屏设计器(暂不开源)
|
||||
│─流程模块功能 (暂不开源)
|
||||
│ ├─流程设计器
|
||||
│ ├─在线表单设计
|
||||
@ -297,14 +309,14 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
|
||||
```
|
||||
|
||||
## 微服务整体解决方案(2.3+版本)
|
||||
## 微服务整体解决方案(2.4+版本)
|
||||
|
||||
|
||||
1、服务注册和发现 Nacos √
|
||||
|
||||
2、统一配置中心 Nacos √
|
||||
|
||||
3、路由网关 gateway √
|
||||
3、路由网关 gateway(三种加载方式) √
|
||||
|
||||
4、分布式 http feign √
|
||||
|
||||
@ -314,13 +326,13 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
|
||||
7、统一权限控制 JWT + Shiro √
|
||||
|
||||
8、服务监控 SpringBootAdmin [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1761865)
|
||||
8、服务监控 SpringBootAdmin√
|
||||
|
||||
9、链路跟踪 Skywarking [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1771670)
|
||||
9、链路跟踪 Skywarking [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1771670)
|
||||
|
||||
10、消息中间件 SpringCloudStream+RabbitMQ [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1744409)
|
||||
10、消息中间件 RabbitMQ √
|
||||
|
||||
11、分布式任务 xxl-job [参考文档](https://www.kancloud.cn/zhangdaiscott/jeecgcloud/1801263)
|
||||
11、分布式任务 xxl-job √
|
||||
|
||||
12、分布式事务 Seata
|
||||
|
||||
@ -329,12 +341,15 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
14、支持 docker-compose、k8s、jenkins
|
||||
|
||||
15、CAS 单点登录 √
|
||||
|
||||
16、路由限流 √
|
||||
|
||||
|
||||
#### 微服务架构图
|
||||

|
||||
|
||||
### Jeecg Boot 产品功能蓝图
|
||||

|
||||

|
||||
|
||||
|
||||
后台开发环境和依赖
|
||||
@ -344,7 +359,7 @@ Jeecg-Boot低代码开发平台,可以应用在任何J2EE项目的开发中,
|
||||
- jdk8
|
||||
- mysql
|
||||
- redis
|
||||
- 数据库脚本:jeecg-boot\docs\jeecg-boot-mysql.sql
|
||||
- 数据库脚本:jeecg-boot/db/jeecgboot-mysql-5.7.sql
|
||||
- 默认登录账号: admin/123456
|
||||
|
||||
|
||||
|
||||
3
ant-design-vue-jeecg/.env
Normal file
3
ant-design-vue-jeecg/.env
Normal file
@ -0,0 +1,3 @@
|
||||
NODE_ENV=production
|
||||
VUE_APP_PLATFORM_NAME=JeecgBoot 企业级快速开发平台
|
||||
VUE_APP_SSO=false
|
||||
4
ant-design-vue-jeecg/.env.development
Normal file
4
ant-design-vue-jeecg/.env.development
Normal file
@ -0,0 +1,4 @@
|
||||
NODE_ENV=development
|
||||
VUE_APP_API_BASE_URL=http://localhost:8080/jeecg-boot
|
||||
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
|
||||
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
|
||||
4
ant-design-vue-jeecg/.env.production
Normal file
4
ant-design-vue-jeecg/.env.production
Normal file
@ -0,0 +1,4 @@
|
||||
NODE_ENV=production
|
||||
VUE_APP_API_BASE_URL=https://bootapi.jeecg.com
|
||||
VUE_APP_CAS_BASE_URL=http://localhost:8888/cas
|
||||
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
|
||||
4
ant-design-vue-jeecg/.env.test
Normal file
4
ant-design-vue-jeecg/.env.test
Normal file
@ -0,0 +1,4 @@
|
||||
NODE_ENV=production
|
||||
VUE_APP_API_BASE_URL=http://boot.jeecg.com:8080/jeecg-boot
|
||||
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
|
||||
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview
|
||||
@ -1,7 +1,7 @@
|
||||
Ant Design Jeecg Vue
|
||||
====
|
||||
|
||||
当前最新版本: 2.3.0(发布日期:20200914)
|
||||
当前最新版本: 2.4.2(发布日期:20210126)
|
||||
|
||||
Overview
|
||||
----
|
||||
@ -111,7 +111,7 @@ Docker 镜像使用
|
||||
|
||||
```
|
||||
# 1.修改前端项目的后台域名
|
||||
public/index.html
|
||||
.env.development
|
||||
域名改成: http://jeecg-boot-system:8080/jeecg-boot
|
||||
|
||||
# 2.先进入打包前端项目
|
||||
|
||||
7683
ant-design-vue-jeecg/package-lock.json
generated
7683
ant-design-vue-jeecg/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,17 @@
|
||||
{
|
||||
"name": "vue-antd-jeecg",
|
||||
"version": "2.3.0",
|
||||
"version": "2.4.2",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
|
||||
"serve": "vue-cli-service serve",
|
||||
"build:test": "vue-cli-service build --mode test",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"ant-design-vue": "^1.6.3",
|
||||
"@jeecg/antd-online-mini": "2.3.0",
|
||||
"@jeecg/antd-online-mini": "2.4.22-beta",
|
||||
"ant-design-vue": "^1.7.2",
|
||||
"@antv/data-set": "^0.11.4",
|
||||
"viser-vue": "^2.4.8",
|
||||
"axios": "^0.18.0",
|
||||
@ -39,7 +40,6 @@
|
||||
"@toast-ui/editor": "^2.1.2",
|
||||
"vue-area-linkage": "^5.1.0",
|
||||
"area-data": "^5.0.6",
|
||||
"jsoneditor": "^9.0.0",
|
||||
"dom-align": "1.12.0",
|
||||
"xe-utils": "2.4.8",
|
||||
"vxe-table": "2.9.13",
|
||||
@ -58,8 +58,7 @@
|
||||
"less-loader": "^4.1.0",
|
||||
"vue-template-compiler": "^2.6.10",
|
||||
"html-webpack-plugin": "^4.2.0",
|
||||
"compression-webpack-plugin": "^3.1.0",
|
||||
"babel-plugin-import": "^1.13.0"
|
||||
"compression-webpack-plugin": "^3.1.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
@ -97,7 +96,10 @@
|
||||
"vue/html-closing-bracket-newline": 0,
|
||||
"vue/no-parsing-error": 0,
|
||||
"no-tabs": 0,
|
||||
"indent": ["off", 2],
|
||||
"indent": [
|
||||
"off",
|
||||
2
|
||||
],
|
||||
"no-console": 0,
|
||||
"space-before-function-paren": 0
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
7
ant-design-vue-jeecg/public/color.less
vendored
7
ant-design-vue-jeecg/public/color.less
vendored
@ -2421,7 +2421,9 @@ a.listItemMetaTitle {
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
.main {
|
||||
background-color: #fff;
|
||||
//update-begin---author:liusq Date:20210108 for:[JT-409]编译主题色,然后退出登录后的首页是这样子------------
|
||||
//background-color: #fff;
|
||||
//update-end---author:liusq Date:20210108 for:[JT-409]编译主题色,然后退出登录后的首页是这样子------------
|
||||
}
|
||||
.main .leftmenu {
|
||||
border-right: 1px solid #e8e8e8;
|
||||
@ -7687,9 +7689,6 @@ font.weak {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
.ant-menu-submenu-selected {
|
||||
color: @primary-color;
|
||||
}
|
||||
|
||||
// begin -------- JAreaLinkage 三级联动样式 --------------
|
||||
.cascader-menu-list .cascader-menu-option.hover,
|
||||
|
||||
14
ant-design-vue-jeecg/public/index.html
vendored
14
ant-design-vue-jeecg/public/index.html
vendored
@ -5,10 +5,9 @@
|
||||
<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 企业级快速开发平台</title>
|
||||
<title>JeecgBoot 企业级快速开发平台</title>
|
||||
<link rel="icon" href="<%= BASE_URL %>logo.png">
|
||||
<script src="/cdn/babel-polyfill/polyfill_7_2_5.js"></script>
|
||||
|
||||
<script src="<%= BASE_URL %>cdn/babel-polyfill/polyfill_7_2_5.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body,
|
||||
@ -243,23 +242,16 @@
|
||||
<!-- 全局配置 -->
|
||||
<script>
|
||||
window._CONFIG = {};
|
||||
window._CONFIG['domianURL'] = 'http://127.0.0.1:8080/jeecg-boot';
|
||||
window._CONFIG['casPrefixUrl'] = 'http://cas.example.org:8443/cas';
|
||||
window._CONFIG['onlinePreviewDomainURL'] = 'http://fileview.jeecg.com/onlinePreview'
|
||||
window._CONFIG['staticDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/static';
|
||||
//window._CONFIG['downloadUrl'] = window._CONFIG['domianURL'] + '/sys/common/download';
|
||||
window._CONFIG['pdfDomainURL'] = window._CONFIG['domianURL'] + '/sys/common/pdf/pdfPreviewIframe';
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- built files will be auto injected -->
|
||||
<div id="app">
|
||||
<div id="loader-wrapper">
|
||||
<div id="loader"></div>
|
||||
<div class="loader-section section-left"></div>
|
||||
<div class="loader-section section-right"></div>
|
||||
<div class="load_title">正在加载 Jeecg-Boot 快速开发平台,请耐心等待
|
||||
<div class="load_title">正在加载 JeecgBoot 快速开发平台,请耐心等待
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,17 +2,9 @@ import { getAction, deleteAction, putAction, postAction, httpAction } from '@/ap
|
||||
import Vue from 'vue'
|
||||
import {UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
|
||||
|
||||
////根路径
|
||||
// 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 checkRoleCode = (params)=>getAction("/sys/role/checkRoleCode",params);
|
||||
const queryall = (params)=>getAction("/sys/role/queryall",params);
|
||||
|
||||
@ -21,8 +13,6 @@ 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 frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
|
||||
//验证用户是否存在
|
||||
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
|
||||
@ -33,21 +23,15 @@ const changePassword = (params)=>putAction("/sys/user/changePassword",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);
|
||||
/*update_begin author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
|
||||
const getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
|
||||
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
|
||||
const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', params)
|
||||
/*update_end author:wuxianquan date:20190908 for:添加查询一级菜单和子菜单查询api */
|
||||
|
||||
// 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 queryPermissionsByUser = (params)=>getAction("/sys/permission/getUserPermissionByToken",params);
|
||||
const queryPermissionsByUser = ()=>getAction("/sys/permission/getUserPermissionByToken");
|
||||
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
|
||||
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
|
||||
const queryPermissionRule = (params)=>getAction("/sys/permission/queryPermissionRule",params);
|
||||
@ -75,14 +59,9 @@ 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 treeList = (params)=>getAction("/sys/dict/treeList",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);
|
||||
|
||||
//字典标签专用(通过code获取字典数组)
|
||||
export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params);
|
||||
@ -101,14 +80,10 @@ const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",param
|
||||
//获取系统访问量
|
||||
const getLoginfo = (params)=>getAction("/sys/loginfo",params);
|
||||
const getVisitInfo = (params)=>getAction("/sys/visitInfo",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);
|
||||
// 加载分类字典
|
||||
@ -126,8 +101,6 @@ export const transitRESTful = {
|
||||
}
|
||||
|
||||
export {
|
||||
// imgView,
|
||||
// doMian,
|
||||
addRole,
|
||||
editRole,
|
||||
checkRoleCode,
|
||||
|
||||
@ -36,15 +36,15 @@ export function getSmsCaptcha(parameter) {
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo() {
|
||||
return axios({
|
||||
url: '/api/user/info',
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
}
|
||||
})
|
||||
}
|
||||
// export function getInfo() {
|
||||
// return axios({
|
||||
// url: '/api/user/info',
|
||||
// method: 'get',
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/json;charset=UTF-8'
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
export function logout(logoutToken) {
|
||||
return axios({
|
||||
@ -60,11 +60,12 @@ export function logout(logoutToken) {
|
||||
/**
|
||||
* 第三方登录
|
||||
* @param token
|
||||
* @param thirdType
|
||||
* @returns {*}
|
||||
*/
|
||||
export function thirdLogin(token) {
|
||||
export function thirdLogin(token,thirdType) {
|
||||
return axios({
|
||||
url: `/thirdLogin/getLoginUser/${token}`,
|
||||
url: `/sys/thirdLogin/getLoginUser/${token}/${thirdType}`,
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
|
||||
@ -2,11 +2,11 @@ import Vue from 'vue'
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
const api = {
|
||||
user: '/api/user',
|
||||
role: '/api/role',
|
||||
service: '/api/service',
|
||||
permission: '/api/permission',
|
||||
permissionNoPager: '/api/permission/no-pager'
|
||||
user: '/mock/api/user',
|
||||
role: '/mock/api/role',
|
||||
service: '/mock/api/service',
|
||||
permission: '/mock/api/permission',
|
||||
permissionNoPager: '/mock/api/permission/no-pager'
|
||||
}
|
||||
|
||||
export default api
|
||||
|
||||
@ -5,21 +5,25 @@ import store from '@/store'
|
||||
* 单点登录
|
||||
*/
|
||||
const init = (callback) => {
|
||||
console.log("-------单点登录开始-------");
|
||||
let token = Vue.ls.get(ACCESS_TOKEN);
|
||||
let st = getUrlParam("ticket");
|
||||
let sevice = "http://"+window.location.host+"/";
|
||||
if(token){
|
||||
loginSuccess(callback);
|
||||
}else{
|
||||
if(st){
|
||||
validateSt(st,sevice,callback);
|
||||
}else{
|
||||
let serviceUrl = encodeURIComponent(sevice);
|
||||
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
|
||||
if (process.env.VUE_APP_SSO == 'true') {
|
||||
console.log("-------单点登录开始-------");
|
||||
let token = Vue.ls.get(ACCESS_TOKEN);
|
||||
let st = getUrlParam("ticket");
|
||||
let sevice = "http://" + window.location.host + "/";
|
||||
if (token) {
|
||||
loginSuccess(callback);
|
||||
} else {
|
||||
if (st) {
|
||||
validateSt(st, sevice, callback);
|
||||
} else {
|
||||
let serviceUrl = encodeURIComponent(sevice);
|
||||
window.location.href = window._CONFIG['casPrefixUrl'] + "/login?service=" + serviceUrl;
|
||||
}
|
||||
}
|
||||
console.log("-------单点登录结束-------");
|
||||
}else{
|
||||
callback && callback()
|
||||
}
|
||||
console.log("-------单点登录结束-------");
|
||||
};
|
||||
const SSO = {
|
||||
init: init
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
<a-menu-item v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleMoreOperation">
|
||||
<a-menu-item @click="handleMoreOperation(originColumn)">
|
||||
<span><a-icon type="bars"/> 更多</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
@ -55,7 +55,7 @@
|
||||
>
|
||||
<a-button icon="upload">{{originColumn.btnText || '上传文件'}}</a-button>
|
||||
</a-upload>
|
||||
<j-file-pop ref="filePop" @ok="handleFileSuccess"/>
|
||||
<j-file-pop ref="filePop" @ok="handleFileSuccess" :number="number"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -75,6 +75,7 @@
|
||||
data() {
|
||||
return {
|
||||
innerFile: null,
|
||||
number:0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -137,7 +138,18 @@
|
||||
methods: {
|
||||
|
||||
// 点击更多按钮
|
||||
handleMoreOperation() {
|
||||
handleMoreOperation(originColumn) {
|
||||
//update-begin-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件
|
||||
if (originColumn.number) {
|
||||
this.number = originColumn.number
|
||||
} else {
|
||||
this.number = 0
|
||||
}
|
||||
//update-end-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件
|
||||
if(originColumn && originColumn.fieldExtendJson){
|
||||
let json = JSON.parse(originColumn.fieldExtendJson);
|
||||
this.number = json.uploadnum?json.uploadnum:0;
|
||||
}
|
||||
let path = ''
|
||||
if (this.innerFile) {
|
||||
path = this.innerFile.path
|
||||
@ -202,4 +214,4 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
<a-menu-item v-if="originColumn.allowRemove !== false" @click="handleClickDeleteFile">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleMoreOperation">
|
||||
<a-menu-item @click="handleMoreOperation(originColumn)">
|
||||
<span><a-icon type="bars"/> 更多</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
@ -63,7 +63,7 @@
|
||||
>
|
||||
<a-button icon="upload">{{originColumn.btnText || '上传图片'}}</a-button>
|
||||
</a-upload>
|
||||
<j-file-pop ref="filePop" @ok="handleFileSuccess"/>
|
||||
<j-file-pop ref="filePop" @ok="handleFileSuccess" :number="number"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -83,6 +83,7 @@
|
||||
data() {
|
||||
return {
|
||||
innerFile: null,
|
||||
number:0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -146,7 +147,18 @@
|
||||
methods: {
|
||||
|
||||
// 点击更多按钮
|
||||
handleMoreOperation() {
|
||||
handleMoreOperation(originColumn) {
|
||||
//update-begin-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件
|
||||
if (originColumn.number) {
|
||||
this.number = originColumn.number
|
||||
} else {
|
||||
this.number = 0
|
||||
}
|
||||
//update-end-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件
|
||||
if(originColumn && originColumn.fieldExtendJson){
|
||||
let json = JSON.parse(originColumn.fieldExtendJson);
|
||||
this.number = json.uploadnum?json.uploadnum:0;
|
||||
}
|
||||
let path = ''
|
||||
if (this.innerFile) {
|
||||
path = this.innerFile.path
|
||||
@ -227,4 +239,4 @@
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -10,7 +10,9 @@
|
||||
:disabled="disabled"
|
||||
mode="multiple"
|
||||
:placeholder="placeholder"
|
||||
:getPopupContainer="(node) => node.parentNode"
|
||||
:getPopupContainer="getParentContainer"
|
||||
optionFilterProp="children"
|
||||
:filterOption="filterOption"
|
||||
allowClear>
|
||||
<a-select-option
|
||||
v-for="(item,index) in dictOptions"
|
||||
@ -34,13 +36,23 @@
|
||||
disabled: Boolean,
|
||||
value: String,
|
||||
type: String,
|
||||
options:Array
|
||||
options:Array,
|
||||
spliter:{
|
||||
type: String,
|
||||
required: false,
|
||||
default: ','
|
||||
},
|
||||
popContainer:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dictOptions: [],
|
||||
tagType:"",
|
||||
arrayValue:!this.value?[]:this.value.split(",")
|
||||
arrayValue:!this.value?[]:this.value.split(this.spliter)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -66,7 +78,7 @@
|
||||
if(!val){
|
||||
this.arrayValue = []
|
||||
}else{
|
||||
this.arrayValue = this.value.split(",")
|
||||
this.arrayValue = this.value.split(this.spliter)
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -76,8 +88,9 @@
|
||||
this.dictOptions = [...this.options]
|
||||
}else{
|
||||
//优先从缓存中读取字典配置
|
||||
if(getDictItemsFromCache(this.dictCode)){
|
||||
this.dictOptions = getDictItemsFromCache(this.dictCode);
|
||||
let cacheOption = getDictItemsFromCache(this.dictCode)
|
||||
if(cacheOption && cacheOption.length>0){
|
||||
this.dictOptions = cacheOption
|
||||
return
|
||||
}
|
||||
//根据字典Code, 初始化字典数组
|
||||
@ -90,14 +103,26 @@
|
||||
|
||||
},
|
||||
onChange (selectedValue) {
|
||||
this.$emit('change', selectedValue.join(","));
|
||||
this.$emit('change', selectedValue.join(this.spliter));
|
||||
},
|
||||
setCurrentDictOptions(dictOptions){
|
||||
this.dictOptions = dictOptions
|
||||
},
|
||||
getCurrentDictOptions(){
|
||||
return this.dictOptions
|
||||
},
|
||||
getParentContainer(node){
|
||||
if(!this.popContainer){
|
||||
return node.parentNode
|
||||
}else{
|
||||
return document.querySelector(this.popContainer)
|
||||
}
|
||||
},
|
||||
// update--begin--autor:lvdandan-----date:20201120------for:LOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
|
||||
filterOption(input, option) {
|
||||
return option.componentOptions.children[0].children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
|
||||
}
|
||||
// update--end--autor:lvdandan-----date:20201120------for:LOWCOD-1086 下拉多选框,搜索时只字典code进行搜索不能通过字典text搜索
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
showSearch
|
||||
labelInValue
|
||||
:disabled="disabled"
|
||||
:getPopupContainer="(node) => node.parentNode"
|
||||
:getPopupContainer="getParentContainer"
|
||||
@search="loadData"
|
||||
:placeholder="placeholder"
|
||||
v-model="selectedAsyncValue"
|
||||
@ -21,7 +21,7 @@
|
||||
|
||||
<a-select
|
||||
v-else
|
||||
:getPopupContainer="(node) => node.parentNode"
|
||||
:getPopupContainer="getParentContainer"
|
||||
showSearch
|
||||
:disabled="disabled"
|
||||
:placeholder="placeholder"
|
||||
@ -55,6 +55,16 @@
|
||||
type:String,
|
||||
default:"请选择",
|
||||
required:false
|
||||
},
|
||||
popContainer:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
pageSize:{
|
||||
type: Number,
|
||||
default: 10,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
@ -126,7 +136,7 @@
|
||||
this.options = []
|
||||
this.loading=true
|
||||
// 字典code格式:table,text,code
|
||||
getAction(`/sys/dict/loadDict/${this.dict}`,{keyword:value}).then(res=>{
|
||||
getAction(`/sys/dict/loadDict/${this.dict}`,{keyword:value, pageSize: this.pageSize}).then(res=>{
|
||||
this.loading=false
|
||||
if(res.success){
|
||||
if(currentLoad!=this.lastLoad){
|
||||
@ -171,6 +181,17 @@
|
||||
})
|
||||
}
|
||||
}
|
||||
}else{
|
||||
//异步一开始也加载一点数据
|
||||
this.loading=true
|
||||
getAction(`/sys/dict/loadDict/${this.dict}`,{pageSize: this.pageSize, keyword:''}).then(res=>{
|
||||
this.loading=false
|
||||
if(res.success){
|
||||
this.options = res.result
|
||||
}else{
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
filterOption(input, option) {
|
||||
@ -182,9 +203,18 @@
|
||||
this.callback()
|
||||
},
|
||||
handleAsyncChange(selectedObj){
|
||||
this.selectedAsyncValue = selectedObj
|
||||
this.selectedValue = selectedObj.key
|
||||
//update-begin-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
|
||||
if(selectedObj){
|
||||
this.selectedAsyncValue = selectedObj
|
||||
this.selectedValue = selectedObj.key
|
||||
}else{
|
||||
this.selectedAsyncValue = null
|
||||
this.selectedValue = null
|
||||
this.options = null
|
||||
this.loadData("")
|
||||
}
|
||||
this.callback()
|
||||
//update-end-author:scott date:20201222 for:【搜索】搜索查询组件,删除条件,默认下拉还是上次的缓存数据,不好 JT-191
|
||||
},
|
||||
callback(){
|
||||
this.$emit('change', this.selectedValue);
|
||||
@ -194,7 +224,14 @@
|
||||
},
|
||||
getCurrentDictOptions(){
|
||||
return this.options
|
||||
}
|
||||
},
|
||||
getParentContainer(node){
|
||||
if(!this.popContainer){
|
||||
return node.parentNode
|
||||
}else{
|
||||
return document.querySelector(this.popContainer)
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
model: {
|
||||
|
||||
@ -1,7 +1,16 @@
|
||||
import T from './JDictSelectTag.vue'
|
||||
const JDictSelectTag = {
|
||||
import JDictSelectTag from './JDictSelectTag.vue'
|
||||
import JMultiSelectTag from './JMultiSelectTag.vue'
|
||||
import JSearchSelectTag from './JSearchSelectTag.vue'
|
||||
import { filterMultiDictText,filterDictText,initDictOptions,filterDictTextByCache } from './JDictSelectUtil'
|
||||
|
||||
export default {
|
||||
install: function (Vue) {
|
||||
Vue.component('JDictSelectTag',T);
|
||||
Vue.component('JDictSelectTag',JDictSelectTag);
|
||||
Vue.component('JMultiSelectTag',JMultiSelectTag);
|
||||
Vue.component('JSearchSelectTag',JSearchSelectTag);
|
||||
Vue.prototype.$initDictOptions = (dictCode) => initDictOptions(dictCode)
|
||||
Vue.prototype.$filterMultiDictText = (dictOptions, text) => filterMultiDictText(dictOptions, text)
|
||||
Vue.prototype.$filterDictText = (dictOptions, text) => filterDictText(dictOptions, text)
|
||||
Vue.prototype.$filterDictTextByCache = (...param) => filterDictTextByCache(...param)
|
||||
}
|
||||
}
|
||||
export default JDictSelectTag;
|
||||
}
|
||||
@ -251,6 +251,9 @@
|
||||
},
|
||||
style: {}
|
||||
}
|
||||
if(isIE() || isIE11()){
|
||||
props.style['height'] = '240px'
|
||||
}
|
||||
if (this.fullCoder) {
|
||||
props.style['z-index'] = this.zIndex
|
||||
}
|
||||
|
||||
@ -1,282 +0,0 @@
|
||||
<template>
|
||||
<div v-bind="fullScreenParentProps">
|
||||
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
|
||||
|
||||
<div class="code-editor-cust full-screen-child">
|
||||
<a-textarea auto-size v-model="textareaValue" :placeholder="placeholderShow" @change="handleChange" :style="{'max-height': maxHeight+'px','min-height': minHeight+'px'}"></a-textarea>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/ecmascript-6">
|
||||
export default {
|
||||
name: 'JCodeEditor',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
// 是否显示全屏按钮
|
||||
fullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 全屏以后的z-index
|
||||
zIndex: {
|
||||
type: [Number, String],
|
||||
default: 999
|
||||
},
|
||||
// 是否自适应高度,可以传String或Boolean
|
||||
// 传 String 类型只能写"!ie" ,
|
||||
// 填写这个字符串,代表其他浏览器自适应高度
|
||||
// 唯独IE下不自适应高度,因为IE下不支持min、max-height样式
|
||||
// 如果填写的不是"!ie"就视为true
|
||||
autoHeight: {
|
||||
type: [String, Boolean],
|
||||
default: true
|
||||
},
|
||||
// 不自适应高度的情况下生效的固定高度
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: '240px'
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
minHeight:{
|
||||
type:Number,
|
||||
default: 100,
|
||||
required:false
|
||||
},
|
||||
maxHeight:{
|
||||
type:Number,
|
||||
default: 320,
|
||||
required:false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
textareaValue: '',
|
||||
// 内部真实的内容
|
||||
code: '',
|
||||
iconType: 'fullscreen',
|
||||
hasCode:false,
|
||||
// 默认的语法类型
|
||||
mode: 'javascript',
|
||||
// 编辑器实例
|
||||
coder: null,
|
||||
// 默认配置
|
||||
options: {
|
||||
// 缩进格式
|
||||
tabSize: 2,
|
||||
// 主题,对应主题库 JS 需要提前引入
|
||||
theme: 'panda-syntax',
|
||||
line: true,
|
||||
// extraKeys: {'Ctrl': 'autocomplete'},//自定义快捷键
|
||||
hintOptions: {
|
||||
tables: {
|
||||
users: ['name', 'score', 'birthDate'],
|
||||
countries: ['name', 'population', 'size']
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// code 编辑器 是否全屏
|
||||
fullCoder: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fullCoder:{
|
||||
handler(value) {
|
||||
if(value){
|
||||
this.iconType="fullscreen-exit"
|
||||
}else{
|
||||
this.iconType="fullscreen"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
placeholderShow() {
|
||||
if (this.placeholder == null) {
|
||||
return `请在此输入代码`
|
||||
} else {
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
isAutoHeight() {
|
||||
let {autoHeight} = this
|
||||
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
|
||||
autoHeight = !(isIE() || isIE11())
|
||||
} else {
|
||||
autoHeight = true
|
||||
}
|
||||
return autoHeight
|
||||
},
|
||||
fullScreenParentProps() {
|
||||
let props = {
|
||||
class: {
|
||||
'full-screen-parent': true,
|
||||
'full-screen': this.fullCoder,
|
||||
'auto-height': this.isAutoHeight
|
||||
},
|
||||
style: {}
|
||||
}
|
||||
if (this.fullCoder) {
|
||||
props.style['z-index'] = this.zIndex
|
||||
}
|
||||
if (!this.isAutoHeight) {
|
||||
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
|
||||
}
|
||||
return props
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 初始化
|
||||
this._initialize()
|
||||
},
|
||||
methods: {
|
||||
// 初始化
|
||||
_initialize () {
|
||||
this.setCodeContent(this.value)
|
||||
},
|
||||
handleChange(e){
|
||||
this.$emit('input', e.target.value)
|
||||
},
|
||||
getCodeContent(){
|
||||
return this.value
|
||||
},
|
||||
setCodeContent(val){
|
||||
setTimeout(()=>{
|
||||
if(!val){
|
||||
this.textareaValue = ''
|
||||
}else{
|
||||
this.textareaValue = val
|
||||
}
|
||||
},300)
|
||||
},
|
||||
nullTipClick(){
|
||||
this.coder.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.code-editor-cust{
|
||||
flex-grow:1;
|
||||
display:flex;
|
||||
position:relative;
|
||||
height:100%;
|
||||
.CodeMirror{
|
||||
flex-grow:1;
|
||||
z-index:1;
|
||||
.CodeMirror-code{
|
||||
line-height:19px;
|
||||
}
|
||||
|
||||
}
|
||||
.code-mode-select{
|
||||
position:absolute;
|
||||
z-index:2;
|
||||
right:10px;
|
||||
top:10px;
|
||||
max-width:130px;
|
||||
}
|
||||
.CodeMirror{
|
||||
height: auto;
|
||||
min-height:100%;
|
||||
}
|
||||
.null-tip{
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 36px;
|
||||
z-index: 10;
|
||||
color: #ffffffc9;
|
||||
line-height: initial;
|
||||
}
|
||||
.null-tip-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* 全屏样式 */
|
||||
.full-screen-parent {
|
||||
position: relative;
|
||||
|
||||
.full-screen-icon {
|
||||
opacity: 0;
|
||||
color: black;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
z-index: 9;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.full-screen-icon {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.full-screen {
|
||||
position: fixed;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
width: calc(100% - 20px);
|
||||
height: calc(100% - 20px);
|
||||
padding: 10px;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.full-screen-icon {
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
}
|
||||
|
||||
.full-screen-child {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.full-screen-child {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.auto-height {
|
||||
.full-screen-child {
|
||||
min-height: 120px;
|
||||
max-height: 320px;
|
||||
height: unset;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&.full-screen .full-screen-child {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
min-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.CodeMirror-cursor{
|
||||
height:18.4px !important;
|
||||
}
|
||||
</style>
|
||||
@ -11,13 +11,13 @@
|
||||
<a-col>
|
||||
<!-- 操作按钮 -->
|
||||
<div v-if="actionButton" class="action-button">
|
||||
<a-button type="primary" icon="plus" @click="handleClickAdd" :disabled="disabled">新增</a-button>
|
||||
<a-button v-if="buttonPermission('add')" type="primary" icon="plus" @click="handleClickAdd" :disabled="disabled">新增</a-button>
|
||||
<span class="gap"></span>
|
||||
<template v-if="selectedRowIds.length>0">
|
||||
<a-popconfirm
|
||||
:title="`确定要删除这 ${selectedRowIds.length} 项吗?`"
|
||||
@confirm="handleConfirmDelete">
|
||||
<a-button type="primary" icon="minus" :disabled="disabled">删除</a-button>
|
||||
<a-button v-if="buttonPermission('batch_delete')" type="primary" icon="minus" :disabled="disabled">删除</a-button>
|
||||
<span class="gap"></span>
|
||||
</a-popconfirm>
|
||||
<template v-if="showClearSelectButton">
|
||||
@ -188,6 +188,7 @@
|
||||
:getPopupContainer="getParentContainer"
|
||||
:placeholder="replaceProps(col, col.placeholder)"
|
||||
:filterOption="(i,o)=>handleSelectFilterOption(i,o,col)"
|
||||
:maxTagCount="1"
|
||||
@change="(v)=>handleChangeSelectCommon(v,id,row,col)"
|
||||
@search="(v)=>handleSearchSelect(v,id,row,col)"
|
||||
@blur="(v)=>handleBlurSearch(v,id,row,col)"
|
||||
@ -201,6 +202,55 @@
|
||||
>{{ getSelectTranslateText(selectValues[id], row, col) }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<!-- 部门选择 -->
|
||||
<template v-else-if="col.type === formTypes.sel_depart">
|
||||
<a-tooltip v-bind="buildTooltipProps(row, col, id)">
|
||||
<j-select-depart
|
||||
v-if="isEditRow(row, col)"
|
||||
:id="id"
|
||||
:key="i"
|
||||
v-bind="buildProps(row,col)"
|
||||
style="width: 100%;"
|
||||
:value="departCompValues[id]"
|
||||
:placeholder="replaceProps(col, col.placeholder)"
|
||||
:trigger-change="true"
|
||||
:multi="true"
|
||||
@change="(v)=>handleChangeDepartCommon(v,id,row,col)"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="j-td-span no-edit"
|
||||
:class="{disabled: buildProps(row,col).disabled}"
|
||||
@click="handleEditRow(row, col)"
|
||||
>{{ departCompValues[id] }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<!-- 用户选择 -->
|
||||
<template v-else-if="col.type === formTypes.sel_user">
|
||||
<a-tooltip v-bind="buildTooltipProps(row, col, id)">
|
||||
<j-select-user-by-dep
|
||||
v-if="isEditRow(row, col)"
|
||||
:id="id"
|
||||
:key="i"
|
||||
v-bind="buildProps(row,col)"
|
||||
style="width: 100%;"
|
||||
:value="userCompValues[id]"
|
||||
:placeholder="replaceProps(col, col.placeholder)"
|
||||
:trigger-change="true"
|
||||
:multi="true"
|
||||
@change="(v)=>handleChangeUserCommon(v,id,row,col)"
|
||||
/>
|
||||
<span
|
||||
v-else
|
||||
class="j-td-span no-edit"
|
||||
:class="{disabled: buildProps(row,col).disabled}"
|
||||
@click="handleEditRow(row, col)"
|
||||
>{{ userCompValues[id] }}</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
|
||||
<!-- date -->
|
||||
<template v-else-if="col.type === formTypes.date || col.type === formTypes.datetime">
|
||||
<a-tooltip v-bind="buildTooltipProps(row, col, id)">
|
||||
@ -375,7 +425,7 @@
|
||||
<a-menu-item @click="handleClickDelFile(id)">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleMoreOperation(id)">
|
||||
<a-menu-item @click="handleMoreOperation(id,col,col)">
|
||||
<span><a-icon type="bars" /> 更多</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
@ -410,7 +460,7 @@
|
||||
<a-icon type="loading"/>
|
||||
</template>
|
||||
<template v-else-if="uploadValues[id]['path']">
|
||||
<img class="j-editable-image" :src="getCellImageView(id)" alt="无图片" @click="handleMoreOperation(id,'img')"/>
|
||||
<img class="j-editable-image" :src="getCellImageView(id)" alt="无图片" @click="handleMoreOperation(id,'img',col)"/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-icon type="exclamation-circle" style="color: red;" @click="handleClickShowImageError(id)"/>
|
||||
@ -443,7 +493,7 @@
|
||||
<a-menu-item @click="handleClickDelFile(id)">
|
||||
<span><a-icon type="delete"/> 删除</span>
|
||||
</a-menu-item>
|
||||
<a-menu-item @click="handleMoreOperation(id,'img')">
|
||||
<a-menu-item @click="handleMoreOperation(id,'img',col)">
|
||||
<span><a-icon type="bars" /> 更多</span>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
@ -612,7 +662,7 @@
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<j-file-pop ref="filePop" @ok="handleFileSuccess"></j-file-pop>
|
||||
<j-file-pop ref="filePop" @ok="handleFileSuccess" :number="number"></j-file-pop>
|
||||
</div>
|
||||
</a-spin>
|
||||
</template>
|
||||
@ -628,6 +678,7 @@
|
||||
import { getFileAccessHttpUrl } from '@/api/manage';
|
||||
import JInputPop from '@/components/jeecg/minipop/JInputPop'
|
||||
import JFilePop from '@/components/jeecg/minipop/JFilePop'
|
||||
import { getNoAuthCols } from "@/utils/authFilter"
|
||||
|
||||
// 行高,需要在实例加载完成前用到
|
||||
let rowHeight = 61
|
||||
@ -704,6 +755,11 @@
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
authPre: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -749,6 +805,10 @@
|
||||
uploadValues: {},
|
||||
//popup信息
|
||||
popupValues: {},
|
||||
//部门组件信息
|
||||
departCompValues:{},
|
||||
//用户组件信息
|
||||
userCompValues: {},
|
||||
|
||||
radioValues: {},
|
||||
metaCheckboxValues: {},
|
||||
@ -774,6 +834,9 @@
|
||||
currentEditRows: {},
|
||||
// 上次push数据的事件,用于判断是否点击过快
|
||||
lastPushTimeMap: new Map(),
|
||||
number:0,
|
||||
//不显示的按钮编码
|
||||
excludeCode:[]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -882,6 +945,8 @@
|
||||
columns: {
|
||||
immediate: true,
|
||||
handler(columns) {
|
||||
//列改变的时候重新设置按钮权限信息
|
||||
this.loadExcludeCode()
|
||||
// 兼容IE
|
||||
this.getElementPromise('tbody').then(() => {
|
||||
columns.forEach(column => {
|
||||
@ -963,41 +1028,46 @@
|
||||
this.visibleTrEls = []
|
||||
// 判断是否是首次进入该方法,如果是就不清空行,防止删除了预添加的数据
|
||||
if (!this.isFirst) {
|
||||
// inputValues:用来存储input表单的值
|
||||
// 数组里的每项都是一个对象,对象里每个key都是input的rowKey,值就是input的值,其中有个id的字段来区分
|
||||
// 示例:
|
||||
// [{
|
||||
// id: "_jet-4sp0iu-15541771111770"
|
||||
// dbDefaultVal: "aaa",
|
||||
// dbFieldName: "bbb",
|
||||
// dbFieldTxt: "ccc",
|
||||
// dbLength: 32
|
||||
// }]
|
||||
this.inputValues = []
|
||||
this.rows = []
|
||||
this.deleteIds = []
|
||||
this.selectValues = {}
|
||||
this.checkboxValues = {}
|
||||
this.jdateValues = {}
|
||||
this.jInputPopValues = {}
|
||||
this.slotValues = {}
|
||||
this.selectedRowIds = []
|
||||
this.tooltips = {}
|
||||
this.notPassedIds = []
|
||||
this.uploadValues = []
|
||||
this.popupValues = []
|
||||
this.radioValues = []
|
||||
this.multiSelectValues = []
|
||||
this.searchSelectValues = []
|
||||
this.scrollTop = 0
|
||||
this.$nextTick(() => {
|
||||
this.getElement('tbody').scrollTop = 0
|
||||
})
|
||||
this.clearRow();
|
||||
} else {
|
||||
this.isFirst = false
|
||||
}
|
||||
},
|
||||
|
||||
/**清空行*/
|
||||
clearRow(){
|
||||
// inputValues:用来存储input表单的值
|
||||
// 数组里的每项都是一个对象,对象里每个key都是input的rowKey,值就是input的值,其中有个id的字段来区分
|
||||
// 示例:
|
||||
// [{
|
||||
// id: "_jet-4sp0iu-15541771111770"
|
||||
// dbDefaultVal: "aaa",
|
||||
// dbFieldName: "bbb",
|
||||
// dbFieldTxt: "ccc",
|
||||
// dbLength: 32
|
||||
// }]
|
||||
this.inputValues = []
|
||||
this.rows = []
|
||||
this.deleteIds = []
|
||||
this.selectValues = {}
|
||||
this.checkboxValues = {}
|
||||
this.jdateValues = {}
|
||||
this.jInputPopValues = {}
|
||||
this.departCompValues = {}
|
||||
this.userCompValues = {}
|
||||
this.slotValues = {}
|
||||
this.selectedRowIds = []
|
||||
this.tooltips = {}
|
||||
this.notPassedIds = []
|
||||
this.uploadValues = []
|
||||
this.popupValues = []
|
||||
this.radioValues = []
|
||||
this.multiSelectValues = []
|
||||
this.searchSelectValues = []
|
||||
this.scrollTop = 0
|
||||
this.$nextTick(() => {
|
||||
this.getElement('tbody').scrollTop = 0
|
||||
})
|
||||
},
|
||||
/** 同步滚动条状态 */
|
||||
syncScrollBar(scrollLeft) {
|
||||
// this.style.tbody.left = `${scrollLeft}px`
|
||||
@ -1057,6 +1127,8 @@
|
||||
let checkboxValues = { ...this.checkboxValues }
|
||||
let selectValues = { ...this.selectValues }
|
||||
let jdateValues = { ...this.jdateValues }
|
||||
let departCompValues = { ...this.departCompValues }
|
||||
let userCompValues = { ...this.userCompValues }
|
||||
let jInputPopValues = { ...this.jInputPopValues }
|
||||
let slotValues = { ...this.slotValues }
|
||||
let uploadValues = { ...this.uploadValues }
|
||||
@ -1143,6 +1215,10 @@
|
||||
|
||||
} else if (column.type === FormTypes.popup) {
|
||||
popupValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.sel_depart) {
|
||||
departCompValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.sel_user) {
|
||||
userCompValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.input_pop) {
|
||||
jInputPopValues[inputId] = sourceValue
|
||||
} else if (column.type === FormTypes.radio) {
|
||||
@ -1203,6 +1279,12 @@
|
||||
this.inputValues.splice(insertIndex, 0, value)
|
||||
}
|
||||
}
|
||||
//update-begin-author:lvdandan date:20201105 for:LOWCOD-987 【online】js增强的问题--数据对象带有id,且和现有数据一致时,替换患有数据
|
||||
if(-1 !== rows.findIndex(item => item.id === row.id)){
|
||||
added = true
|
||||
this.inputValues = this.inputValues.map(item => item.id === row.id ? value : item)
|
||||
}
|
||||
//update-begin-author:lvdandan date:20201105 for:LOWCOD-987 【online】js增强的问题--数据对象带有id,且和现有数据一致时,替换患有数据
|
||||
if (!added) {
|
||||
rows.push(row)
|
||||
this.inputValues.push(value)
|
||||
@ -1218,6 +1300,8 @@
|
||||
this.checkboxValues = checkboxValues
|
||||
this.selectValues = selectValues
|
||||
this.jdateValues = jdateValues
|
||||
this.departCompValues = departCompValues
|
||||
this.userCompValues = userCompValues
|
||||
this.jInputPopValues = jInputPopValues
|
||||
this.slotValues = slotValues
|
||||
this.uploadValues = uploadValues
|
||||
@ -1433,6 +1517,12 @@
|
||||
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
|
||||
value[column.key] = this.jdateValues[inputId]
|
||||
|
||||
} else if (column.type === FormTypes.sel_depart) {
|
||||
value[column.key] = this.departCompValues[inputId]
|
||||
|
||||
} else if (column.type === FormTypes.sel_user) {
|
||||
value[column.key] = this.userCompValues[inputId]
|
||||
|
||||
} else if (column.type === FormTypes.input_pop) {
|
||||
value[column.key] = this.jInputPopValues[inputId]
|
||||
|
||||
@ -1572,6 +1662,8 @@
|
||||
selectValues: this.selectValues,
|
||||
checkboxValues: this.checkboxValues,
|
||||
jdateValues: this.jdateValues,
|
||||
departCompValues: this.departCompValues,
|
||||
userCompValues: this.userCompValues,
|
||||
jInputPopValues: this.jInputPopValues,
|
||||
slotValues: this.slotValues,
|
||||
uploadValues: this.uploadValues,
|
||||
@ -1626,6 +1718,10 @@
|
||||
edited = true
|
||||
} else if (column.type === FormTypes.date || column.type === FormTypes.datetime) {
|
||||
edited = this.setOneValue(this.jdateValues, modelKey, newValue)
|
||||
} else if (column.type === FormTypes.sel_depart) {
|
||||
edited = this.setOneValue(this.departCompValues, modelKey, newValue)
|
||||
} else if (column.type === FormTypes.sel_user) {
|
||||
edited = this.setOneValue(this.userCompValues, modelKey, newValue)
|
||||
} else if (column.type === FormTypes.input_pop) {
|
||||
edited = this.setOneValue(this.jInputPopValues, modelKey, newValue)
|
||||
} else if (column.type === FormTypes.slot) {
|
||||
@ -1802,7 +1898,7 @@
|
||||
|
||||
// 兼容 online 的规则
|
||||
let foo = [
|
||||
{ title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,18}$/ },
|
||||
{ title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,16}$/ },
|
||||
{ title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/ },
|
||||
{ title: '6到18位字母', value: 's6-18', pattern: /^[a-z|A-Z]{6,18}$/ },
|
||||
{ title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/ },
|
||||
@ -2143,8 +2239,12 @@
|
||||
}
|
||||
target.value = value
|
||||
}
|
||||
// 做单个表单验证
|
||||
this.validateOneInput(value, row, column, this.notPassedIds, true, 'blur')
|
||||
//update--begin--autor:lvdandan-----date:20201126------for:LOWCOD-1088 JEditableTable输入校验提示框位置偏移 #2005
|
||||
setTimeout(()=>{
|
||||
// 做单个表单验证
|
||||
this.validateOneInput(value, row, column, this.notPassedIds, true, 'blur')
|
||||
}, 100)
|
||||
//update--end--autor:lvdandan-----date:20201126------for:LOWCOD-1088 JEditableTable输入校验提示框位置偏移 #2005
|
||||
},
|
||||
handleChangeCheckboxCommon(event, row, column) {
|
||||
let { id, checked } = event.target
|
||||
@ -2172,6 +2272,20 @@
|
||||
this.elemValueChange(FormTypes.date, row, column, value)
|
||||
}
|
||||
},
|
||||
//部门组件值改变
|
||||
handleChangeDepartCommon(value, id, row, column){
|
||||
this.departCompValues = this.bindValuesChange(value, id, 'departCompValues')
|
||||
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
|
||||
// 触发valueChange 事件
|
||||
this.elemValueChange(FormTypes.sel_depart, row, column, value)
|
||||
},
|
||||
//用户组件值改变
|
||||
handleChangeUserCommon(value, id, row, column){
|
||||
this.userCompValues = this.bindValuesChange(value, id, 'userCompValues')
|
||||
this.validateOneInput(value, row, column, this.notPassedIds, true, 'change')
|
||||
// 触发valueChange 事件
|
||||
this.elemValueChange(FormTypes.sel_user, row, column, value)
|
||||
},
|
||||
handleChangeJInputPopCommon(value, id, row, column){
|
||||
this.jInputPopValues = this.bindValuesChange(value, id, 'jInputPopValues')
|
||||
// 做单个表单验证
|
||||
@ -2201,7 +2315,18 @@
|
||||
// 触发valueChange 事件
|
||||
this.elemValueChange(column.type, row, column, value)
|
||||
},
|
||||
handleMoreOperation(id,flag){
|
||||
handleMoreOperation(id,flag,column){
|
||||
//update-begin-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件
|
||||
if(column.number){
|
||||
this.number = column.number;
|
||||
}else{
|
||||
this.number = 0;
|
||||
}
|
||||
//update-end-author:wangshuai date:20201021 for:LOWCOD-969 判断传过来的字段是否存在number,用于控制上传文件
|
||||
if(column && column.fieldExtendJson){
|
||||
let json = JSON.parse(column.fieldExtendJson);
|
||||
this.number = json.uploadnum?json.uploadnum:0;
|
||||
}
|
||||
//console.log("this.uploadValues[id]",this.uploadValues[id])
|
||||
let path = ''
|
||||
if(this.uploadValues && this.uploadValues[id]){
|
||||
@ -2452,6 +2577,19 @@
|
||||
} else {
|
||||
style['width'] = '120px'
|
||||
}
|
||||
//update-begin-author:lvdandan date:20201116 for:LOWCOD-984 默认风格功能测试附表样式问题 日期时间控件长度太大
|
||||
//如果是时间控件设为200px
|
||||
if(col.type === FormTypes.datetime){
|
||||
style['width'] = '200px'
|
||||
}
|
||||
if(col.type === FormTypes.sel_user && !col.width){
|
||||
style['width'] = '220px'
|
||||
}
|
||||
if(col.type === FormTypes.sel_depart && !col.width){
|
||||
style['width'] = '160px'
|
||||
}
|
||||
//update-end-author:lvdandan date:20201116 for:LOWCOD-984 默认风格功能测试附表样式问题 日期时间控件长度太大
|
||||
|
||||
// checkbox 居中显示
|
||||
let isCheckbox = col.type === FormTypes.checkbox
|
||||
if (isCheckbox) {
|
||||
@ -2685,15 +2823,35 @@
|
||||
removeEventListener() {
|
||||
window.removeEventListener('mouseup', this.handleMouseup)
|
||||
},
|
||||
|
||||
/* --------------------------- 2020年5月18日 默认span模式 ------------------------------ */
|
||||
|
||||
//获取没有授权的按钮编码
|
||||
loadExcludeCode(){
|
||||
if(!this.authPre || this.authPre.length==0){
|
||||
this.excludeCode = []
|
||||
}else{
|
||||
let pre = this.authPre
|
||||
if(!pre.endsWith(':')){
|
||||
pre += ':'
|
||||
}
|
||||
this.excludeCode = getNoAuthCols(pre)
|
||||
}
|
||||
},
|
||||
//判断button是否显示
|
||||
buttonPermission(code){
|
||||
if(!this.excludeCode || this.excludeCode.length==0){
|
||||
return true
|
||||
}else{
|
||||
return this.excludeCode.indexOf(code)<0
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.removeEventListener()
|
||||
this.destroyCleanGroupRequest = true
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -3061,4 +3219,4 @@
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -15,10 +15,12 @@
|
||||
@change="handleChange"
|
||||
@preview="handlePreview"
|
||||
:class="!isMultiple?'imgupload':''">
|
||||
<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="height:104px;max-width:300px"/>
|
||||
<div v-else class="iconp">
|
||||
<a-icon :type="uploadLoading ? 'loading' : 'plus'" />
|
||||
<div class="ant-upload-text">{{ text }}</div>
|
||||
<div :style="{'width':(!isMultiple?'104px':'auto'),'height':(!isMultiple?'104px':'auto')}">
|
||||
<img v-if="!isMultiple && picUrl" :src="getAvatarView()" style="width:100%;height:100%"/>
|
||||
<div v-else class="iconp">
|
||||
<a-icon :type="uploadLoading ? 'loading' : 'plus'" />
|
||||
<div class="ant-upload-text">{{ text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel()">
|
||||
<img alt="example" style="width: 100%" :src="previewImage"/>
|
||||
@ -80,18 +82,29 @@
|
||||
type:Boolean,
|
||||
required:false,
|
||||
default: false
|
||||
},
|
||||
//update-begin-author:wangshuai date:20201021 for:LOWCOD-969 新增number属性,用于判断上传数量
|
||||
number:{
|
||||
type:Number,
|
||||
required:false,
|
||||
default:0
|
||||
}
|
||||
//update-end-author:wangshuai date:20201021 for:LOWCOD-969 新增number属性,用于判断上传数量
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if (val instanceof Array) {
|
||||
this.initFileList(val.join(','))
|
||||
} else {
|
||||
this.initFileList(val)
|
||||
}
|
||||
if(!val || val.length==0){
|
||||
this.picUrl = false;
|
||||
}
|
||||
value: {
|
||||
handler(val,oldValue) {
|
||||
if (val instanceof Array) {
|
||||
this.initFileList(val.join(','))
|
||||
} else {
|
||||
this.initFileList(val)
|
||||
}
|
||||
if(!val || val.length==0){
|
||||
this.picUrl = false;
|
||||
}
|
||||
},
|
||||
//立刻执行handler
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
created(){
|
||||
@ -132,6 +145,11 @@
|
||||
handleChange(info) {
|
||||
this.picUrl = false;
|
||||
let fileList = info.fileList
|
||||
//update-begin-author:wangshuai date:20201022 for:LOWCOD-969 判断number是否大于0和是否多选,返回选定的元素。
|
||||
if(this.number>0 && this.isMultiple){
|
||||
fileList = fileList.slice(-this.number);
|
||||
}
|
||||
//update-end-author:wangshuai date:20201022 for:LOWCOD-969 判断number是否大于0和是否多选,返回选定的元素。
|
||||
if(info.file.status==='done'){
|
||||
if(info.file.response.success){
|
||||
this.picUrl = true;
|
||||
@ -217,4 +235,4 @@
|
||||
/deep/ .imgupload .ant-upload.ant-upload-select-picture-card{ width:120px;height: 120px;}
|
||||
/deep/ .imgupload .iconp{padding:32px;}
|
||||
/* update--end--autor:lvdandan-----date:20201016------for:j-image-upload图片组件单张图片详情回显空白*/
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -21,7 +21,6 @@ export default {
|
||||
'outdent',
|
||||
'divider',
|
||||
'table',
|
||||
'image',
|
||||
'link',
|
||||
'divider',
|
||||
'code',
|
||||
|
||||
@ -1,5 +1,28 @@
|
||||
<template>
|
||||
<div class="j-markdown-editor" :id="id"/>
|
||||
<div>
|
||||
<div class="j-markdown-editor" :id="id"/>
|
||||
<div v-if="isShow">
|
||||
<j-modal
|
||||
title="图片上传"
|
||||
:visible.sync="dialogVisible"
|
||||
width="30%"
|
||||
:before-close="handleClose"
|
||||
@ok="handleOk">
|
||||
<a-tabs default-active-key="1" @change="handleChange">
|
||||
<a-tab-pane tab="本地图片上传" key="1" :forceRender="true">
|
||||
<j-upload v-model="fileList" :number="1"></j-upload>
|
||||
<div style="margin-top: 20px">
|
||||
<a-input v-model="remark" placeholder="请填写备注"></a-input>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="网络图片地址" key="2" :forceRender="true">
|
||||
<a-input v-model="networkPic" placeholder="请填写网络图片地址"></a-input>
|
||||
<a-input style="margin-top: 20px" v-model="remark" placeholder="请填写备注"></a-input>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</j-modal>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@ -9,9 +32,14 @@ import '@toast-ui/editor/dist/i18n/zh-cn';
|
||||
|
||||
import Editor from '@toast-ui/editor';
|
||||
import defaultOptions from './default-options'
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import { getFileAccessHttpUrl } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
name: 'JMarkdownEditor',
|
||||
components: {
|
||||
JUpload,
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
@ -47,7 +75,16 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: null
|
||||
editor: null,
|
||||
isShow:false,
|
||||
activeIndex:"1",
|
||||
dialogVisible:false,
|
||||
index:"1",
|
||||
fileList:[],
|
||||
remark:"",
|
||||
imageName:"",
|
||||
imageUrl:"",
|
||||
networkPic:""
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -94,6 +131,40 @@ export default {
|
||||
this.editor.on('change', () => {
|
||||
this.$emit('change', this.editor.getMarkdown())
|
||||
})
|
||||
//--begin 添加自定义上传按钮
|
||||
/*
|
||||
* 添加自定义按钮
|
||||
*/
|
||||
//获取编辑器上的功能条
|
||||
let toolbar = this.editor.getUI().getToolbar();
|
||||
let fileDom = this.$refs.files;
|
||||
//添加图片点击事件
|
||||
this.editor.eventManager.addEventType('isShowClickEvent');
|
||||
this.editor.eventManager.listen('isShowClickEvent', () => {
|
||||
this.isShow = true
|
||||
this.dialogVisible = true
|
||||
});
|
||||
//addImageBlobHook图片上传、剪切、拖拽都会走此方法
|
||||
// 删除默认监听事件
|
||||
this.editor.eventManager.removeEventHandler('addImageBlobHook')
|
||||
// 添加自定义监听事件
|
||||
this.editor.eventManager.listen('addImageBlobHook', (blob, callback) => {
|
||||
this.upload(blob, url => {
|
||||
callback(url)
|
||||
})
|
||||
})
|
||||
// 添加自定义按钮 第二个参数代表位置,不传默认放在最后
|
||||
toolbar.insertItem(15,{
|
||||
type: 'button',
|
||||
options:{
|
||||
name: 'customize',
|
||||
className: 'tui-image tui-toolbar-icons',
|
||||
event: 'isShowClickEvent',
|
||||
tooltip: '上传图片',
|
||||
}
|
||||
//
|
||||
});
|
||||
//--end 添加自定义上传按钮
|
||||
},
|
||||
destroyEditor() {
|
||||
if (!this.editor) return
|
||||
@ -111,7 +182,57 @@ export default {
|
||||
},
|
||||
getHtml() {
|
||||
return this.editor.getHtml()
|
||||
}
|
||||
},
|
||||
handleOk(){
|
||||
if(this.index=='1'){
|
||||
this.imageUrl = getFileAccessHttpUrl(this.fileList)
|
||||
if(this.remark){
|
||||
this.addImgToMd(this.imageUrl,this.remark)
|
||||
}else{
|
||||
this.addImgToMd(this.imageUrl,"")
|
||||
}
|
||||
}else{
|
||||
if(this.remark){
|
||||
this.addImgToMd(this.networkPic,this.remark)
|
||||
}else{
|
||||
this.addImgToMd(this.networkPic,"")
|
||||
}
|
||||
}
|
||||
this.index="1"
|
||||
this.fileList=[]
|
||||
this.imageName="";
|
||||
this.imageUrl="";
|
||||
this.remark=""
|
||||
this.networkPic=""
|
||||
this.dialogVisible=false
|
||||
this.isShow=false;
|
||||
},
|
||||
handleClose(done) {
|
||||
done();
|
||||
},
|
||||
handleChange(val){
|
||||
this.fileList=[]
|
||||
this.remark=""
|
||||
this.imageName=""
|
||||
this.imageUrl=""
|
||||
this.networkPic=""
|
||||
this.index=val
|
||||
},
|
||||
//添加图片到markdown
|
||||
addImgToMd(data,name) {
|
||||
let editor = this.editor.getCodeMirror();
|
||||
let editorHtml = this.editor.getCurrentModeEditor();
|
||||
let isMarkdownMode = this.editor.isMarkdownMode();
|
||||
if (isMarkdownMode) {
|
||||
editor.replaceSelection(``);
|
||||
} else {
|
||||
let range = editorHtml.getRange();
|
||||
let img = document.createElement('img');
|
||||
img.src = `${data}`;
|
||||
img.alt = name;
|
||||
range.insertNode(img);
|
||||
}
|
||||
},
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
:code="code"
|
||||
:multi="multi"
|
||||
:groupId="uniqGroupId"
|
||||
:param="param"
|
||||
@ok="callBack"
|
||||
/>
|
||||
|
||||
@ -75,6 +76,17 @@
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
//popup动态参数 支持系统变量语法
|
||||
param:{
|
||||
type: Object,
|
||||
required: false,
|
||||
default: ()=>{}
|
||||
},
|
||||
spliter:{
|
||||
type: String,
|
||||
required: false,
|
||||
default: ','
|
||||
},
|
||||
/** 分组ID,用于将多个popup的请求合并到一起,不传不分组 */
|
||||
groupId: String
|
||||
|
||||
@ -101,7 +113,7 @@
|
||||
if (!val) {
|
||||
this.showText = ''
|
||||
} else {
|
||||
this.showText = val
|
||||
this.showText = val.split(this.spliter).join(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,7 +193,11 @@
|
||||
} else {
|
||||
//v-model时 需要传一个参数field 表示当前这个字段 从而根据这个字段的顺序找到原始值
|
||||
// this.$emit("input",row[orgFieldsArr[destFieldsArr.indexOf(this.field)]])
|
||||
this.$emit('input', this.showText, res)
|
||||
let str = ''
|
||||
if(this.showText){
|
||||
str = this.showText.split(',').join(this.spliter)
|
||||
}
|
||||
this.$emit('input', str, res)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
<a-select-option
|
||||
v-for="(item,index) in options"
|
||||
:key="index"
|
||||
:getPopupContainer="getParentContainer"
|
||||
:value="item.value">
|
||||
{{ item.text || item.label }}
|
||||
</a-select-option>
|
||||
@ -36,11 +37,21 @@
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
spliter:{
|
||||
type: String,
|
||||
required: false,
|
||||
default: ','
|
||||
},
|
||||
popContainer:{
|
||||
type:String,
|
||||
default:'',
|
||||
required:false
|
||||
},
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
arrayValue:!this.value?[]:this.value.split(",")
|
||||
arrayValue:!this.value?[]:this.value.split(this.spliter)
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
@ -48,18 +59,25 @@
|
||||
if(!val){
|
||||
this.arrayValue = []
|
||||
}else{
|
||||
this.arrayValue = this.value.split(",")
|
||||
this.arrayValue = this.value.split(this.spliter)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
onChange (selectedValue) {
|
||||
if(this.triggerChange){
|
||||
this.$emit('change', selectedValue.join(","));
|
||||
this.$emit('change', selectedValue.join(this.spliter));
|
||||
}else{
|
||||
this.$emit('input', selectedValue.join(","));
|
||||
this.$emit('input', selectedValue.join(this.spliter));
|
||||
}
|
||||
},
|
||||
getParentContainer(node){
|
||||
if(!this.popContainer){
|
||||
return node.parentNode
|
||||
}else{
|
||||
return document.querySelector(this.popContainer)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@ -101,7 +101,15 @@
|
||||
</a-col>
|
||||
|
||||
<a-col :md="8" :xs="24" style="margin-bottom: 12px;">
|
||||
<template v-if="item.dictCode">
|
||||
<!-- 下拉搜索 -->
|
||||
<j-search-select-tag v-if="item.type==='sel_search'" v-model="item.val" :dict="getDictInfo(item)" placeholder="请选择"/>
|
||||
<!-- 下拉多选 -->
|
||||
<template v-else-if="item.type==='list_multi'">
|
||||
<j-multi-select-tag v-if="item.options" v-model="item.val" :options="item.options" placeholder="请选择"/>
|
||||
<j-multi-select-tag v-else v-model="item.val" :dictCode="getDictInfo(item)" placeholder="请选择"/>
|
||||
</template>
|
||||
|
||||
<template v-else-if="item.dictCode">
|
||||
<template v-if="item.type === 'table-dict'">
|
||||
<j-popup
|
||||
v-model="item.val"
|
||||
@ -109,6 +117,7 @@
|
||||
:field="item.dictCode"
|
||||
:orgFields="item.dictCode"
|
||||
:destFields="item.dictCode"
|
||||
:multi="true"
|
||||
></j-popup>
|
||||
</template>
|
||||
<template v-else>
|
||||
@ -116,7 +125,13 @@
|
||||
<j-dict-select-tag v-show="!allowMultiple(item)" v-model="item.val" :dictCode="item.dictCode" placeholder="请选择"/>
|
||||
</template>
|
||||
</template>
|
||||
<j-popup v-else-if="item.type === 'popup'" :value="item.val" v-bind="item.popup" group-id="superQuery" @input="(e,v)=>handleChangeJPopup(item,e,v)"/>
|
||||
<j-popup
|
||||
v-else-if="item.type === 'popup'"
|
||||
:value="item.val"
|
||||
v-bind="item.popup"
|
||||
group-id="superQuery"
|
||||
@input="(e,v)=>handleChangeJPopup(item,e,v)"
|
||||
:multi="true"/>
|
||||
<j-select-multi-user
|
||||
v-else-if="item.type === 'select-user' || item.type === 'sel_user'"
|
||||
v-model="item.val"
|
||||
@ -338,6 +353,17 @@
|
||||
}
|
||||
this.visible = true
|
||||
},
|
||||
|
||||
getDictInfo(item) {
|
||||
let str = ''
|
||||
if(!item.dictTable){
|
||||
str = item.dictCode
|
||||
}else{
|
||||
str = item.dictTable+','+item.dictText+','+item.dictCode
|
||||
}
|
||||
console.log('高级查询字典信息',str)
|
||||
return str
|
||||
},
|
||||
handleOk() {
|
||||
if (!this.isNullArray(this.queryParamsModel)) {
|
||||
let event = {
|
||||
@ -386,11 +412,12 @@
|
||||
this.queryParamsModel.splice(index, 1)
|
||||
},
|
||||
handleSelected(node, item) {
|
||||
let { type, options, dictCode, dictTable, customReturnField, popup } = node.dataRef
|
||||
let { type, options, dictCode, dictTable, dictText, customReturnField, popup } = node.dataRef
|
||||
item['type'] = type
|
||||
item['options'] = options
|
||||
item['dictCode'] = dictCode
|
||||
item['dictTable'] = dictTable
|
||||
item['dictText'] = dictText
|
||||
item['customReturnField'] = customReturnField
|
||||
if (popup) {
|
||||
item['popup'] = popup
|
||||
|
||||
@ -374,14 +374,17 @@
|
||||
},
|
||||
mounted(){
|
||||
const moverObj = document.getElementById(this.containerId+'-mover');
|
||||
moverObj.addEventListener('mouseover',()=>{
|
||||
this.moverHold = true
|
||||
this.moveDisplay = 'block';
|
||||
});
|
||||
moverObj.addEventListener('mouseout',()=>{
|
||||
this.moverHold = false
|
||||
this.moveDisplay = 'none';
|
||||
});
|
||||
if(moverObj){
|
||||
moverObj.addEventListener('mouseover',()=>{
|
||||
this.moverHold = true
|
||||
this.moveDisplay = 'block';
|
||||
});
|
||||
moverObj.addEventListener('mouseout',()=>{
|
||||
this.moverHold = false
|
||||
this.moveDisplay = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
let picList = document.getElementById(this.containerId)?document.getElementById(this.containerId).getElementsByClassName('ant-upload-list-picture-card'):[];
|
||||
if(picList && picList.length>0){
|
||||
picList[0].addEventListener('mouseover',(ev)=>{
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-popover :visible="visible" placement="bottom" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle">
|
||||
<a-popover :visible="visible" :placement="placement" overlayClassName="j-vxe-popover-overlay" :overlayStyle="overlayStyle">
|
||||
<div class="j-vxe-popover-title" slot="title">
|
||||
<div>子表</div>
|
||||
<div class="j-vxe-popover-title-close" @click="close">
|
||||
@ -34,6 +34,7 @@
|
||||
width: null,
|
||||
zIndex: 100
|
||||
},
|
||||
placement: 'bottom'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -41,6 +42,14 @@
|
||||
methods: {
|
||||
|
||||
toggle(event) {
|
||||
|
||||
//update-begin-author:taoyan date:20200921 for: 弹出子表时,子表会闪一下,类似重新计算子表的位置
|
||||
if(document.body.clientHeight - event.$event.clientY > 350){
|
||||
this.placement = 'bottom'
|
||||
}else{
|
||||
this.placement = 'top'
|
||||
}
|
||||
//update-end-author:taoyan date:20200921 for: 弹出子表时,子表会闪一下,类似重新计算子表的位置
|
||||
if (this.row == null) {
|
||||
this.open(event)
|
||||
} else {
|
||||
@ -83,13 +92,22 @@
|
||||
this.$refs.div.style.height = clientHeight + 'px'
|
||||
this.overlayStyle.width = Number.parseInt((clientWidth - clientWidth * 0.04)) + 'px'
|
||||
this.overlayStyle.maxWidth = this.overlayStyle.width
|
||||
domAlign(this.$refs.div, tr, {
|
||||
//update-begin-author:taoyan date:20200921 for: 子表弹出位置存在现实位置问题。
|
||||
//let realTable = getParentNodeByTagName(tr, 'table')
|
||||
//let left = realTable.parentNode.scrollLeft
|
||||
let h = event.$event.clientY
|
||||
if(h){
|
||||
h = h-140
|
||||
}
|
||||
let toolbar = this.$refs.div.nextSibling
|
||||
domAlign(this.$refs.div, toolbar, {
|
||||
points: ['tl', 'tl'],
|
||||
offset: [0, 0],
|
||||
offset: [0, h],
|
||||
overflow: {
|
||||
alwaysByViewport: true
|
||||
},
|
||||
})
|
||||
//update-end-author:taoyan date:20200921 for: 子表弹出位置存在现实位置问题。
|
||||
this.$nextTick(() => {
|
||||
this.visible = true
|
||||
this.$nextTick(() => {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import XEUtils from 'xe-utils'
|
||||
import PropTypes from 'ant-design-vue/es/_util/vue-types'
|
||||
import { JVXETypes } from '@/components/jeecg/JVxeTable/index'
|
||||
import { JVXETypes } from '@/components/jeecg/JVxeTable/jvxeTypes'
|
||||
import VxeWebSocketMixins from '../mixins/vxe.web.socket.mixins'
|
||||
import { initDictOptions } from '@/components/dict/JDictSelectUtil'
|
||||
|
||||
@ -181,6 +181,28 @@ export default {
|
||||
if (column.cellRender) {
|
||||
Object.assign(column.cellRender, renderOptions)
|
||||
}
|
||||
// update--begin--autor:lvdandan-----date:20201019------for:LOWCOD-882 【新行编辑】列表上带按钮的遮挡问题
|
||||
if (column.$type === JVXETypes.file || column.$type === JVXETypes.image) {
|
||||
if (column.width && column.width.endsWith('px')) {
|
||||
column.width = Number.parseInt(column.width.substr(0,column.width.length-2))+Number.parseInt(1)+'px';
|
||||
}
|
||||
}
|
||||
// update--begin--autor:lvdandan-----date:20201019------for:LOWCOD-882 【新行编辑】列表上带按钮的遮挡问题
|
||||
|
||||
// update--begin--autor:lvdandan-----date:20201211------for:JT-118 【online】 日期、时间控件长度较小
|
||||
if (column.$type === JVXETypes.datetime || column.$type === JVXETypes.userSelect || column.$type === JVXETypes.departSelect) {
|
||||
let width = column.width && column.width.endsWith('px')?Number.parseInt(column.width.substr(0,column.width.length-2)):0;
|
||||
if(width <= 190){
|
||||
column.width = '190px'
|
||||
}
|
||||
}
|
||||
if (column.$type === JVXETypes.date) {
|
||||
let width = column.width && column.width.endsWith('px')?Number.parseInt(column.width.substr(0,column.width.length-2)):0;
|
||||
if(width <= 135){
|
||||
column.width = '135px'
|
||||
}
|
||||
}
|
||||
// update--end--autor:lvdandan-----date:20201211------for:JT-118 【online】 日期、时间控件长度较小
|
||||
})
|
||||
return this._innerColumns
|
||||
},
|
||||
@ -702,6 +724,11 @@ export default {
|
||||
deleteData: this.getDeleteData()
|
||||
}
|
||||
},
|
||||
/** 获取表格表单里的值 */
|
||||
getValues(callback, rowIds) {
|
||||
let tableData = this.getTableData({rowIds: rowIds})
|
||||
callback('', tableData)
|
||||
},
|
||||
/** 获取表格数据 */
|
||||
getTableData(options = {}) {
|
||||
let {rowIds} = options
|
||||
@ -727,6 +754,11 @@ export default {
|
||||
newData.forEach(row => delete row.id)
|
||||
return newData
|
||||
},
|
||||
/** 仅获取新增的数据,带有id */
|
||||
getNewDataWithId() {
|
||||
let newData = cloneObject(this.$refs.vxe.getInsertRecords())
|
||||
return newData
|
||||
},
|
||||
/** 根据ID获取行,新增的行也能查出来 */
|
||||
getIfRowById(id) {
|
||||
let row = this.getRowById(id), isNew = false
|
||||
@ -760,8 +792,8 @@ export default {
|
||||
* @param rows
|
||||
* @return
|
||||
*/
|
||||
async addRows(rows = {}) {
|
||||
return this._addOrInsert(rows, -1, 'added')
|
||||
async addRows(rows = {}, isOnlJs) {
|
||||
return this._addOrInsert(rows, -1, 'added', isOnlJs)
|
||||
},
|
||||
|
||||
/**
|
||||
@ -852,6 +884,8 @@ export default {
|
||||
trigger(name, event = {}) {
|
||||
event.$target = this
|
||||
event.$table = this.$refs.vxe
|
||||
//online增强参数兼容
|
||||
event.target = this
|
||||
this.$emit(name, event)
|
||||
},
|
||||
|
||||
@ -873,7 +907,11 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//options自定义赋值 刷新
|
||||
virtualRefresh(){
|
||||
this.scrolling = true
|
||||
this.closeScrolling()
|
||||
},
|
||||
// 设置 this.scrolling 防抖模式
|
||||
closeScrolling: simpleDebounce(function () {
|
||||
this.scrolling = false
|
||||
@ -1005,7 +1043,7 @@ export default {
|
||||
return await xTable.updateData()
|
||||
},
|
||||
|
||||
async _addOrInsert(rows = {}, index, triggerName) {
|
||||
async _addOrInsert(rows = {}, index, triggerName, isOnlJs) {
|
||||
let {xTable} = this.$refs.vxe.$refs
|
||||
let records
|
||||
if (Array.isArray(rows)) {
|
||||
@ -1017,14 +1055,19 @@ export default {
|
||||
records.forEach(record => this._createRow(record))
|
||||
let result = await this.pushRows(records, {index: index, setActive: true})
|
||||
// 遍历插入的行
|
||||
for (let i = 0; i < result.rows.length; i++) {
|
||||
let row = result.rows[i]
|
||||
this.trigger(triggerName, {
|
||||
row: row,
|
||||
$table: xTable,
|
||||
target: this,
|
||||
})
|
||||
// update--begin--autor:lvdandan-----date:20201117------for:LOWCOD-987 【新行编辑】js增强附表内置方法调用问题 #1819
|
||||
// online js增强时以传过来值为准,不再赋默认值
|
||||
if (isOnlJs != true) {
|
||||
for (let i = 0; i < result.rows.length; i++) {
|
||||
let row = result.rows[i]
|
||||
this.trigger(triggerName, {
|
||||
row: row,
|
||||
$table: xTable,
|
||||
target: this,
|
||||
})
|
||||
}
|
||||
}
|
||||
// update--end--autor:lvdandan-----date:20201117------for:LOWCOD-987 【新行编辑】js增强附表内置方法调用问题 #1819
|
||||
return result
|
||||
},
|
||||
// 创建新行,自动添加默认值
|
||||
@ -1035,7 +1078,7 @@ export default {
|
||||
let col = column.own
|
||||
if (record[col.key] == null || record[col.key] === '') {
|
||||
// 设置默认值
|
||||
let createValue = getEnhancedMixins(col.$type, 'createValue')
|
||||
let createValue = getEnhancedMixins(col.$type || col.type, 'createValue')
|
||||
record[col.key] = createValue({row: record, column, $table: xTable})
|
||||
}
|
||||
})
|
||||
@ -1184,7 +1227,7 @@ export default {
|
||||
// 兼容 online 的规则
|
||||
const fooPatterns = [
|
||||
{title: '非空', value: '*', pattern: /^.+$/},
|
||||
{title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,18}$/},
|
||||
{title: '6到16位数字', value: 'n6-16', pattern: /^\d{6,16}$/},
|
||||
{title: '6到16位任意字符', value: '*6-16', pattern: /^.{6,16}$/},
|
||||
{title: '6到18位字母', value: 's6-18', pattern: /^[a-z|A-Z]{6,18}$/},
|
||||
{title: '网址', value: 'url', pattern: /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/},
|
||||
|
||||
@ -59,7 +59,7 @@
|
||||
// TODO 需要将remove替换batch_delete
|
||||
// 系统默认的批量删除编码配置为 batch_delete 此处需要转化一下
|
||||
if(exclude.indexOf('batch_delete')>=0){
|
||||
exclude.add('remove')
|
||||
exclude.push('remove')
|
||||
}
|
||||
// 按钮权限 需要去掉不被授权的按钮
|
||||
return arr.filter(item=>{
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-input
|
||||
v-show="!departIds"
|
||||
@click="openSelect"
|
||||
placeholder="请点击选择部门"
|
||||
v-model="departNames"
|
||||
readOnly
|
||||
:disabled="componentDisabled"
|
||||
class="jvxe-select-input">
|
||||
<a-icon slot="prefix" type="cluster" title="部门选择控件"/>
|
||||
</a-input>
|
||||
<j-select-depart-modal
|
||||
ref="innerDepartSelectModal"
|
||||
:modal-width="modalWidth"
|
||||
:multi="multi"
|
||||
:rootOpened="rootOpened"
|
||||
:depart-id="departIds"
|
||||
@ok="handleOK"
|
||||
@initComp="initComp"/>
|
||||
<span style="display: inline-block;height:100%;padding-left:14px" v-if="departIds" >
|
||||
<span @click="openSelect" style="display: inline-block;vertical-align: middle">{{ departNames }}</span>
|
||||
<a-icon style="margin-left:5px;vertical-align: middle" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
|
||||
import JSelectDepartModal from '@/components/jeecgbiz/modal/JSelectDepartModal'
|
||||
|
||||
export default {
|
||||
name: 'JVxeDepartSelectCell',
|
||||
mixins: [JVxeCellMixins],
|
||||
components:{
|
||||
JSelectDepartModal
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
departNames: '',
|
||||
departIds: '',
|
||||
selectedOptions: [],
|
||||
customReturnField: 'id'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
custProps() {
|
||||
const {departIds, originColumn: col, caseId, cellProps} = this
|
||||
return {
|
||||
...cellProps,
|
||||
value: departIds,
|
||||
field: col.field || col.key,
|
||||
groupId: caseId,
|
||||
class: 'jvxe-select'
|
||||
}
|
||||
},
|
||||
componentDisabled(){
|
||||
if(this.cellProps.disabled==true){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
modalWidth(){
|
||||
if(this.cellProps.modalWidth){
|
||||
return this.cellProps.modalWidth
|
||||
}else{
|
||||
return 500
|
||||
}
|
||||
},
|
||||
multi(){
|
||||
if(this.cellProps.multi==false){
|
||||
return false
|
||||
}else{
|
||||
return true
|
||||
}
|
||||
},
|
||||
rootOpened(){
|
||||
if(this.cellProps.open==false){
|
||||
return false
|
||||
}else{
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
innerValue: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
if (val == null || val === '') {
|
||||
this.departIds = ''
|
||||
} else {
|
||||
this.departIds = val
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openSelect(){
|
||||
this.$refs.innerDepartSelectModal.show()
|
||||
},
|
||||
handleEmpty(){
|
||||
this.handleOK('')
|
||||
},
|
||||
handleOK(rows, idstr) {
|
||||
let value = ''
|
||||
if (!rows && rows.length <= 0) {
|
||||
this.departNames = ''
|
||||
this.departIds = ''
|
||||
} else {
|
||||
value = rows.map(row => row[this.customReturnField]).join(',')
|
||||
this.departNames = rows.map(row => row['departName']).join(',')
|
||||
this.departIds = idstr
|
||||
}
|
||||
this.handleChangeCommon(this.departIds)
|
||||
},
|
||||
initComp(departNames){
|
||||
this.departNames = departNames
|
||||
},
|
||||
handleChange(value) {
|
||||
this.handleChangeCommon(value)
|
||||
}
|
||||
},
|
||||
enhanced: {
|
||||
switches: {
|
||||
visible: true
|
||||
},
|
||||
translate: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/ .jvxe-select-input .ant-input{
|
||||
border: none !important;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-input
|
||||
v-show="!userIds"
|
||||
@click="openSelect"
|
||||
placeholder="请选择用户"
|
||||
v-model="userNames"
|
||||
readOnly
|
||||
class="jvxe-select-input"
|
||||
:disabled="componentDisabled">
|
||||
<a-icon slot="prefix" type="user" title="用户选择控件"/>
|
||||
</a-input>
|
||||
<j-select-user-by-dep-modal
|
||||
ref="selectModal"
|
||||
:modal-width="modalWidth"
|
||||
:multi="multi"
|
||||
:user-ids="userIds"
|
||||
@ok="selectOK"
|
||||
@initComp="initComp"/>
|
||||
<span style="display: inline-block;height:100%;padding-left:14px" v-if="userIds" >
|
||||
<span @click="openSelect" style="display: inline-block;vertical-align: middle">{{ userNames }}</span>
|
||||
<a-icon style="margin-left:5px;vertical-align: middle" type="close-circle" @click="handleEmpty" title="清空"/>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- <j-select-user-by-dep
|
||||
v-bind="custProps"
|
||||
@change="handleChange"
|
||||
:trigger-change="true">
|
||||
</j-select-user-by-dep>-->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JVxeCellMixins, { dispatchEvent } from '@/components/jeecg/JVxeTable/mixins/JVxeCellMixins'
|
||||
import JSelectUserByDepModal from '@/components/jeecgbiz/modal/JSelectUserByDepModal'
|
||||
|
||||
export default {
|
||||
name: 'JVxeUserSelectCell',
|
||||
mixins: [JVxeCellMixins],
|
||||
components: { JSelectUserByDepModal },
|
||||
data() {
|
||||
return {
|
||||
userIds:'',
|
||||
userNames:'',
|
||||
innerUserValue: '',
|
||||
selectedOptions: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
custProps() {
|
||||
const {userIds, originColumn: col, caseId, cellProps} = this
|
||||
return {
|
||||
...cellProps,
|
||||
value: userIds,
|
||||
field: col.field || col.key,
|
||||
groupId: caseId,
|
||||
class: 'jvxe-select'
|
||||
}
|
||||
},
|
||||
componentDisabled(){
|
||||
console.log('333',this.cellProps)
|
||||
if(this.cellProps.disabled==true){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
modalWidth(){
|
||||
if(this.cellProps.modalWidth){
|
||||
return this.cellProps.modalWidth
|
||||
}else{
|
||||
return 1250
|
||||
}
|
||||
},
|
||||
multi(){
|
||||
if(this.cellProps.multi==false){
|
||||
return false
|
||||
}else{
|
||||
return true
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
innerValue: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
if (val == null || val === '') {
|
||||
this.userIds = ''
|
||||
} else {
|
||||
this.userIds = val
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openSelect() {
|
||||
this.$refs.selectModal.showModal()
|
||||
},
|
||||
selectOK(rows, idstr) {
|
||||
console.log("当前选中用户", rows)
|
||||
console.log("当前选中用户ID", idstr)
|
||||
if (!rows) {
|
||||
this.userNames = ''
|
||||
this.userIds = ''
|
||||
} else {
|
||||
let temp = ''
|
||||
for (let item of rows) {
|
||||
temp += ',' + item.realname
|
||||
}
|
||||
this.userNames = temp.substring(1)
|
||||
this.userIds = idstr
|
||||
}
|
||||
this.handleChangeCommon(this.userIds)
|
||||
},
|
||||
handleEmpty(){
|
||||
this.selectOK('')
|
||||
},
|
||||
initComp(userNames) {
|
||||
this.userNames = userNames
|
||||
},
|
||||
},
|
||||
enhanced: {
|
||||
switches: {
|
||||
visible: true
|
||||
},
|
||||
translate: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/deep/ .jvxe-select-input .ant-input {
|
||||
border: none !important;
|
||||
}
|
||||
</style>
|
||||
@ -1,3 +1,4 @@
|
||||
import * as jvxeTypes from './jvxeTypes'
|
||||
import { installCell, mapCell } from './install'
|
||||
import JVxeTable from './components/JVxeTable'
|
||||
|
||||
@ -12,46 +13,13 @@ import { TagsInputCell, TagsSpanCell } from './components/cells/JVxeTagsCell'
|
||||
import JVxeProgressCell from './components/cells/JVxeProgressCell'
|
||||
import JVxeTextareaCell from './components/cells/JVxeTextareaCell'
|
||||
import JVxeDragSortCell from './components/cells/JVxeDragSortCell'
|
||||
import JVxeDepartSelectCell from './components/cells/JVxeDepartSelectCell'
|
||||
import JVxeUserSelectCell from './components/cells/JVxeUserSelectCell'
|
||||
|
||||
//update--begin--autor:lvdandan-----date:20201216------for:JVxeTable--JVXETypes 【online】代码结构调整,便于online打包
|
||||
// 组件类型
|
||||
export const JVXETypes = {
|
||||
// 为了防止和 vxe 内置的类型冲突,所以加上一个前缀
|
||||
// 前缀是自动加的,代码中直接用就行(JVXETypes.input)
|
||||
_prefix: 'j-',
|
||||
|
||||
// 行号列
|
||||
rowNumber: 'row-number',
|
||||
// 选择列
|
||||
rowCheckbox: 'row-checkbox',
|
||||
// 单选列
|
||||
rowRadio: 'row-radio',
|
||||
// 展开列
|
||||
rowExpand: 'row-expand',
|
||||
// 上下排序
|
||||
rowDragSort: 'row-drag-sort',
|
||||
|
||||
input: 'input',
|
||||
inputNumber: 'inputNumber',
|
||||
textarea: 'textarea',
|
||||
select: 'select',
|
||||
date: 'date',
|
||||
datetime: 'datetime',
|
||||
checkbox: 'checkbox',
|
||||
upload: 'upload',
|
||||
// 下拉搜索
|
||||
selectSearch: 'select-search',
|
||||
// 下拉多选
|
||||
selectMultiple: 'select-multiple',
|
||||
// 进度条
|
||||
progress: 'progress',
|
||||
|
||||
// 拖轮Tags(暂无用)
|
||||
tags: 'tags',
|
||||
|
||||
slot: 'slot',
|
||||
normal: 'normal',
|
||||
hidden: 'hidden',
|
||||
}
|
||||
export const JVXETypes = jvxeTypes.JVXETypes
|
||||
//update--end--autor:lvdandan-----date:20201216------for:JVxeTable--JVXETypes 【online】代码结构调整,便于online打包
|
||||
|
||||
// 注册自定义组件
|
||||
export const AllCells = {
|
||||
@ -72,6 +40,8 @@ export const AllCells = {
|
||||
|
||||
...mapCell(JVXETypes.rowDragSort, JVxeDragSortCell),
|
||||
...mapCell(JVXETypes.slot, JVxeSlotCell),
|
||||
...mapCell(JVXETypes.departSelect, JVxeDepartSelectCell),
|
||||
...mapCell(JVXETypes.userSelect, JVxeUserSelectCell)
|
||||
|
||||
/* hidden 是特殊的组件,不在这里注册 */
|
||||
}
|
||||
|
||||
@ -62,8 +62,8 @@ VXETable.interceptor.add('event.clearActived', function (params, event, target)
|
||||
if (className.includes('j-input-pop')) {
|
||||
return false
|
||||
}
|
||||
// 点击的标签是JPopup的弹出层
|
||||
if (className.includes('j-popup-modal')) {
|
||||
// 点击的标签是JPopup的弹出层、部门选择、用户选择
|
||||
if (className.includes('j-popup-modal') || className.includes('j-depart-select-modal') || className.includes('j-user-select-modal')) {
|
||||
return false
|
||||
}
|
||||
// 执行增强
|
||||
|
||||
@ -0,0 +1,44 @@
|
||||
// 组件类型
|
||||
export default JVXETypes
|
||||
export const JVXETypes = {
|
||||
// 为了防止和 vxe 内置的类型冲突,所以加上一个前缀
|
||||
// 前缀是自动加的,代码中直接用就行(JVXETypes.input)
|
||||
_prefix: 'j-',
|
||||
|
||||
// 行号列
|
||||
rowNumber: 'row-number',
|
||||
// 选择列
|
||||
rowCheckbox: 'row-checkbox',
|
||||
// 单选列
|
||||
rowRadio: 'row-radio',
|
||||
// 展开列
|
||||
rowExpand: 'row-expand',
|
||||
// 上下排序
|
||||
rowDragSort: 'row-drag-sort',
|
||||
|
||||
input: 'input',
|
||||
inputNumber: 'inputNumber',
|
||||
textarea: 'textarea',
|
||||
select: 'select',
|
||||
date: 'date',
|
||||
datetime: 'datetime',
|
||||
checkbox: 'checkbox',
|
||||
upload: 'upload',
|
||||
// 下拉搜索
|
||||
selectSearch: 'select-search',
|
||||
// 下拉多选
|
||||
selectMultiple: 'select-multiple',
|
||||
// 进度条
|
||||
progress: 'progress',
|
||||
//部门选择
|
||||
departSelect: 'sel_depart',
|
||||
//用户选择
|
||||
userSelect: 'sel_user',
|
||||
|
||||
// 拖轮Tags(暂无用)
|
||||
tags: 'tags',
|
||||
|
||||
slot: 'slot',
|
||||
normal: 'normal',
|
||||
hidden: 'hidden',
|
||||
}
|
||||
@ -149,6 +149,8 @@ export default {
|
||||
packageEvent(name, event = {}) {
|
||||
event.row = this.row
|
||||
event.column = this.column
|
||||
//online增强参数兼容
|
||||
event.column['key'] = this.column['property']
|
||||
event.cellTarget = this
|
||||
if (!event.type) {
|
||||
event.type = name
|
||||
|
||||
@ -258,7 +258,7 @@ export default {
|
||||
components: { JTreeTable },
|
||||
data() {
|
||||
return {
|
||||
url: '/api/asynTreeList',
|
||||
url: '/mock/api/asynTreeList',
|
||||
columns: [
|
||||
{ title: '菜单名称', dataIndex: 'name' },
|
||||
{ title: '组件', dataIndex: 'component' },
|
||||
|
||||
@ -1,246 +0,0 @@
|
||||
<template>
|
||||
<div class="tinymce-containerty" :style="{width:containerWidth}">
|
||||
<textarea :id="tinymceId" class="tinymce-textarea" @change="ada"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* docs:
|
||||
* https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
|
||||
*/
|
||||
import load from './load'
|
||||
//const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']
|
||||
//const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']
|
||||
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
|
||||
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
|
||||
|
||||
export default {
|
||||
name: 'JEditorDyn',
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
toolbar: {
|
||||
type: [String, Array],
|
||||
required: false,
|
||||
default: 'undo redo | formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists link unlink image media table | removeformat | fullscreen',
|
||||
},
|
||||
menubar: {
|
||||
type: String,
|
||||
default: 'file edit insert view format table'
|
||||
},
|
||||
height: {
|
||||
type: [Number, String],
|
||||
required: false,
|
||||
default: 360
|
||||
},
|
||||
width: {
|
||||
type: [Number, String],
|
||||
required: false,
|
||||
default: 'auto'
|
||||
},
|
||||
plugins: {
|
||||
type: [String, Array],
|
||||
default: 'lists image link media table textcolor wordcount contextmenu fullscreen'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasChange: false,
|
||||
hasInit: false,
|
||||
tinymceId: this.id,
|
||||
fullscreen: false,
|
||||
languageTypeList: {
|
||||
'en': 'en',
|
||||
'zh': 'zh_CN',
|
||||
'es': 'es_MX',
|
||||
'ja': 'ja'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
containerWidth() {
|
||||
const width = this.width
|
||||
if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
|
||||
return `${width}px`
|
||||
}
|
||||
return width
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
if (!this.hasChange && this.hasInit) {
|
||||
this.$nextTick(() =>
|
||||
window.tinymce.get(this.tinymceId).setContent(val || ''))
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
activated() {
|
||||
if (window.tinymce) {
|
||||
this.initTinymce()
|
||||
}
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce()
|
||||
},
|
||||
destroyed() {
|
||||
this.destroyTinymce()
|
||||
},
|
||||
methods: {
|
||||
ada() {
|
||||
console.log('change')
|
||||
},
|
||||
init() {
|
||||
// dynamic load tinymce from cdn
|
||||
load(tinymceCDN, (err) => {
|
||||
if (err) {
|
||||
this.$message.error(err.message)
|
||||
return
|
||||
}
|
||||
this.initTinymce()
|
||||
})
|
||||
},
|
||||
initTinymce() {
|
||||
const _this = this
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
language: this.languageTypeList['zh'],
|
||||
height: this.height,
|
||||
body_class: 'panel-body ',
|
||||
object_resizing: false,
|
||||
toolbar: this.toolbar,
|
||||
menubar: false,
|
||||
plugins: this.plugins,
|
||||
end_container_on_empty_block: true,
|
||||
powerpaste_word_import: 'clean',
|
||||
code_dialog_height: 450,
|
||||
code_dialog_width: 1000,
|
||||
advlist_bullet_styles: 'square',
|
||||
advlist_number_styles: 'default',
|
||||
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
|
||||
default_link_target: '_blank',
|
||||
link_title: false,
|
||||
nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin
|
||||
init_instance_callback: editor => {
|
||||
if (_this.value) {
|
||||
editor.setContent(_this.value)
|
||||
}
|
||||
_this.hasInit = true
|
||||
editor.on('NodeChange Change KeyUp SetContent', () => {
|
||||
this.hasChange = true
|
||||
this.$emit('input', editor.getContent())
|
||||
})
|
||||
},
|
||||
setup(editor) {
|
||||
editor.on('FullscreenStateChanged', (e) => {
|
||||
_this.fullscreen = e.state
|
||||
})
|
||||
},
|
||||
// it will try to keep these URLs intact
|
||||
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
|
||||
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
|
||||
convert_urls: false
|
||||
// 整合七牛上传
|
||||
// images_dataimg_filter(img) {
|
||||
// setTimeout(() => {
|
||||
// const $image = $(img);
|
||||
// $image.removeAttr('width');
|
||||
// $image.removeAttr('height');
|
||||
// if ($image[0].height && $image[0].width) {
|
||||
// $image.attr('data-wscntype', 'image');
|
||||
// $image.attr('data-wscnh', $image[0].height);
|
||||
// $image.attr('data-wscnw', $image[0].width);
|
||||
// $image.addClass('wscnph');
|
||||
// }
|
||||
// }, 0);
|
||||
// return img
|
||||
// },
|
||||
// images_upload_handler(blobInfo, success, failure, progress) {
|
||||
// progress(0);
|
||||
// const token = _this.$store.getters.token;
|
||||
// getToken(token).then(response => {
|
||||
// const url = response.data.qiniu_url;
|
||||
// const formData = new FormData();
|
||||
// formData.append('token', response.data.qiniu_token);
|
||||
// formData.append('key', response.data.qiniu_key);
|
||||
// formData.append('file', blobInfo.blob(), url);
|
||||
// upload(formData).then(() => {
|
||||
// success(url);
|
||||
// progress(100);
|
||||
// })
|
||||
// }).catch(err => {
|
||||
// failure('err')
|
||||
// console.log(err);
|
||||
// });
|
||||
// },
|
||||
})
|
||||
},
|
||||
destroyTinymce() {
|
||||
const tinymce = window.tinymce.get(this.tinymceId)
|
||||
if (this.fullscreen) {
|
||||
tinymce.execCommand('mceFullScreen')
|
||||
}
|
||||
|
||||
if (tinymce) {
|
||||
tinymce.destroy()
|
||||
}
|
||||
},
|
||||
setContent(value) {
|
||||
window.tinymce.get(this.tinymceId).setContent(value)
|
||||
},
|
||||
getContent() {
|
||||
window.tinymce.get(this.tinymceId).getContent()
|
||||
},
|
||||
imageSuccessCBK(arr) {
|
||||
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`))
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tinymce-containerty {
|
||||
position: relative;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.tinymce-containerty {
|
||||
::v-deep {
|
||||
.mce-fullscreen {
|
||||
z-index: 10000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tinymce-textarea {
|
||||
visibility: hidden;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.editor-custom-btn-container {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 4px;
|
||||
/*z-index: 2005;*/
|
||||
}
|
||||
|
||||
.fullscreen .editor-custom-btn-container {
|
||||
z-index: 10000;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.editor-upload-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
@ -1,142 +0,0 @@
|
||||
<template>
|
||||
<div class="j-markdown-editor" :id="dynamicId"/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import load from './load'
|
||||
import { md_js, md_zh_cn_js } from './Resource'
|
||||
import defaultOptions from '@/components/jeecg/JMarkdownEditor/default-options.js'
|
||||
|
||||
export default {
|
||||
name: 'JMdEditorDyn',
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: false,
|
||||
default() {
|
||||
return 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||
}
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default() {
|
||||
return defaultOptions
|
||||
}
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'markdown'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '300px'
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'zh-CN'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
dynamicId: this.id
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
editorOptions() {
|
||||
const options = Object.assign({}, defaultOptions, this.options)
|
||||
options.initialEditType = this.mode
|
||||
options.height = this.height
|
||||
options.language = this.language
|
||||
return options
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newValue, preValue) {
|
||||
if (newValue !== preValue && newValue !== this.editor.getMarkdown()) {
|
||||
this.editor.setMarkdown(newValue)
|
||||
}
|
||||
},
|
||||
language(val) {
|
||||
this.destroyEditor()
|
||||
this.initEditor()
|
||||
},
|
||||
height(newValue) {
|
||||
this.editor.height(newValue)
|
||||
},
|
||||
mode(newValue) {
|
||||
this.editor.changeMode(newValue)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
destroyed() {
|
||||
this.destroyEditor()
|
||||
},
|
||||
methods: {
|
||||
init(){
|
||||
|
||||
this.initEditor()
|
||||
/* load(md_js,'',()=>{
|
||||
load(md_zh_cn_js,'',()=>{
|
||||
|
||||
})
|
||||
})*/
|
||||
},
|
||||
initEditor() {
|
||||
const Editor = toastui.Editor
|
||||
this.editor = new Editor({
|
||||
el: document.getElementById(this.dynamicId),
|
||||
...this.editorOptions
|
||||
})
|
||||
if (this.value) {
|
||||
this.editor.setMarkdown(this.value)
|
||||
}
|
||||
this.editor.on('change', () => {
|
||||
this.$emit('change', this.editor.getMarkdown())
|
||||
})
|
||||
},
|
||||
destroyEditor() {
|
||||
if (!this.editor) return
|
||||
this.editor.off('change')
|
||||
this.editor.remove()
|
||||
},
|
||||
setMarkdown(value) {
|
||||
this.editor.setMarkdown(value)
|
||||
},
|
||||
getMarkdown() {
|
||||
return this.editor.getMarkdown()
|
||||
},
|
||||
setHtml(value) {
|
||||
this.editor.setHtml(value)
|
||||
},
|
||||
getHtml() {
|
||||
return this.editor.getHtml()
|
||||
}
|
||||
},
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
|
||||
.j-markdown-editor {
|
||||
/deep/ .tui-editor-defaultUI {
|
||||
.te-mode-switch,
|
||||
.tui-scrollsync
|
||||
{
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@ -1,325 +0,0 @@
|
||||
<template>
|
||||
<div class="jeecg-editor-ty" :class="fullCoder?'jeecg-editor-max':'jeecg-editor-min'">
|
||||
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
|
||||
<textarea :id="dynamicId" />
|
||||
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden': hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import load from './load'
|
||||
import '@/assets/less/codemirror_idea.css'
|
||||
import './cm_sql_hint.js'
|
||||
import { sql_keyword } from './Resource'
|
||||
|
||||
|
||||
export default {
|
||||
name: 'JSqlCodeEditorDyn',
|
||||
props:{
|
||||
id: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return 'vue-editor-' + new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 显示行号
|
||||
lineNumbers: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
zIndex: {
|
||||
type: [Number, String],
|
||||
default: 999
|
||||
},
|
||||
autoHeight: {
|
||||
type: [String, Boolean],
|
||||
default: true
|
||||
},
|
||||
// 不自适应高度的情况下生效的固定高度
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: '240px'
|
||||
},
|
||||
autoHeight: {
|
||||
type: [String, Boolean],
|
||||
default: true
|
||||
},
|
||||
// 是否显示全屏按钮
|
||||
fullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
autoHint:{
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
dynamicId: this.id,
|
||||
coder: '',
|
||||
hasCode: false,
|
||||
code: '',
|
||||
// code 编辑器 是否全屏
|
||||
fullCoder: false,
|
||||
iconType: 'fullscreen',
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
placeholderShow() {
|
||||
if (this.placeholder == null) {
|
||||
return `请在此输入javascript代码`
|
||||
} else {
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
nullTipStyle(){
|
||||
if (this.lineNumbers) {
|
||||
return { left: '36px' }
|
||||
} else {
|
||||
return { left: '12px' }
|
||||
}
|
||||
},
|
||||
isAutoHeight() {
|
||||
let {autoHeight} = this
|
||||
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
|
||||
autoHeight = !(isIE() || isIE11())
|
||||
} else {
|
||||
autoHeight = true
|
||||
}
|
||||
return autoHeight
|
||||
},
|
||||
fullScreenParentProps() {
|
||||
let props = {
|
||||
class: {
|
||||
'full-screen-parent': true,
|
||||
'full-screen': this.fullCoder,
|
||||
'auto-height': this.isAutoHeight
|
||||
},
|
||||
style: {}
|
||||
}
|
||||
if (this.fullCoder) {
|
||||
props.style['z-index'] = this.zIndex
|
||||
}
|
||||
if (!this.isAutoHeight) {
|
||||
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
|
||||
}
|
||||
return props
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fullCoder:{
|
||||
handler(value) {
|
||||
if(value){
|
||||
this.iconType="fullscreen-exit"
|
||||
}else{
|
||||
this.iconType="fullscreen"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods:{
|
||||
init(){
|
||||
this.main();
|
||||
},
|
||||
main(){
|
||||
let obj = document.getElementById(this.dynamicId);
|
||||
const that = this;
|
||||
let editor = CodeMirror.fromTextArea(obj,{
|
||||
theme:'idea',
|
||||
lineNumbers: this.lineNumbers,
|
||||
lineWrapping: true,
|
||||
mode: "sql",
|
||||
indentUnit: 1,
|
||||
indentWithTabs: true,
|
||||
styleActiveLine: true,
|
||||
/* styleSelectedText: false, */
|
||||
extraKeys: {
|
||||
"F11": function(cm) {
|
||||
that.fullCoder = !that.fullCoder
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
"Esc": function(cm) {
|
||||
that.fullCoder = false
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
},
|
||||
"Alt-/": function(cm) {
|
||||
cm.showHint();
|
||||
},
|
||||
"Tab": (cm) => {
|
||||
if (cm.somethingSelected()) {
|
||||
cm.indentSelection('add');
|
||||
} else {
|
||||
//cm.indentLine(cm.getCursor().line, "add");
|
||||
//走两格 第三格输入
|
||||
cm.replaceSelection(Array(3).join(" "), "end", "+input");
|
||||
}
|
||||
},
|
||||
"Shift-Tab": (cm) => {
|
||||
if (cm.somethingSelected()) {
|
||||
cm.indentSelection('subtract');
|
||||
} else {
|
||||
// cm.indentLine(cm.getCursor().line, "subtract");
|
||||
const cursor = cm.getCursor();
|
||||
// 光标回退 indexUnit 字符
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch - 4});
|
||||
}
|
||||
return ;
|
||||
}
|
||||
}
|
||||
})
|
||||
this.coder = editor
|
||||
this.addEvent();
|
||||
this.setCoderValue();
|
||||
this.addSystemHint();
|
||||
},
|
||||
setCoderValue(){
|
||||
if(this.value||this.code){
|
||||
this.hasCode=true
|
||||
this.setCodeContent(this.value || this.code)
|
||||
}else{
|
||||
this.coder.setValue('')
|
||||
this.hasCode=false
|
||||
}
|
||||
},
|
||||
getCodeContent(){
|
||||
return this.code
|
||||
},
|
||||
setCodeContent(val){
|
||||
setTimeout(()=>{
|
||||
if(!val){
|
||||
this.coder.setValue('')
|
||||
}else{
|
||||
this.coder.setValue(val)
|
||||
}
|
||||
},300)
|
||||
},
|
||||
addSystemHint(){
|
||||
this.coder.setOption('hintOptions', {
|
||||
completeSingle: false,
|
||||
tables: sql_keyword
|
||||
});
|
||||
},
|
||||
addEvent(){
|
||||
if(this.autoHint){
|
||||
this.coder.on('cursorActivity', ()=>{
|
||||
this.coder.showHint();
|
||||
});
|
||||
}
|
||||
this.coder.on('change', (coder) => {
|
||||
this.code = coder.getValue()
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
if (this.$emit) {
|
||||
this.$emit('input', this.code)
|
||||
}
|
||||
});
|
||||
this.coder.on('focus', () => {
|
||||
this.hasCode=true
|
||||
});
|
||||
this.coder.on('blur', () => {
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
});
|
||||
},
|
||||
loadResource(src,type){
|
||||
return new Promise((resolve,reject)=>{
|
||||
load(src,type,(msg)=>{
|
||||
if(!msg){
|
||||
resolve();
|
||||
}else{
|
||||
reject(msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
nullTipClick(){
|
||||
this.coder.focus()
|
||||
},
|
||||
fullToggle(){
|
||||
this.fullCoder = !this.fullCoder
|
||||
this.coder.setOption("fullScreen", this.fullCoder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="less" >
|
||||
.jeecg-editor-ty{
|
||||
position: relative;
|
||||
|
||||
.full-screen-icon {
|
||||
opacity: 0;
|
||||
color: black;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 2px;
|
||||
z-index: 9;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
&:hover {
|
||||
.full-screen-icon {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.null-tip{
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 36px;
|
||||
z-index: 10;
|
||||
font-size:16px;
|
||||
color: #acaaaac9;
|
||||
line-height: initial;
|
||||
}
|
||||
.null-tip-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.jeecg-editor-max{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
height: 100%;
|
||||
width: 100% !important;
|
||||
|
||||
.CodeMirror{
|
||||
position: inherit !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.full-screen-icon{
|
||||
z-index:9999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,319 +0,0 @@
|
||||
<template>
|
||||
<div class="jeecg-editor-ty" :class="fullCoder?'jeecg-editor-max':'jeecg-editor-min'">
|
||||
<a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
|
||||
<textarea :id="dynamicId" />
|
||||
<span @click="nullTipClick" class="null-tip" :class="{'null-tip-hidden': hasCode}" :style="nullTipStyle">{{ placeholderShow }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import '@/assets/less/codemirror_idea.css'
|
||||
import './cm_hint.js'
|
||||
|
||||
export default {
|
||||
name: 'JsCodeEditorDyn',
|
||||
props:{
|
||||
id: {
|
||||
type: String,
|
||||
default: function() {
|
||||
return 'vue-editor-' + new Date() + ((Math.random() * 1000).toFixed(0) + '')
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 显示行号
|
||||
lineNumbers: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
zIndex: {
|
||||
type: [Number, String],
|
||||
default: 999
|
||||
},
|
||||
autoHeight: {
|
||||
type: [String, Boolean],
|
||||
default: true
|
||||
},
|
||||
// 不自适应高度的情况下生效的固定高度
|
||||
height: {
|
||||
type: [String, Number],
|
||||
default: '240px'
|
||||
},
|
||||
autoHeight: {
|
||||
type: [String, Boolean],
|
||||
default: true
|
||||
},
|
||||
// 是否显示全屏按钮
|
||||
fullScreen: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
dynamicId: this.id,
|
||||
coder: '',
|
||||
hasCode: false,
|
||||
code: '',
|
||||
// code 编辑器 是否全屏
|
||||
fullCoder: false,
|
||||
iconType: 'fullscreen',
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
placeholderShow() {
|
||||
if (this.placeholder == null) {
|
||||
return `请在此输入javascript代码`
|
||||
} else {
|
||||
return this.placeholder
|
||||
}
|
||||
},
|
||||
nullTipStyle(){
|
||||
if (this.lineNumbers) {
|
||||
return { left: '36px' }
|
||||
} else {
|
||||
return { left: '12px' }
|
||||
}
|
||||
},
|
||||
isAutoHeight() {
|
||||
let {autoHeight} = this
|
||||
if (typeof autoHeight === 'string' && autoHeight.toLowerCase().trim() === '!ie') {
|
||||
autoHeight = !(isIE() || isIE11())
|
||||
} else {
|
||||
autoHeight = true
|
||||
}
|
||||
return autoHeight
|
||||
},
|
||||
fullScreenParentProps() {
|
||||
let props = {
|
||||
class: {
|
||||
'full-screen-parent': true,
|
||||
'full-screen': this.fullCoder,
|
||||
'auto-height': this.isAutoHeight
|
||||
},
|
||||
style: {}
|
||||
}
|
||||
if (this.fullCoder) {
|
||||
props.style['z-index'] = this.zIndex
|
||||
}
|
||||
if (!this.isAutoHeight) {
|
||||
props.style['height'] = (typeof this.height === 'number' ? this.height + 'px' : this.height)
|
||||
}
|
||||
return props
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fullCoder:{
|
||||
handler(value) {
|
||||
if(value){
|
||||
this.iconType="fullscreen-exit"
|
||||
}else{
|
||||
this.iconType="fullscreen"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods:{
|
||||
init(){
|
||||
this.main();
|
||||
},
|
||||
main(){
|
||||
let obj = document.getElementById(this.dynamicId);
|
||||
const that = this;
|
||||
let editor = CodeMirror.fromTextArea(obj,{
|
||||
theme:'idea',
|
||||
lineNumbers: this.lineNumbers,
|
||||
lineWrapping: true,
|
||||
mode: "javascript",
|
||||
indentUnit: 1,
|
||||
indentWithTabs: true,
|
||||
styleActiveLine: true,
|
||||
/* styleSelectedText: false, */
|
||||
extraKeys: {
|
||||
"F11": function(cm) {
|
||||
that.fullCoder = !that.fullCoder
|
||||
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
|
||||
},
|
||||
"Esc": function(cm) {
|
||||
that.fullCoder = false
|
||||
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
|
||||
},
|
||||
"Alt-/": function(cm) {
|
||||
let a = cm.getValue()+""
|
||||
console.log('a',a)
|
||||
cm.showHint();
|
||||
},
|
||||
"Tab": (cm) => {
|
||||
if (cm.somethingSelected()) {
|
||||
cm.indentSelection('add');
|
||||
} else {
|
||||
//cm.indentLine(cm.getCursor().line, "add");
|
||||
//走两格 第三格输入
|
||||
cm.replaceSelection(Array(3).join(" "), "end", "+input");
|
||||
}
|
||||
},
|
||||
"Shift-Tab": (cm) => {
|
||||
if (cm.somethingSelected()) {
|
||||
cm.indentSelection('subtract');
|
||||
} else {
|
||||
// cm.indentLine(cm.getCursor().line, "subtract");
|
||||
const cursor = cm.getCursor();
|
||||
// 光标回退 indexUnit 字符
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch - 4});
|
||||
}
|
||||
return ;
|
||||
}
|
||||
}
|
||||
})
|
||||
this.coder = editor
|
||||
this.addEvent();
|
||||
this.setCoderValue();
|
||||
},
|
||||
setCoderValue(){
|
||||
if(this.value||this.code){
|
||||
this.hasCode=true
|
||||
this.setCodeContent(this.value || this.code)
|
||||
}else{
|
||||
this.coder.setValue('')
|
||||
this.hasCode=false
|
||||
}
|
||||
},
|
||||
getCodeContent(){
|
||||
return this.code
|
||||
},
|
||||
setCodeContent(val){
|
||||
setTimeout(()=>{
|
||||
if(!val){
|
||||
this.coder.setValue('')
|
||||
}else{
|
||||
this.coder.setValue(val)
|
||||
}
|
||||
},300)
|
||||
},
|
||||
addEvent(){
|
||||
const that = this;
|
||||
this.coder.on('cursorActivity',function(wl) {
|
||||
let arr = wl.state.activeLines
|
||||
if(arr && arr.length>0){
|
||||
let text = arr[0].text
|
||||
if(text.lastIndexOf('that.')>=0){
|
||||
that.coder.showHint();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.coder.on('change', (coder) => {
|
||||
this.code = coder.getValue()
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
if (this.$emit) {
|
||||
this.$emit('input', this.code)
|
||||
}
|
||||
});
|
||||
this.coder.on('focus', () => {
|
||||
this.hasCode=true
|
||||
});
|
||||
this.coder.on('blur', () => {
|
||||
if(this.code){
|
||||
this.hasCode=true
|
||||
}else{
|
||||
this.hasCode=false
|
||||
}
|
||||
});
|
||||
},
|
||||
loadResource(src,type){
|
||||
return new Promise((resolve,reject)=>{
|
||||
load(src,type,(msg)=>{
|
||||
if(!msg){
|
||||
resolve();
|
||||
}else{
|
||||
reject(msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
nullTipClick(){
|
||||
this.coder.focus()
|
||||
},
|
||||
fullToggle(){
|
||||
this.fullCoder = !this.fullCoder
|
||||
this.coder.setOption("fullScreen", this.fullCoder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
</script>
|
||||
<style lang="less" >
|
||||
.jeecg-editor-ty{
|
||||
position: relative;
|
||||
|
||||
.full-screen-icon {
|
||||
opacity: 0;
|
||||
color: black;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 24px;
|
||||
background-color: white;
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 2px;
|
||||
z-index: 9;
|
||||
cursor: pointer;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
&:hover {
|
||||
.full-screen-icon {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(255, 255, 255, 0.88);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.null-tip{
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
left: 36px;
|
||||
z-index: 10;
|
||||
font-size:16px;
|
||||
color: #acaaaac9;
|
||||
line-height: initial;
|
||||
}
|
||||
.null-tip-hidden{
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.jeecg-editor-max{
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 999;
|
||||
height: 100%;
|
||||
width: 100% !important;
|
||||
|
||||
.CodeMirror{
|
||||
position: inherit !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.full-screen-icon{
|
||||
z-index:9999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,24 +0,0 @@
|
||||
|
||||
/**js编辑器关键词用于提示*/
|
||||
const js_keyword = [
|
||||
'that',
|
||||
'getAction','postAction','deleteAction',
|
||||
'beforeAdd','beforeEdit','beforeDelete','mounted','created','show'
|
||||
]
|
||||
|
||||
/**js编辑器 方法名用于提示*/
|
||||
const js_method = [
|
||||
'.getSelectOptions','.changeOptions','.triggleChangeValues','.immediateEnhance ','.simpleDateFormat','.lodash'
|
||||
]
|
||||
|
||||
/**sql编辑器 表名字段名用于提示*/
|
||||
const sql_keyword = {
|
||||
sys_user: ['USERNAME', 'REALNAME', 'ID','BIRTHDAY','AGE'],
|
||||
demo: ['name', 'age', 'id', 'sex']
|
||||
}
|
||||
|
||||
export {
|
||||
js_keyword,
|
||||
js_method,
|
||||
sql_keyword
|
||||
}
|
||||
@ -1,177 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
||||
import { js_keyword, js_method } from './Resource'
|
||||
(function(mod) {
|
||||
mod(CodeMirror);
|
||||
/*if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
else // Plain browser env*/
|
||||
|
||||
})(function(CodeMirror) {
|
||||
var Pos = CodeMirror.Pos;
|
||||
|
||||
function forEach(arr, f) {
|
||||
for (var i = 0, e = arr.length; i < e; ++i) f(arr[i]);
|
||||
}
|
||||
|
||||
function arrayContains(arr, item) {
|
||||
if (!Array.prototype.indexOf) {
|
||||
var i = arr.length;
|
||||
while (i--) {
|
||||
if (arr[i] === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return arr.indexOf(item) != -1;
|
||||
}
|
||||
|
||||
function scriptHint(editor, keywords, getToken, options) {
|
||||
// Find the token at the cursor
|
||||
var cur = editor.getCursor(), token = getToken(editor, cur);
|
||||
if (/\b(?:string|comment)\b/.test(token.type)) return;
|
||||
var innerMode = CodeMirror.innerMode(editor.getMode(), token.state);
|
||||
if (innerMode.mode.helperType === "json") return;
|
||||
token.state = innerMode.state;
|
||||
if('.' === token.string){
|
||||
let arr = []
|
||||
for(let k of js_method){
|
||||
arr.push(k)
|
||||
}
|
||||
return {
|
||||
list: arr,
|
||||
from: Pos(cur.line, token.start),
|
||||
to: Pos(cur.line, token.end)
|
||||
};
|
||||
}
|
||||
// If it's not a 'word-style' token, ignore the token.
|
||||
if (!/^[\w$_]*$/.test(token.string)) {
|
||||
token = {start: cur.ch, end: cur.ch, string: "", state: token.state,
|
||||
type: token.string == "." ? "property" : null};
|
||||
} else if (token.end > cur.ch) {
|
||||
token.end = cur.ch;
|
||||
token.string = token.string.slice(0, cur.ch - token.start);
|
||||
}
|
||||
|
||||
var tprop = token;
|
||||
// If it is a property, find out what it is a property of.
|
||||
while (tprop.type == "property") {
|
||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||
if (tprop.string != ".") return;
|
||||
tprop = getToken(editor, Pos(cur.line, tprop.start));
|
||||
if (!context) var context = [];
|
||||
context.push(tprop);
|
||||
}
|
||||
return {list: getCompletions(token, context, keywords, options),
|
||||
from: Pos(cur.line, token.start),
|
||||
to: Pos(cur.line, token.end)};
|
||||
}
|
||||
|
||||
function javascriptHint(editor, options) {
|
||||
return scriptHint(editor, javascriptKeywords,
|
||||
function (e, cur) {return e.getTokenAt(cur);},
|
||||
options);
|
||||
};
|
||||
CodeMirror.registerHelper("hint", "javascript", javascriptHint);
|
||||
|
||||
function getCoffeeScriptToken(editor, cur) {
|
||||
// This getToken, it is for coffeescript, imitates the behavior of
|
||||
// getTokenAt method in javascript.js, that is, returning "property"
|
||||
// type and treat "." as indepenent token.
|
||||
var token = editor.getTokenAt(cur);
|
||||
if (cur.ch == token.start + 1 && token.string.charAt(0) == '.') {
|
||||
token.end = token.start;
|
||||
token.string = '.';
|
||||
token.type = "property";
|
||||
}
|
||||
else if (/^\.[\w$_]*$/.test(token.string)) {
|
||||
token.type = "property";
|
||||
token.start++;
|
||||
token.string = token.string.replace(/\./, '');
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
function coffeescriptHint(editor, options) {
|
||||
return scriptHint(editor, coffeescriptKeywords, getCoffeeScriptToken, options);
|
||||
}
|
||||
CodeMirror.registerHelper("hint", "coffeescript", coffeescriptHint);
|
||||
|
||||
var stringProps = ("charAt charCodeAt indexOf lastIndexOf substring substr slice trim trimLeft trimRight " +
|
||||
"toUpperCase toLowerCase split concat match replace search").split(" ");
|
||||
var arrayProps = ("length concat join splice push pop shift unshift slice reverse sort indexOf " +
|
||||
"lastIndexOf every some filter forEach map reduce reduceRight ").split(" ");
|
||||
var funcProps = "prototype apply call bind".split(" ");
|
||||
|
||||
var javascriptKeywords = ("break case catch class const continue debugger default delete do else export extends false finally for function " +
|
||||
"if in import instanceof new null return super switch this throw true try typeof var void while with yield that").split(" ");
|
||||
for(let jk of js_keyword){
|
||||
javascriptKeywords.push(jk)
|
||||
}
|
||||
var coffeescriptKeywords = ("and break catch class continue delete do else extends false finally for " +
|
||||
"if in instanceof isnt new no not null of off on or return switch then throw true try typeof until void while with yes").split(" ");
|
||||
|
||||
function forAllProps(obj, callback) {
|
||||
if (!Object.getOwnPropertyNames || !Object.getPrototypeOf) {
|
||||
for (var name in obj) callback(name)
|
||||
} else {
|
||||
for (var o = obj; o; o = Object.getPrototypeOf(o))
|
||||
Object.getOwnPropertyNames(o).forEach(callback)
|
||||
}
|
||||
}
|
||||
|
||||
function getCompletions(token, context, keywords, options) {
|
||||
var found = [], start = token.string, global = options && options.globalScope || window;
|
||||
function maybeAdd(str) {
|
||||
if (str.lastIndexOf(start, 0) == 0 && !arrayContains(found, str)) found.push(str);
|
||||
}
|
||||
function gatherCompletions(obj) {
|
||||
if (typeof obj == "string") forEach(stringProps, maybeAdd);
|
||||
else if (obj instanceof Array) forEach(arrayProps, maybeAdd);
|
||||
else if (obj instanceof Function) forEach(funcProps, maybeAdd);
|
||||
forAllProps(obj, maybeAdd)
|
||||
}
|
||||
|
||||
if (context && context.length) {
|
||||
// If this is a property, see if it belongs to some object we can
|
||||
// find in the current environment.
|
||||
var obj = context.pop(), base;
|
||||
if (obj.type && obj.type.indexOf("variable") === 0) {
|
||||
if (options && options.additionalContext)
|
||||
base = options.additionalContext[obj.string];
|
||||
if (!options || options.useGlobalScope !== false)
|
||||
base = base || global[obj.string];
|
||||
} else if (obj.type == "string") {
|
||||
base = "";
|
||||
} else if (obj.type == "atom") {
|
||||
base = 1;
|
||||
} else if (obj.type == "function") {
|
||||
if (global.jQuery != null && (obj.string == '$' || obj.string == 'jQuery') &&
|
||||
(typeof global.jQuery == 'function'))
|
||||
base = global.jQuery();
|
||||
else if (global._ != null && (obj.string == '_') && (typeof global._ == 'function'))
|
||||
base = global._();
|
||||
}
|
||||
while (base != null && context.length)
|
||||
base = base[context.pop().string];
|
||||
if (base != null) gatherCompletions(base);
|
||||
} else {
|
||||
// If not, just look in the global object, any local scope, and optional additional-context
|
||||
// (reading into JS mode internals to get at the local and global variables)
|
||||
for (var v = token.state.localVars; v; v = v.next) maybeAdd(v.name);
|
||||
for (var c = token.state.context; c; c = c.prev)
|
||||
for (var v = c.vars; v; v = v.next) maybeAdd(v.name)
|
||||
for (var v = token.state.globalVars; v; v = v.next) maybeAdd(v.name);
|
||||
if (options && options.additionalContext != null)
|
||||
for (var key in options.additionalContext)
|
||||
maybeAdd(key);
|
||||
if (!options || options.useGlobalScope !== false)
|
||||
gatherCompletions(global);
|
||||
forEach(keywords, maybeAdd);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
});
|
||||
@ -1,305 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
/*if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"), require("../../mode/sql/sql"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../../mode/sql/sql"], mod);
|
||||
else */
|
||||
// Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
var tables;
|
||||
var defaultTable;
|
||||
var keywords;
|
||||
var identifierQuote;
|
||||
var CONS = {
|
||||
QUERY_DIV: ";",
|
||||
ALIAS_KEYWORD: "AS"
|
||||
};
|
||||
var Pos = CodeMirror.Pos, cmpPos = CodeMirror.cmpPos;
|
||||
|
||||
function isArray(val) { return Object.prototype.toString.call(val) == "[object Array]" }
|
||||
|
||||
function getKeywords(editor) {
|
||||
var mode = editor.doc.modeOption;
|
||||
if (mode === "sql") mode = "text/x-sql";
|
||||
return CodeMirror.resolveMode(mode).keywords;
|
||||
}
|
||||
|
||||
function getIdentifierQuote(editor) {
|
||||
var mode = editor.doc.modeOption;
|
||||
if (mode === "sql") mode = "text/x-sql";
|
||||
return CodeMirror.resolveMode(mode).identifierQuote || "`";
|
||||
}
|
||||
|
||||
function getText(item) {
|
||||
return typeof item == "string" ? item : item.text;
|
||||
}
|
||||
|
||||
function wrapTable(name, value) {
|
||||
if (isArray(value)) value = {columns: value}
|
||||
if (!value.text) value.text = name
|
||||
return value
|
||||
}
|
||||
|
||||
function parseTables(input) {
|
||||
var result = {}
|
||||
if (isArray(input)) {
|
||||
for (var i = input.length - 1; i >= 0; i--) {
|
||||
var item = input[i]
|
||||
result[getText(item).toUpperCase()] = wrapTable(getText(item), item)
|
||||
}
|
||||
} else if (input) {
|
||||
for (var name in input)
|
||||
result[name.toUpperCase()] = wrapTable(name, input[name])
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
function getTable(name) {
|
||||
return tables[name.toUpperCase()]
|
||||
}
|
||||
|
||||
function shallowClone(object) {
|
||||
var result = {};
|
||||
for (var key in object) if (object.hasOwnProperty(key))
|
||||
result[key] = object[key];
|
||||
return result;
|
||||
}
|
||||
|
||||
function match(string, word) {
|
||||
var len = string.length;
|
||||
var sub = getText(word).substr(0, len);
|
||||
return string.toUpperCase() === sub.toUpperCase();
|
||||
}
|
||||
|
||||
function addMatches(result, search, wordlist, formatter) {
|
||||
if (isArray(wordlist)) {
|
||||
for (var i = 0; i < wordlist.length; i++)
|
||||
if (match(search, wordlist[i])) result.push(formatter(wordlist[i]))
|
||||
} else {
|
||||
for (var word in wordlist) if (wordlist.hasOwnProperty(word)) {
|
||||
var val = wordlist[word]
|
||||
if (!val || val === true)
|
||||
val = word
|
||||
else
|
||||
val = val.displayText ? {text: val.text, displayText: val.displayText} : val.text
|
||||
if (match(search, val)) result.push(formatter(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function cleanName(name) {
|
||||
// Get rid name from identifierQuote and preceding dot(.)
|
||||
if (name.charAt(0) == ".") {
|
||||
name = name.substr(1);
|
||||
}
|
||||
// replace doublicated identifierQuotes with single identifierQuotes
|
||||
// and remove single identifierQuotes
|
||||
var nameParts = name.split(identifierQuote+identifierQuote);
|
||||
for (var i = 0; i < nameParts.length; i++)
|
||||
nameParts[i] = nameParts[i].replace(new RegExp(identifierQuote,"g"), "");
|
||||
return nameParts.join(identifierQuote);
|
||||
}
|
||||
|
||||
function insertIdentifierQuotes(name) {
|
||||
var nameParts = getText(name).split(".");
|
||||
for (var i = 0; i < nameParts.length; i++)
|
||||
nameParts[i] = identifierQuote +
|
||||
// doublicate identifierQuotes
|
||||
nameParts[i].replace(new RegExp(identifierQuote,"g"), identifierQuote+identifierQuote) +
|
||||
identifierQuote;
|
||||
var escaped = nameParts.join(".");
|
||||
if (typeof name == "string") return escaped;
|
||||
name = shallowClone(name);
|
||||
name.text = escaped;
|
||||
return name;
|
||||
}
|
||||
|
||||
function nameCompletion(cur, token, result, editor) {
|
||||
// Try to complete table, column names and return start position of completion
|
||||
var useIdentifierQuotes = false;
|
||||
var nameParts = [];
|
||||
var start = token.start;
|
||||
var cont = true;
|
||||
while (cont) {
|
||||
cont = (token.string.charAt(0) == ".");
|
||||
useIdentifierQuotes = useIdentifierQuotes || (token.string.charAt(0) == identifierQuote);
|
||||
|
||||
start = token.start;
|
||||
nameParts.unshift(cleanName(token.string));
|
||||
|
||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||
if (token.string == ".") {
|
||||
cont = true;
|
||||
token = editor.getTokenAt(Pos(cur.line, token.start));
|
||||
}
|
||||
}
|
||||
|
||||
// Try to complete table names
|
||||
var string = nameParts.join(".");
|
||||
addMatches(result, string, tables, function(w) {
|
||||
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
||||
});
|
||||
|
||||
// Try to complete columns from defaultTable
|
||||
addMatches(result, string, defaultTable, function(w) {
|
||||
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
||||
});
|
||||
|
||||
// Try to complete columns
|
||||
string = nameParts.pop();
|
||||
var table = nameParts.join(".");
|
||||
|
||||
var alias = false;
|
||||
var aliasTable = table;
|
||||
// Check if table is available. If not, find table by Alias
|
||||
if (!getTable(table)) {
|
||||
var oldTable = table;
|
||||
table = findTableByAlias(table, editor);
|
||||
if (table !== oldTable) alias = true;
|
||||
}
|
||||
|
||||
var columns = getTable(table);
|
||||
if (columns && columns.columns)
|
||||
columns = columns.columns;
|
||||
|
||||
if (columns) {
|
||||
addMatches(result, string, columns, function(w) {
|
||||
var tableInsert = table;
|
||||
if (alias == true) tableInsert = aliasTable;
|
||||
if (typeof w == "string") {
|
||||
w = tableInsert + "." + w;
|
||||
} else {
|
||||
w = shallowClone(w);
|
||||
w.text = tableInsert + "." + w.text;
|
||||
}
|
||||
return useIdentifierQuotes ? insertIdentifierQuotes(w) : w;
|
||||
});
|
||||
}
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
function eachWord(lineText, f) {
|
||||
var words = lineText.split(/\s+/)
|
||||
for (var i = 0; i < words.length; i++)
|
||||
if (words[i]) f(words[i].replace(/[,;]/g, ''))
|
||||
}
|
||||
|
||||
function findTableByAlias(alias, editor) {
|
||||
var doc = editor.doc;
|
||||
var fullQuery = doc.getValue();
|
||||
var aliasUpperCase = alias.toUpperCase();
|
||||
var previousWord = "";
|
||||
var table = "";
|
||||
var separator = [];
|
||||
var validRange = {
|
||||
start: Pos(0, 0),
|
||||
end: Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).length)
|
||||
};
|
||||
|
||||
//add separator
|
||||
var indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV);
|
||||
while(indexOfSeparator != -1) {
|
||||
separator.push(doc.posFromIndex(indexOfSeparator));
|
||||
indexOfSeparator = fullQuery.indexOf(CONS.QUERY_DIV, indexOfSeparator+1);
|
||||
}
|
||||
separator.unshift(Pos(0, 0));
|
||||
separator.push(Pos(editor.lastLine(), editor.getLineHandle(editor.lastLine()).text.length));
|
||||
|
||||
//find valid range
|
||||
var prevItem = null;
|
||||
var current = editor.getCursor()
|
||||
for (var i = 0; i < separator.length; i++) {
|
||||
if ((prevItem == null || cmpPos(current, prevItem) > 0) && cmpPos(current, separator[i]) <= 0) {
|
||||
validRange = {start: prevItem, end: separator[i]};
|
||||
break;
|
||||
}
|
||||
prevItem = separator[i];
|
||||
}
|
||||
|
||||
if (validRange.start) {
|
||||
var query = doc.getRange(validRange.start, validRange.end, false);
|
||||
|
||||
for (var i = 0; i < query.length; i++) {
|
||||
var lineText = query[i];
|
||||
eachWord(lineText, function(word) {
|
||||
var wordUpperCase = word.toUpperCase();
|
||||
if (wordUpperCase === aliasUpperCase && getTable(previousWord))
|
||||
table = previousWord;
|
||||
if (wordUpperCase !== CONS.ALIAS_KEYWORD)
|
||||
previousWord = word;
|
||||
});
|
||||
if (table) break;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
CodeMirror.registerHelper("hint", "sql", function(editor, options) {
|
||||
tables = parseTables(options && options.tables)
|
||||
var defaultTableName = options && options.defaultTable;
|
||||
var disableKeywords = options && options.disableKeywords;
|
||||
defaultTable = defaultTableName && getTable(defaultTableName);
|
||||
keywords = getKeywords(editor);
|
||||
identifierQuote = getIdentifierQuote(editor);
|
||||
|
||||
if (defaultTableName && !defaultTable)
|
||||
defaultTable = findTableByAlias(defaultTableName, editor);
|
||||
|
||||
defaultTable = defaultTable || [];
|
||||
|
||||
if (defaultTable.columns)
|
||||
defaultTable = defaultTable.columns;
|
||||
|
||||
var cur = editor.getCursor();
|
||||
var result = [];
|
||||
var token = editor.getTokenAt(cur), start, end, search;
|
||||
if (token.end > cur.ch) {
|
||||
token.end = cur.ch;
|
||||
token.string = token.string.slice(0, cur.ch - token.start);
|
||||
}
|
||||
|
||||
if (token.string.match(/^[.`"'\w@][\w$#]*$/g)) {
|
||||
search = token.string;
|
||||
start = token.start;
|
||||
end = token.end;
|
||||
} else {
|
||||
start = end = cur.ch;
|
||||
search = "";
|
||||
}
|
||||
if (search.charAt(0) == "." || search.charAt(0) == identifierQuote) {
|
||||
start = nameCompletion(cur, token, result, editor);
|
||||
} else {
|
||||
var objectOrClass = function(w, className) {
|
||||
if (typeof w === "object") {
|
||||
w.className = className;
|
||||
} else {
|
||||
w = { text: w, className: className };
|
||||
}
|
||||
return w;
|
||||
};
|
||||
addMatches(result, search, defaultTable, function(w) {
|
||||
return objectOrClass(w, "CodeMirror-hint-table CodeMirror-hint-default-table");
|
||||
});
|
||||
addMatches(
|
||||
result,
|
||||
search,
|
||||
tables, function(w) {
|
||||
return objectOrClass(w, "CodeMirror-hint-table");
|
||||
}
|
||||
);
|
||||
if (!disableKeywords)
|
||||
addMatches(result, search, keywords, function(w) {
|
||||
return objectOrClass(w.toUpperCase(), "CodeMirror-hint-keyword");
|
||||
});
|
||||
}
|
||||
|
||||
return {list: result, from: Pos(cur.line, start), to: Pos(cur.line, end)};
|
||||
});
|
||||
});
|
||||
@ -1,92 +0,0 @@
|
||||
let callbacks = []
|
||||
|
||||
function loadSuccess(key) {
|
||||
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
|
||||
// check is successfully downloaded script
|
||||
return window[key]
|
||||
}
|
||||
|
||||
const load = (src, type, callback) => {
|
||||
if(type=='link'){
|
||||
|
||||
loadStyle(src, callback)
|
||||
}else{
|
||||
let loadKey = ''
|
||||
if(src.indexOf('tinymce')>=0){
|
||||
loadKey = 'tinymce'
|
||||
}else if(src.indexOf('codemirror')>=0){
|
||||
loadKey = 'CodeMirror'
|
||||
}
|
||||
const scriptTag = document.getElementById(src)
|
||||
//const cb = callback || function() {}
|
||||
if (!scriptTag) {
|
||||
const script = document.createElement('script')
|
||||
script.src = src // src url for the third-party library being loaded.
|
||||
script.id = src
|
||||
script.onload=()=>callback()
|
||||
script.onerror=()=>callback('加载失败:'+src)
|
||||
document.body.appendChild(script)
|
||||
//callbacks.push(cb)
|
||||
// const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
|
||||
// onEnd(script)
|
||||
}else{
|
||||
if (loadSuccess(loadKey)) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
if (scriptTag) {
|
||||
/* else {
|
||||
callbacks.push(cb)
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
function stdOnEnd(script) {
|
||||
script['onload'] = function() {
|
||||
// this.onload = null here is necessary
|
||||
// because even IE9 works not like others
|
||||
this.onerror = this.onload = null
|
||||
for (const cb of callbacks) {
|
||||
cb(null, script)
|
||||
}
|
||||
callbacks = null
|
||||
}
|
||||
script['onerror'] = function() {
|
||||
this.onerror = this.onload = null
|
||||
cb(new Error('Failed to load ' + src), script)
|
||||
}
|
||||
}
|
||||
|
||||
function ieOnEnd(script) {
|
||||
script.onreadystatechange = function() {
|
||||
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
|
||||
this.onreadystatechange = null
|
||||
for (const cb of callbacks) {
|
||||
cb(null, script) // there is no way to catch loading errors in IE8
|
||||
}
|
||||
callbacks = null
|
||||
}
|
||||
}
|
||||
|
||||
function loadStyle(src, callback) {
|
||||
const link = document.getElementById(src)
|
||||
if (!link) {
|
||||
const link = document.createElement('link')
|
||||
link.setAttribute("rel", "stylesheet");
|
||||
link.setAttribute("type", "text/css");
|
||||
link.setAttribute("href", src);
|
||||
link.id = src
|
||||
let heads = document.getElementsByTagName("head")
|
||||
if(heads.length){
|
||||
heads[0].appendChild(link)
|
||||
}else{
|
||||
document.documentElement.appendChild(link)
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default load
|
||||
@ -1,11 +1,75 @@
|
||||
import JModal from './JModal'
|
||||
import JFormContainer from './JFormContainer.vue'
|
||||
import JPopup from './JPopup.vue'
|
||||
import JMarkdownEditor from './JMarkdownEditor'
|
||||
import JCodeEditor from './JCodeEditor.vue'
|
||||
import JEditor from './JEditor.vue'
|
||||
import JEditableTable from './JEditableTable.vue'
|
||||
import JAreaLinkage from './JAreaLinkage.vue'
|
||||
import JSuperQuery from './JSuperQuery.vue'
|
||||
import JUpload from './JUpload.vue'
|
||||
import JTreeSelect from './JTreeSelect.vue'
|
||||
import JCategorySelect from './JCategorySelect.vue'
|
||||
import JImageUpload from './JImageUpload.vue'
|
||||
import JImportModal from './JImportModal.vue'
|
||||
import JTreeDict from './JTreeDict.vue'
|
||||
import JCheckbox from './JCheckbox.vue'
|
||||
import JCron from './JCron.vue'
|
||||
import JDate from './JDate.vue'
|
||||
import JEllipsis from './JEllipsis.vue'
|
||||
import JInput from './JInput.vue'
|
||||
import JPopupOnlReport from './modal/JPopupOnlReport.vue'
|
||||
import JFilePop from './minipop/JFilePop.vue'
|
||||
import JInputPop from './minipop/JInputPop.vue'
|
||||
import JSelectMultiple from './JSelectMultiple.vue'
|
||||
import JSlider from './JSlider.vue'
|
||||
import JSwitch from './JSwitch.vue'
|
||||
import JTime from './JTime.vue'
|
||||
import JTreeTable from './JTreeTable.vue'
|
||||
|
||||
//jeecgbiz
|
||||
import JSelectDepart from '../jeecgbiz/JSelectDepart.vue'
|
||||
import JSelectMultiUser from '../jeecgbiz/JSelectMultiUser.vue'
|
||||
import JSelectPosition from '../jeecgbiz/JSelectPosition.vue'
|
||||
import JSelectRole from '../jeecgbiz/JSelectRole.vue'
|
||||
import JSelectUserByDep from '../jeecgbiz/JSelectUserByDep.vue'
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
Vue.component('JFormContainer', JFormContainer)
|
||||
Vue.component('JPopup', JPopup)
|
||||
Vue.component('JMarkdownEditor', JMarkdownEditor)
|
||||
Vue.component(JModal.name, JModal)
|
||||
Vue.component('JPopupOnlReport', JPopupOnlReport)
|
||||
Vue.component('JFilePop', JFilePop)
|
||||
Vue.component('JInputPop', JInputPop)
|
||||
Vue.component('JAreaLinkage', JAreaLinkage)
|
||||
Vue.component('JCategorySelect', JCategorySelect)
|
||||
Vue.component('JCheckbox', JCheckbox)
|
||||
Vue.component('JCodeEditor', JCodeEditor)
|
||||
Vue.component('JCron', JCron)
|
||||
Vue.component('JDate', JDate)
|
||||
Vue.component('JEditableTable', JEditableTable)
|
||||
Vue.component('JEditor', JEditor)
|
||||
Vue.component('JEllipsis', JEllipsis)
|
||||
Vue.component('JFormContainer', JFormContainer)
|
||||
Vue.component('JImageUpload', JImageUpload)
|
||||
Vue.component('JImportModal', JImportModal)
|
||||
Vue.component('JInput', JInput)
|
||||
Vue.component('JPopup', JPopup)
|
||||
Vue.component('JSelectMultiple', JSelectMultiple)
|
||||
Vue.component('JSlider', JSlider)
|
||||
Vue.component('JSuperQuery', JSuperQuery)
|
||||
Vue.component('JSwitch', JSwitch)
|
||||
Vue.component('JTime', JTime)
|
||||
Vue.component('JTreeDict', JTreeDict)
|
||||
Vue.component('JTreeSelect', JTreeSelect)
|
||||
Vue.component('JTreeTable', JTreeTable)
|
||||
Vue.component('JUpload', JUpload)
|
||||
|
||||
//jeecgbiz
|
||||
Vue.component('JSelectDepart', JSelectDepart)
|
||||
Vue.component('JSelectMultiUser', JSelectMultiUser)
|
||||
Vue.component('JSelectPosition', JSelectPosition)
|
||||
Vue.component('JSelectRole', JSelectRole)
|
||||
Vue.component('JSelectUserByDep', JSelectUserByDep)
|
||||
}
|
||||
}
|
||||
@ -8,13 +8,12 @@
|
||||
cancelText="取消"
|
||||
@cancel="close">
|
||||
<!--style="top: 20px;"-->
|
||||
<j-upload :file-type="fileType" :value="filePath" @change="handleChange" :disabled="disabled"></j-upload>
|
||||
<j-upload :file-type="fileType" :value="filePath" @change="handleChange" :disabled="disabled" :number="number"></j-upload>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JUpload from '@/components/jeecg/JUpload'
|
||||
import { getFileAccessHttpUrl } from '@/api/manage';
|
||||
|
||||
const getFileName=(path)=>{
|
||||
@ -27,7 +26,7 @@
|
||||
|
||||
export default {
|
||||
name: 'JFilePop',
|
||||
components: { JUpload },
|
||||
components: { },
|
||||
props:{
|
||||
title:{
|
||||
type:String,
|
||||
@ -59,6 +58,11 @@
|
||||
type:Boolean,
|
||||
default:false,
|
||||
required:false
|
||||
},
|
||||
number:{
|
||||
type:Number,
|
||||
required:false,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
data(){
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
const MODAL_WIDTH = 1200;
|
||||
export default {
|
||||
name: 'JPopupOnlReport',
|
||||
props: ['multi', 'code', 'groupId'],
|
||||
props: ['multi', 'code', 'groupId', 'param'],
|
||||
components:{
|
||||
},
|
||||
data(){
|
||||
@ -121,16 +121,24 @@
|
||||
},
|
||||
cgRpConfigId:"",
|
||||
modalWidth:MODAL_WIDTH,
|
||||
tableScroll:{x:MODAL_WIDTH-100}
|
||||
tableScroll:{x:true},
|
||||
dynamicParam:{}
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadColumnsInfo()
|
||||
//this.loadColumnsInfo()
|
||||
},
|
||||
watch: {
|
||||
code() {
|
||||
this.loadColumnsInfo()
|
||||
},
|
||||
param:{
|
||||
deep:true,
|
||||
handler(){
|
||||
this.dynamicParamHandler()
|
||||
this.loadData();
|
||||
},
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
@ -162,7 +170,6 @@
|
||||
}
|
||||
this.table.columns = [...currColumns]
|
||||
this.initQueryInfo()
|
||||
this.loadData(1)
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -176,12 +183,43 @@
|
||||
httpGroupRequest(() => getAction(url), groupIdKey).then((res) => {
|
||||
// console.log("获取查询条件", res);
|
||||
if (res.success) {
|
||||
this.dynamicParamHandler(res.result)
|
||||
this.queryInfo = res.result
|
||||
//查询条件加载后再请求数据
|
||||
this.loadData(1)
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
//处理动态参数
|
||||
dynamicParamHandler(arr){
|
||||
if(arr && arr.length>0){
|
||||
//第一次加载查询条件前 初始化queryParam为空对象
|
||||
let queryTemp = {}
|
||||
for(let item of arr){
|
||||
if(item.mode==='single'){
|
||||
queryTemp[item.field] = ''
|
||||
}
|
||||
}
|
||||
this.queryParam = {...queryTemp}
|
||||
}
|
||||
let dynamicTemp = {}
|
||||
if(this.param){
|
||||
Object.keys(this.param).map(key=>{
|
||||
let str = this.param[key]
|
||||
if(key in this.queryParam){
|
||||
if(str && str.startsWith("'") && str.endsWith("'")){
|
||||
str = str.substring(1,str.length-1)
|
||||
}
|
||||
//如果查询条件包含参数 设置值
|
||||
this.queryParam[key]=str
|
||||
}
|
||||
dynamicTemp[key] = this.param[key]
|
||||
})
|
||||
}
|
||||
this.dynamicParam = {...dynamicTemp}
|
||||
},
|
||||
loadData(arg) {
|
||||
if (arg == 1) {
|
||||
this.table.pagination.current = 1
|
||||
@ -208,7 +246,14 @@
|
||||
})
|
||||
},
|
||||
getQueryParams() {
|
||||
let param = Object.assign({}, this.queryParam, this.sorter);
|
||||
let paramTarget = {}
|
||||
if(this.dynamicParam){
|
||||
//处理自定义参数
|
||||
Object.keys(this.dynamicParam).map(key=>{
|
||||
paramTarget['self_'+key] = this.dynamicParam[key]
|
||||
})
|
||||
}
|
||||
let param = Object.assign(paramTarget, this.queryParam, this.sorter);
|
||||
param.pageNo = this.table.pagination.current;
|
||||
param.pageSize = this.table.pagination.pageSize;
|
||||
return filterObj(param);
|
||||
@ -272,7 +317,8 @@
|
||||
this.onClearSelected()
|
||||
},
|
||||
show(){
|
||||
this.visible = true;
|
||||
this.visible = true
|
||||
this.loadColumnsInfo()
|
||||
},
|
||||
handleToggleSearch(){
|
||||
this.toggleSearchStatus = !this.toggleSearchStatus;
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
:open="selectOpen"
|
||||
style="width: 100%;"
|
||||
@dropdownVisibleChange="handleDropdownVisibleChange"
|
||||
@click.native="visible=(buttons?visible:true)"
|
||||
@click.native="visible=(buttons || disabled ?visible:true)"
|
||||
/>
|
||||
</slot>
|
||||
</a-col>
|
||||
|
||||
@ -53,6 +53,11 @@
|
||||
customReturnField: {
|
||||
type: String,
|
||||
default: 'id'
|
||||
},
|
||||
backDepart: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data(){
|
||||
@ -68,9 +73,11 @@
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
if (this.customReturnField === 'id') {
|
||||
//update-begin-author:wangshuai date:20201124 for:组件 JSelectDepart.vue不是默认id时新内容编辑问题 gitee I247X2
|
||||
// if (this.customReturnField === 'id') {
|
||||
this.departIds = val
|
||||
}
|
||||
// }
|
||||
//update-end-author:wangshuai date:20201124 for:组件 JSelectDepart.vue不是默认id时新内容编辑问题 gitee I247X2
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
@ -88,6 +95,24 @@
|
||||
}).join(',')
|
||||
}
|
||||
//update-end-author:lvdandan date:20200513 for:TESTA-438 部门选择组件自定义返回值,数据无法回填
|
||||
this.backDeparInfo()
|
||||
},
|
||||
//返回选中的部门信息
|
||||
backDeparInfo(){
|
||||
if(this.backDepart===true){
|
||||
if(this.departIds && this.departIds.length>0){
|
||||
let arr1 = this.departIds.split(',')
|
||||
let arr2 = this.departNames.split(',')
|
||||
let info = []
|
||||
for(let i=0;i<arr1.length;i++){
|
||||
info.push({
|
||||
value: arr1[i],
|
||||
text: arr2[i]
|
||||
})
|
||||
}
|
||||
this.$emit('back', info)
|
||||
}
|
||||
}
|
||||
},
|
||||
openModal(){
|
||||
this.$refs.innerDepartSelectModal.show()
|
||||
|
||||
@ -38,6 +38,11 @@
|
||||
default: true,
|
||||
required: false
|
||||
},
|
||||
backUser: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -61,6 +66,23 @@
|
||||
initComp(userNames) {
|
||||
this.userNames = userNames
|
||||
},
|
||||
//返回选中的用户信息
|
||||
backDeparInfo(){
|
||||
if(this.backUser===true){
|
||||
if(this.userIds && this.userIds.length>0){
|
||||
let arr1 = this.userIds.split(',')
|
||||
let arr2 = this.userNames.split(',')
|
||||
let info = []
|
||||
for(let i=0;i<arr1.length;i++){
|
||||
info.push({
|
||||
value: arr1[i],
|
||||
text: arr2[i]
|
||||
})
|
||||
}
|
||||
this.$emit('back', info)
|
||||
}
|
||||
}
|
||||
},
|
||||
onSearchDepUser() {
|
||||
this.$refs.selectModal.showModal()
|
||||
},
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
:confirmLoading="confirmLoading"
|
||||
@ok="handleSubmit"
|
||||
@cancel="handleCancel"
|
||||
wrapClassName="j-depart-select-modal"
|
||||
switchFullscreen
|
||||
cancelText="关闭">
|
||||
<a-spin tip="Loading..." :spinning="false">
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
:visible="visible"
|
||||
:title="title"
|
||||
switchFullscreen
|
||||
wrapClassName="j-user-select-modal"
|
||||
@ok="handleSubmit"
|
||||
@cancel="close"
|
||||
style="top:50px"
|
||||
@ -100,7 +101,7 @@
|
||||
{
|
||||
title: '部门',
|
||||
align: 'center',
|
||||
dataIndex: 'orgCode'
|
||||
dataIndex: 'orgCodeTxt'
|
||||
}
|
||||
],
|
||||
scrollTrigger: {},
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<keep-alive>
|
||||
<keep-alive :include="includedComponents">
|
||||
<router-view v-if="keepAlive" />
|
||||
</keep-alive>
|
||||
<router-view v-if="!keepAlive" />
|
||||
@ -8,9 +8,32 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import { CACHE_INCLUDED_ROUTES } from "@/store/mutation-types"
|
||||
|
||||
export default {
|
||||
name: "RouteView",
|
||||
computed: {
|
||||
//update-begin--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
includedComponents() {
|
||||
const includedRouters = Vue.ls.get(CACHE_INCLUDED_ROUTES)
|
||||
console.log("includedRouters:" + includedRouters)
|
||||
|
||||
//如果是缓存路由,则加入到 cache_included_routes
|
||||
if (this.$route.meta.keepAlive && this.$route.meta.componentName) {
|
||||
let cacheRouterArray = Vue.ls.get(CACHE_INCLUDED_ROUTES) || []
|
||||
if(!cacheRouterArray.includes(this.$route.meta.componentName)){
|
||||
cacheRouterArray.push(this.$route.meta.componentName)
|
||||
// cacheRouterArray.push("OnlCgformHeadList")
|
||||
console.log("Vue ls set componentName :" + this.$route.meta.componentName)
|
||||
Vue.ls.set(CACHE_INCLUDED_ROUTES, cacheRouterArray)
|
||||
console.log("Vue ls includedRouterArrays :" + Vue.ls.get(CACHE_INCLUDED_ROUTES))
|
||||
return cacheRouterArray;
|
||||
}
|
||||
}
|
||||
return includedRouters;
|
||||
},
|
||||
//update-end--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
keepAlive () {
|
||||
return this.$route.meta.keepAlive
|
||||
}
|
||||
|
||||
@ -14,19 +14,19 @@
|
||||
@change="changePage"
|
||||
@tabClick="tabCallBack"
|
||||
@edit="editPage">
|
||||
<a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList">
|
||||
<a-tab-pane :id="page.fullPath" :key="page.fullPath" v-for="page in pageList" :closable="!(page.meta.title=='首页')">
|
||||
<span slot="tab" :pagekey="page.fullPath">{{ page.meta.title }}</span>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
<div style="margin: 12px 12px 0;">
|
||||
<transition name="page-toggle">
|
||||
<keep-alive v-if="multipage">
|
||||
<router-view v-if="reloadFlag"/>
|
||||
</keep-alive>
|
||||
<template v-else>
|
||||
<router-view v-if="reloadFlag"/>
|
||||
</template>
|
||||
</transition>
|
||||
<!-- update-begin-author:taoyan date:20201221 for:此处删掉transition标签 不知道为什么加上后 页面路由切换的时候即1及菜单切到2及菜单的时候 两个菜单页面会同时出现300-500秒左右 -->
|
||||
<keep-alive v-if="multipage">
|
||||
<router-view v-if="reloadFlag"/>
|
||||
</keep-alive>
|
||||
<template v-else>
|
||||
<router-view v-if="reloadFlag"/>
|
||||
</template>
|
||||
<!-- update-end-author:taoyan date:20201221 for:此处删掉transition标签 不知道为什么加上后 页面路由切换的时候即1及菜单切到2及菜单的时候 两个菜单页面会同时出现300-500秒左右 -->
|
||||
</div>
|
||||
</global-layout>
|
||||
</template>
|
||||
@ -36,8 +36,9 @@
|
||||
import Contextmenu from '@/components/menu/Contextmenu'
|
||||
import { mixin, mixinDevice } from '@/utils/mixin.js'
|
||||
import { triggerWindowResizeEvent } from '@/utils/util'
|
||||
|
||||
const indexKey = '/dashboard/analysis'
|
||||
import Vue from 'vue'
|
||||
import { CACHE_INCLUDED_ROUTES } from "@/store/mutation-types"
|
||||
|
||||
export default {
|
||||
name: 'TabLayout',
|
||||
@ -115,11 +116,11 @@
|
||||
}else if (this.linkList.indexOf(newRoute.fullPath) < 0) {
|
||||
this.linkList.push(newRoute.fullPath)
|
||||
this.pageList.push(Object.assign({},newRoute))
|
||||
// update-begin-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍 #842
|
||||
//// update-begin-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍 #842
|
||||
// if (newRoute.meta.keepAlive) {
|
||||
// this.routeReload()
|
||||
// }
|
||||
// update-end-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍 #842
|
||||
//// update-end-author:sunjianlei date:20200103 for: 如果新增的页面配置了缓存路由,那么就强制刷新一遍 #842
|
||||
} else if (this.linkList.indexOf(newRoute.fullPath) >= 0) {
|
||||
let oldIndex = this.linkList.indexOf(newRoute.fullPath)
|
||||
let oldPositionRoute = this.pageList[oldIndex]
|
||||
@ -132,8 +133,8 @@
|
||||
// 【TESTA-523】修复:不允许重复跳转路由异常
|
||||
if (waitRouter.fullPath !== this.$route.fullPath) {
|
||||
this.$router.push(Object.assign({}, waitRouter))
|
||||
this.changeTitle(waitRouter.meta.title)
|
||||
}
|
||||
this.changeTitle(waitRouter.meta.title)
|
||||
},
|
||||
'multipage': function(newVal) {
|
||||
if(this.reloadFlag){
|
||||
@ -185,7 +186,12 @@
|
||||
},
|
||||
tabCallBack() {
|
||||
this.$nextTick(() => {
|
||||
triggerWindowResizeEvent()
|
||||
//update-begin-author:taoyan date: 20201211 for:【新版】online报错 JT-100
|
||||
setTimeout(()=>{
|
||||
//省市区组件里面给window绑定了个resize事件 导致切换页面的时候触发了他的resize,但是切换页面,省市区组件还没被销毁前就触发了该事件,导致控制台报错,加个延迟
|
||||
triggerWindowResizeEvent()
|
||||
},20)
|
||||
//update-end-author:taoyan date: 20201211 for:【新版】online报错 JT-100
|
||||
})
|
||||
},
|
||||
editPage(key, action) {
|
||||
@ -201,11 +207,27 @@
|
||||
return
|
||||
}
|
||||
console.log("this.pageList ",this.pageList );
|
||||
let removeRoute = this.pageList.filter(item => item.fullPath == key)
|
||||
this.pageList = this.pageList.filter(item => item.fullPath !== key)
|
||||
let index = this.linkList.indexOf(key)
|
||||
this.linkList = this.linkList.filter(item => item !== key)
|
||||
index = index >= this.linkList.length ? this.linkList.length - 1 : index
|
||||
this.activePage = this.linkList[index]
|
||||
|
||||
//update-begin--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
//关闭页面则从缓存cache_included_routes中删除路由,下次点击菜单会重新加载页面
|
||||
let cacheRouterArray = Vue.ls.get(CACHE_INCLUDED_ROUTES) || []
|
||||
if (removeRoute && removeRoute[0]) {
|
||||
let componentName = removeRoute[0].meta.componentName
|
||||
console.log("key: ", key);
|
||||
console.log("componentName: ", componentName);
|
||||
if(cacheRouterArray.includes(componentName)){
|
||||
cacheRouterArray.splice(cacheRouterArray.findIndex(item => item === componentName), 1)
|
||||
Vue.ls.set(CACHE_INCLUDED_ROUTES, cacheRouterArray)
|
||||
}
|
||||
}
|
||||
//update-end--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
|
||||
},
|
||||
onContextmenu(e) {
|
||||
const pagekey = this.getPageKey(e.target)
|
||||
@ -401,4 +423,4 @@
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
/**
|
||||
* 按需加载antd组件
|
||||
*/
|
||||
import Vue from 'vue'
|
||||
|
||||
// base library
|
||||
@ -50,6 +53,11 @@ import {
|
||||
TreeSelect,
|
||||
Carousel,
|
||||
Pagination,
|
||||
FormModel,
|
||||
Cascader,
|
||||
Slider,
|
||||
Transfer,
|
||||
Rate
|
||||
} from 'ant-design-vue'
|
||||
import Viser from 'viser-vue'
|
||||
|
||||
@ -99,6 +107,11 @@ Vue.use(Tree)
|
||||
Vue.use(TreeSelect)
|
||||
Vue.use(Carousel)
|
||||
Vue.use(Pagination)
|
||||
Vue.use(FormModel)
|
||||
Vue.use(Cascader)
|
||||
Vue.use(Slider)
|
||||
Vue.use(Transfer)
|
||||
Vue.use(Rate)
|
||||
|
||||
Vue.prototype.$confirm = Modal.confirm
|
||||
Vue.prototype.$message = message
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-layout-sider
|
||||
:class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null ]"
|
||||
width="200px"
|
||||
width="208px"
|
||||
:collapsible="collapsible"
|
||||
v-model="collapsed"
|
||||
:trigger="null">
|
||||
@ -141,7 +141,6 @@
|
||||
}
|
||||
|
||||
/* update_end author:sunjianlei date:20190509 for: 修改侧边导航栏滚动条的样式 */
|
||||
|
||||
</style>
|
||||
|
||||
<!-- update_begin author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
|
||||
@ -174,4 +173,4 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<!-- update_end author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
|
||||
<!-- update_end author:sunjianlei date:20190530 for: 选中首页的时候不显示背景颜色 -->
|
||||
|
||||
@ -131,6 +131,11 @@
|
||||
//--update-begin----author:scott---date:20190320------for:根据后台菜单配置,判断是否路由菜单字段,动态选择是否生成路由(为了支持参数URL菜单)------
|
||||
//this.menus = this.mainRouters.find((item) => item.path === '/').children;
|
||||
this.menus = this.permissionMenuList
|
||||
|
||||
//--update-begin----author:liusq---date:20210223------for:关于测边菜单遮挡内容问题详细说明 #2255
|
||||
this.collapsed=!this.sidebarOpened;
|
||||
//--update-begin----author:liusq---date:20210223------for:关于测边菜单遮挡内容问题详细说明 #2255
|
||||
|
||||
// 根据后台配置菜单,重新排序加载路由信息
|
||||
//console.log('----加载菜单逻辑----')
|
||||
//console.log(this.mainRouters)
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
:closable="false"
|
||||
@close="onClose"
|
||||
:visible="visible"
|
||||
:style="{}"
|
||||
style="height: 100%;overflow: auto;"
|
||||
>
|
||||
<div class="setting-drawer-index-content">
|
||||
|
||||
@ -113,7 +113,7 @@
|
||||
<div slot="title" :style="{ textDecoration: !fixedHeader ? 'line-through' : 'unset' }">下滑时隐藏 Header</div>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item >
|
||||
<a-list-item>
|
||||
<a-switch slot="actions" size="small" :disabled="(layoutMode === 'topmenu')" :checked="dataFixSiderbar" @change="handleFixSiderbar" />
|
||||
<a-list-item-meta>
|
||||
<div slot="title" :style="{ textDecoration: layoutMode === 'topmenu' ? 'line-through' : 'unset' }">固定侧边菜单</div>
|
||||
@ -178,19 +178,12 @@
|
||||
mixins: [mixin, mixinDevice],
|
||||
data() {
|
||||
return {
|
||||
visible: true,
|
||||
visible: false,
|
||||
colorList,
|
||||
dataFixSiderbar: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
const vm = this
|
||||
setTimeout(() => {
|
||||
vm.visible = false
|
||||
}, 16)
|
||||
// 当主题色不是默认色时,才进行主题编译
|
||||
if (this.primaryColor !== config.primaryColor) {
|
||||
updateTheme(this.primaryColor)
|
||||
@ -327,4 +320,4 @@
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@ -133,6 +133,15 @@
|
||||
this.searchMenus(lists,this.permissionMenuList)
|
||||
this.searchMenuOptions=[...lists]
|
||||
},
|
||||
mounted() {
|
||||
//如果是单点登录模式
|
||||
if (process.env.VUE_APP_SSO == 'true') {
|
||||
let depart = this.userInfo().orgCode
|
||||
if (!depart) {
|
||||
this.updateCurrentDepart()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
// 后台菜单
|
||||
|
||||
10
ant-design-vue-jeecg/src/config/index.js
Normal file
10
ant-design-vue-jeecg/src/config/index.js
Normal file
@ -0,0 +1,10 @@
|
||||
/** init domain config */
|
||||
import Vue from 'vue'
|
||||
//设置全局API_BASE_URL
|
||||
Vue.prototype.API_BASE_URL = process.env.VUE_APP_API_BASE_URL
|
||||
window._CONFIG['domianURL'] = Vue.prototype.API_BASE_URL
|
||||
//单点登录地址
|
||||
window._CONFIG['casPrefixUrl'] = process.env.VUE_APP_CAS_BASE_URL
|
||||
window._CONFIG['onlinePreviewDomainURL'] = process.env.VUE_APP_ONLINE_BASE_URL
|
||||
window._CONFIG['staticDomainURL'] = Vue.prototype.API_BASE_URL + '/sys/common/static'
|
||||
window._CONFIG['pdfDomainURL'] = Vue.prototype.API_BASE_URL+ '/sys/common/pdf/pdfPreviewIframe'
|
||||
@ -308,17 +308,17 @@ export const constantRouterMap = [
|
||||
{
|
||||
path: 'register',
|
||||
name: 'register',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Register')
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/register/Register')
|
||||
},
|
||||
{
|
||||
path: 'register-result',
|
||||
name: 'registerResult',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/RegisterResult')
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/register/RegisterResult')
|
||||
},
|
||||
{
|
||||
path: 'alteration',
|
||||
name: 'alteration',
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Alteration')
|
||||
component: () => import(/* webpackChunkName: "user" */ '@/views/user/alteration/Alteration')
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
/** init domain config */
|
||||
import './config'
|
||||
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import Storage from 'vue-ls'
|
||||
import router from './router'
|
||||
import store from './store/'
|
||||
|
||||
import { VueAxios } from "@/utils/request"
|
||||
|
||||
require('@jeecg/antd-online-mini')
|
||||
require('@jeecg/antd-online-mini/dist/OnlineForm.css')
|
||||
|
||||
import Antd, { version } from 'ant-design-vue'
|
||||
console.log('ant-design-vue version:', version)
|
||||
|
||||
@ -18,11 +23,7 @@ import Print from 'vue-print-nb-jeecg'
|
||||
/*import '@babel/polyfill'*/
|
||||
import preview from 'vue-photo-preview'
|
||||
import 'vue-photo-preview/dist/skin.css'
|
||||
|
||||
require('@jeecg/antd-online-mini')
|
||||
require('@jeecg/antd-online-mini/dist/OnlineForm.css')
|
||||
|
||||
|
||||
import SSO from '@/cas/sso.js'
|
||||
import {
|
||||
ACCESS_TOKEN,
|
||||
DEFAULT_COLOR,
|
||||
@ -60,21 +61,26 @@ Vue.use(vueBus);
|
||||
Vue.use(JeecgComponents);
|
||||
Vue.use(VueAreaLinkage);
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
mounted () {
|
||||
store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
|
||||
store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
|
||||
store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
|
||||
store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
|
||||
store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
|
||||
store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
|
||||
store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
|
||||
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
|
||||
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
|
||||
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
|
||||
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
|
||||
},
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
SSO.init(() => {
|
||||
main()
|
||||
})
|
||||
function main() {
|
||||
new Vue({
|
||||
router,
|
||||
store,
|
||||
mounted () {
|
||||
store.commit('SET_SIDEBAR_TYPE', Vue.ls.get(SIDEBAR_TYPE, true))
|
||||
store.commit('TOGGLE_THEME', Vue.ls.get(DEFAULT_THEME, config.navTheme))
|
||||
store.commit('TOGGLE_LAYOUT_MODE', Vue.ls.get(DEFAULT_LAYOUT_MODE, config.layout))
|
||||
store.commit('TOGGLE_FIXED_HEADER', Vue.ls.get(DEFAULT_FIXED_HEADER, config.fixedHeader))
|
||||
store.commit('TOGGLE_FIXED_SIDERBAR', Vue.ls.get(DEFAULT_FIXED_SIDEMENU, config.fixSiderbar))
|
||||
store.commit('TOGGLE_CONTENT_WIDTH', Vue.ls.get(DEFAULT_CONTENT_WIDTH_TYPE, config.contentWidth))
|
||||
store.commit('TOGGLE_FIXED_HEADER_HIDDEN', Vue.ls.get(DEFAULT_FIXED_HEADER_HIDDEN, config.autoHideHeader))
|
||||
store.commit('TOGGLE_WEAK', Vue.ls.get(DEFAULT_COLOR_WEAK, config.colorWeak))
|
||||
store.commit('TOGGLE_COLOR', Vue.ls.get(DEFAULT_COLOR, config.primaryColor))
|
||||
store.commit('SET_TOKEN', Vue.ls.get(ACCESS_TOKEN))
|
||||
store.commit('SET_MULTI_PAGE',Vue.ls.get(DEFAULT_MULTI_PAGE,config.multipage))
|
||||
},
|
||||
render: h => h(App)
|
||||
}).$mount('#app')
|
||||
}
|
||||
@ -48,21 +48,30 @@ export const JEditableTableMixin = {
|
||||
|
||||
/** 当点击新增按钮时调用此方法 */
|
||||
add() {
|
||||
if (typeof this.addBefore === 'function') this.addBefore()
|
||||
// 默认新增空数据
|
||||
let rowNum = this.addDefaultRowNum
|
||||
if (typeof rowNum !== 'number') {
|
||||
rowNum = 1
|
||||
console.warn('由于你没有在 data 中定义 addDefaultRowNum 或 addDefaultRowNum 不是数字,所以默认添加一条空数据,如果不想默认添加空数据,请将定义 addDefaultRowNum 为 0')
|
||||
}
|
||||
this.eachAllTable((item) => {
|
||||
item.add(rowNum)
|
||||
//update-begin-author:lvdandan date:20201113 for:LOWCOD-1049 JEditaTable,子表默认添加一条数据,addDefaultRowNum设置无效 #1930
|
||||
return new Promise((resolve) => {
|
||||
this.tableReset();
|
||||
resolve();
|
||||
}).then(() => {
|
||||
// 默认新增空数据
|
||||
let rowNum = this.addDefaultRowNum
|
||||
if (typeof rowNum !== 'number') {
|
||||
rowNum = 1
|
||||
console.warn('由于你没有在 data 中定义 addDefaultRowNum 或 addDefaultRowNum 不是数字,所以默认添加一条空数据,如果不想默认添加空数据,请将定义 addDefaultRowNum 为 0')
|
||||
}
|
||||
this.eachAllTable((item) => {
|
||||
item.add(rowNum)
|
||||
})
|
||||
if (typeof this.addAfter === 'function') this.addAfter(this.model)
|
||||
this.edit({})
|
||||
})
|
||||
if (typeof this.addAfter === 'function') this.addAfter(this.model)
|
||||
this.edit({})
|
||||
//update-end-author:lvdandan date:20201113 for:LOWCOD-1049 JEditaTable,子表默认添加一条数据,addDefaultRowNum设置无效 #1930
|
||||
},
|
||||
/** 当点击了编辑(修改)按钮时调用此方法 */
|
||||
edit(record) {
|
||||
if(record && '{}'!=JSON.stringify(record)){
|
||||
this.tableReset();
|
||||
}
|
||||
if (typeof this.editBefore === 'function') this.editBefore(record)
|
||||
this.visible = true
|
||||
this.activeKey = this.refKeys[0]
|
||||
@ -73,12 +82,14 @@ export const JEditableTableMixin = {
|
||||
/** 关闭弹窗,并将所有JEditableTable实例回归到初始状态 */
|
||||
close() {
|
||||
this.visible = false
|
||||
this.eachAllTable((item) => {
|
||||
item.initialize()
|
||||
})
|
||||
this.$emit('close')
|
||||
},
|
||||
|
||||
//清空子表table的数据
|
||||
tableReset(){
|
||||
this.eachAllTable((item) => {
|
||||
item.clearRow()
|
||||
})
|
||||
},
|
||||
/** 查询某个tab的数据 */
|
||||
requestSubTableData(url, params, tab, success) {
|
||||
tab.loading = true
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
import { filterObj } from '@/utils/util';
|
||||
import { deleteAction, getAction,downFile,getFileAccessHttpUrl } from '@/api/manage'
|
||||
import Vue from 'vue'
|
||||
import { ACCESS_TOKEN } from "@/store/mutation-types"
|
||||
import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
|
||||
import store from '@/store'
|
||||
import {Modal} from 'ant-design-vue'
|
||||
|
||||
export const JeecgListMixin = {
|
||||
data(){
|
||||
return {
|
||||
//token header
|
||||
tokenHeader: {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)},
|
||||
/* 查询条件-请不要在queryParam中声明非字符串值的属性 */
|
||||
queryParam: {},
|
||||
/* 数据源 */
|
||||
@ -60,6 +60,17 @@ export const JeecgListMixin = {
|
||||
this.initDictConfig();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
//token header
|
||||
tokenHeader(){
|
||||
let head = {'X-Access-Token': Vue.ls.get(ACCESS_TOKEN)}
|
||||
let tenantid = Vue.ls.get(TENANT_ID)
|
||||
if(tenantid){
|
||||
head['tenant_id'] = tenantid
|
||||
}
|
||||
return head;
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
loadData(arg) {
|
||||
if(!this.url.list){
|
||||
@ -74,8 +85,15 @@ export const JeecgListMixin = {
|
||||
this.loading = true;
|
||||
getAction(this.url.list, params).then((res) => {
|
||||
if (res.success) {
|
||||
this.dataSource = res.result.records;
|
||||
this.ipagination.total = res.result.total;
|
||||
//update-begin---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
|
||||
this.dataSource = res.result.records||res.result;
|
||||
if(res.result.total)
|
||||
{
|
||||
this.ipagination.total = res.result.total;
|
||||
}else{
|
||||
this.ipagination.total = 0;
|
||||
}
|
||||
//update-end---author:zhangyafei Date:20201118 for:适配不分页的数据列表------------
|
||||
}
|
||||
if(res.code===510){
|
||||
this.$message.warning(res.message)
|
||||
@ -217,6 +235,8 @@ export const JeecgListMixin = {
|
||||
modalFormOk() {
|
||||
// 新增/修改 成功时,重载列表
|
||||
this.loadData();
|
||||
//清空列表选中
|
||||
this.onClearSelected()
|
||||
},
|
||||
handleDetail:function(record){
|
||||
this.$refs.modalForm.edit(record);
|
||||
@ -233,7 +253,7 @@ export const JeecgListMixin = {
|
||||
if(!fileName || typeof fileName != "string"){
|
||||
fileName = "导出文件"
|
||||
}
|
||||
let param = {...this.queryParam};
|
||||
let param = this.getQueryParams();
|
||||
if(this.selectedRowKeys && this.selectedRowKeys.length>0){
|
||||
param['selections'] = this.selectedRowKeys.join(",")
|
||||
}
|
||||
@ -271,8 +291,7 @@ export const JeecgListMixin = {
|
||||
let href = window._CONFIG['domianURL'] + fileUrl
|
||||
this.$warning({
|
||||
title: message,
|
||||
content: (
|
||||
<div>
|
||||
content: (<div>
|
||||
<span>{msg}</span><br/>
|
||||
<span>具体详情请 <a href={href} target="_blank" download={fileName}>点击下载</a> </span>
|
||||
</div>
|
||||
@ -286,7 +305,26 @@ export const JeecgListMixin = {
|
||||
this.$message.error(`${info.file.name} ${info.file.response.message}.`);
|
||||
}
|
||||
} else if (info.file.status === 'error') {
|
||||
this.$message.error(`文件上传失败: ${info.file.msg} `);
|
||||
if (info.file.response.status === 500) {
|
||||
let data = info.file.response
|
||||
const token = Vue.ls.get(ACCESS_TOKEN)
|
||||
if (token && data.message.includes("Token失效")) {
|
||||
Modal.error({
|
||||
title: '登录已过期',
|
||||
content: '很抱歉,登录已过期,请重新登录',
|
||||
okText: '重新登录',
|
||||
mask: false,
|
||||
onOk: () => {
|
||||
store.dispatch('Logout').then(() => {
|
||||
Vue.ls.remove(ACCESS_TOKEN)
|
||||
window.location.reload();
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
this.$message.error(`文件上传失败: ${info.file.msg} `);
|
||||
}
|
||||
}
|
||||
},
|
||||
/* 图片预览 */
|
||||
|
||||
@ -1,116 +0,0 @@
|
||||
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
|
||||
|
||||
export const HrefJump = {
|
||||
data() {
|
||||
return {
|
||||
fieldHrefSlots: [],
|
||||
hrefComponent: {
|
||||
model: {
|
||||
title: '',
|
||||
width: '100%',
|
||||
visible: false,
|
||||
destroyOnClose: true,
|
||||
style: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
height: '100%',
|
||||
margin: 0,
|
||||
padding: 0
|
||||
},
|
||||
bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' },
|
||||
// 隐藏掉取消按钮
|
||||
cancelButtonProps: { style: { display: 'none' } }
|
||||
},
|
||||
on: {
|
||||
ok: () => this.hrefComponent.model.visible = false,
|
||||
cancel: () => this.hrefComponent.model.visible = false
|
||||
},
|
||||
is: null,
|
||||
params: {},
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 处理接收href参数
|
||||
handleAcceptHrefParams(){
|
||||
this.acceptHrefParams={}
|
||||
let hrefparam = this.$route.query;
|
||||
if(hrefparam){
|
||||
this.acceptHrefParams = {...hrefparam}
|
||||
}
|
||||
},
|
||||
//支持链接href跳转
|
||||
handleClickFieldHref(field, record) {
|
||||
let href = field.href
|
||||
let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?/
|
||||
let compPattern = /\.vue(\?.*)?$/
|
||||
if (typeof href === 'string') {
|
||||
href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2])
|
||||
if (urlPattern.test(href)) {
|
||||
window.open(href, '_blank')
|
||||
} else if (compPattern.test(href)) {
|
||||
this.openHrefCompModal(href)
|
||||
} else {
|
||||
this.$router.push(href)
|
||||
}
|
||||
}
|
||||
},
|
||||
openHrefCompModal(href) {
|
||||
// 解析 href 参数
|
||||
let index = href.indexOf('?')
|
||||
let path = href
|
||||
if (index !== -1) {
|
||||
path = href.substring(0, index)
|
||||
let paramString = href.substring(index + 1, href.length)
|
||||
let paramArray = paramString.split('&')
|
||||
let params = {}
|
||||
paramArray.forEach(paramObject => {
|
||||
let paramItem = paramObject.split('=')
|
||||
params[paramItem[0]] = paramItem[1]
|
||||
})
|
||||
this.hrefComponent.params = params
|
||||
} else {
|
||||
this.hrefComponent.params = {}
|
||||
}
|
||||
this.hrefComponent.model.visible = true
|
||||
this.hrefComponent.model.title = '操作'
|
||||
this.hrefComponent.is = () => import('@/views/' + (path.startsWith('/') ? path.slice(1) : path))
|
||||
},
|
||||
/** 处理列中的 href 跳转和 dict 字典,使两者可以兼容存在 */
|
||||
handleColumnHrefAndDict(column = {}, fieldHrefSlotKeysMap = {}) {
|
||||
let { customRender, hrefSlotName } = column
|
||||
if (!hrefSlotName && (column.scopedSlots && column.scopedSlots.customRender)) {
|
||||
//hrefSlotName = column.scopedSlots.customRender
|
||||
}
|
||||
// 如果 customRender 有值则代表使用了字典
|
||||
// 如果 hrefSlotName 有值则代表使用了href跳转
|
||||
// 两者可以兼容。兼容的具体思路为:先获取到字典替换的值,再添加href链接跳转
|
||||
if (customRender || hrefSlotName) {
|
||||
let dictCode = customRender
|
||||
let replaceFlag = '_replace_text_'
|
||||
column.customRender = (text, record) => {
|
||||
let value = text
|
||||
// 如果 dictCode 有值,就进行字典转换
|
||||
if (dictCode) {
|
||||
if (dictCode.startsWith(replaceFlag)) {
|
||||
let textFieldName = dictCode.replace(replaceFlag, '')
|
||||
value = record[textFieldName]
|
||||
} else {
|
||||
value = filterMultiDictText(this.dictOptions[dictCode], text)
|
||||
}
|
||||
}
|
||||
// 如果 hrefSlotName 有值,就生成一个 a 标签,包裹住字典替换后(或原生)的值
|
||||
if (hrefSlotName) {
|
||||
let field = fieldHrefSlotKeysMap[hrefSlotName]
|
||||
if (field) {
|
||||
// 此处为 JSX 语法
|
||||
return (<a onClick={() => this.handleClickFieldHref(field, record)}>{value}</a>)
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
@ -2,16 +2,6 @@ import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import { constantRouterMap } from '@/config/router.config'
|
||||
|
||||
//update-begin-author:taoyan date:20191011 for:TASK #3214 【优化】访问online功能测试 浏览器控制台抛出异常
|
||||
try {
|
||||
const originalPush = Router.prototype.push
|
||||
Router.prototype.push = function push(location) {
|
||||
return originalPush.call(this, location).catch(err => err)
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
//update-end-author:taoyan date:20191011 for:TASK #3214 【优化】访问online功能测试 浏览器控制台抛出异常
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
import { login, logout, phoneLogin, thirdLogin } from "@/api/login"
|
||||
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH,UI_CACHE_DB_DICT_DATA,TENANT_ID } from "@/store/mutation-types"
|
||||
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH,UI_CACHE_DB_DICT_DATA,TENANT_ID,CACHE_INCLUDED_ROUTES } from "@/store/mutation-types"
|
||||
import { welcome } from "@/utils/util"
|
||||
import { queryPermissionsByUser } from '@/api/api'
|
||||
import { getAction } from '@/api/manage'
|
||||
@ -44,7 +44,7 @@ const user = {
|
||||
// CAS验证登录
|
||||
ValidateLogin({ commit }, userInfo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
getAction("/cas/client/validateLogin",userInfo).then(response => {
|
||||
getAction("/sys/cas/client/validateLogin",userInfo).then(response => {
|
||||
console.log("----cas 登录--------",response);
|
||||
if(response.success){
|
||||
const result = response.result
|
||||
@ -116,9 +116,7 @@ const user = {
|
||||
// 获取用户信息
|
||||
GetPermissionList({ commit }) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let v_token = Vue.ls.get(ACCESS_TOKEN);
|
||||
let params = {token:v_token};
|
||||
queryPermissionsByUser(params).then(response => {
|
||||
queryPermissionsByUser().then(response => {
|
||||
const menuData = response.result.menu;
|
||||
const authData = response.result.auth;
|
||||
const allAuthData = response.result.allAuth;
|
||||
@ -157,12 +155,17 @@ const user = {
|
||||
commit('SET_TOKEN', '')
|
||||
commit('SET_PERMISSIONLIST', [])
|
||||
Vue.ls.remove(ACCESS_TOKEN)
|
||||
Vue.ls.remove(USER_INFO)
|
||||
Vue.ls.remove(USER_NAME)
|
||||
Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
|
||||
Vue.ls.remove(CACHE_INCLUDED_ROUTES)
|
||||
//console.log('logoutToken: '+ logoutToken)
|
||||
logout(logoutToken).then(() => {
|
||||
//let sevice = "http://"+window.location.host+"/";
|
||||
//let serviceUrl = encodeURIComponent(sevice);
|
||||
//window.location.href = window._CONFIG['casPrefixUrl']+"/logout?service="+serviceUrl;
|
||||
if (process.env.VUE_APP_SSO == 'true') {
|
||||
let sevice = 'http://' + window.location.host + '/'
|
||||
let serviceUrl = encodeURIComponent(sevice)
|
||||
window.location.href = process.env.VUE_APP_CAS_BASE_URL + '/logout?service=' + serviceUrl
|
||||
}
|
||||
resolve()
|
||||
}).catch(() => {
|
||||
resolve()
|
||||
@ -170,9 +173,9 @@ const user = {
|
||||
})
|
||||
},
|
||||
// 第三方登录
|
||||
ThirdLogin({ commit }, token) {
|
||||
ThirdLogin({ commit }, param) {
|
||||
return new Promise((resolve, reject) => {
|
||||
thirdLogin(token).then(response => {
|
||||
thirdLogin(param.token,param.thirdType).then(response => {
|
||||
if(response.code =='200'){
|
||||
const result = response.result
|
||||
const userInfo = result.userInfo
|
||||
|
||||
@ -19,7 +19,8 @@ export const UI_CACHE_DB_DICT_DATA = 'UI_CACHE_DB_DICT_DATA'
|
||||
export const INDEX_MAIN_PAGE_PATH = '/dashboard/analysis'
|
||||
export const TENANT_ID = 'TENANT_ID'
|
||||
export const ONL_AUTH_FIELDS = 'ONL_AUTH_FIELDS'
|
||||
|
||||
//路由缓存问题,关闭了tab页时再打开就不刷新 #842
|
||||
export const CACHE_INCLUDED_ROUTES = 'CACHE_INCLUDED_ROUTES'
|
||||
export const CONTENT_WIDTH_TYPE = {
|
||||
Fluid: 'Fluid',
|
||||
Fixed: 'Fixed'
|
||||
|
||||
@ -17,7 +17,8 @@ const FormTypes = {
|
||||
radio:'radio',
|
||||
checkbox_meta:"checkbox_meta",
|
||||
input_pop:'input_pop',
|
||||
|
||||
sel_depart: 'sel_depart',
|
||||
sel_user: 'sel_user',
|
||||
slot: 'slot',
|
||||
hidden: 'hidden'
|
||||
}
|
||||
|
||||
@ -206,6 +206,37 @@ export function getNoAuthCols(pre){
|
||||
return cols;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Online的行编辑按钮权限,添加至本地存储
|
||||
*/
|
||||
export function addOnlineBtAuth2Storage(pre, authList){
|
||||
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
|
||||
let newAuthList = allAuthList.filter(item=>{
|
||||
if(!item.action){
|
||||
return true
|
||||
}
|
||||
return item.action.indexOf(pre)<0
|
||||
})
|
||||
if(authList && authList.length>0){
|
||||
for(let item of authList){
|
||||
newAuthList.push({
|
||||
action: pre+item,
|
||||
type:1,
|
||||
status:1
|
||||
})
|
||||
}
|
||||
let temp = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
|
||||
let newArr = temp.filter(item=>{
|
||||
if(!item.action){
|
||||
return true
|
||||
}
|
||||
return item.action.indexOf(pre)<0 || authList.indexOf(item.action.replace(pre, ''))<0
|
||||
})
|
||||
sessionStorage.setItem(USER_AUTH, JSON.stringify(newArr))
|
||||
}
|
||||
sessionStorage.setItem(SYS_BUTTON_AUTH, JSON.stringify(newAuthList))
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
import router from '@/router'
|
||||
import { getAction } from '@api/manage'
|
||||
|
||||
/** 表单设计器路由类型 */
|
||||
export const DESFORM_ROUTE_TYPE = {
|
||||
/** 跳转到表单 */
|
||||
form: '1',
|
||||
/** 跳转到菜单 */
|
||||
menu: '2',
|
||||
/** 跳转到外部链接 */
|
||||
href: '3',
|
||||
}
|
||||
/** 表单设计器路由跳转带过来的ID名字 */
|
||||
export const DESFORM_ROUTE_DATA_ID = 'routeDataId'
|
||||
|
||||
/**
|
||||
* 获取当前路由或指定路由的 routeDataId
|
||||
*
|
||||
* @param $route 路由对象,默认为当前路由
|
||||
*/
|
||||
export function getDesformRouteDataId($route) {
|
||||
if (arguments.length === 0) {
|
||||
$route = router.currentRoute
|
||||
}
|
||||
if ($route) {
|
||||
return $route.query[DESFORM_ROUTE_DATA_ID]
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据路由跳转带过来的ID来获取表单设计器的数据
|
||||
* @param param 表单设计器路由跳转带过来的ID(可以直接传id字符串,也可以传 this.$route,自动从$route里获取id,如果不传就获取当前路由的参数)
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
export async function getDesformDataByRouteDataId(param) {
|
||||
if (!param) {
|
||||
param = router.currentRoute
|
||||
}
|
||||
let id
|
||||
if (typeof param == 'string') {
|
||||
id = param
|
||||
} else if (typeof param.query === 'object') {
|
||||
id = getDesformRouteDataId(param)
|
||||
if (!id) {
|
||||
// 当前$route.query里没有带表单设计器路由ID,直接返回null
|
||||
return null
|
||||
}
|
||||
} else {
|
||||
throw new Error('传递的参数不能识别,可以直接传id字符串,也可以传 this.$route,自动从$route里获取id,如果不传就获取当前路由的参数')
|
||||
}
|
||||
let url = `/desform/data/queryById?id=${id}`
|
||||
let { success, result, message } = await getAction(url)
|
||||
if (success) {
|
||||
result.desformDataJson = JSON.parse(result.desformDataJson)
|
||||
return result
|
||||
} else {
|
||||
throw new Error('表单设计器路由数据获取失败:' + message)
|
||||
}
|
||||
}
|
||||
@ -1,185 +0,0 @@
|
||||
/*
|
||||
* 省市区联动组件通用工具类。
|
||||
* 列表翻译、组件反推、表单设计器组件反推等功能都可以用该工具类实现。
|
||||
*
|
||||
* 1. leafName字段的意义:
|
||||
* AntdvUI和ElementUI的叶级节点名字是不一样的,
|
||||
* AntdvUI的名字是 isLeaf,ElementUI是 leaf,
|
||||
* 默认是AntdvUI的名字,在表单设计器那边需要手动 setLeafName
|
||||
*/
|
||||
|
||||
import { pcaa } from 'area-data'
|
||||
|
||||
export { pcaa }
|
||||
|
||||
/** 根节点Code = 86 */
|
||||
export const ROOT_CODE = '86'
|
||||
|
||||
/** 叶级节点的名字 */
|
||||
let leafName = 'isLeaf'
|
||||
|
||||
/**
|
||||
* set leafName
|
||||
* @param $leafName
|
||||
*/
|
||||
export function setLeafName($leafName = 'isLeaf') {
|
||||
leafName = $leafName
|
||||
}
|
||||
|
||||
/**
|
||||
* 将地区数据转换成下拉框等组件可识别的Options数组
|
||||
* @param data 地区data
|
||||
* @param labelName label标签名字
|
||||
* @return
|
||||
*/
|
||||
export function transToOptions(data, labelName = 'label') {
|
||||
if (data) {
|
||||
return Object.keys(data).map(key => ({ value: key, [labelName]: data[key] }))
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子级Data对象
|
||||
*
|
||||
* @param code 父级地区Code
|
||||
*/
|
||||
export function getChildrenDataByCode(code) {
|
||||
return pcaa[code]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子级Options对象
|
||||
*
|
||||
* @param code 父级地区Code
|
||||
* @return {Array} 返回的值一定是一个数组,如果数组length===0,则代表没有子级
|
||||
*/
|
||||
export function getChildrenOptionsByCode(code) {
|
||||
let options = []
|
||||
let data = getChildrenDataByCode(code)
|
||||
if (data) {
|
||||
for (let key in data) {
|
||||
if (data.hasOwnProperty(key)) {
|
||||
options.push({ value: key, label: data[key], })
|
||||
}
|
||||
}
|
||||
return options
|
||||
} else {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取兄弟Data对象
|
||||
*
|
||||
* @param code 地区Code
|
||||
*/
|
||||
export function getSiblingsDataByCode(code) {
|
||||
if (typeof code === 'string' && code.length === 6) {
|
||||
// 父级节点Code
|
||||
let parentCode = `${code.substring(0, 4)}00`
|
||||
return getChildrenDataByCode(parentCode)
|
||||
} else {
|
||||
console.warn('[getSiblingsByCode]: code不合法')
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对应的 Label
|
||||
*
|
||||
* @param code 地区Code
|
||||
*/
|
||||
export function getLabelByCode(code) {
|
||||
if (code) {
|
||||
// 获取当前code所有的兄弟节点
|
||||
let siblingsData = getSiblingsDataByCode(code)
|
||||
// 然后取出自己的值
|
||||
return siblingsData[code]
|
||||
} else {
|
||||
return code
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的 Label,包括自身和所有父级
|
||||
*
|
||||
* @param code 地区Code
|
||||
* @param joinText 合并文本
|
||||
*/
|
||||
export function getAllLabelByCode(code, joinText = ' / ') {
|
||||
if (code) {
|
||||
let { labels } = getAllParentByCode(code)
|
||||
return labels.join(joinText)
|
||||
} else {
|
||||
return code
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过子级 code 反推所有父级的 code
|
||||
*
|
||||
* @param code 子级地区Code
|
||||
* @returns {Object} options: 所有父级的选项;codes: 所有父级的code;labels: 所有父级的显示名
|
||||
*/
|
||||
export function getAllParentByCode(code) {
|
||||
code = (typeof code === 'string' ? code : '').trim()
|
||||
if (code.length === 0) {
|
||||
return { options: [], codes: [], labels: [] }
|
||||
}
|
||||
// 获取第一级数据
|
||||
let rootOptions = getChildrenOptionsByCode(ROOT_CODE)
|
||||
hasChildren(rootOptions)
|
||||
// 父级code数组,code长度
|
||||
let parentCodes = [code], length = code.length
|
||||
// 父级label数组
|
||||
let parentLabels = [getLabelByCode(code)]
|
||||
// 级别,位数,是否继续循环
|
||||
let level = 1, num = 2, flag = true
|
||||
|
||||
let options = rootOptions
|
||||
do {
|
||||
let endIndex = num * level++
|
||||
// 末尾补零个数
|
||||
let zeroPadding = [...new Array(length - endIndex)].map(i => '0').join('')
|
||||
// 裁剪并补零(获取上级的方式就是将当前code的后两位变成 00)
|
||||
let parentCode = code.substring(0, endIndex) + zeroPadding
|
||||
// 是否找到在选项中的位置
|
||||
let findIt = false
|
||||
for (let option of options) {
|
||||
if (option.value === parentCode) {
|
||||
if (option[leafName]) {
|
||||
flag = false
|
||||
} else {
|
||||
let children = getChildrenOptionsByCode(option.value)
|
||||
hasChildren(children)
|
||||
option.children = children
|
||||
options = children
|
||||
parentCodes.splice(parentCodes.length - 1, 0, option.value)
|
||||
parentLabels.splice(parentLabels.length - 1, 0, option.label)
|
||||
}
|
||||
findIt = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (findIt) {
|
||||
findIt = false
|
||||
} else {
|
||||
flag = false
|
||||
}
|
||||
} while (flag)
|
||||
return { options: rootOptions, codes: parentCodes, labels: parentLabels }
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断所有的项是否有子节点
|
||||
*
|
||||
* @param options
|
||||
*/
|
||||
export function hasChildren(options) {
|
||||
options.forEach(option => {
|
||||
option[leafName] = getChildrenOptionsByCode(option.value).length === 0
|
||||
})
|
||||
}
|
||||
@ -108,6 +108,7 @@ export function filterGlobalPermission(el, binding, vnode) {
|
||||
}
|
||||
let permissions = [];
|
||||
for (let item of permissionList) {
|
||||
//权限策略1显示2禁用
|
||||
if(item.type != '2'){
|
||||
//update--begin--autor:wangshuai-----date:20200729------for:按钮权限,授权标识的提示信息是多个用逗号分隔逻辑处理 gitee#I1OUGU-------
|
||||
if(item.action){
|
||||
|
||||
@ -22,7 +22,6 @@ const service = axios.create({
|
||||
|
||||
const err = (error) => {
|
||||
if (error.response) {
|
||||
let that=this;
|
||||
let data = error.response.data
|
||||
const token = Vue.ls.get(ACCESS_TOKEN)
|
||||
console.log("------异常响应------",token)
|
||||
@ -32,6 +31,14 @@ const err = (error) => {
|
||||
notification.error({ message: '系统提示', description: '拒绝访问',duration: 4})
|
||||
break
|
||||
case 500:
|
||||
console.log("------error.response------",error.response)
|
||||
// update-begin- --- author:liusq ------ date:20200910 ---- for:处理Blob情况----
|
||||
let type=error.response.request.responseType;
|
||||
if(type === 'blob'){
|
||||
blobToJson(data);
|
||||
break;
|
||||
}
|
||||
// update-end- --- author:liusq ------ date:20200910 ---- for:处理Blob情况----
|
||||
//notification.error({ message: '系统提示', description:'Token失效,请重新登录!',duration: 4})
|
||||
if(token && data.message.includes("Token失效")){
|
||||
// update-begin- --- author:scott ------ date:20190225 ---- for:Token失效采用弹框模式,不直接跳转----
|
||||
@ -123,6 +130,41 @@ const installer = {
|
||||
Vue.use(VueAxios, router, service)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Blob解析
|
||||
* @param data
|
||||
*/
|
||||
function blobToJson(data) {
|
||||
let fileReader = new FileReader();
|
||||
let token = Vue.ls.get(ACCESS_TOKEN);
|
||||
fileReader.onload = function() {
|
||||
try {
|
||||
let jsonData = JSON.parse(this.result); // 说明是普通对象数据,后台转换失败
|
||||
console.log("jsonData",jsonData)
|
||||
if (jsonData.status === 500) {
|
||||
console.log("token----------》",token)
|
||||
if(token && jsonData.message.includes("Token失效")){
|
||||
Modal.error({
|
||||
title: '登录已过期',
|
||||
content: '很抱歉,登录已过期,请重新登录',
|
||||
okText: '重新登录',
|
||||
mask: false,
|
||||
onOk: () => {
|
||||
store.dispatch('Logout').then(() => {
|
||||
Vue.ls.remove(ACCESS_TOKEN)
|
||||
window.location.reload()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// 解析成对象失败,说明是正常的文件流
|
||||
console.log("blob解析fileReader返回err",err)
|
||||
}
|
||||
};
|
||||
fileReader.readAsText(data)
|
||||
}
|
||||
|
||||
export {
|
||||
installer as VueAxios,
|
||||
|
||||
@ -126,6 +126,8 @@ function generateChildRouters (data) {
|
||||
componentPath = onlineCommons.OnlCgformTreeList
|
||||
}else if(item.component=="modules/online/cgform/auto/erp/OnlCgformErpList"){
|
||||
componentPath = onlineCommons.OnlCgformErpList
|
||||
}else if(item.component=="modules/online/cgform/auto/tab/OnlCgformTabList"){
|
||||
componentPath = onlineCommons.OnlCgformTabList
|
||||
}else if(item.component=="modules/online/cgform/auto/innerTable/OnlCgformInnerTableList"){
|
||||
componentPath = onlineCommons.OnlCgformInnerTableList
|
||||
}else if(item.component=="modules/online/cgreport/OnlCgreportHeadList"){
|
||||
@ -136,12 +138,12 @@ function generateChildRouters (data) {
|
||||
componentPath = resolve => require(['@/' + component+'.vue'], resolve)
|
||||
}
|
||||
|
||||
|
||||
let menu = {
|
||||
path: item.path,
|
||||
name: item.name,
|
||||
redirect:item.redirect,
|
||||
component: componentPath,
|
||||
//component: resolve => require(['@/' + component+'.vue'], resolve),
|
||||
hidden:item.hidden,
|
||||
//component:()=> import(`@/views/${item.component}.vue`),
|
||||
meta: {
|
||||
@ -151,8 +153,9 @@ function generateChildRouters (data) {
|
||||
permissionList:item.meta.permissionList,
|
||||
keepAlive:item.meta.keepAlive,
|
||||
/*update_begin author:wuxianquan date:20190908 for:赋值 */
|
||||
internalOrExternal:item.meta.internalOrExternal
|
||||
internalOrExternal:item.meta.internalOrExternal,
|
||||
/*update_end author:wuxianquan date:20190908 for:赋值 */
|
||||
componentName:item.meta.componentName
|
||||
}
|
||||
}
|
||||
if(item.alwaysShow){
|
||||
@ -537,4 +540,24 @@ export function getVmParentByName(vm, name) {
|
||||
*/
|
||||
export function neverNull(value, def) {
|
||||
return value == null ? (neverNull(def, '')) : value
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据元素值移除数组中的一个元素
|
||||
* @param array 数组
|
||||
* @param prod 属性名
|
||||
* @param value 属性值
|
||||
* @returns {string}
|
||||
*/
|
||||
export function removeArrayElement(array, prod, value) {
|
||||
let index = -1
|
||||
for(let i = 0;i<array.length;i++){
|
||||
if(array[i][prod] == value){
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(index>=0){
|
||||
array.splice(index, 1);
|
||||
}
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
404 page
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "404"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@ -137,7 +137,7 @@
|
||||
return getFileAccessHttpUrl(this.avatar());
|
||||
},
|
||||
getTeams() {
|
||||
this.$http.get('/api/workplace/teams')
|
||||
this.$http.get('/mock/api/workplace/teams')
|
||||
.then(res => {
|
||||
this.teams = res.result
|
||||
this.teamSpinning = false
|
||||
|
||||
@ -205,20 +205,20 @@
|
||||
methods: {
|
||||
...mapGetters(["nickname", "welcome"]),
|
||||
getProjects() {
|
||||
this.$http.get('/api/list/search/projects')
|
||||
this.$http.get('/mock/api/list/search/projects')
|
||||
.then(res => {
|
||||
this.projects = res.result && res.result.data
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
getActivity() {
|
||||
this.$http.get('/api/workplace/activity')
|
||||
this.$http.get('/mock/api/workplace/activity')
|
||||
.then(res => {
|
||||
this.activities = res.result
|
||||
})
|
||||
},
|
||||
getTeams() {
|
||||
this.$http.get('/api/workplace/teams')
|
||||
this.$http.get('/mock/api/workplace/teams')
|
||||
.then(res => {
|
||||
this.teams = res.result
|
||||
})
|
||||
@ -226,7 +226,7 @@
|
||||
initRadar() {
|
||||
this.radarLoading = true
|
||||
|
||||
this.$http.get('/api/workplace/radar')
|
||||
this.$http.get('/mock/api/workplace/radar')
|
||||
.then(res => {
|
||||
|
||||
const dv = new DataSet.View().source(res.result)
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Result from '../../result/Result'
|
||||
import Result from '../../../result/Result'
|
||||
|
||||
export default {
|
||||
name: "Step3",
|
||||
@ -5,7 +5,7 @@
|
||||
:dataSource="dataSource"
|
||||
>
|
||||
<a-list-item slot="renderItem" slot-scope="item, index">
|
||||
<template v-if="item === null">
|
||||
<template v-if="index === 0">
|
||||
<a-button class="new-btn" type="dashed">
|
||||
<a-icon type="plus"/>
|
||||
新增产品
|
||||
@ -32,8 +32,7 @@
|
||||
<script>
|
||||
|
||||
const dataSource = []
|
||||
dataSource.push(null)
|
||||
for (let i = 0; i < 11; i++) {
|
||||
for (let i = 0; i < 12; i++) {
|
||||
dataSource.push({
|
||||
title: 'Alipay',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png',
|
||||
@ -95,7 +94,7 @@
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
width: 100%;
|
||||
height: 188px;
|
||||
height: 186px;
|
||||
}
|
||||
|
||||
.meta-content {
|
||||
@ -192,7 +192,7 @@
|
||||
permissionList: null,
|
||||
// 加载数据方法 必须为 Promise 对象
|
||||
loadData: parameter => {
|
||||
return this.$http.get('/api/permission', {
|
||||
return this.$http.get('/mock/api/permission', {
|
||||
params: Object.assign(parameter, this.queryParam)
|
||||
}).then(res => {
|
||||
let result = res.result
|
||||
@ -128,7 +128,7 @@
|
||||
],
|
||||
// 加载数据方法 必须为 Promise 对象
|
||||
loadData: parameter => {
|
||||
return this.$http.get('/api/role', {
|
||||
return this.$http.get('/mock/api/role', {
|
||||
params: Object.assign(parameter, this.queryParam)
|
||||
}).then(res => {
|
||||
return res.result
|
||||
@ -62,7 +62,7 @@
|
||||
</div>
|
||||
|
||||
<div class="table-operator">
|
||||
<a-button type="primary" icon="plus" @click="() => $router.push({name: 'anime-add'})">新建</a-button>
|
||||
<a-button type="primary" icon="plus" @click="() => this.handleModalVisible(true)">新建</a-button>
|
||||
<a-dropdown v-if="selectedRowKeys.length > 0">
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1"><a-icon type="delete" />删除</a-menu-item>
|
||||
@ -111,7 +111,14 @@
|
||||
</div>
|
||||
</template>
|
||||
</s-table>
|
||||
|
||||
<a-modal title="新建规则" destroyOnClose :visible="visibleCreateModal" @ok="handleCreateModalOk" @cancel="handleCreateModalCancel">
|
||||
<!---->
|
||||
<a-form style="margin-top: 8px" :autoFormCreate="(form)=>{this.createForm = form}">
|
||||
<a-form-item :labelCol="{ span: 5 }" :wrapperCol="{ span: 15 }" label="描述" fieldDecoratorId="description" :fieldDecoratorOptions="{rules: [{ required: true, message: '请输入至少五个字符的规则描述!', min: 5 }]}">
|
||||
<a-input placeholder="请输入" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
@ -173,7 +180,7 @@
|
||||
],
|
||||
// 加载数据方法 必须为 Promise 对象
|
||||
loadData: parameter => {
|
||||
return this.$http.get('/api/service', {
|
||||
return this.$http.get('/mock/api/service', {
|
||||
params: Object.assign(parameter, this.queryParam)
|
||||
}).then(res => {
|
||||
return res.result
|
||||
@ -181,7 +188,8 @@
|
||||
},
|
||||
|
||||
selectedRowKeys: [],
|
||||
selectedRows: []
|
||||
selectedRows: [],
|
||||
visibleCreateModal:false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -230,6 +238,16 @@
|
||||
toggleAdvanced () {
|
||||
this.advanced = !this.advanced
|
||||
},
|
||||
//添加逻辑
|
||||
handleModalVisible(isVisible) {
|
||||
this.visibleCreateModal = isVisible;
|
||||
},
|
||||
handleCreateModalCancel() {
|
||||
this.visibleCreateModal = false;
|
||||
},
|
||||
handleCreateModalOk() {
|
||||
this.visibleCreateModal = false;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
/*
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user