提交 109a95a9 编写于 作者: JEECG低代码平台's avatar JEECG低代码平台

Jeecg Boot 2.2.1 版本发布,低代码平台

上级 cb7ae9ca
......@@ -7,7 +7,7 @@
JEECG BOOT 低代码开发平台(前后端分离版本)
===============
当前最新版本: 2.2.0(发布日期:2020-05-06
当前最新版本: 2.2.1(发布日期:2020-07-11
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
......
docs
public
src
.dockerignore
.editorconfig
.eslintignore
.gitattributes
.gitignore
.prettierrc
babel.config.js
Dockerfile
idea.config.js
LICENSE
package.json
package-lock.json
README.md
vue.config.js
yarn
yarn.lock
yarn-error.log
.idea
.svn
node_modules
\ No newline at end of file
FROM nginx
MAINTAINER jeecgos@163.com
VOLUME /tmp
ENV LANG en_US.UTF-8
RUN echo "server { \
listen 80; \
location ^~ /jeecg-boot { \
proxy_pass http://jeecg-boot-system:8080/jeecg-boot/; \
proxy_set_header Host jeecg-boot-system; \
proxy_set_header X-Real-IP \$remote_addr; \
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; \
} \
#解决Router(mode: 'history')模式下,刷新路由地址不能找到页面的问题 \
location / { \
root /var/www/html/; \
index index.html index.htm; \
if (!-e \$request_filename) { \
rewrite ^(.*)\$ /index.html?s=\$1 last; \
break; \
} \
} \
access_log /var/log/nginx/access.log ; \
} " > /etc/nginx/conf.d/default.conf \
&& mkdir -p /var/www \
&& mkdir -p /var/www/html
ADD dist/ /var/www/html/
EXPOSE 80
EXPOSE 443
\ No newline at end of file
Ant Design Jeecg Vue
====
当前最新版本: 2.2.0(发布日期:2020-05-06
当前最新版本: 2.2.1(发布日期:20200711
Overview
----
......@@ -103,4 +103,33 @@ yarn run lint
备注
----
> @vue/cli 升级后,eslint 规则更新了。由于影响到全部 .vue 文件,需要逐个验证。既暂时关闭部分原本不验证的规则,后期维护时,在逐步修正这些 rules
\ No newline at end of file
> @vue/cli 升级后,eslint 规则更新了。由于影响到全部 .vue 文件,需要逐个验证。既暂时关闭部分原本不验证的规则,后期维护时,在逐步修正这些 rules
Docker 镜像使用
----
```
# 1.修改前端项目的后台域名
public/index.html
域名改成: http://jeecg-boot-system:8080/jeecg-boot
# 2.先进入打包前端项目
yarn run build
# 3.构建镜像
docker build -t nginx:jeecgboot .
# 4.启动镜像
docker run --name jeecg-boot-nginx -p 80:80 -d nginx:jeecgboot
# 5.配置host
# jeecgboot
127.0.0.1 jeecg-boot-redis
127.0.0.1 jeecg-boot-mysql
127.0.0.1 jeecg-boot-system
# 6.访问前台项目
http://localhost:80
```
\ No newline at end of file
module.exports = {
presets: [
['@vue/app',
{ useBuiltIns: 'entry' }]
{ useBuiltIns: 'entry' }]
]
}
此差异已折叠。
{
"name": "vue-antd-jeecg",
"version": "2.2.0",
"version": "2.2.1",
"private": true,
"scripts": {
"pre": "yarn --registry https://registry.npm.taobao.org || cnpm install || npm install --registry https://registry.npm.taobao.org ",
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@antv/data-set": "^0.11.2",
"@jeecg/antd-online-beta220": "^1.0.1",
"@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "1.5.2",
"area-data": "^5.0.6",
"ant-design-vue": "^1.6.3",
"@antv/data-set": "^0.11.4",
"@jeecg/antd-online-mini": "2.2.1",
"viser-vue": "^2.4.8",
"axios": "^0.18.0",
"clipboard": "^2.0.4",
"codemirror": "^5.46.0",
"dayjs": "^1.8.0",
"enquire.js": "^2.1.6",
"js-cookie": "^2.2.0",
......@@ -24,20 +21,25 @@
"lodash.pick": "^4.4.0",
"md5": "^2.2.1",
"nprogress": "^0.2.0",
"tinymce": "^5.1.4",
"viser-vue": "^2.4.4",
"vue": "^2.6.10",
"vue-area-linkage": "^5.1.0",
"vue-cropper": "^0.4.8",
"vue-cropper": "^0.5.4",
"vue-i18n": "^8.7.0",
"vue-loader": "^15.7.0",
"vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.9",
"vue-router": "^3.0.1",
"vuex": "^3.1.0",
"vue-print-nb-jeecg": "^1.0.9",
"clipboard": "^2.0.4",
"vue-photo-preview": "^1.1.3",
"vue-splitpane": "^1.0.4",
"vuedraggable": "^2.20.0",
"vuex": "^3.1.0"
"codemirror": "^5.46.0",
"@tinymce/tinymce-vue": "^2.1.0",
"tinymce": "^5.3.2",
"@toast-ui/editor": "^2.1.2",
"vue-area-linkage": "^5.1.0",
"area-data": "^5.0.6",
"jsoneditor": "^9.0.0"
},
"devDependencies": {
"@babel/polyfill": "^7.2.5",
......@@ -45,7 +47,7 @@
"@vue/cli-plugin-eslint": "^3.3.0",
"@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"babel-eslint": "7.2.3",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0",
......@@ -89,9 +91,10 @@
"vue/no-use-v-if-with-v-for": 0,
"vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0,
"no-console": 0,
"no-tabs": 0,
"indent": [1, 4]
"indent": ["off", 2],
"no-console": 0,
"space-before-function-paren": 0
}
},
"postcss": {
......
......@@ -7680,6 +7680,13 @@ font.weak {
color: #f5222d;
}
// 侧边导航栏首页颜色跟随主题变化
.ant-menu.ant-menu-root > .ant-menu-item:first-child.ant-menu-item-selected {
& > a,
& > a:hover {
color: @primary-color;
}
}
// begin -------- JAreaLinkage 三级联动样式 --------------
.cascader-menu-list .cascader-menu-option.hover,
......@@ -7698,4 +7705,14 @@ font.weak {
.area-select:active {
box-shadow: 0 0 0 2px color(~`colorPalette("@{primary-color}", 1)`);
}
// end -------- JAreaLinkage 三级联动样式 --------------
\ No newline at end of file
// end -------- JAreaLinkage 三级联动样式 --------------
// TESTA-521
.ant-menu-submenu-selected {
color: @primary-color;
}
// TESTA-521
.tab-layout-tabs.ant-tabs.ant-tabs-card > .ant-tabs-bar .ant-tabs-tab-active {
border-color: @primary-color !important;
}
\ No newline at end of file
......@@ -246,6 +246,7 @@
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>
......
......@@ -2,10 +2,17 @@ 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);
......@@ -14,6 +21,8 @@ const addUser = (params)=>postAction("/sys/user/add",params);
const editUser = (params)=>putAction("/sys/user/edit",params);
const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params);
const getUserList = (params)=>getAction("/sys/user/list",params);
// const deleteUser = (params)=>deleteAction("/sys/user/delete",params);
// const deleteUserList = (params)=>deleteAction("/sys/user/deleteBatch",params);
const frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
//验证用户是否存在
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
......@@ -24,15 +33,20 @@ 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 loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
......@@ -54,15 +68,21 @@ const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/sa
const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params);
//日志管理
//const getLogList = (params)=>getAction("/sys/log/list",params);
const deleteLog = (params)=>deleteAction("/sys/log/delete",params);
const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params);
//数据字典
const addDict = (params)=>postAction("/sys/dict/add",params);
const editDict = (params)=>putAction("/sys/dict/edit",params);
//const getDictList = (params)=>getAction("/sys/dict/list",params);
const 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);
......@@ -81,18 +101,33 @@ 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);
// 加载分类字典
const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params);
const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params)
//我的通告
//加载我的通告信息
const getUserNoticeInfo= (params)=>getAction("/sys/sysAnnouncementSend/getMyAnnouncementSend",params);
const getTransitURL = url => `/sys/common/transitRESTful?url=${encodeURIComponent(url)}`
// 中转HTTP请求
export const transitRESTful = {
get: (url, parameter) => getAction(getTransitURL(url), parameter),
post: (url, parameter) => postAction(getTransitURL(url), parameter),
put: (url, parameter) => putAction(getTransitURL(url), parameter),
http: (url, parameter) => httpAction(getTransitURL(url), parameter),
}
export {
// imgView,
// doMian,
addRole,
editRole,
checkRoleCode,
......
......@@ -55,4 +55,7 @@
/* 内嵌子表背景颜色 */
.j-inner-table-wrapper /deep/ .ant-table-expanded-row .ant-table-wrapper .ant-table-tbody .ant-table-row {
background-color: #FFFFFF;
}
\ No newline at end of file
}
/**隐藏样式-modal确定按钮 */
.jee-hidden{display: none}
\ No newline at end of file
......@@ -7,7 +7,7 @@
<a-radio-button v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio-button>
</a-radio-group>
<a-select v-else-if="tagType=='select'" :getPopupContainer = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput">
<a-select v-else-if="tagType=='select'" :getPopupContainer = "getPopupContainer" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput">
<a-select-option :value="undefined">请选择</a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
<span style="display: inline-block;width: 100%" :title=" item.text || item.label ">
......@@ -28,7 +28,11 @@
triggerChange: Boolean,
disabled: Boolean,
value: [String, Number],
type: String
type: String,
getPopupContainer:{
type: Function,
default: (node) => node.parentNode
}
},
data() {
return {
......@@ -56,7 +60,10 @@
},
computed: {
getValueSting(){
return this.value != null ? this.value.toString() : null;
// update-begin author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
// 当有null或“” placeholder不显示
return this.value != null ? this.value.toString() : undefined;
// update-end author:wangshuai date:20200601 for: 不显示placeholder的文字 ------
},
},
methods: {
......
......@@ -36,15 +36,20 @@ export async function initDictOptions(dictCode) {
*/
export function filterDictText(dictOptions, text) {
// --update-begin----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
if (text != null && dictOptions instanceof Array) {
if (text != null && Array.isArray(dictOptions)) {
let result = []
// 允许多个逗号分隔
let splitText = text.toString().trim().split(',')
// 允许多个逗号分隔,允许传数组对象
let splitText
if (Array.isArray(text)) {
splitText = text
} else {
splitText = text.toString().trim().split(',')
}
for (let txt of splitText) {
let dictText = txt
for (let dictItem of dictOptions) {
if (txt === dictItem.value.toString()) {
dictText = dictItem.text
if (txt.toString() === dictItem.value.toString()) {
dictText = (dictItem.text || dictItem.title || dictItem.label)
break
}
}
......
<template>
<div v-if="!reloading" class="j-area-linkage">
<div class="j-area-linkage">
<div v-if="reloading">
<span> Reloading... </span>
</div>
<area-cascader
v-if="_type === enums.type[0]"
v-else-if="_type === enums.type[0]"
:value="innerValue"
:data="pcaa"
:level="1"
......@@ -90,19 +93,23 @@
this.initAreaData();
},
methods: {
/** 重新加载组件 */
reload() {
this.reloading = true
this.$nextTick(() => this.reloading = false)
},
/** 通过 value 反推 options */
loadDataByValue(value) {
if(!value || value.length==0){
if (!value || value.length === 0) {
this.innerValue = []
this.reloading = true;
setTimeout(()=>{
this.reloading = false
},100)
}else{
this.initAreaData();
let arr = this.areaData.getRealCode(value);
} else {
this.initAreaData()
let arr = this.areaData.getRealCode(value)
this.innerValue = arr
}
this.reload()
},
/** 通过地区code获取子级 */
loadDataByCode(value) {
......
......@@ -196,9 +196,14 @@
if(!value){
this.$emit('change', '');
this.treeValue = ''
} else if (value instanceof Array) {
//this.$emit('change', value.map(item => item.value).join(','))
//this.treeValue = value
} else if (Array.isArray(value)) {
let labels = []
let values = value.map(item => {
labels.push(item.label)
return item.value
})
this.backValue(values.join(','), labels.join(','))
this.treeValue = value
} else {
this.backValue(value.value,value.label)
this.treeValue = value
......
......@@ -46,6 +46,8 @@
import 'codemirror/mode/swift/swift.js'
import 'codemirror/mode/vue/vue.js'
import { isIE11, isIE } from '@/utils/browser'
// 尝试获取全局实例
const CodeMirror = window.CodeMirror || _CodeMirror
......@@ -85,7 +87,21 @@
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'
},
},
data () {
return {
......@@ -217,14 +233,30 @@
hintOptions: this.options.hintOptions
}
},
fullScreenParentProps(){
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', this.fullCoder ? 'full-screen' : ''],
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
}
},
......@@ -240,7 +272,8 @@
// 编辑器赋值
if(this.value||this.code){
this.hasCode=true
this.coder.setValue(this.value || this.code)
//this.coder.setValue(this.value || this.code)
this.setCodeContent(this.value || this.code)
}else{
this.coder.setValue('')
this.hasCode=false
......@@ -408,6 +441,7 @@
top: 12px;
right: 12px;
}
.full-screen-child {
height: 100%;
max-height: 100%;
......@@ -416,9 +450,22 @@
}
.full-screen-child {
min-height: 120px;
max-height: 320px;
overflow:hidden;
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%;
}
}
}
......
<template>
<a-date-picker
dropdownClassName="j-date-picker"
:disabled="disabled || readOnly"
:placeholder="placeholder"
@change="handleDateChange"
......
<template>
<div class="tinymce-editor">
<editor
v-if="!reloading"
v-model="myValue"
:init="init"
:disabled="disabled"
......@@ -23,7 +24,9 @@
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/fullscreen'
import 'tinymce/icons/default'
import { uploadAction,getFileAccessHttpUrl } from '@/api/manage'
import { getVmParentByName } from '@/utils/util'
export default {
components: {
Editor
......@@ -83,21 +86,51 @@
})
}
},
myValue: this.value
myValue: this.value,
reloading: false,
}
},
mounted() {
tinymce.init({})
this.initATabsChangeAutoReload()
},
methods: {
reload() {
this.reloading = true
this.$nextTick(() => this.reloading = false)
},
onClick(e) {
this.$emit('onClick', e, tinymce)
},
//可以添加一些自己的自定义事件,如清空内容
clear() {
this.myValue = ''
}
},
/**
* 自动判断父级是否是 <a-tabs/> 组件,然后添加事件监听,自动触发reload()
*
* 由于 tabs 组件切换会导致 tinymce 无法输入,
* 只有重新加载才能使用(无论是vue版的还是jQuery版tinymce都有这个通病)
*/
initATabsChangeAutoReload() {
// 获取父级
let tabs = getVmParentByName(this, 'ATabs')
let tabPane = getVmParentByName(this, 'ATabPane')
if (tabs && tabPane) {
// 用户自定义的 key
let currentKey = tabPane.$vnode.key
// 添加事件监听
tabs.$on('change', (key) => {
// 切换到自己时执行reload
if (currentKey === key) {
this.reload()
}
})
}
},
},
watch: {
value(newValue) {
......
......@@ -86,6 +86,9 @@
} else {
this.initFileList(val)
}
if(!val || val.length==0){
this.picUrl = false;
}
}
},
created(){
......
export default {
minHeight: '200px',
previewStyle: 'vertical',
useCommandShortcut: true,
useDefaultHTMLSanitizer: true,
usageStatistics: false,
hideModeSwitch: false,
toolbarItems: [
'heading',
'bold',
'italic',
'strike',
'divider',
'hr',
'quote',
'divider',
'ul',
'ol',
'task',
'indent',
'outdent',
'divider',
'table',
'image',
'link',
'divider',
'code',
'codeblock'
]
}
<template>
<div class="j-markdown-editor" :id="id"/>
</template>
<script>
import 'codemirror/lib/codemirror.css'
import '@toast-ui/editor/dist/toastui-editor.css';
import '@toast-ui/editor/dist/i18n/zh-cn';
import Editor from '@toast-ui/editor';
import defaultOptions from './default-options'
export default {
name: 'JMarkdownEditor',
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
}
},
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.initEditor()
},
destroyed() {
this.destroyEditor()
},
methods: {
initEditor() {
this.editor = new Editor({
el: document.getElementById(this.id),
...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>
\ No newline at end of file
......@@ -39,6 +39,7 @@
<script>
import { getClass, getStyle } from '@/utils/props-util'
import { triggerWindowResizeEvent } from '@/utils/util'
export default {
name: 'JModal',
......@@ -151,6 +152,7 @@
/** 切换全屏 */
toggleFullscreen() {
this.innerFullscreen = !this.innerFullscreen
triggerWindowResizeEvent()
},
}
......@@ -165,7 +167,12 @@
left: 0;
padding: 0;
height: 100vh;
// 兼容1.6.2版本的antdv
& .ant-modal {
top: 0;
padding: 0;
height: 100vh;
}
& .ant-modal-content {
height: 100vh;
......@@ -189,7 +196,6 @@
height: 100%;
}
}
}
.j-modal-title-row {
......@@ -208,12 +214,9 @@
&:hover {
color: rgba(0, 0, 0, 0.75);
}
}
}
}
}
@media (max-width: 767px) {
......
<template>
<div class="components-input-demo-presuffix" v-if="avalid">
<!---->
<a-input @click="openModal" :placeholder="placeholder" v-model="showText" readOnly :disabled="disabled">
<a-icon slot="prefix" type="cluster" :title="title"/>
<a-icon v-if="showText" slot="suffix" type="close-circle" @click="handleEmpty" title="清空"/>
</a-input>
<j-popup-onl-report
ref="jPopupOnlReport"
:code="code"
:multi="multi"
:groupId="uniqGroupId"
@ok="callBack"
/>
</div>
</template>
<script>
import JPopupOnlReport from './modal/JPopupOnlReport'
export default {
name: 'JPopup',
components: {
JPopupOnlReport
},
props: {
code: {
type: String,
default: '',
required: false
},
field: {
type: String,
default: '',
required: false
},
orgFields: {
type: String,
default: '',
required: false
},
destFields: {
type: String,
default: '',
required: false
},
width: {
type: Number,
default: 1200,
required: false
},
placeholder: {
type: String,
default: '请选择',
required: false
},
value: {
type: String,
required: false
},
triggerChange: {
type: Boolean,
required: false,
default: false
},
disabled: {
type: Boolean,
required: false,
default: false
},
multi: {
type: Boolean,
required: false,
default: false
},
/** 分组ID,用于将多个popup的请求合并到一起,不传不分组 */
groupId: String
},
data() {
return {
showText: '',
title: '',
avalid: true
}
},
computed: {
uniqGroupId() {
if (this.groupId) {
let { groupId, code, field, orgFields, destFields } = this
return `${groupId}_${code}_${field}_${orgFields}_${destFields}`
}
}
},
watch: {
value: {
immediate: true,
handler: function(val) {
if (!val) {
this.showText = ''
} else {
this.showText = val
}
}
}
},
created() {
},
mounted() {
if (!this.orgFields || !this.destFields || !this.code) {
this.$message.error('popup参数未正确配置!')
this.avalid = false
}
if (this.destFields.split(',').length != this.orgFields.split(',').length) {
this.$message.error('popup参数未正确配置,原始值和目标值数量不一致!')
this.avalid = false
}
},
methods: {
openModal() {
if (this.disabled === false) {
this.$refs.jPopupOnlReport.show()
}
},
handleEmpty() {
this.showText = ''
let destFieldsArr = this.destFields.split(',')
if (destFieldsArr.length === 0) {
return
}
let res = {}
for (let i = 0; i < destFieldsArr.length; i++) {
res[destFieldsArr[i]] = ''
}
if (this.triggerChange) {
this.$emit('callback', res)
} else {
this.$emit('input', '', res)
}
},
callBack(rows) {
// update--begin--autor:lvdandan-----date:20200630------for:多选时未带回多个值------
let orgFieldsArr = this.orgFields.split(',')
let destFieldsArr = this.destFields.split(',')
let resetText = false
if (this.field && this.field.length > 0) {
this.showText = ''
resetText = true
}
let res = {}
if (orgFieldsArr.length > 0) {
for (let i = 0; i < orgFieldsArr.length; i++) {
let tempDestArr = []
for(let rw of rows){
let val = rw[orgFieldsArr[i]]
if(!val){
val = ""
}
tempDestArr.push(val)
}
res[destFieldsArr[i]] = tempDestArr.join(",")
}
if (resetText === true) {
let tempText = []
for(let rw of rows){
let val = rw[orgFieldsArr[destFieldsArr.indexOf(this.field)]]
if(!val){
val = ""
}
tempText.push(val)
}
this.showText = tempText.join(",")
}
// update--end--autor:lvdandan-----date:20200630------for:多选时未带回多个值------
}
if (this.triggerChange) {
//v-dec时即triggerChange为true时 将整个对象给form页面 让他自己setFieldsValue
this.$emit('callback', res)
} else {
//v-model时 需要传一个参数field 表示当前这个字段 从而根据这个字段的顺序找到原始值
// this.$emit("input",row[orgFieldsArr[destFieldsArr.indexOf(this.field)]])
this.$emit('input', this.showText, res)
}
}
}
}
</script>
<style scoped>
.components-input-demo-presuffix .anticon-close-circle {
cursor: pointer;
color: #ccc;
transition: color 0.3s;
font-size: 12px;
}
.components-input-demo-presuffix .anticon-close-circle:hover {
color: #f5222d;
}
.components-input-demo-presuffix .anticon-close-circle:active {
color: #666;
}
</style>
\ No newline at end of file
......@@ -145,6 +145,10 @@
<j-date v-else-if=" item.type=='datetime' " v-model="item.val" placeholder="请选择时间" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"></j-date>
<a-time-picker v-else-if="item.type==='time'" :value="item.val ? moment(item.val,'HH:mm:ss') : null" format="HH:mm:ss" style="width: 100%" @change="(time,value)=>item.val=value"/>
<a-input-number v-else-if=" item.type=='int'||item.type=='number' " style="width: 100%" placeholder="请输入数值" v-model="item.val"/>
<a-select v-else-if="item.type=='switch'" placeholder="请选择" v-model="item.val">
<a-select-option value="Y"></a-select-option>
<a-select-option value="N"></a-select-option>
</a-select>
<a-input v-else v-model="item.val" placeholder="请输入值"/>
</a-col>
......@@ -508,8 +512,17 @@
renderSaveTreeData(item) {
item.icon = this.treeIcon
item.originTitle = item['title']
item.title = (fn, vNode) => {
let { originTitle } = vNode.dataRef
item.title = (arg1, arg2) => {
let vNode
// 兼容旧版的Antdv
if (arg1.dataRef) {
vNode = arg1
} else if (arg2.dataRef) {
vNode = arg2
} else {
return <span style="color:red;">Antdv版本不支持</span>
}
let {originTitle} = vNode.dataRef
return (
<div class="j-history-tree-title">
<span>{originTitle}</span>
......
<template>
<a-switch v-model="checkStatus" :disabled="disabled" @change="handleChange"/>
<div>
<a-select v-if="query" style="width: 100%" @change="handleSelectChange">
<a-select-option v-for="(item, index) in queryOption" :key="index" :value="item.value">
{{ item.text }}
</a-select-option>
</a-select>
<a-switch v-else v-model="checkStatus" :disabled="disabled" @change="handleChange"/>
</div>
</template>
<script>
......@@ -7,7 +14,7 @@
name: 'JSwitch',
props: {
value:{
type: String,
type: String | Number,
required: false
},
disabled:{
......@@ -19,6 +26,11 @@
type:Array,
required:false,
default:()=>['Y','N']
},
query:{
type: Boolean,
required: false,
default: false
}
},
data () {
......@@ -30,23 +42,37 @@
value:{
immediate: true,
handler(val){
if(!val){
this.checkStatus = false
this.$emit('change', this.options[1]);
}else{
if(this.options[0]==val){
this.checkStatus = true
}else{
if(!this.query){
if(!val){
this.checkStatus = false
this.$emit('change', this.options[1]);
}else{
if(this.options[0]==val){
this.checkStatus = true
}else{
this.checkStatus = false
}
}
}
}
}
},
computed:{
queryOption(){
let arr = []
arr.push({value:this.options[0],text:''})
arr.push({value:this.options[1],text:''})
return arr;
}
},
methods: {
handleChange(checked){
let flag = checked===false?this.options[1]:this.options[0];
this.$emit('change', flag);
},
handleSelectChange(value){
this.$emit('change', value);
}
},
model: {
......
......@@ -121,7 +121,6 @@
getAction(this.url_root,param).then(res=>{
if(res.success){
this.handleTreeNodeValue(res.result)
console.log("aaaa",res.result)
this.treeData = [...res.result]
}else{
this.$message.error(res.message)
......
......@@ -236,7 +236,6 @@
}else{
try {
let test=JSON.parse(mycondition);
console.log("aaaaasdsdd",typeof test)
if(typeof test == 'object' && test){
resolve()
}else{
......
......@@ -225,7 +225,13 @@
let arr = [];
for(var a=0;a<uploadFiles.length;a++){
arr.push(uploadFiles[a].response.message)
// update-begin-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时,控制台报错
if(uploadFiles[a].status === 'done' ) {
arr.push(uploadFiles[a].response.message)
}else{
return;
}
// update-end-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时,控制台报错
}
if(arr.length>0){
path = arr.join(",")
......@@ -279,12 +285,18 @@
//returnUrl为false时返回文件名称、文件路径及文件大小
this.newFileList = [];
for(var a=0;a<fileList.length;a++){
var fileJson = {
fileName:fileList[a].name,
filePath:fileList[a].response.message,
fileSize:fileList[a].size
};
this.newFileList.push(fileJson);
// update-begin-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时,控制台报错
if(fileList[a].status === 'done' ) {
var fileJson = {
fileName:fileList[a].name,
filePath:fileList[a].response.message,
fileSize:fileList[a].size
};
this.newFileList.push(fileJson);
}else{
return;
}
// update-end-author:lvdandan date:20200603 for:【TESTA-514】【开源issue】多个文件同时上传时,控制台报错
}
this.$emit('change', this.newFileList);
}
......
# JPopup 弹窗选择组件
## 参数配置
| 参数 | 类型 | 必填 |说明|
|--------------|---------|----|---------|
| placeholder |string | | placeholder |
| code |string | | online报表编码 |
| orgFields |string | | online报表中显示的列,多个以逗号隔开 |
| destFields |string | | 回调对象的属性,多个以逗号隔开,其顺序和orgFields一一对应 |
| field |string | | v-model模式专用,表示从destFields中选择一个属性的值返回给当前组件 |
| triggerChange |Boolean | | v-decorator模式下需设置成true |
| callback(事件) |function | | 回调事件,v-decorator模式下用到,用于设置form控件的值 |
使用示例
----
```vue
<template>
<a-form :form="form">
<a-form-item label="v-model模式指定一个值返回至当前组件" style="width: 300px">
<j-popup
v-model="selectValue"
code="user_msg"
org-fields="username,realname"
dest-fields="popup,other"
field="popup"/>
{{ selectValue }}
</a-form-item>
<a-form-item label="v-decorator模式支持回调多个值至当前表单" style="width: 300px">
<j-popup
v-decorator="['one']"
:trigger-change="true"
code="user_msg"
org-fields="username,realname"
dest-fields="one,two"
@callback="popupCallback"/>
{{ getFormFieldValue('one') }}
</a-form-item>
<a-form-item label="v-decorator模式被回调的值" style="width: 300px">
<a-input v-decorator="['two']"></a-input>
</a-form-item>
</a-form >
</template>
<script>
export default {
data() {
return {
form: this.$form.createForm(this),
selectValue:"",
}
},
methods:{
getFormFieldValue(field){
return this.form.getFieldValue(field)
},
popupCallback(row){
this.form.setFieldsValue(row)
}
}
}
</script>
import JModal from './JModal'
import JFormContainer from './JFormContainer.vue'
import JPopup from './JPopup.vue'
export default {
install(Vue) {
Vue.component('JFormContainer', JFormContainer)
Vue.component('JPopup', JPopup)
Vue.component(JModal.name, JModal)
}
}
\ No newline at end of file
<template>
<a-popover trigger="contextmenu" v-model="visible" :placement="position">
<a-popover trigger="contextmenu" v-model="visible" :placement="position" overlayClassName="j-input-pop">
<!--"(node) => node.parentNode.parentNode"-->
<div slot="title">
<span>{{ title }}</span>
......@@ -7,11 +7,11 @@
<a-icon type="close" @click="visible=false"/>
</span>
</div>
<a-input :value="inputContent" @change="handleInputChange">
<a-input :value="inputContent" :disabled="disabled" @change="handleInputChange">
<a-icon slot="suffix" type="fullscreen" @click.stop="pop" />
</a-input>
<div slot="content">
<textarea :value="inputContent" @input="handleInputChange" :style="{ height: height + 'px', width: width + 'px' }"></textarea>
<textarea :value="inputContent" :disabled="disabled" @input="handleInputChange" :style="{ height: height + 'px', width: width + 'px' }"></textarea>
</div>
</a-popover>
</template>
......@@ -48,7 +48,11 @@
type:String,
default:'',
required:false
}
},
disabled: {
type: Boolean,
default: false,
},
},
data(){
......
<template>
<j-modal
:title="title"
:width="modalWidth"
:visible="visible"
:confirmLoading="confirmLoading"
switchFullscreen
wrapClassName="j-popup-modal"
@ok="handleSubmit"
@cancel="handleCancel"
cancelText="关闭">
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchByquery">
<a-row :gutter="24" v-if="showSearchFlag">
<template v-for="(item,index) in queryInfo">
<template v-if=" item.hidden==='1' ">
<a-col :md="8" :sm="24" :key=" 'query'+index " v-show="toggleSearchStatus">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
</template>
<template v-else>
<a-col :md="8" :sm="24" :key=" 'query'+index ">
<online-query-form-item :queryParam="queryParam" :item="item" :dictOptions="dictOptions"></online-query-form-item>
</a-col>
</template>
</template>
<a-col :md="8" :sm="8">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchByquery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</span>
</a-col>
</a-row>
</a-form>
</div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
已选择&nbsp;<a style="font-weight: 600">{{ table.selectedRowKeys.length }}</a>&nbsp;&nbsp;
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
<a v-if="!showSearchFlag" style="margin-left: 24px" @click="onlyReload">刷新</a>
</div>
<a-table
ref="table"
size="middle"
bordered
:rowKey="combineRowKey"
:columns="table.columns"
:dataSource="table.dataSource"
:pagination="table.pagination"
:loading="table.loading"
:rowSelection="{fixed:true,selectedRowKeys: table.selectedRowKeys, onChange: handleChangeInTableSelect}"
@change="handleChangeInTable"
style="min-height: 300px"
:scroll="tableScroll"
:customRow="clickThenCheck">
</a-table>
</j-modal>
</template>
<script>
import { getAction } from '@/api/manage'
import {filterObj} from '@/utils/util'
import { filterMultiDictText } from '@/components/dict/JDictSelectUtil'
import { httpGroupRequest } from '@/api/GroupRequest.js'
const MODAL_WIDTH = 1200;
export default {
name: 'JPopupOnlReport',
props: ['multi', 'code', 'groupId'],
components:{
},
data(){
return {
visible:false,
title:"",
confirmLoading:false,
queryInfo:[],
toggleSearchStatus:false,
queryParam:{
},
dictOptions: {},
url: {
getColumns: '/online/cgreport/api/getRpColumns/',
getData: '/online/cgreport/api/getData/',
getQueryInfo: '/online/cgreport/api/getQueryInfo/'
},
table: {
loading: true,
// 表头
columns: [],
//数据集
dataSource: [],
// 选择器
selectedRowKeys: [],
selectionRows: [],
// 分页参数
pagination: {
current: 1,
pageSize: 10,
pageSizeOptions: ['10', '20', '30'],
showTotal: (total, range) => {
return range[0] + '-' + range[1] + '' + total + ''
},
showQuickJumper: true,
showSizeChanger: true,
total: 0
}
},
cgRpConfigId:"",
modalWidth:MODAL_WIDTH,
tableScroll:{x:MODAL_WIDTH-100}
}
},
mounted() {
this.loadColumnsInfo()
},
watch: {
code() {
this.loadColumnsInfo()
}
},
computed:{
showSearchFlag(){
return this.queryInfo && this.queryInfo.length>0
}
},
methods:{
loadColumnsInfo(){
let url = `${this.url.getColumns}${this.code}`
//缓存key
let groupIdKey
if (this.groupId) {
groupIdKey = this.groupId + url
}
httpGroupRequest(() => getAction(url), groupIdKey).then(res => {
if(res.success){
this.initDictOptionData(res.result.dictOptions);
this.cgRpConfigId = res.result.cgRpConfigId
this.title = res.result.cgRpConfigName
let currColumns = res.result.columns
for(let a=0;a<currColumns.length;a++){
if(currColumns[a].customRender){
let dictCode = currColumns[a].customRender;
currColumns[a].customRender=(text)=>{
return filterMultiDictText(this.dictOptions[dictCode], text+"");
}
}
}
this.table.columns = [...currColumns]
this.initQueryInfo()
this.loadData(1)
}
})
},
initQueryInfo() {
let url = `${this.url.getQueryInfo}${this.cgRpConfigId}`
//缓存key
let groupIdKey
if (this.groupId) {
groupIdKey = this.groupId + url
}
httpGroupRequest(() => getAction(url), groupIdKey).then((res) => {
// console.log("获取查询条件", res);
if (res.success) {
this.queryInfo = res.result
} else {
this.$message.warning(res.message)
}
})
},
loadData(arg) {
if (arg == 1) {
this.table.pagination.current = 1
}
let params = this.getQueryParams();//查询条件
this.table.loading = true
let url = `${this.url.getData}${this.cgRpConfigId}`
//缓存key
let groupIdKey
if (this.groupId) {
groupIdKey = this.groupId + url + JSON.stringify(params)
}
httpGroupRequest(() => getAction(url, params), groupIdKey).then(res => {
this.table.loading = false
// console.log("daa",res)
let data = res.result
if (data) {
this.table.pagination.total = Number(data.total)
this.table.dataSource = data.records
} else {
this.table.pagination.total = 0
this.table.dataSource = []
}
})
},
getQueryParams() {
let param = Object.assign({}, this.queryParam, this.sorter);
param.pageNo = this.table.pagination.current;
param.pageSize = this.table.pagination.pageSize;
return filterObj(param);
},
handleChangeInTableSelect(selectedRowKeys, selectionRows) {
this.table.selectedRowKeys = selectedRowKeys
this.table.selectionRows = selectionRows
},
handleChangeInTable(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
if (Object.keys(sorter).length > 0) {
this.sorter.column = sorter.field
this.sorter.order = 'ascend' == sorter.order ? 'asc' : 'desc'
}
this.table.pagination = pagination
this.loadData()
},
handleCancel() {
this.close()
},
handleSubmit() {
if(!this.multi){
if(this.table.selectionRows && this.table.selectionRows.length>1){
this.$message.warning("请选择一条记录")
return false
}
}
if(!this.table.selectionRows || this.table.selectionRows.length==0){
this.$message.warning("请选择一条记录")
return false
}
this.$emit('ok', this.table.selectionRows);
this.close()
},
close() {
this.$emit('close');
this.visible = false;
this.onClearSelected()
},
show(){
this.visible = true;
},
handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus;
},
searchByquery(){
this.loadData(1);
},
onlyReload(){
this.loadData();
},
searchReset(){
Object.keys(this.queryParam).forEach(key=>{
this.queryParam[key]=""
})
this.loadData(1);
},
onClearSelected(){
this.table.selectedRowKeys = []
this.table.selectionRows = []
},
combineRowKey(record){
let res = ''
Object.keys(record).forEach(key=>{
res+=record[key]
})
if(res.length>50){
res = res.substring(0,50)
}
return res
},
clickThenCheck(record){
return {
on: {
click: () => {
let rowKey = this.combineRowKey(record)
if(!this.table.selectedRowKeys || this.table.selectedRowKeys.length==0){
let arr1=[],arr2=[]
arr1.push(record)
arr2.push(rowKey)
this.table.selectedRowKeys=arr2
this.table.selectionRows=arr1
}else{
if(this.table.selectedRowKeys.indexOf(rowKey)<0){
this.table.selectedRowKeys.push(rowKey)
this.table.selectionRows.push(record)
}else{
let rowKey_index = this.table.selectedRowKeys.indexOf(rowKey)
this.table.selectedRowKeys.splice(rowKey_index,1);
this.table.selectionRows.splice(rowKey_index,1);
}
}
}
}
}
},
//防止字典中有垃圾数据
initDictOptionData(dictOptions){
let obj = { }
Object.keys(dictOptions).map(k=>{
obj[k] = dictOptions[k].filter(item=>{
return item!=null
});
});
this.dictOptions = obj
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<a-modal
<j-modal
centered
:title="name + '选择'"
:width="width"
:visible="visible"
switchFullscreen
@ok="handleOk"
@cancel="close"
cancelText="关闭">
......@@ -32,7 +33,7 @@
</div>
<a-table
size="small"
size="middle"
bordered
:rowKey="rowKey"
:columns="innerColumns"
......@@ -49,7 +50,7 @@
<a-col :span="8">
<a-card :title="'已选' + name" :bordered="false" :head-style="{padding:0}" :body-style="{padding:0}">
<a-table size="small" :rowKey="rowKey" bordered v-bind="selectedTable">
<a-table size="middle" :rowKey="rowKey" bordered v-bind="selectedTable">
<span slot="action" slot-scope="text, record, index">
<a @click="handleDeleteSelected(record, index)">删除</a>
</span>
......@@ -58,7 +59,7 @@
</a-card>
</a-col>
</a-row>
</a-modal>
</j-modal>
</template>
<script>
......
......@@ -118,10 +118,12 @@
deep: true,
handler(val) {
let rows = val.map(key => this.dataSourceMap[key])
this.$emit('select', rows)
let data = val.join(',')
this.$emit('input', data)
this.$emit('change', data)
if (data !== this.value) {
this.$emit('select', rows)
this.$emit('input', data)
this.$emit('change', data)
}
}
}
},
......
......@@ -76,6 +76,18 @@
methods:{
initComp(departNames){
this.departNames = departNames
//update-begin-author:lvdandan date:20200513 for:TESTA-438 部门选择组件自定义返回值,数据无法回填
//TODO 当返回字段为部门名称时会有问题,因为部门名称不唯一
//返回字段不为id时,根据返回字段获取id
if(this.customReturnField !== 'id' && this.value){
const dataList = this.$refs.innerDepartSelectModal.dataList;
console.log('this.value',this.value)
this.departIds = this.value.split(',').map(item => {
const data = dataList.filter(d=>d[this.customReturnField] === item)
return data.length > 0 ? data[0].id : ''
}).join(',')
}
//update-end-author:lvdandan date:20200513 for:TESTA-438 部门选择组件自定义返回值,数据无法回填
},
openModal(){
this.$refs.innerDepartSelectModal.show()
......
......@@ -19,7 +19,7 @@
import JSelectBizComponent from './JSelectBizComponent'
export default {
name: 'JSelectMultiUser',
name: 'JSelectRole',
components: { JSelectBizComponent },
props: ['value'],
data() {
......
<template>
<a-modal
<j-modal
title="选择部门"
:width="modalWidth"
:visible="visible"
:confirmLoading="confirmLoading"
@ok="handleSubmit"
@cancel="handleCancel"
switchFullscreen
cancelText="关闭">
<a-spin tip="Loading..." :spinning="false">
<a-input-search style="margin-bottom: 1px" placeholder="请输入部门名称按回车进行搜索" @search="onSearch" />
......@@ -31,7 +32,7 @@
</a-tree>
</a-spin>
</a-modal>
</j-modal>
</template>
<script>
......
<template>
<a-modal
<j-modal
:width="modalWidth"
:visible="visible"
:title="title"
switchFullscreen
@ok="handleSubmit"
@cancel="close"
style="top:50px"
cancelText="关闭"
style="margin-top: -70px"
wrapClassName="ant-modal-cust-warp"
>
<a-row :gutter="10" style="background-color: #ececec; padding: 10px; margin: -10px">
<a-col :md="6" :sm="24">
......@@ -51,7 +51,7 @@
</a-card>
</a-col>
</a-row>
</a-modal>
</j-modal>
</template>
<script>
......
......@@ -82,16 +82,19 @@
if (this.$route.path != indexKey) {
this.addIndexToFirst()
}
// 复制一个route对象出来,不能影响原route
let currentRoute = Object.assign({}, this.$route)
currentRoute.meta = Object.assign({}, currentRoute.meta)
// update-begin-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
let storeKey = 'route:title:' + this.$route.fullPath
let storeKey = 'route:title:' + currentRoute.fullPath
let routeTitle = this.$ls.get(storeKey)
if (routeTitle) {
this.$route.meta.title = routeTitle
currentRoute.meta.title = routeTitle
}
// update-end-author:sunjianlei date:20191223 for: 修复刷新后菜单Tab名字显示异常
this.pageList.push(this.$route)
this.linkList.push(this.$route.fullPath)
this.activePage = this.$route.fullPath
this.pageList.push(currentRoute)
this.linkList.push(currentRoute.fullPath)
this.activePage = currentRoute.fullPath
},
mounted() {
},
......@@ -126,8 +129,11 @@
'activePage': function(key) {
let index = this.linkList.lastIndexOf(key)
let waitRouter = this.pageList[index]
this.$router.push(Object.assign({},waitRouter));
this.changeTitle(waitRouter.meta.title)
// 【TESTA-523】修复:不允许重复跳转路由异常
if (waitRouter.fullPath !== this.$route.fullPath) {
this.$router.push(Object.assign({}, waitRouter))
this.changeTitle(waitRouter.meta.title)
}
},
'multipage': function(newVal) {
if(this.reloadFlag){
......@@ -352,7 +358,7 @@
}
.ant-tabs {
.tab-layout-tabs.ant-tabs {
&.ant-tabs-card .ant-tabs-tab {
......@@ -380,7 +386,7 @@
}
.ant-tabs.ant-tabs-card > .ant-tabs-bar {
.tab-layout-tabs.ant-tabs.ant-tabs-card > .ant-tabs-bar {
.ant-tabs-tab {
border: none !important;
border-bottom: 1px solid transparent !important;
......
......@@ -43,6 +43,7 @@
</div>
</div>
</a-layout-header>
</template>
......@@ -58,7 +59,7 @@
components: {
UserMenu,
SMenu,
Logo
Logo,
},
mixins: [mixin],
props: {
......@@ -96,7 +97,8 @@
topNavHeader: {},
headerIndexRight: {},
topSmenuStyle: {}
}
},
chatStatus: '',
}
},
watch: {
......
......@@ -131,10 +131,10 @@
//this.menus = this.mainRouters.find((item) => item.path === '/').children;
this.menus = this.permissionMenuList
// 根据后台配置菜单,重新排序加载路由信息
console.log('----加载菜单逻辑----')
console.log(this.mainRouters)
console.log(this.permissionMenuList)
console.log('----navTheme------'+this.navTheme)
//console.log('----加载菜单逻辑----')
//console.log(this.mainRouters)
//console.log(this.permissionMenuList)
//console.log('----navTheme------'+this.navTheme)
//--update-end----author:scott---date:20190320------for:根据后台菜单配置,判断是否路由菜单字段,动态选择是否生成路由(为了支持参数URL菜单)------
},
methods: {
......
......@@ -124,7 +124,7 @@
// this.heartCheckFun();
},
destroyed: function () { // 离开页面生命周期函数
this.websocketclose();
this.websocketOnclose();
},
methods: {
timerFun() {
......@@ -186,10 +186,8 @@
}
},
toMyAnnouncement(){
this.$router.push({
path: '/isps/userAnnouncement',
name: 'isps-userAnnouncement'
path: '/isps/userAnnouncement'
});
},
modalFormOk(){
......@@ -202,7 +200,7 @@
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
var userId = store.getters.userInfo.id;
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://")+"/websocket/"+userId;
console.log(url);
//console.log(url);
this.websock = new WebSocket(url);
this.websock.onopen = this.websocketOnopen;
this.websock.onerror = this.websocketOnerror;
......@@ -232,7 +230,10 @@
//this.heartCheck.reset().start();
},
websocketOnclose: function (e) {
console.log("connection closed (" + e.code + ")");
console.log("connection closed (" + e + ")");
if(e){
console.log("connection closed (" + e.code + ")");
}
this.reconnect();
},
websocketSend(text) { // 数据发送
......
......@@ -62,6 +62,10 @@
<a-icon type="cluster"/>
<span>切换部门</span>
</a-menu-item>
<a-menu-item key="6" @click="clearCache">
<a-icon type="sync"/>
<span>清理缓存</span>
</a-menu-item>
<!-- <a-menu-item key="2" disabled>
<a-icon type="setting"/>
<span>测试</span>
......@@ -94,7 +98,9 @@
import DepartSelect from './DepartSelect'
import { mapActions, mapGetters,mapState } from 'vuex'
import { mixinDevice } from '@/utils/mixin.js'
import { getFileAccessHttpUrl } from "@/api/manage"
import { getFileAccessHttpUrl,getAction } from "@/api/manage"
import Vue from 'vue'
import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
export default {
name: "UserMenu",
......@@ -168,7 +174,9 @@
content: '真的要注销登录吗 ?',
onOk() {
return that.Logout({}).then(() => {
window.location.href="/";
// update-begin author:wangshuai date:20200601 for: 退出登录跳转登录页面
that.$router.push({ path: '/user/login' });
// update-end author:wangshuai date:20200601 for: 退出登录跳转登录页面
//window.location.reload()
}).catch(err => {
that.$message.error({
......@@ -214,9 +222,28 @@
this.$router.push({ path: route.path })
}
this.searchMenuVisible = false
}
},
// update_end author:sunjianlei date:20191230 for: 解决外部链接打开失败的问题
/*update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航*/
/*update_begin author:liushaoqian date:20200507 for: 刷新缓存*/
clearCache(){
getAction("sys/dict/refleshCache").then((res) => {
if (res.success) {
//重新加载缓存
getAction("sys/dict/queryAllDictItems").then((res) => {
if (res.success) {
Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
Vue.ls.set(UI_CACHE_DB_DICT_DATA, res.result, 7 * 24 * 60 * 60 * 1000)
}
})
this.$message.success("刷新缓存完成!");
}
}).catch(e=>{
this.$message.warn("刷新缓存失败!");
console.log("刷新失败",e)
})
}
/*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
}
}
</script>
......
......@@ -64,7 +64,7 @@ const updateTheme = primaryColor => {
const lessConfigNode = document.createElement('script');
const lessScriptNode = document.createElement('script');
lessStyleNode.setAttribute('rel', 'stylesheet/less');
lessStyleNode.setAttribute('href', '/color.less');
lessStyleNode.setAttribute('href', __webpack_public_path__ + 'color.less')
lessConfigNode.innerHTML = `
window.less = {
async: true,
......
......@@ -17,8 +17,8 @@ import Print from 'vue-print-nb-jeecg'
import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css'
require('@jeecg/antd-online-beta220')
require('@jeecg/antd-online-beta220/dist/OnlineForm.css')
require('@jeecg/antd-online-mini')
require('@jeecg/antd-online-mini/dist/OnlineForm.css')
import {
ACCESS_TOKEN,
......
......@@ -297,7 +297,8 @@ export const JeecgListMixin = {
return getFileAccessHttpUrl(text)
},
/* 文件下载 */
uploadFile(text){
// update--autor:lvdandan-----date:20200630------for:修改下载文件方法名uploadFile改为downloadFile------
downloadFile(text){
if(!text){
this.$message.warning("未知的文件")
return;
......
import store from '@/store/'
export const WebsocketMixin = {
mounted() {
this.initWebSocket();
},
destroyed: function () {
// 离开页面生命周期函数
this.websocketOnclose();
},
methods:{
initWebSocket: function () {
console.log("------------WebSocket连接成功");
// WebSocket与普通的请求所用协议有所不同,ws等同于http,wss等同于https
var userId = store.getters.userInfo.id;
if(!this.socketUrl.startsWith('/')){
this.socketUrl = '/' + this.socketUrl
}
if(!this.socketUrl.endsWith('/')){
this.socketUrl = this.socketUrl + '/'
}
var url = window._CONFIG['domianURL'].replace("https://","wss://").replace("http://","ws://") + this.socketUrl + userId;
this.websock = new WebSocket(url);
this.websock.onopen = this.websocketOnopen;
this.websock.onerror = this.websocketOnerror;
this.websock.onmessage = this.websocketOnmessage;
this.websock.onclose = this.websocketOnclose;
},
websocketOnopen: function () {
console.log("WebSocket连接成功");
},
websocketOnerror: function (e) {
console.log("WebSocket连接发生错误");
this.reconnect();
},
websocketOnclose: function (e) {
this.reconnect();
},
websocketSend(text) {
// 数据发送
try {
this.websock.send(text);
} catch (err) {
console.log("send failed (" + err.code + ")");
}
},
reconnect() {
var that = this;
if(that.lockReconnect) return;
that.lockReconnect = true;
//没连接上会一直重连,设置延迟避免请求过多
setTimeout(function () {
console.info("尝试重连...");
that.initWebSocket();
that.lockReconnect = false;
}, 5000);
},
}
}
\ No newline at end of file
......@@ -23,7 +23,7 @@ router.beforeEach((to, from, next) => {
if (store.getters.permissionList.length === 0) {
store.dispatch('GetPermissionList').then(res => {
const menuData = res.result.menu;
console.log(res.message)
//console.log(res.message)
if (menuData === null || menuData === "" || menuData === undefined) {
return;
}
......
......@@ -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({
......
......@@ -60,7 +60,7 @@ const permission = {
SET_ROUTERS: (state, data) => {
state.addRouters = data
state.routers = constantRouterMap.concat(data)
console.log('-----mutations---SET_ROUTERS----', data)
//console.log('-----mutations---SET_ROUTERS----', data)
}
},
actions: {
......
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 } from "@/store/mutation-types"
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH,UI_CACHE_DB_DICT_DATA,TENANT_ID } from "@/store/mutation-types"
import { welcome } from "@/utils/util"
import { queryPermissionsByUser } from '@/api/api'
import { getAction } from '@/api/manage'
......@@ -10,6 +10,7 @@ const user = {
token: '',
username: '',
realname: '',
tenantid:'',
welcome: '',
avatar: '',
permissionList: [],
......@@ -34,6 +35,9 @@ const user = {
SET_INFO: (state, info) => {
state.info = info
},
SET_TENANT: (state, id) => {
state.tenantid = id
},
},
actions: {
......@@ -133,7 +137,7 @@ const user = {
}
}
})
console.log(" menu show json ", menuData)
//console.log(" menu show json ", menuData)
//update--end--autor:qinfeng-----date:20200109------for:JEECG-63 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示------
commit('SET_PERMISSIONLIST', menuData)
} else {
......@@ -188,6 +192,11 @@ const user = {
})
})
},
saveTenant({ commit }, id){
Vue.ls.set(TENANT_ID, id, 7 * 24 * 60 * 60 * 1000)
commit('SET_TENANT', id)
}
}
}
......
......@@ -17,6 +17,7 @@ export const ENCRYPTED_STRING = 'ENCRYPTED_STRING'
export const ENHANCE_PRE = 'enhance_'
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 CONTENT_WIDTH_TYPE = {
Fluid: 'Fluid',
......
import { getVmParentByName } from '@/utils/util'
const FormTypes = {
normal: 'normal',
input: 'input',
......@@ -88,7 +90,7 @@ export function validateTables(cases, deleteTempId) {
return new Promise((resolve, reject) => {
let tables = []
let index = 0;
if(!cases || cases.length==0){
if(!cases || cases.length === 0){
resolve()
}
(function next() {
......@@ -104,7 +106,13 @@ export function validateTables(cases, deleteTempId) {
}, error => {
// 出现未验证通过的表单,不再进行下一步校验,直接返回失败并跳转到该表格
if (error === VALIDATE_NO_PASSED) {
reject({ error: VALIDATE_NO_PASSED, index })
// 尝试获取tabKey,如果在ATab组件内即可获取
let paneKey;
let tabPane = getVmParentByName(vm, 'ATabPane')
if (tabPane) {
paneKey = tabPane.$vnode.key
}
reject({error: VALIDATE_NO_PASSED, index, paneKey})
}
reject(error)
})
......
//判断是否IE<11浏览器
export function isIE() {
return navigator.userAgent.indexOf('compatible') > -1 && navigator.userAgent.indexOf('MSIE') > -1
}
export function isIE11() {
return navigator.userAgent.indexOf('Trident') > -1 && navigator.userAgent.indexOf('rv:11.0') > -1
}
//判断是否IE的Edge浏览器
export function isEdge() {
return navigator.userAgent.indexOf('Edge') > -1 && !isIE()
}
export function getIEVersion() {
let userAgent = navigator.userAgent //取得浏览器的userAgent字符串
let isIE = isIE()
let isIE11 = isIE11()
let isEdge = isEdge()
if (isIE) {
let reIE = new RegExp('MSIE (\\d+\\.\\d+);')
reIE.test(userAgent)
let fIEVersion = parseFloat(RegExp['$1'])
if (fIEVersion === 7 || fIEVersion === 8 || fIEVersion === 9 || fIEVersion === 10) {
return fIEVersion
} else {
return 6//IE版本<7
}
} else if (isEdge) {
return 'edge'
} else if (isIE11) {
return 11
} else {
return -1
}
}
\ No newline at end of file
......@@ -2,7 +2,7 @@ import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
const hasPermission = {
install (Vue, options) {
console.log(options);
//console.log(options);
Vue.directive('has', {
inserted: (el, binding, vnode)=>{
console.log("页面权限控制----");
......
......@@ -3,7 +3,7 @@ import axios from 'axios'
import store from '@/store'
import { VueAxios } from './axios'
import {Modal, notification} from 'ant-design-vue'
import { ACCESS_TOKEN } from "@/store/mutation-types"
import { ACCESS_TOKEN, TENANT_ID } from "@/store/mutation-types"
/**
* 【指定 axios的 baseURL】
......@@ -12,7 +12,7 @@ import { ACCESS_TOKEN } from "@/store/mutation-types"
* @type {*|string}
*/
let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
console.log("apiBaseUrl= ",apiBaseUrl)
//console.log("apiBaseUrl= ",apiBaseUrl)
// 创建 axios 实例
const service = axios.create({
//baseURL: '/jeecg-boot',
......@@ -22,6 +22,7 @@ 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)
......@@ -45,7 +46,14 @@ const err = (error) => {
onOk: () => {
store.dispatch('Logout').then(() => {
Vue.ls.remove(ACCESS_TOKEN)
window.location.reload()
try {
let path=that.$route.path;
if(path.indexOf('/user/login')==-1){
window.location.reload()
}
}catch (e) {
window.location.reload()
}
})
}
})
......@@ -86,6 +94,13 @@ service.interceptors.request.use(config => {
if (token) {
config.headers[ 'X-Access-Token' ] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
}
//update-begin-author:taoyan date:2020707 for:多租户
let tenantid = Vue.ls.get(TENANT_ID)
if (!tenantid) {
tenantid = 0;
}
config.headers[ 'tenant_id' ] = tenantid
//update-end-author:taoyan date:2020707 for:多租户
if(config.method=='get'){
if(config.url.indexOf("sys/dict/getDictItems")<0){
config.params = {
......
import * as api from '@/api/api'
import { isURL } from '@/utils/validate'
import onlineCommons from '@jeecg/antd-online-beta220'
import onlineCommons from '@jeecg/antd-online-mini'
export function timeFix() {
const time = new Date()
......@@ -115,7 +115,6 @@ function generateChildRouters (data) {
item.meta.url = URL;
}
//online菜单路由加载逻辑
let componentPath
if(item.component=="modules/online/cgform/OnlCgformHeadList"){
componentPath = onlineCommons.OnlCgformHeadList
......@@ -137,6 +136,7 @@ function generateChildRouters (data) {
componentPath = resolve => require(['@/' + component+'.vue'], resolve)
}
let menu = {
path: item.path,
name: item.name,
......@@ -478,3 +478,53 @@ export function replaceAll(text, checker, replacer) {
}
return text
}
/**
* 获取事件冒泡路径,兼容 IE11,Edge,Chrome,Firefox,Safari
* 目前使用的地方:JEditableTable Span模式
*/
export function getEventPath(event) {
let target = event.target
let path = (event.composedPath && event.composedPath()) || event.path
if (path != null) {
return (path.indexOf(window) < 0) ? path.concat(window) : path
}
if (target === window) {
return [window]
}
let getParents = (node, memo) => {
memo = memo || []
const parentNode = node.parentNode
if (!parentNode) {
return memo
} else {
return getParents(parentNode, memo.concat(parentNode))
}
}
return [target].concat(getParents(target), window)
}
/**
* 根据组件名获取父级
* @param vm
* @param name
* @returns {Vue | null|null|Vue}
*/
export function getVmParentByName(vm, name) {
let parent = vm.$parent
if (parent && parent.$options) {
if (parent.$options.name === name) {
return parent
} else {
let res = getVmParentByName(parent, name)
if (res) {
return res
}
}
}
return null
}
\ No newline at end of file
......@@ -7,7 +7,7 @@
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area :datasource="chartData.sll" />
<mini-area :data-source="chartData.sll" />
</div>
<template slot="footer">今日受理量:<span>{{ todaySll }}</span></template>
</chart-card>
......@@ -18,7 +18,7 @@
<a-icon type="info-circle-o" />
</a-tooltip>
<div>
<mini-area :datasource="chartData.bjl"/>
<mini-area :data-source="chartData.bjl"/>
</div>
<template slot="footer">今日办结量:<span>{{ todayBjl }}</span></template>
</chart-card>
......
......@@ -209,7 +209,6 @@
})
getVisitInfo().then(res=>{
if(res.success){
console.log("aaaaaa",res.result)
this.visitInfo = res.result;
}
})
......
......@@ -7,7 +7,7 @@ const types = {
404: {
img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg',
title: '404',
desc: '抱歉,你访问的页面不存在或仍在开发中'
desc: '抱歉,你访问的页面不存在或无权访问'
},
500: {
img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg',
......
<template>
<div class="wrapper">
<div class="model" v-show="model">
<div class="model-show" @click="model = false">
<img :src="modelSrc" alt="" @click="model = false">
</div>
</div>
<div class="content">
<div class="show-info">
<div class="test test1">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:fixedBox="option.fixedBox"
:original="option.original"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:centerBox="option.centerBox"
:high="option.high"
:infoTrue="option.infoTrue"
:maxImgSize="option.maxImgSize"
@realTime="realTime"
@imgLoad="imgLoad"
@cropMoving="cropMoving"
:enlarge="option.enlarge"
:mode="option.mode"
:limitMinSize="option.limitMinSize"
></vueCropper>
</div>
<div class="test-button">
<button @click="changeImg" class="btn">changeImg</button>
<label class="btn" for="uploads">upload</label>
<input type="file" id="uploads" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event, 1)" ref="uploadImg">
<button @click="startCrop" v-if="!crap" class="btn">start</button>
<button @click="stopCrop" v-else class="btn">stop</button>
<button @click="clearCrop" class="btn">clear</button>
<button @click="refreshCrop" class="btn">refresh</button>
<button @click="changeScale(1)" class="btn">+</button>
<button @click="changeScale(-1)" class="btn">-</button>
<button @click="rotateLeft" class="btn">rotateLeft</button>
<button @click="rotateRight" class="btn">rotateRight</button>
<button @click="finish('base64')" class="btn">preview(base64)</button>
<button @click="finish('blob')" class="btn">preview(blob)</button>
<button @click="() => option.img = ''" class="btn">清除图片</button>
<a @click="down('base64')" class="btn">download(base64)</a>
<a @click="down('blob')" class="btn">download(blob)</a>
<a :href="downImg" download="demo.png" ref="downloadDom"></a>
</div>
<div class="pre">
<section class="pre-item">
<p>截图框大小</p>
<div class="show-preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden',
'margin': '5px'}">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</section>
<section class="pre-item">
<p>中等大小</p>
<div :style="previewStyle1">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</section>
<section class="pre-item">
<p>迷你大小</p>
<div :style="previewStyle2">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</section>
<section class="pre-item" title="zoom: (100 / previews.w)">
<p>固定为100宽度</p>
<div :style="previewStyle3">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</section>
<section class="pre-item" title="zoom: (100 / previews.h)">
<p>固定为100高度</p>
<div :style="previewStyle4">
<div :style="previews.div">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</section>
</div>
<div style="display:block; width: 100%;">
<label class="c-item">
<span>图片默认渲染方式</span>
<select v-model="option.mode">
<option value="contain">contain</option>
<option value="cover">cover</option>
<option value="400px auto">400px auto</option>
<option value="auto 400px">auto 400px</option>
<option value="50%">50%</option>
<option value="auto 50%">auto 50%</option>
</select>
<section>
类似css background属性设置 设置不符合规范不生效, 参照文档说明
</section>
</label>
<label class="c-item">
<span>上传时图片最大大小(默认会压缩尺寸到这个大小)</span>
<input type="nubmer" v-model="option.maxImgSize">
</label>
<label class="c-item">
<span>上传图片是否显示原始宽高 (针对大图 可以铺满)</span>
<input type="checkbox" v-model="option.original">
<span>original: {{ option.original}}</span>
</label>
<label class="c-item">
<span>是否根据dpr生成适合屏幕的高清图片</span>
<input type="checkbox" v-model="option.high">
<span>high: {{ option.high}}</span>
</label>
<label class="c-item">
<span>是否输出原图比例的截图</span>
<input type="checkbox" v-model="option.full">
<span>full: {{ option.full}}</span>
</label>
<label class="c-item">
<span>截图信息展示是否是真实的输出宽高</span>
<input type="checkbox" v-model="option.infoTrue">
<span>infoTrue: {{ option.infoTrue}}</span>
</label>
<label class="c-item">
<span>能否拖动图片</span>
<input type="checkbox" v-model="option.canMove">
<span>canMove: {{ option.canMove}}</span>
</label>
<label class="c-item">
<span>能否拖动截图框</span>
<input type="checkbox" v-model="option.canMoveBox">
<span>canMoveBox: {{ option.canMoveBox}}</span>
</label>
<label class="c-item">
<span>截图框固定大小</span>
<input type="checkbox" v-model="option.fixedBox">
<span>fixedBox: {{ option.fixedBox}}</span>
</label>
<label class="c-item">
<span>是否自动生成截图框</span>
<input type="checkbox" v-model="option.autoCrop">
<span>autoCrop: {{ option.autoCrop}}</span>
</label>
<label class="c-item">
<span>自动生成截图框的宽高</span>
<span>宽度: </span><input type="number" v-model="option.autoCropWidth">
<span>高度: </span><input type="number" v-model="option.autoCropHeight">
</label>
<label class="c-item">
<span>截图框是否限制在图片里(只有在自动生成截图框时才能生效)</span>
<input type="checkbox" v-model="option.centerBox">
<span>centerBox: {{ option.centerBox}}</span>
</label>
<label class="c-item">
<span>是否按照截图框比例输出 默认为1 </span>
<input type="number" v-model="option.enlarge">
</label>
<p>输出图片格式</p>
<label class="c-item">
<label>jpg <input type="radio" name="type" value="jpeg" v-model="option.outputType"></label>
<label>png <input type="radio" name="type" value="png" v-model="option.outputType"></label>
<label>webp <input type="radio" name="type" value="webp" v-model="option.outputType"></label>
</label>
</div>
</div>
</div>
</div>
</template>
<script>
import { VueCropper } from 'vue-cropper'
export default {
name: 'ImagCropper',
components: {
VueCropper
},
data () {
return {
model: false,
modelSrc: "",
crap: false,
previews: {},
lists: [
{img: "https://avatars2.githubusercontent.com/u/15681693?s=460&v=4"},
{img: "http://cdn.xyxiao.cn/Landscape_1.jpg"},
{img: "http://cdn.xyxiao.cn/Landscape_2.jpg"},
{img: "http://cdn.xyxiao.cn/Landscape_3.jpg"},
{img: "http://cdn.xyxiao.cn/Landscape_4.jpg"},
{img: "http://cdn.xyxiao.cn/Portrait_1.jpg"},
{img: "http://cdn.xyxiao.cn/Portrait_2.jpg"}
],
option: {
img: "",
size: 1,
full: false,
outputType: "png",
canMove: true,
fixedBox: false,
original: false,
canMoveBox: true,
autoCrop: true,
// 只有自动截图开启 宽度高度才生效
autoCropWidth: 200,
autoCropHeight: 150,
centerBox: false,
high: false,
cropData: {},
enlarge: 1,
mode: 'contain',
maxImgSize: 3000,
limitMinSize: [100, 120]
},
example2: {
img: "http://cdn.xyxiao.cn/Landscape_2.jpg",
info: true,
size: 1,
outputType: "jpeg",
canScale: true,
autoCrop: true,
// 只有自动截图开启 宽度高度才生效
autoCropWidth: 300,
autoCropHeight: 250,
fixed: true,
// 真实的输出宽高
infoTrue: true,
fixedNumber: [4, 3]
},
example3: {
img: "http://cdn.xyxiao.cn/Landscape_1.jpg",
autoCrop: true,
autoCropWidth: 200,
autoCropHeight: 200,
fixedBox: true
},
downImg: "#",
previewStyle1: {},
previewStyle2: {},
previewStyle3: {},
previewStyle4: {},
code0: '',
code1: '',
code2: '',
code3: '',
preview3: '',
};
},
methods: {
changeImg() {
this.option.img = this.lists[~~(Math.random() * this.lists.length)].img;
},
startCrop() {
// start
this.crap = true;
this.$refs.cropper.startCrop();
},
stopCrop() {
// stop
this.crap = false;
this.$refs.cropper.stopCrop();
},
clearCrop() {
// clear
this.$refs.cropper.clearCrop();
},
refreshCrop() {
// clear
this.$refs.cropper.refresh();
},
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
rotateRight() {
this.$refs.cropper.rotateRight();
},
finish(type) {
if (type === "blob") {
this.$refs.cropper.getCropBlob(data => {
var img = window.URL.createObjectURL(data);
this.model = true;
this.modelSrc = img;
});
} else {
this.$refs.cropper.getCropData(data => {
this.model = true;
this.modelSrc = data;
});
}
},
// 实时预览函数
realTime(data) {
var previews = data;
var h = 0.5;
var w = 0.2;
this.previewStyle1 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: h
};
this.previewStyle2 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: w
};
this.previewStyle3 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: (100 / previews.w)
};
this.previewStyle4 = {
width: previews.w + "px",
height: previews.h + "px",
overflow: "hidden",
margin: "0",
zoom: (100 / previews.h)
};
this.previews = data;
},
finish2(type) {
this.$refs.cropper2.getCropData(data => {
this.model = true;
this.modelSrc = data;
});
},
finish3(type) {
this.$refs.cropper3.getCropData(data => {
this.model = true;
this.modelSrc = data;
});
},
down(type) {
// 输出
if (type === "blob") {
this.$refs.cropper.getCropBlob(data => {
this.downImg = window.URL.createObjectURL(data);
if (window.navigator.msSaveBlob) {
var blobObject = new Blob([data]);
window.navigator.msSaveBlob(blobObject, "demo.png");
} else {
this.$nextTick(() => {
this.$refs.downloadDom.click();
});
}
});
} else {
this.$refs.cropper.getCropData(data => {
this.downImg = data;
if (window.navigator.msSaveBlob) {
var blobObject = new Blob([data]);
window.navigator.msSaveBlob(blobObject, "demo.png");
} else {
this.$nextTick(() => {
this.$refs.downloadDom.click();
});
}
});
}
},
uploadImg(e, num) {
//上传图片
// this.option.img
var file = e.target.files[0];
if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
alert("图片类型必须是.gif,jpeg,jpg,png,bmp中的一种");
return false;
}
var reader = new FileReader();
reader.onload = e => {
let data;
if (typeof e.target.result === "object") {
// 把Array Buffer转化为blob 如果是base64不需要
data = window.URL.createObjectURL(new Blob([e.target.result]));
} else {
data = e.target.result;
}
if (num === 1) {
this.option.img = data;
} else if (num === 2) {
this.example2.img = data;
}
this.$refs.uploadImg.value = ''
};
// 转化为blob
reader.readAsArrayBuffer(file);
},
imgLoad(msg) {
console.log(msg);
},
cropMoving(data) {
this.option.cropData = data;
}
},
components: {
VueCropper
},
mounted() {
this.changeImg();
var list = [].slice.call(document.querySelectorAll("pre code"));
list.forEach((val, index) => {
hljs.highlightBlock(val);
});
}
};
</script>
<style scoped>
* {
margin: 0;
padding: 0;
}
.content {
margin: auto;
max-width: 1200px;
margin-bottom: 100px;
}
.test-button {
display: flex;
flex-wrap: wrap;
}
.btn {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
background: #fff;
border: 1px solid #c0ccda;
color: #1f2d3d;
text-align: center;
box-sizing: border-box;
outline: none;
margin: 20px 10px 0px 0px;
padding: 9px 15px;
font-size: 14px;
border-radius: 4px;
color: #fff;
background-color: #50bfff;
border-color: #50bfff;
transition: all 0.2s ease;
text-decoration: none;
user-select: none;
}
.des {
line-height: 30px;
}
code.language-html {
padding: 10px 20px;
margin: 10px 0px;
display: block;
background-color: #333;
color: #fff;
overflow-x: auto;
font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo,
Lucida, Sans, Type, Writer, Ubuntu, Mono;
border-radius: 5px;
white-space: pre;
}
.show-info {
margin-bottom: 50px;
}
.show-info h2 {
line-height: 50px;
}
.title {
display: block;
text-decoration: none;
text-align: center;
line-height: 1.5;
margin: 20px 0px;
background-image: -webkit-linear-gradient(
left,
#3498db,
#f47920 10%,
#d71345 20%,
#f7acbc 30%,
#ffd400 40%,
#3498db 50%,
#f47920 60%,
#d71345 70%,
#f7acbc 80%,
#ffd400 90%,
#3498db
);
color: transparent;
-webkit-background-clip: text;
background-size: 200% 100%;
animation: slide 5s infinite linear;
font-size: 40px;
}
.test {
height: 500px;
}
.model {
position: fixed;
z-index: 10;
width: 100vw;
height: 100vh;
overflow: auto;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
}
.model-show {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
text-align: center;
}
.model img {
display: block;
margin: auto;
max-width: 80%;
width: auto;
user-select: none;
background-position: 0px 0px, 10px 10px;
background-size: 20px 20px;
background-image: linear-gradient(
45deg,
#eee 25%,
transparent 25%,
transparent 75%,
#eee 75%,
#eee 100%
),
linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);
}
.c-item {
display: block;
padding: 10px 0;
user-select: none;
}
.pre {
display: flex;
flex-wrap: wrap;
}
.pre-item {
padding-right: 20px;
}
@keyframes slide {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}
@media screen and (max-width: 1000px) {
.content {
max-width: 90%;
margin: auto;
}
.test {
height: 400px;
}
}
</style>
\ No newline at end of file
......@@ -374,7 +374,7 @@
</a-col>
<a-col :span="12">输入的值(v-model):{{ formData.jInput }}</a-col>
</a-row>
<!-- <a-row :gutter="24">
<a-row :gutter="24">
<a-col :span="15">
<a-form-item label="MarkdownEditor" style="min-height: 300px">
<j-markdown-editor v-model="content"></j-markdown-editor>
......@@ -383,7 +383,7 @@
<a-col :span="9">
输入的值(v-model):{{ content }}
</a-col>
</a-row>-->
</a-row>
<!-- 省市县级联 -->
<a-row :gutter="24">
......@@ -456,12 +456,14 @@
import JMultiSelectTag from '@comp/dict/JMultiSelectTag'
import JInput from '@comp/jeecg/JInput'
import JAreaLinkage from '@comp/jeecg/JAreaLinkage'
import JMarkdownEditor from '@/components/jeecg/JMarkdownEditor/index'
import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
export default {
name: 'SelectDemo',
inject:['closeCurrent'],
components: {
JMarkdownEditor,
JAreaLinkage,
JInput,
JCategorySelect,
......
......@@ -268,6 +268,9 @@
},
delRowCustom (index) {
console.log(index)
let all = this.form.getFieldsValue()
all['jeecgOrderCustomerList'].splice(index,1);
this.form.setFieldsValue(all)
this.orderMainModel.jeecgOrderCustomerList.splice(index,1);
this.$forceUpdate();
},
......@@ -278,6 +281,9 @@
},
delRowTicket (index) {
console.log(index)
let all = this.form.getFieldsValue()
all['jeecgOrderTicketList'].splice(index,1);
this.form.setFieldsValue(all)
this.orderMainModel.jeecgOrderTicketList.splice(index,1);
this.$forceUpdate();
},
......
......@@ -7,7 +7,7 @@
:closable="true"
@close="close"
:visible="visible"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;">
style="overflow: auto;padding-bottom: 53px;">
<a-spin :spinning="confirmLoading">
<a-form :form="form">
......
......@@ -83,6 +83,7 @@
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item><a @click="executeImmediately(record)">立即执行</a></a-menu-item>
<a-menu-item><a @click="handleEdit(record)">编辑</a></a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
......@@ -192,6 +193,7 @@
resume: "/sys/quartzJob/resume",
exportXlsUrl: "sys/quartzJob/exportXls",
importExcelUrl: "sys/quartzJob/importExcel",
execute: "sys/quartzJob/execute"
},
}
},
......@@ -255,6 +257,25 @@
}
});
},
executeImmediately(record){
var that = this;
//立即执行定时任务
this.$confirm({
title:"确认提示",
content:"是否立即执行任务?",
onOk: function(){
getAction(that.url.execute,{id:record.id}).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.loadData();
that.onClearSelected();
}else{
that.$message.warning(res.message);
}
});
}
});
}
}
}
</script>
......
......@@ -63,7 +63,6 @@
<a @click="handleOpen(record)">用户</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">
更多 <a-icon type="down"/>
......
......@@ -4,10 +4,10 @@
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<!--<a-button type="primary" icon="download" @click="handleExportXls('分类字典')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="download" @click="handleExportXls('分类字典')">导出</a-button>
<a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button>
</a-upload>-->
</a-upload>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
......
<template>
<a-card :bordered="false" style="height: 100%">
<div style="padding-bottom: 2px">
<a-alert type="warning" show-icon>
<div slot="message" style="width: 100%">
<span>路由配置请慎重</span>
<span style="display:inline-block;float:right;padding-right: 5px">
<a @click="clearRedis"><a-icon type="reload" />清除缓存</a>
</span>
</div>
</a-alert>
</div>
<div :id="eleId" :style="{ height: editorHeight + 'px', width: '100%' }"></div>
<div style="text-align: center;padding-top:10px">
<a-button type="primary" @click="submitForm" style="width:160px">保存</a-button>
</div>
</a-card>
</template>
<script>
import JsonEditor from 'jsoneditor'
import 'jsoneditor/dist/jsoneditor.min.css'
import { getAction, postAction } from '@/api/manage'
export default {
name: "SysGatewayRouteList",
data () {
return {
eleId:'jsoneditor',
description: 'gateway路由管理管理页面',
editor: null,
editorWidth:400,
editorHeight:500,
url:{
list: '/sys/gatewayRoute/list',
update: '/sys/gatewayRoute/updateAll',
clear: '/sys/gatewayRoute/clearRedis'
},
}
},
created() {
let winWidth = window.innerWidth;
console.log("页面宽度",winWidth)
this.editorWidth = winWidth
},
mounted(){
this.initJsonEditor();
},
methods: {
initJsonEditor() {
let container = document.getElementById(this.eleId);
let options = {
modes: ['text', 'code', 'tree', 'form', 'view'],
mode: 'tree',
ace: ace,
sortObjectKeys: 'code',
mainMenuBar:['format']
};
this.editor = new JsonEditor(container, options);
this.initRouteData();
},
initRouteData(){
getAction(this.url.list).then(res=>{
if(res.success){
let array = res.result
console.log('当前路由配置信息为', array)
this.editor.set(array)
}
})
},
// 获取json
submitForm() {
let text = this.editor.getText()
console.log("保存的json数据",text)
if(!text || text.length<=0 || text=='{}' || text=='[]'){
this.$message.warning('未录入任何信息')
return ;
}
postAction(this.url.update,{
routes:text
}).then(res=>{
if(res.success){
this.$message.success(res.message)
}else{
this.$message.error(res.message)
}
})
},
clearRedis(){
getAction(this.url.clear).then(res=>{
if(res.success){
this.$message.success(res.message)
}
})
}
}
}
</script>
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24">
</a-row>
</a-form>
</div>
<!-- 查询区域-END -->
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"><a-icon type="delete"/>删除</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作 <a-icon type="down" /></a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i> 已选择 <a style="font-weight: 600">{{ selectedRowKeys.length }}</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
:scroll="{x:true}"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
class="j-table-force-nowrap"
@change="handleTableChange">
<template slot="htmlSlot" slot-scope="text">
<div v-html="text"></div>
</template>
<template slot="imgSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无图片</span>
<img v-else :src="getImgView(text)" height="25px" alt="" style="max-width:80px;font-size: 12px;font-style: italic;"/>
</template>
<template slot="fileSlot" slot-scope="text">
<span v-if="!text" style="font-size: 12px;font-style: italic;">无文件</span>
<a-button
v-else
:ghost="true"
type="primary"
icon="download"
size="small"
@click="uploadFile(text)">
下载
</a-button>
</template>
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down" /></a>
<a-menu slot="overlay">
<a-menu-item>
<a @click="handleDetail(record)">详情</a>
</a-menu-item>
<a-menu-item>
<a-popconfirm title="确定删除吗?" @confirm="() => handleDelete(record.id)">
<a>删除</a>
</a-popconfirm>
</a-menu-item>
</a-menu>
</a-dropdown>
</span>
</a-table>
</div>
<tenant-modal ref="modalForm" @ok="modalFormOk"></tenant-modal>
</a-card>
</template>
<script>
import '@/assets/less/TableExpand.less'
import { mixinDevice } from '@/utils/mixin'
import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import TenantModal from './modules/TenantModal'
export default {
name: "TenantList",
mixins:[JeecgListMixin, mixinDevice],
components: {
TenantModal
},
data () {
return {
description: 'adad管理页面',
// 表头
columns: [
{
title:'租户名称',
align:"center",
dataIndex: 'name'
},{
title:'租户编号',
align:"center",
dataIndex: 'id'
},
{
title:'开始时间',
align:"center",
dataIndex: 'beginDate'
},
{
title:'结束时间',
align:"center",
dataIndex: 'endDate'
},
{
title:'状态',
align:"center",
dataIndex: 'status_dictText'
},
{
title: '操作',
dataIndex: 'action',
align:"center",
fixed:"right",
width:147,
scopedSlots: { customRender: 'action' }
}
],
url: {
list: "/sys/tenant/list",
delete: "/sys/tenant/delete",
deleteBatch: "/sys/tenant/deleteBatch"
},
dictOptions:{},
}
},
created() {
},
computed: {
importExcelUrl: function(){
return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}`;
},
},
methods: {
initDictConfig(){
}
}
}
</script>
<style scoped>
@import '~@assets/less/common.less';
</style>
\ No newline at end of file
......@@ -119,10 +119,9 @@
</template>
<span slot="action" slot-scope="text, record">
<!-- <a @click="handleEdit(record)" v-has="'user:edit'">编辑</a>-->
<a @click="handleEdit(record)">编辑</a>
<a @click="handleEdit(record)" >编辑</a>
<a-divider type="vertical"/>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link">
......@@ -260,13 +259,7 @@
title: '部门',
align: "center",
width: 180,
dataIndex: 'orgCode'
},
{
title: '负责部门',
align: "center",
width: 180,
dataIndex: 'departIds_dictText'
dataIndex: 'orgCodeTxt'
},
{
title: '状态',
......
<template>
<a-card :bordered="false">
<template v-if="this.departId">
<a-form>
<a-form-item label='所拥有的权限'>
<a-tree
checkable
@check="onCheck"
:checkedKeys="checkedKeys"
:treeData="treeData"
@expand="onExpand"
@select="onTreeNodeSelect"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeysss"
:checkStrictly="checkStrictly"
style="height:500px;overflow: auto;">
<span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
{{ slotTitle }}
<a-icon v-if="ruleFlag" type="align-left" style="margin-left:5px;color: red;"></a-icon>
</span>
</a-tree>
</a-form-item>
</a-form>
<a-spin :spinning="loading">
<a-form>
<a-form-item label='所拥有的权限'>
<a-tree
checkable
@check="onCheck"
:checkedKeys="checkedKeys"
:treeData="treeData"
@expand="onExpand"
@select="onTreeNodeSelect"
:selectedKeys="selectedKeys"
:expandedKeys="expandedKeysss"
:checkStrictly="checkStrictly"
style="height:500px;overflow: auto;">
<span slot="hasDatarule" slot-scope="{slotTitle,ruleFlag}">
{{ slotTitle }}
<a-icon v-if="ruleFlag" type="align-left" style="margin-left:5px;color: red;"></a-icon>
</span>
</a-tree>
</a-form-item>
</a-form>
</a-spin>
<div class="anty-form-btn">
<a-dropdown style="float: left" :trigger="['click']" placement="topCenter">
<a-menu slot="overlay">
......@@ -156,6 +158,7 @@
this.form.resetFields()
},
loadData(){
this.loading = true;
queryTreeListForRole().then((res) => {
this.treeData = res.result.treeList
this.allTreeKeys = res.result.ids
......@@ -176,6 +179,7 @@
this.halfCheckedKeys = [...halfCheckedKeys]
this.defaultCheckedKeys = [...halfCheckedKeys, ...checkedKeys];
this.expandedKeysss = this.allTreeKeys;
this.loading = false;
})
})
}
......
......@@ -7,7 +7,7 @@
:closable="true"
@close="close"
:visible="visible"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;">
style="overflow: auto;padding-bottom: 53px;">
<a-form>
<a-form-item label='所拥有的部门权限'>
......
......@@ -7,7 +7,7 @@
:closable="true"
@close="close"
:visible="visible"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;">
style="overflow: auto;padding-bottom: 53px;">
<a-spin :spinning="confirmLoading">
......@@ -102,7 +102,7 @@
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
getAction(this.url.getDeptRoleByUserId,{userId:this.userId}).then((res) => {
getAction(this.url.getDeptRoleByUserId,{userId:this.userId,departId:this.currentDeptId}).then((res) => {
if (res.success) {
var designName = [];
for (let value of res.result) {
......
......@@ -183,7 +183,7 @@
that.selectionRows=[];
selectUser.forEach(function(record,index){
console.log(record)
that.selectionRows.push({id: that.selectedRowKeys[index],realname:record})
that.selectionRows.push({id: that.selectedRowKeys[index],realname:record.label})
})
// this.selectionRows = selectUser;
}
......
......@@ -108,8 +108,10 @@
<a-select
mode="multiple"
placeholder="请选择用户"
:labelInValue=true
v-model="selectedUser"
@dropdownVisibleChange="selectUserIds"
@change="handleChange"
>
</a-select>
</a-form-item>
......@@ -166,7 +168,6 @@
xs: { span: 24 },
sm: { span: 21 },
},
confirmLoading: false,
form: this.$form.createForm(this),
validatorRules:{
......@@ -187,6 +188,7 @@
selectedUser:[],
disabled:false,
msgContent:"",
userList:[]
}
},
created () {
......@@ -210,15 +212,22 @@
this.userIds = record.userIds;
getAction(this.url.queryByIds,{userIds:this.userIds}).then((res)=>{
if(res.success){
//update--begin--autor:wangshuai-----date:20200601------for:系统公告选人后,不能删除------
var userList=[];
for(var i=0;i<res.result.length;i++){
this.selectedUser.push(res.result[i].realname);
var user={};
user.label =res.result[i].realname;
user.key=res.result[i].id;
userList.push(user);
}
this.selectedUser=userList;
//update--begin--autor:wangshuai-----date:20200601------for:系统公告选人后,不能删除------
this.$refs.UserListModal.edit(res.result,this.userIds);
}
});
}
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,'endTime','startTime','titile','msgContent','sender','priority','msgCategory','msgType','sendStatus','delFlag','msgAbstract'))
this.form.setFieldsValue(pick(this.model,'endTime','startTime','titile','msgContent','priority','msgCategory','msgType','sendStatus','msgAbstract'))
});
},
close () {
......@@ -298,7 +307,12 @@
this.selectedUser = [];
this.userIds = [];
for(var i=0;i<userList.length;i++){
this.selectedUser.push(userList[i].realname);
//update--begin--autor:wangshuai-----date:20200601------for:系统公告选人后,不能删除------
var user={};
user.label =userList[i].realname;
user.key=userList[i].id;
this.selectedUser.push(user);
//update--end--autor:wangshuai-----date:20200601------for:系统公告选人后,不能删除------
this.userIds += userList[i].id+","
}
},
......@@ -321,8 +335,21 @@
}else{
callback("结束时间需大于开始时间")
}
},
handleChange(userList) {
if (userList) {
this.userIds = [];
var users=[];
for (var i = 0; i < userList.length; i++) {
var user={};
user.id=userList[i].key;
user.realname=userList[i].label;
this.userIds += userList[i].key + ',';
users.push(user);
}
}
this.$refs.UserListModal.edit(users,this.userIds);
}
}
}
</script>
......
......@@ -29,7 +29,7 @@
import { validateCheckRule } from '@/utils/util'
export default {
name: 'SysCheckRuleModal',
name: 'SysCheckRuleTestModal',
data() {
return {
title: '操作',
......
<template>
<a-spin :spinning="confirmLoading">
<j-form-container :disabled="formDisabled">
<a-form :form="form" slot="detail">
<a-row>
<a-col :span="24">
<a-form-item label="租户名称" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input v-decorator="['name']" placeholder="请输入租户名称"></a-input>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="租户编号" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-input-number style="width: 100%" :min="1" v-decorator="['id',{rules: [{ required: true, message: '请输入租户编号'}]}]" placeholder="请输入租户编号"></a-input-number>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="开始时间" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-date placeholder="请选择开始时间" v-decorator="['beginDate']" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="结束时间" :labelCol="labelCol" :wrapperCol="wrapperCol">
<j-date placeholder="请选择结束时间" v-decorator="['endDate']" :trigger-change="true" :show-time="true" date-format="YYYY-MM-DD HH:mm:ss" style="width: 100%"/>
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="状态" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-radio-group name="tenantStatus" v-decorator="[ 'status', {initialValue:1}]">
<a-radio :value="1">正常</a-radio>
<a-radio :value="0">冻结</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
<a-col v-if="showFlowSubmitButton" :span="24" style="text-align: center">
<a-button @click="submitForm">提 交</a-button>
</a-col>
</a-row>
</a-form>
</j-form-container>
</a-spin>
</template>
<script>
import { httpAction, getAction } from '@/api/manage'
import pick from 'lodash.pick'
import { validateDuplicateValue } from '@/utils/util'
import JFormContainer from '@/components/jeecg/JFormContainer'
import JDate from '@/components/jeecg/JDate'
import JDictSelectTag from "@/components/dict/JDictSelectTag"
export default {
name: "TenantForm",
components: {
JFormContainer,
JDate,
JDictSelectTag,
},
props: {
formData: {
type: Object,
default: ()=>{},
required: false
},
normal: {
type: Boolean,
default: false,
required: false
},
disabled: {
type: Boolean,
default: false,
required: false
}
},
data () {
return {
form: this.$form.createForm(this),
model: {},
labelCol: {
xs: { span: 24 },
sm: { span: 5 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 16 },
},
confirmLoading: false,
validatorRules: {
},
url: {
add: "/sys/tenant/add",
edit: "/sys/tenant/edit",
queryById: "/sys/tenant/queryById"
}
}
},
computed: {
formDisabled(){
if(this.normal===false){
if(this.formData.disabled===false){
return false
}else{
return true
}
}
return this.disabled
},
showFlowSubmitButton(){
if(this.normal===false){
if(this.formData.disabled===false){
return true
}else{
return false
}
}else{
return false
}
}
},
created () {
this.showFlowData();
},
methods: {
add () {
this.edit({});
},
edit (record) {
this.form.resetFields();
this.model = Object.assign({}, record);
this.visible = true;
this.$nextTick(() => {
this.form.setFieldsValue(pick(this.model,'id','name','beginDate','endDate','status'))
})
},
showFlowData(){
if(this.normal === false){
let params = {id:this.formData.dataId};
getAction(this.url.queryById,params).then((res)=>{
if(res.success){
this.edit (res.result);
}
});
}
},
submitForm () {
const that = this;
// 触发表单验证
this.form.validateFields((err, values) => {
if (!err) {
that.confirmLoading = true;
let httpurl = '';
let method = '';
if(!this.model.id){
httpurl+=this.url.add;
method = 'post';
}else{
httpurl+=this.url.edit;
method = 'put';
}
let formData = Object.assign(this.model, values);
console.log("表单提交数据",formData)
httpAction(httpurl,formData,method).then((res)=>{
if(res.success){
that.$message.success(res.message);
that.$emit('ok');
}else{
that.$message.warning(res.message);
}
}).finally(() => {
that.confirmLoading = false;
})
}
})
},
popupCallback(row){
this.form.setFieldsValue(pick(row, 'id', 'name','beginDate','endDate','status'))
},
}
}
</script>
\ No newline at end of file
<template>
<j-modal
:title="title"
:width="width"
:visible="visible"
switchFullscreen
@ok="handleOk"
:okButtonProps="{ class:{'jee-hidden': disableSubmit} }"
@cancel="handleCancel"
cancelText="关闭">
<tenant-form ref="realForm" @ok="submitCallback" :disabled="disableSubmit" normal></tenant-form>
</j-modal>
</template>
<script>
import TenantForm from './TenantForm'
export default {
name: "TenantModal",
components: {
TenantForm
},
data () {
return {
title:'',
width:800,
visible: false,
disableSubmit: false
}
},
methods: {
add () {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.add();
})
},
edit (record) {
this.visible=true
this.$nextTick(()=>{
this.$refs.realForm.edit(record);
})
},
close () {
this.$emit('close');
this.visible = false;
},
handleOk () {
this.$refs.realForm.submitForm();
},
submitCallback(){
this.$emit('ok');
this.visible = false;
},
handleCancel () {
this.close()
}
}
}
</script>
\ No newline at end of file
......@@ -7,7 +7,7 @@
:closable="true"
@close="close"
:visible="visible"
style="height: calc(100% - 55px);overflow: auto;padding-bottom: 53px;">
style="overflow: auto;padding-bottom: 53px;">
<a-form>
<a-form-item label='所拥有的权限'>
......
<template>
<a-card :bordered="false" style="width: 130%;text-align: center;margin-left:-10%">
<a-steps class="steps" :current="currentTab">
<a-step title="用户账户"/>
<a-step title="手机验证"/>
<a-step title="密码"/>
<a-step title="完成"/>
</a-steps>
<div class="content">
<step1 v-if="currentTab === 0" @nextStep="nextStep"/>
<step2 v-if="currentTab === 1" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/>
<step3 v-if="currentTab === 2" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/>
<step4 v-if="currentTab === 3" @prevStep="prevStep" @finish="finish" :userList="userList"/>
<step2 v-if="currentTab === 0" @nextStep="nextStep"/>
<step3 v-if="currentTab === 1" @nextStep="nextStep" @prevStep="prevStep" :userList="userList"/>
<step4 v-if="currentTab === 2" @prevStep="prevStep" @finish="finish" :userList="userList"/>
</div>
</a-card>
</template>
......
此差异已折叠。
*.js linguist-language=Java
*.css linguist-language=Java
*.html linguist-language=Java
*.vue linguist-language=Java
/target/
/.idea/
*.iml
jeecg-boot-module-demo
rebel.xml
\ No newline at end of file
此差异已折叠。
此差异已折叠。
-- 创建mysql库
create database `jeecg-boot` default character set utf8mb4 collate utf8mb4_general_ci;
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册