Commit 9e046a07 by zhangdaiscott

Jeecg-Boot 2.2.0 版本发布 | 重磅升级

parent 046831e7
...@@ -7,12 +7,12 @@ ...@@ -7,12 +7,12 @@
Jeecg-Boot 快速开发平台(前后端分离版本) Jeecg-Boot 快速开发平台(前后端分离版本)
=============== ===============
当前最新版本: 2.1.4(发布日期:2020-02-24 当前最新版本: 2.2.0(发布日期:2020-05-06
[![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE) [![AUR](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg)](https://github.com/zhangdaiscott/jeecg-boot/blob/master/LICENSE)
[![](https://img.shields.io/badge/Author-JEECG团队-orange.svg)](http://www.jeecg.com) [![](https://img.shields.io/badge/Author-JEECG团队-orange.svg)](http://www.jeecg.com)
[![](https://img.shields.io/badge/version-2.1.4-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot) [![](https://img.shields.io/badge/version-2.2.0-brightgreen.svg)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot) [![GitHub stars](https://img.shields.io/github/stars/zhangdaiscott/jeecg-boot.svg?style=social&label=Stars)](https://github.com/zhangdaiscott/jeecg-boot)
[![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot) [![GitHub forks](https://img.shields.io/github/forks/zhangdaiscott/jeecg-boot.svg?style=social&label=Fork)](https://github.com/zhangdaiscott/jeecg-boot)
......
Ant Design Jeecg Vue Ant Design Jeecg Vue
==== ====
当前最新版本: 2.1.4(发布日期:2020-02-24 当前最新版本: 2.2.0(发布日期:2020-05-06
Overview Overview
---- ----
......
...@@ -6,19 +6,19 @@ function resolve (dir) { ...@@ -6,19 +6,19 @@ function resolve (dir) {
} }
module.exports = { module.exports = {
context: path.resolve(__dirname, './'), context: path.resolve(__dirname, './'),
resolve: { resolve: {
extensions: ['.js', '.vue', '.json'], extensions: ['.js', '.vue', '.json'],
alias: { alias: {
'config': resolve('config'), 'config': resolve('config'),
'@': resolve('src'), '@': resolve('src'),
'@views': resolve('src/views'), '@views': resolve('src/views'),
'@comp': resolve('src/components'), '@comp': resolve('src/components'),
'@core': resolve('src/core'), '@core': resolve('src/core'),
'@utils': resolve('src/utils'), '@utils': resolve('src/utils'),
'@entry': resolve('src/entry'), '@entry': resolve('src/entry'),
'@router': resolve('src/router'), '@router': resolve('src/router'),
'@store': resolve('src/store') '@store': resolve('src/store')
} }
} },
} }
\ No newline at end of file
{ {
"name": "vue-antd-jeecg", "name": "vue-antd-jeecg",
"version": "2.1.4", "version": "2.2.0",
"private": true, "private": true,
"scripts": { "scripts": {
"pre": "cnpm install || yarn --registry https://registry.npm.taobao.org || npm install --registry https://registry.npm.taobao.org ", "pre": "yarn --registry https://registry.npm.taobao.org || cnpm install || npm install --registry https://registry.npm.taobao.org ",
"serve": "vue-cli-service serve", "serve": "vue-cli-service serve",
"build": "vue-cli-service build", "build": "vue-cli-service build",
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"@antv/data-set": "^0.10.2", "@antv/data-set": "^0.11.2",
"@jeecg/antd-online-214": "^2.1.41", "@jeecg/antd-online-beta220": "^1.0.1",
"@tinymce/tinymce-vue": "^2.0.0", "@tinymce/tinymce-vue": "^2.0.0",
"ant-design-vue": "^1.4.11", "ant-design-vue": "^1.5.2",
"apexcharts": "^3.6.5", "area-data": "^5.0.6",
"axios": "^0.18.0", "axios": "^0.18.0",
"clipboard": "^2.0.4", "clipboard": "^2.0.4",
"codemirror": "^5.46.0", "codemirror": "^5.46.0",
...@@ -25,22 +25,20 @@ ...@@ -25,22 +25,20 @@
"md5": "^2.2.1", "md5": "^2.2.1",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"tinymce": "^5.1.4", "tinymce": "^5.1.4",
"tui-editor": "^1.4.10",
"viser-vue": "^2.4.4", "viser-vue": "^2.4.4",
"vue": "^2.6.10", "vue": "^2.6.10",
"vue-apexcharts": "^1.3.2", "vue-area-linkage": "^5.1.0",
"vue-class-component": "^6.0.0",
"vue-cropper": "^0.4.8", "vue-cropper": "^0.4.8",
"vue-i18n": "^8.7.0", "vue-i18n": "^8.7.0",
"vue-loader": "^15.7.0", "vue-loader": "^15.7.0",
"vue-ls": "^3.2.0", "vue-ls": "^3.2.0",
"vue-photo-preview": "^1.1.3", "vue-photo-preview": "^1.1.3",
"vue-print-nb-jeecg": "^1.0.9", "vue-print-nb-jeecg": "^1.0.9",
"vue-property-decorator": "^7.3.0",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue-splitpane": "^1.0.4", "vue-splitpane": "^1.0.4",
"vuedraggable": "^2.20.0", "vuedraggable": "^2.20.0",
"vuex": "^3.0.1", "vuex": "^3.1.0"
"vuex-class": "^0.3.1"
}, },
"devDependencies": { "devDependencies": {
"@babel/polyfill": "^7.2.5", "@babel/polyfill": "^7.2.5",
...@@ -49,9 +47,10 @@ ...@@ -49,9 +47,10 @@
"@vue/cli-service": "^3.3.0", "@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0", "@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"compression-webpack-plugin": "^3.1.0",
"eslint": "^5.16.0", "eslint": "^5.16.0",
"eslint-plugin-vue": "^5.1.0", "eslint-plugin-vue": "^5.1.0",
"html-webpack-plugin": "^4.0.0-beta.11", "html-webpack-plugin": "^4.2.0",
"less": "^3.9.0", "less": "^3.9.0",
"less-loader": "^4.1.0", "less-loader": "^4.1.0",
"vue-template-compiler": "^2.6.10" "vue-template-compiler": "^2.6.10"
...@@ -91,7 +90,7 @@ ...@@ -91,7 +90,7 @@
"vue/no-use-v-if-with-v-for": 0, "vue/no-use-v-if-with-v-for": 0,
"vue/html-closing-bracket-newline": 0, "vue/html-closing-bracket-newline": 0,
"vue/no-parsing-error": 0, "vue/no-parsing-error": 0,
"no-console": 0, "no-console": 0,
"no-tabs": 0, "no-tabs": 0,
"indent": [1, 4] "indent": [1, 4]
} }
......
...@@ -7679,3 +7679,23 @@ font.medium { ...@@ -7679,3 +7679,23 @@ font.medium {
font.weak { font.weak {
color: #f5222d; color: #f5222d;
} }
// begin -------- JAreaLinkage 三级联动样式 --------------
.cascader-menu-list .cascader-menu-option.hover,
.cascader-menu-list .cascader-menu-option:hover {
background-color: color(~`colorPalette("@{primary-color}", 1)`);
}
.area-selectable-list .area-select-option.hover {
background-color: color(~`colorPalette("@{primary-color}", 1)`);
}
.area-select:hover {
border-color: @primary-color;
}
.area-select:active {
box-shadow: 0 0 0 2px color(~`colorPalette("@{primary-color}", 1)`);
}
// end -------- JAreaLinkage 三级联动样式 --------------
\ No newline at end of file
import Vue from 'vue'
/**
* 将一个请求分组
*
* @param getPromise 传入一个可以获取到Promise对象的方法
* @param groupId 分组ID,如果不传或者为空则不分组
* @param expire 过期时间,默认 半分钟
*/
export function httpGroupRequest(getPromise, groupId, expire = 1000 * 30) {
if (groupId == null || groupId === '') {
console.log("--------popup----------getFrom DB-------with---no--groupId ")
return getPromise()
}
if (Vue.ls.get(groupId)) {
console.log("---------popup--------getFrom Cache--------groupId = " + groupId)
return Promise.resolve(Vue.ls.get(groupId));
} else {
console.log("--------popup----------getFrom DB---------groupId = " + groupId)
}
// 还没有发出请求,就发出第一次的请求
return getPromise().then(res => {
Vue.ls.set(groupId, res, expire);
return Promise.resolve(res);
})
}
import { getAction,deleteAction,putAction,postAction} from '@/api/manage' import { getAction, deleteAction, putAction, postAction, httpAction } from '@/api/manage'
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 addRole = (params)=>postAction("/sys/role/add",params);
const editRole = (params)=>putAction("/sys/role/edit",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 checkRoleCode = (params)=>getAction("/sys/role/checkRoleCode",params);
const queryall = (params)=>getAction("/sys/role/queryall",params); const queryall = (params)=>getAction("/sys/role/queryall",params);
...@@ -19,8 +14,6 @@ const addUser = (params)=>postAction("/sys/user/add",params); ...@@ -19,8 +14,6 @@ const addUser = (params)=>postAction("/sys/user/add",params);
const editUser = (params)=>putAction("/sys/user/edit",params); const editUser = (params)=>putAction("/sys/user/edit",params);
const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params); const queryUserRole = (params)=>getAction("/sys/user/queryUserRole",params);
const getUserList = (params)=>getAction("/sys/user/list",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 frozenBatch = (params)=>putAction("/sys/user/frozenBatch",params);
//验证用户是否存在 //验证用户是否存在
const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params); const checkOnlyUser = (params)=>getAction("/sys/user/checkOnlyUser",params);
...@@ -31,20 +24,15 @@ const changePassword = (params)=>putAction("/sys/user/changePassword",params); ...@@ -31,20 +24,15 @@ const changePassword = (params)=>putAction("/sys/user/changePassword",params);
const addPermission= (params)=>postAction("/sys/permission/add",params); const addPermission= (params)=>postAction("/sys/permission/add",params);
const editPermission= (params)=>putAction("/sys/permission/edit",params); const editPermission= (params)=>putAction("/sys/permission/edit",params);
const getPermissionList = (params)=>getAction("/sys/permission/list",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 getSystemMenuList = (params)=>getAction("/sys/permission/getSystemMenuList",params);
const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params); const getSystemSubmenu = (params)=>getAction("/sys/permission/getSystemSubmenu",params);
const getSystemSubmenuBatch = (params) => getAction('/sys/permission/getSystemSubmenuBatch', 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 queryTreeList = (params)=>getAction("/sys/permission/queryTreeList",params);
const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params); const queryTreeListForRole = (params)=>getAction("/sys/role/queryTreeList",params);
const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params); const queryListAsync = (params)=>getAction("/sys/permission/queryListAsync",params);
const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params); const queryRolePermission = (params)=>getAction("/sys/permission/queryRolePermission",params);
const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params); const saveRolePermission = (params)=>postAction("/sys/permission/saveRolePermission",params);
//const queryPermissionsByUser = (params)=>getAction("/sys/permission/queryByUser",params);
const queryPermissionsByUser = (params)=>getAction("/sys/permission/getUserPermissionByToken",params); const queryPermissionsByUser = (params)=>getAction("/sys/permission/getUserPermissionByToken",params);
const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params); const loadAllRoleIds = (params)=>getAction("/sys/permission/loadAllRoleIds",params);
const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params); const getPermissionRuleList = (params)=>getAction("/sys/permission/getPermRuleListByPermId",params);
...@@ -66,24 +54,26 @@ const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/sa ...@@ -66,24 +54,26 @@ const saveDeptRolePermission = (params)=>postAction("/sys/sysDepartPermission/sa
const queryMyDepartTreeList = (params)=>getAction("/sys/sysDepart/queryMyDeptTreeList",params); 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 deleteLog = (params)=>deleteAction("/sys/log/delete",params);
const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params); const deleteLogList = (params)=>deleteAction("/sys/log/deleteBatch",params);
//数据字典 //数据字典
const addDict = (params)=>postAction("/sys/dict/add",params); const addDict = (params)=>postAction("/sys/dict/add",params);
const editDict = (params)=>putAction("/sys/dict/edit",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 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 addDictItem = (params)=>postAction("/sys/dictItem/add",params);
const editDictItem = (params)=>putAction("/sys/dictItem/edit",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获取字典数组) //字典标签专用(通过code获取字典数组)
export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params); export const ajaxGetDictItems = (code, params)=>getAction(`/sys/dict/getDictItems/${code}`,params);
//从缓存中获取字典配置
function getDictItemsFromCache(dictCode) {
if (Vue.ls.get(UI_CACHE_DB_DICT_DATA) && Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode]) {
let dictItems = Vue.ls.get(UI_CACHE_DB_DICT_DATA)[dictCode];
console.log("-----------getDictItemsFromCache----------dictCode="+dictCode+"---- dictItems=",dictItems)
return dictItems;
}
}
//系统通告 //系统通告
const doReleaseData = (params)=>getAction("/sys/annountCement/doReleaseData",params); const doReleaseData = (params)=>getAction("/sys/annountCement/doReleaseData",params);
...@@ -91,23 +81,18 @@ const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",param ...@@ -91,23 +81,18 @@ const doReovkeData = (params)=>getAction("/sys/annountCement/doReovkeData",param
//获取系统访问量 //获取系统访问量
const getLoginfo = (params)=>getAction("/sys/loginfo",params); const getLoginfo = (params)=>getAction("/sys/loginfo",params);
const getVisitInfo = (params)=>getAction("/sys/visitInfo",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 queryUserByDepId = (params)=>getAction("/sys/user/queryUserByDepId",params);
// 查询用户角色表里的所有信息
const queryUserRoleMap = (params)=>getAction("/sys/user/queryUserRoleMap",params);
// 重复校验 // 重复校验
const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params); const duplicateCheck = (params)=>getAction("/sys/duplicate/check",params);
// 加载分类字典 // 加载分类字典
const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params); const loadCategoryData = (params)=>getAction("/sys/category/loadAllData",params);
const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params) const checkRuleByCode = (params) => getAction('/sys/checkRule/checkByCode', params)
//我的通告
const getUserNoticeInfo= (params)=>getAction("/sys/sysAnnouncementSend/getMyAnnouncementSend",params);
export { export {
// imgView,
// doMian,
addRole, addRole,
editRole, editRole,
checkRoleCode, checkRoleCode,
...@@ -147,7 +132,6 @@ export { ...@@ -147,7 +132,6 @@ export {
getLoginfo, getLoginfo,
getVisitInfo, getVisitInfo,
queryUserByDepId, queryUserByDepId,
queryUserRoleMap,
duplicateCheck, duplicateCheck,
queryTreeListForRole, queryTreeListForRole,
getSystemMenuList, getSystemMenuList,
...@@ -160,7 +144,9 @@ export { ...@@ -160,7 +144,9 @@ export {
queryTreeListForDeptRole, queryTreeListForDeptRole,
queryDeptRolePermission, queryDeptRolePermission,
saveDeptRolePermission, saveDeptRolePermission,
queryMyDepartTreeList queryMyDepartTreeList,
getUserNoticeInfo,
getDictItemsFromCache
} }
......
...@@ -55,4 +55,19 @@ export function logout(logoutToken) { ...@@ -55,4 +55,19 @@ export function logout(logoutToken) {
'X-Access-Token': logoutToken 'X-Access-Token': logoutToken
} }
}) })
}
/**
* 第三方登录
* @param token
* @returns {*}
*/
export function thirdLogin(token) {
return axios({
url: `/thirdLogin/getLoginUser/${token}`,
method: 'get',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
})
} }
\ No newline at end of file
import Vue from 'vue'
import { axios } from '@/utils/request' import { axios } from '@/utils/request'
const api = { const api = {
...@@ -113,16 +114,64 @@ export function downFile(url,parameter){ ...@@ -113,16 +114,64 @@ export function downFile(url,parameter){
} }
/** /**
* 获取文件访问路径 * 下载文件
* @param url 文件路径
* @param fileName 文件名
* @param parameter
* @returns {*}
*/
export function downloadFile(url, fileName, parameter) {
return downFile(url, parameter).then((data) => {
if (!data || data.size === 0) {
Vue.prototype['$message'].warning('文件下载失败')
return
}
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(new Blob([data]), fileName)
} else {
let url = window.URL.createObjectURL(new Blob([data]))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
document.body.removeChild(link) //下载完成移除元素
window.URL.revokeObjectURL(url) //释放掉blob对象
}
})
}
/**
* 文件上传 用于富文本上传图片
* @param url
* @param parameter
* @returns {*}
*/
export function uploadAction(url,parameter){
return axios({
url: url,
data: parameter,
method:'post' ,
headers: {
'Content-Type': 'multipart/form-data', // 文件上传
},
})
}
/**
* 获取文件服务访问路径
* @param avatar * @param avatar
* @param imgerver * @param subStr
* @param str
* @returns {*} * @returns {*}
*/ */
export function getFileAccessHttpUrl(avatar,imgerver,subStr) { export function getFileAccessHttpUrl(avatar,subStr) {
if(avatar && avatar.indexOf(subStr) != -1 ){ if(!subStr) subStr = 'http'
if(avatar && avatar.startsWith(subStr)){
return avatar; return avatar;
}else{ }else{
return imgerver + "/" + avatar; if(avatar && avatar.length>0 && avatar.indexOf('[')==-1){
return window._CONFIG['staticDomainURL'] + "/" + avatar;
}
} }
} }
.area-zoom-in-top-enter-active,
.area-zoom-in-top-leave-active {
opacity: 1;
transform: scaleY(1);
}
.area-zoom-in-top-enter,
.area-zoom-in-top-leave-active {
opacity: 0;
transform: scaleY(0);
}
.area-select {
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0, 0, 0, 0.65);
font-size: 14px;
font-variant: tabular-nums;
line-height: 1.5;
list-style: none;
font-feature-settings: 'tnum';
position: relative;
outline: 0;
display: block;
background-color: #fff;
border: 1px solid #d9d9d9;
border-top-width: 1.02px;
border-radius: 4px;
outline: none;
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
.area-select-wrap .area-select {
display: inline-block;
}
.area-select * {
box-sizing: border-box;
}
.area-select:hover {
border-color: #40a9ff;
border-right-width: 1px !important;
outline: 0;
}
.area-select:active {
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
}
.area-select.small {
width: 126px;
}
.area-select.medium {
width: 160px;
}
.area-select.large {
width: 194px;
}
.area-select.is-disabled {
background: #eceff5;
cursor: not-allowed;
}
.area-select.is-disabled:hover {
border-color: #e1e2e6;
}
.area-select.is-disabled .area-selected-trigger {
cursor: not-allowed;
}
.area-select .area-selected-trigger {
position: relative;
display: block;
font-size: 14px;
cursor: pointer;
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
height: 100%;
padding: 8px 20px 7px 12px;
}
.area-select .area-select-icon {
position: absolute;
top: 50%;
margin-top: -2px;
right: 6px;
content: "";
width: 0;
height: 0;
border: 6px solid transparent;
border-top-color: rgba(0, 0, 0, 0.25);
transition: all .3s linear;
transform-origin: center;
}
.area-select .area-select-icon.active {
margin-top: -8px;
transform: rotate(180deg);
}
.area-selectable-list-wrap {
position: absolute;
width: 100%;
max-height: 275px;
z-index: 15000;
background-color: #fff;
box-sizing: border-box;
overflow-x: auto;
margin: 2px 0;
border-radius: 4px;
outline: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
transition: opacity 0.15s, transform 0.3s !important;
transform-origin: center top !important;
}
.area-selectable-list {
position: relative;
margin: 0;
padding: 6px 0;
width: 100%;
font-size: 14px;
color: #565656;
list-style: none;
}
.area-selectable-list .area-select-option {
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
padding: 0 15px 0 10px;
height: 32px;
line-height: 32px;
}
.area-selectable-list .area-select-option.hover {
background-color: #e6f7ff;
}
.area-selectable-list .area-select-option.selected {
color: rgba(0, 0, 0, 0.65);
font-weight: 600;
background-color: #efefef;
}
.cascader-menu-list-wrap {
position: absolute;
white-space: nowrap;
z-index: 15000;
background-color: #fff;
box-sizing: border-box;
overflow: hidden;
font-size: 0;
margin: 2px 0;
border-radius: 4px;
outline: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
transition: opacity 0.15s, transform 0.3s !important;
transform-origin: center top !important;
}
.cascader-menu-list {
position: relative;
margin: 0;
font-size: 14px;
color: #565656;
padding: 6px 0;
list-style: none;
display: inline-block;
height: 204px;
overflow-x: hidden;
overflow-y: auto;
min-width: 160px;
vertical-align: top;
background-color: #fff;
border-right: 1px solid #e4e7ed;
}
.cascader-menu-list:last-child {
border-right: none;
}
.cascader-menu-list .cascader-menu-option {
position: relative;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
cursor: pointer;
padding: 0 15px 0 10px;
height: 32px;
line-height: 32px;
}
.cascader-menu-list .cascader-menu-option.hover,
.cascader-menu-list .cascader-menu-option:hover {
background-color: #e6f7ff;
}
.cascader-menu-list .cascader-menu-option.selected {
color: rgba(0, 0, 0, 0.65);
font-weight: 600;
background-color: #efefef;
}
.cascader-menu-list .cascader-menu-option.cascader-menu-extensible:after {
position: absolute;
top: 50%;
margin-top: -4px;
right: 5px;
content: "";
width: 0;
height: 0;
border: 4px solid transparent;
border-left-color: #a1a4ad;
}
.cascader-menu-list::-webkit-scrollbar,
.area-selectable-list-wrap::-webkit-scrollbar {
width: 8px;
background: transparent;
}
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:decremen,
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:end:decrement,
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:increment,
.area-selectable-list-wrap::-webkit-scrollbar-button:vertical:start:increment,
.cascader-menu-list::-webkit-scrollbar-button:vertical:decremen,
.cascader-menu-list::-webkit-scrollbar-button:vertical:end:decrement,
.cascader-menu-list::-webkit-scrollbar-button:vertical:increment,
.cascader-menu-list::-webkit-scrollbar-button:vertical:start:increment {
display: none;
}
.cascader-menu-list::-webkit-scrollbar-thumb:vertical,
.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical {
background-color: #b8b8b8;
border-radius: 4px;
}
.cascader-menu-list::-webkit-scrollbar-thumb:vertical:hover,
.area-selectable-list-wrap::-webkit-scrollbar-thumb:vertical:hover {
background-color: #777;
}
\ No newline at end of file
/** [表格主题样式一] 表格强制列不换行 */
.j-table-force-nowrap {
td, th {
white-space: nowrap;
}
.ant-table-selection-column {
padding: 12px 22px !important;
}
/** 列自适应,弊端会导致列宽失效 */
&.ant-table-wrapper .ant-table-content {
overflow-x: auto;
}
}
/*列表上方操作按钮区域*/ /*列表上方操作按钮区域*/
.ant-card-body .table-operator { .ant-card-body .table-operator {
margin-bottom: 18px; margin-bottom: 8px;
} }
/** Button按钮间距 */ /** Button按钮间距 */
.table-operator .ant-btn { .table-operator .ant-btn {
margin: 8px 8px 0 0; margin: 0 8px 8px 0;
}
.table-operator .ant-btn-group .ant-btn {
margin: 0;
}
.table-operator .ant-btn-group .ant-btn:last-child {
margin: 0 8px 8px 0;
} }
/*列表td的padding设置 可以控制列表大小*/ /*列表td的padding设置 可以控制列表大小*/
.ant-table-tbody .ant-table-row td { .ant-table-tbody .ant-table-row td {
...@@ -45,3 +52,7 @@ ...@@ -45,3 +52,7 @@
/*erp风格子表外框padding设置*/ /*erp风格子表外框padding设置*/
.ant-card-wider-padding.cust-erp-sub-tab>.ant-card-body{padding:5px 12px} .ant-card-wider-padding.cust-erp-sub-tab>.ant-card-body{padding:5px 12px}
/* 内嵌子表背景颜色 */
.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
...@@ -8,14 +8,14 @@ const init = (callback) => { ...@@ -8,14 +8,14 @@ const init = (callback) => {
console.log("-------单点登录开始-------"); console.log("-------单点登录开始-------");
let token = Vue.ls.get(ACCESS_TOKEN); let token = Vue.ls.get(ACCESS_TOKEN);
let st = getUrlParam("ticket"); let st = getUrlParam("ticket");
var sevice = "http://"+window.location.host+"/"; let sevice = "http://"+window.location.host+"/";
if(token){ if(token){
loginSuccess(callback); loginSuccess(callback);
}else{ }else{
if(st){ if(st){
validateSt(st,sevice,callback); validateSt(st,sevice,callback);
}else{ }else{
var serviceUrl = encodeURIComponent(sevice); let serviceUrl = encodeURIComponent(sevice);
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl; window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
} }
} }
...@@ -26,14 +26,14 @@ const SSO = { ...@@ -26,14 +26,14 @@ const SSO = {
}; };
function getUrlParam(paraName) { function getUrlParam(paraName) {
var url = document.location.toString(); let url = document.location.toString();
var arrObj = url.split("?"); let arrObj = url.split("?");
if (arrObj.length > 1) { if (arrObj.length > 1) {
var arrPara = arrObj[1].split("&"); let arrPara = arrObj[1].split("&");
var arr; let arr;
for (var i = 0; i < arrPara.length; i++) { for (let i = 0; i < arrPara.length; i++) {
arr = arrPara[i].split("="); arr = arrPara[i].split("=");
if (arr != null && arr[0] == paraName) { if (arr != null && arr[0] == paraName) {
...@@ -57,8 +57,8 @@ function validateSt(ticket,service,callback){ ...@@ -57,8 +57,8 @@ function validateSt(ticket,service,callback){
if(res.success){ if(res.success){
loginSuccess(callback); loginSuccess(callback);
}else{ }else{
var sevice = "http://"+window.location.host+"/"; let sevice = "http://"+window.location.host+"/";
var serviceUrl = encodeURIComponent(sevice); let serviceUrl = encodeURIComponent(sevice);
window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl; window.location.href = window._CONFIG['casPrefixUrl']+"/login?service="+serviceUrl;
} }
}).catch((err) => { }).catch((err) => {
......
<script> <script>
import Tooltip from 'ant-design-vue/es/tooltip'
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil' import { cutStrByFullLength, getStrFullLength } from '@/components/_util/StringUtil'
/*
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
const TooltipOverlayStyle = {
overflowWrap: 'break-word',
wordWrap: 'break-word',
};
*/
export default { export default {
name: 'Ellipsis', name: 'Ellipsis',
components: {
Tooltip
},
props: { props: {
prefixCls: { prefixCls: {
type: String, type: String,
default: 'ant-pro-ellipsis' default: 'ant-pro-ellipsis'
}, },
tooltip: { tooltip: {
type: Boolean type: Boolean,
default: true,
}, },
length: { length: {
type: Number, type: Number,
required: true default: 25,
}, },
lines: { lines: {
type: Number, type: Number,
...@@ -36,28 +25,25 @@ ...@@ -36,28 +25,25 @@
default: false default: false
} }
}, },
methods: { methods: {},
getStrDom (str) { render() {
return ( const { tooltip, length } = this.$props
<span>{ cutStrByFullLength(str, this.length) + '...' }</span> let text = ''
) // 处理没有default插槽时的特殊情况
}, if (this.$slots.default) {
getTooltip ( fullStr) { text = this.$slots.default.map(vNode => vNode.text).join('')
}
// 判断是否显示 tooltip
if (tooltip && getStrFullLength(text) > length) {
return ( return (
<Tooltip> <a-tooltip>
<template slot="title">{ fullStr }</template> <template slot="title">{text}</template>
{ this.getStrDom(fullStr) } <span>{cutStrByFullLength(text, this.length) + '…'}</span>
</Tooltip> </a-tooltip>
) )
} else {
return (<span>{text}</span>)
} }
},
render () {
const { tooltip, length } = this.$props
let str = this.$slots.default.map(vNode => vNode.text).join("")
const strDom = tooltip && getStrFullLength(str) > length ? this.getTooltip(str) : this.getStrDom(str);
return (
strDom
)
} }
} }
</script> </script>
\ No newline at end of file
import { pcaa } from 'area-data'
/**
* 省市区
*/
export default class Area {
/**
* 构造器
* @param express
*/
constructor() {
let arr = []
const province = pcaa['86']
Object.keys(province).map(key=>{
arr.push({id:key, text:province[key], pid:'86'});
const city = pcaa[key];
Object.keys(city).map(key2=>{
arr.push({id:key2, text:city[key2], pid:key});
const qu = pcaa[key2];
Object.keys(qu).map(key3=>{
arr.push({id:key3, text:qu[key3], pid:key2});
})
})
})
this.all = arr;
}
get pca(){
return this.all;
}
getCode(text){
if(!text || text.length==0){
return ''
}
for(let item of this.all){
if(item.text === text){
return item.id;
}
}
}
getText(code){
if(!code || code.length==0){
return ''
}
let arr = []
this.getAreaBycode(code,arr);
return arr.join('/')
}
getRealCode(code){
let arr = []
this.getPcode(code, arr)
return arr;
}
getPcode(id, arr){
for(let item of this.all){
if(item.id === id){
arr.unshift(id)
if(item.pid != '86'){
this.getPcode(item.pid,arr)
}
}
}
}
getAreaBycode(code,arr){
//console.log("this.all.length",this.all)
for(let item of this.all){
if(item.id === code){
arr.unshift(item.text);
this.getAreaBycode(item.pid,arr)
}
}
}
}
\ No newline at end of file
<template>
<div>
<v-chart :forceFit="true" :height="height" :data="data">
<v-coord type="rect" direction="LB" />
<v-tooltip />
<v-legend />
<v-axis dataKey="State" :label="label" />
<v-stack-bar position="State*流程数量" color="流程状态" />
</v-chart>
</div>
</template>
<script>
const DataSet = require('@antv/data-set');
export default {
name: 'StackBar',
props: {
dataSource: {
type: Array,
required: true,
default: () => [
{ 'State': '请假', '流转中': 25, '已归档': 18 },
{ 'State': '出差', '流转中': 30, '已归档': 20 },
{ 'State': '加班', '流转中': 38, '已归档': 42},
{ 'State': '用车', '流转中': 51, '已归档': 67}
]
},
height: {
type: Number,
default: 254
}
},
data() {
return {
label: { offset: 12 }
}
},
computed: {
data() {
const dv = new DataSet.View().source(this.dataSource);
dv.transform({
type: 'fold',
fields: ['流转中', '已归档'],
key: '流程状态',
value: '流程数量',
retains: ['State'],
});
return dv.rows;
}
}
}
</script>
\ No newline at end of file
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
<a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio> <a-radio v-for="(item, key) in dictOptions" :key="key" :value="item.value">{{ item.text }}</a-radio>
</a-radio-group> </a-radio-group>
<a-radio-group v-else-if="tagType=='radioButton'" buttonStyle="solid" @change="handleInput" :value="getValueSting" :disabled="disabled">
<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 = "(target) => target.parentNode" :placeholder="placeholder" :disabled="disabled" :value="getValueSting" @change="handleInput">
<a-select-option :value="undefined">请选择</a-select-option> <a-select-option :value="undefined">请选择</a-select-option>
<a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value"> <a-select-option v-for="(item, key) in dictOptions" :key="key" :value="item.value">
...@@ -14,7 +18,7 @@ ...@@ -14,7 +18,7 @@
</template> </template>
<script> <script>
import {ajaxGetDictItems} from '@/api/api' import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default { export default {
name: "JDictSelectTag", name: "JDictSelectTag",
...@@ -52,11 +56,17 @@ ...@@ -52,11 +56,17 @@
}, },
computed: { computed: {
getValueSting(){ getValueSting(){
return this.value ? this.value.toString() : null; return this.value != null ? this.value.toString() : null;
}, },
}, },
methods: { methods: {
initDictData() { initDictData() {
//优先从缓存中读取字典配置
if(getDictItemsFromCache(this.dictCode)){
this.dictOptions = getDictItemsFromCache(this.dictCode);
return
}
//根据字典Code, 初始化字典数组 //根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dictCode, null).then((res) => { ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) { if (res.success) {
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* date: 20190109 * date: 20190109
*/ */
import {ajaxGetDictItems} from '@/api/api' import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
import {getAction} from '@/api/manage' import {getAction} from '@/api/manage'
/** /**
...@@ -16,6 +16,13 @@ export async function initDictOptions(dictCode) { ...@@ -16,6 +16,13 @@ export async function initDictOptions(dictCode) {
if (!dictCode) { if (!dictCode) {
return '字典Code不能为空!'; return '字典Code不能为空!';
} }
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let res = {}
res.result = getDictItemsFromCache(dictCode);
res.success = true;
return res;
}
//获取字典数组 //获取字典数组
let res = await ajaxGetDictItems(dictCode); let res = await ajaxGetDictItems(dictCode);
return res; return res;
...@@ -28,16 +35,25 @@ export async function initDictOptions(dictCode) { ...@@ -28,16 +35,25 @@ export async function initDictOptions(dictCode) {
* @return String * @return String
*/ */
export function filterDictText(dictOptions, text) { export function filterDictText(dictOptions, text) {
//--update-begin----author:sunjianlei---date:20191025------for:修复字典替换方法在字典没有加载完成之前报错的问题、修复没有找到字典时返回空值的问题--- // --update-begin----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
if (dictOptions instanceof Array) { if (text != null && dictOptions instanceof Array) {
for (let dictItem of dictOptions) { let result = []
if (text === dictItem.value) { // 允许多个逗号分隔
return dictItem.text let 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
break
}
} }
result.push(dictText)
} }
return result.join(',')
} }
return text return text
//--update-end----author:sunjianlei---date:20191025------for:修复字典替换方法在字典没有加载完成之前报错的问题、修复没有找到字典时返回空值的问题--- // --update-end----author:sunjianlei---date:20200323------for: 字典翻译 text 允许逗号分隔 ---
} }
/** /**
...@@ -49,24 +65,28 @@ export function filterDictText(dictOptions, text) { ...@@ -49,24 +65,28 @@ export function filterDictText(dictOptions, text) {
export function filterMultiDictText(dictOptions, text) { export function filterMultiDictText(dictOptions, text) {
//js “!text” 认为0为空,所以做提前处理 //js “!text” 认为0为空,所以做提前处理
if(text === 0 || text === '0'){ if(text === 0 || text === '0'){
for (let dictItem of dictOptions) { if(dictOptions){
if (text == dictItem.value) { for (let dictItem of dictOptions) {
return dictItem.text if (text == dictItem.value) {
return dictItem.text
}
} }
} }
} }
if(!text || !dictOptions || dictOptions.length==0){ if(!text || text=='null' || !dictOptions || dictOptions.length==0){
return "" return ""
} }
let re = ""; let re = "";
text = text.toString() text = text.toString()
let arr = text.split(",") let arr = text.split(",")
dictOptions.forEach(function (option) { dictOptions.forEach(function (option) {
for(let i=0;i<arr.length;i++){ if(option){
if (arr[i] === option.value) { for(let i=0;i<arr.length;i++){
re += option.text+","; if (arr[i] === option.value) {
break; re += option.text+",";
break;
}
} }
} }
}); });
...@@ -81,20 +101,42 @@ export function filterMultiDictText(dictOptions, text) { ...@@ -81,20 +101,42 @@ export function filterMultiDictText(dictOptions, text) {
* @param children * @param children
* @returns string * @returns string
*/ */
export async function ajaxFilterDictText(dictCode, key) { export function filterDictTextByCache(dictCode, key) {
if(key==null ||key.length==0){
return;
}
if (!dictCode) { if (!dictCode) {
return '字典Code不能为空!'; return '字典Code不能为空!';
} }
//console.log(`key : ${key}`); //优先从缓存中读取字典配置
if (!key) { if(getDictItemsFromCache(dictCode)){
return ''; let item = getDictItemsFromCache(dictCode).filter(t => t["value"] == key)
} if(item && item.length>0){
//通过请求读取字典文本 return item[0]["text"]
let res = await getAction(`/sys/dict/getDictText/${dictCode}/${key}`); }
if (res.success) {
// console.log('restult: '+ res.result);
return res.result;
} else {
return '';
} }
}
/** 通过code获取字典数组 */
export async function getDictItems(dictCode, params) {
//优先从缓存中读取字典配置
if(getDictItemsFromCache(dictCode)){
let desformDictItems = getDictItemsFromCache(dictCode).map(item => ({...item, label: item.text}))
return desformDictItems;
}
//缓存中没有,就请求后台
return await ajaxGetDictItems(dictCode, params).then(({success, result}) => {
if (success) {
let res = result.map(item => ({...item, label: item.text}))
console.log('------- 从DB中获取到了字典-------dictCode : ', dictCode, res)
return Promise.resolve(res)
} else {
console.error('getDictItems error: : ', res)
return Promise.resolve([])
}
}).catch((res) => {
console.error('getDictItems error: ', res)
return Promise.resolve([])
})
} }
\ No newline at end of file
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
:disabled="disabled" :disabled="disabled"
mode="multiple" mode="multiple"
:placeholder="placeholder" :placeholder="placeholder"
:getPopupContainer="(node) => node.parentNode"
allowClear> allowClear>
<a-select-option <a-select-option
v-for="(item,index) in dictOptions" v-for="(item,index) in dictOptions"
...@@ -24,7 +25,7 @@ ...@@ -24,7 +25,7 @@
</template> </template>
<script> <script>
import {ajaxGetDictItems} from '@/api/api' import {ajaxGetDictItems,getDictItemsFromCache} from '@/api/api'
export default { export default {
name: 'JMultiSelectTag', name: 'JMultiSelectTag',
props: { props: {
...@@ -49,12 +50,18 @@ ...@@ -49,12 +50,18 @@
this.tagType = this.type this.tagType = this.type
} }
//获取字典数据 //获取字典数据
this.initDictData(); //this.initDictData();
}, },
watch:{ watch:{
options: function(val){ options: function(val){
this.setCurrentDictOptions(val); this.setCurrentDictOptions(val);
}, },
dictCode:{
immediate:true,
handler() {
this.initDictData()
},
},
value (val) { value (val) {
if(!val){ if(!val){
this.arrayValue = [] this.arrayValue = []
...@@ -68,6 +75,11 @@ ...@@ -68,6 +75,11 @@
if(this.options && this.options.length>0){ if(this.options && this.options.length>0){
this.dictOptions = [...this.options] this.dictOptions = [...this.options]
}else{ }else{
//优先从缓存中读取字典配置
if(getDictItemsFromCache(this.dictCode)){
this.dictOptions = getDictItemsFromCache(this.dictCode);
return
}
//根据字典Code, 初始化字典数组 //根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dictCode, null).then((res) => { ajaxGetDictItems(this.dictCode, null).then((res) => {
if (res.success) { if (res.success) {
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
v-if="async" v-if="async"
showSearch showSearch
labelInValue labelInValue
:disabled="disabled"
:getPopupContainer="(node) => node.parentNode"
@search="loadData" @search="loadData"
:placeholder="placeholder" :placeholder="placeholder"
v-model="selectedAsyncValue" v-model="selectedAsyncValue"
...@@ -19,7 +21,9 @@ ...@@ -19,7 +21,9 @@
<a-select <a-select
v-else v-else
:getPopupContainer="(node) => node.parentNode"
showSearch showSearch
:disabled="disabled"
:placeholder="placeholder" :placeholder="placeholder"
optionFilterProp="children" optionFilterProp="children"
style="width: 100%" style="width: 100%"
...@@ -35,7 +39,7 @@ ...@@ -35,7 +39,7 @@
</template> </template>
<script> <script>
import { ajaxGetDictItems } from '@/api/api' import { ajaxGetDictItems,getDictItemsFromCache } from '@/api/api'
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { getAction } from '../../api/manage' import { getAction } from '../../api/manage'
...@@ -43,7 +47,7 @@ ...@@ -43,7 +47,7 @@
name: 'JSearchSelectTag', name: 'JSearchSelectTag',
props:{ props:{
disabled: Boolean, disabled: Boolean,
value: String, value: [String, Number],
dict: String, dict: String,
dictOptions: Array, dictOptions: Array,
async: Boolean, async: Boolean,
...@@ -71,8 +75,12 @@ ...@@ -71,8 +75,12 @@
immediate:true, immediate:true,
handler(val){ handler(val){
if(!val){ if(!val){
this.selectedValue=[] if(val==0){
this.selectedAsyncValue=[] this.initSelectValue()
}else{
this.selectedValue=[]
this.selectedAsyncValue=[]
}
}else{ }else{
this.initSelectValue() this.initSelectValue()
} }
...@@ -100,7 +108,7 @@ ...@@ -100,7 +108,7 @@
}) })
} }
}else{ }else{
this.selectedValue = this.value this.selectedValue = this.value.toString()
} }
}, },
loadData(value){ loadData(value){
...@@ -132,11 +140,28 @@ ...@@ -132,11 +140,28 @@
this.options = [...this.dictOptions] this.options = [...this.dictOptions]
}else{ }else{
//根据字典Code, 初始化字典数组 //根据字典Code, 初始化字典数组
ajaxGetDictItems(this.dict, null).then((res) => { let dictStr = ''
if (res.success) { if(this.dict){
this.options = res.result; let arr = this.dict.split(',')
} if(arr[0].indexOf('where')>0){
}) let tbInfo = arr[0].split('where')
dictStr = tbInfo[0].trim()+','+arr[1]+','+arr[2]+','+encodeURIComponent(tbInfo[1])
}else{
dictStr = this.dict
}
if (this.dict.indexOf(",") == -1) {
//优先从缓存中读取字典配置
if (getDictItemsFromCache(this.dictCode)) {
this.options = getDictItemsFromCache(this.dictCode);
return
}
}
ajaxGetDictItems(dictStr, null).then((res) => {
if (res.success) {
this.options = res.result;
}
})
}
} }
} }
}, },
......
<template>
<div v-if="!reloading" class="j-area-linkage">
<area-cascader
v-if="_type === enums.type[0]"
:value="innerValue"
:data="pcaa"
:level="1"
:style="{width}"
v-bind="$attrs"
v-on="_listeners"
@change="handleChange"
/>
<area-select
v-else-if="_type === enums.type[1]"
:value="innerValue"
:data="pcaa"
:level="2"
v-bind="$attrs"
v-on="_listeners"
@change="handleChange"
/>
<div v-else>
<span style="color:red;"> Bad type value: {{_type}}</span>
</div>
</div>
</template>
<script>
import { pcaa } from 'area-data'
import Area from '@/components/_util/Area'
export default {
name: 'JAreaLinkage',
props: {
value: {
type: String,
required:false
},
// 组件的类型,可选值:
// select 下拉样式
// cascader 级联样式(默认)
type: {
type: String,
default: 'cascader'
},
width: {
type: String,
default: '100%'
}
},
data() {
return {
pcaa,
innerValue: [],
usedListeners: ['change'],
enums: {
type: ['cascader', 'select']
},
reloading: false,
areaData:''
}
},
computed: {
_listeners() {
let listeners = { ...this.$listeners }
// 去掉已使用的事件,防止冲突
this.usedListeners.forEach(key => {
delete listeners[key]
})
return listeners
},
_type() {
if (this.enums.type.includes(this.type)) {
return this.type
} else {
console.error(`JAreaLinkage的type属性只能接收指定的值(${this.enums.type.join('|')})`)
return this.enums.type[0]
}
},
},
watch: {
value: {
immediate: true,
handler() {
this.loadDataByValue(this.value)
}
},
},
created() {
this.initAreaData();
},
methods: {
/** 通过 value 反推 options */
loadDataByValue(value) {
if(!value || value.length==0){
this.innerValue = []
this.reloading = true;
setTimeout(()=>{
this.reloading = false
},100)
}else{
this.initAreaData();
let arr = this.areaData.getRealCode(value);
this.innerValue = arr
}
},
/** 通过地区code获取子级 */
loadDataByCode(value) {
let options = []
let data = pcaa[value]
if (data) {
for (let key in data) {
if (data.hasOwnProperty(key)) {
options.push({ value: key, label: data[key], })
}
}
return options
} else {
return []
}
},
/** 判断是否有子节点 */
hasChildren(options) {
options.forEach(option => {
let data = this.loadDataByCode(option.value)
option.isLeaf = data.length === 0
})
},
handleChange(values) {
let value = values[values.length - 1]
this.$emit('change', value)
},
initAreaData(){
if(!this.areaData){
this.areaData = new Area();
}
},
},
model: { prop: 'value', event: 'change' },
}
</script>
<style lang="less" scoped>
.j-area-linkage {
height:40px;
/deep/ .area-cascader-wrap .area-select {
width: 100%;
}
/deep/ .area-select .area-selected-trigger {
line-height: 1.15;
}
}
</style>
\ No newline at end of file
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
loadRoot(){ loadRoot(){
let param = { let param = {
pid:this.pid, pid:this.pid,
pcode:this.pcode, pcode:!this.pcode?'0':this.pcode,
condition:this.condition condition:this.condition
} }
getAction(this.url,param).then(res=>{ getAction(this.url,param).then(res=>{
...@@ -122,8 +122,6 @@ ...@@ -122,8 +122,6 @@
this.treeValue = [] this.treeValue = []
}else{ }else{
getAction(this.view,{ids:this.value}).then(res=>{ getAction(this.view,{ids:this.value}).then(res=>{
console.log(124345)
console.log(124345,res)
if(res.success){ if(res.success){
let values = this.value.split(',') let values = this.value.split(',')
this.treeValue = res.result.map((item, index) => ({ this.treeValue = res.result.map((item, index) => ({
......
<template> <template>
<div v-bind="fullScreenParentProps"> <div v-bind="fullScreenParentProps">
<a-icon v-if="fullScreen" class="full-screen-icon" type="fullscreen" @click="()=>fullCoder=!fullCoder"/> <a-icon v-if="fullScreen" class="full-screen-icon" :type="iconType" @click="()=>fullCoder=!fullCoder"/>
<div class="code-editor-cust full-screen-child"> <div class="code-editor-cust full-screen-child">
<textarea ref="textarea"></textarea> <textarea ref="textarea"></textarea>
...@@ -91,6 +91,7 @@ ...@@ -91,6 +91,7 @@
return { return {
// 内部真实的内容 // 内部真实的内容
code: '', code: '',
iconType: 'fullscreen',
hasCode:false, hasCode:false,
// 默认的语法类型 // 默认的语法类型
mode: 'javascript', mode: 'javascript',
...@@ -155,6 +156,15 @@ ...@@ -155,6 +156,15 @@
} }
}, },
watch: { watch: {
fullCoder:{
handler(value) {
if(value){
this.iconType="fullscreen-exit"
}else{
this.iconType="fullscreen"
}
}
},
// value: { // value: {
// immediate: false, // immediate: false,
// handler(value) { // handler(value) {
...@@ -408,6 +418,7 @@ ...@@ -408,6 +418,7 @@
.full-screen-child { .full-screen-child {
min-height: 120px; min-height: 120px;
max-height: 320px; max-height: 320px;
overflow:hidden;
} }
} }
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
}, },
getCalendarContainer: { getCalendarContainer: {
type: Function, type: Function,
default: () => document.body default: (node) => node.parentNode
} }
}, },
data () { data () {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
import 'tinymce/plugins/colorpicker' import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor' import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/fullscreen' import 'tinymce/plugins/fullscreen'
import { uploadAction,getFileAccessHttpUrl } from '@/api/manage'
export default { export default {
components: { components: {
Editor Editor
...@@ -65,8 +66,21 @@ ...@@ -65,8 +66,21 @@
menubar: false, menubar: false,
toolbar_drawer: false, toolbar_drawer: false,
images_upload_handler: (blobInfo, success) => { images_upload_handler: (blobInfo, success) => {
const img = 'data:image/jpeg;base64,' + blobInfo.base64() let formData = new FormData()
success(img) formData.append('file', blobInfo.blob(), blobInfo.filename());
formData.append('biz', "jeditor");
formData.append("jeditor","1");
uploadAction(window._CONFIG['domianURL']+"/sys/common/upload", formData).then((res) => {
if (res.success) {
if(res.message == 'local'){
const img = 'data:image/jpeg;base64,' + blobInfo.base64()
success(img)
}else{
let img = getFileAccessHttpUrl(res.message)
success(img)
}
}
})
} }
}, },
myValue: this.value myValue: this.value
......
<template> <template>
<div :class="disabled?'jeecg-form-container-disabled':''"> <div :class="disabled?'jeecg-form-container-disabled':''">
<fieldset disabled> <fieldset :disabled="disabled">
<slot name="detail"></slot> <slot name="detail"></slot>
</fieldset> </fieldset>
<slot name="edit"></slot> <slot name="edit"></slot>
...@@ -46,4 +46,16 @@ ...@@ -46,4 +46,16 @@
-ms-pointer-events: none; -ms-pointer-events: none;
pointer-events: none; pointer-events: none;
} }
.jeecg-form-container-disabled .ant-upload-select{display:none}
.jeecg-form-container-disabled .ant-upload-list{cursor:grabbing}
.jeecg-form-container-disabled fieldset[disabled] .ant-upload-list{
-ms-pointer-events: auto !important;
pointer-events: auto !important;
}
.jeecg-form-container-disabled .ant-upload-list-item-actions .anticon-delete,
.jeecg-form-container-disabled .ant-upload-list-item .anticon-close{
display: none;
}
</style> </style>
\ No newline at end of file
<template>
<div class="gc-canvas" @click="reloadPic">
<canvas id="gc-canvas" :width="contentWidth" :height="contentHeight"></canvas>
</div>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
name: 'JGraphicCode',
props: {
length:{
type: Number,
default: 4
},
fontSizeMin: {
type: Number,
default: 20
},
fontSizeMax: {
type: Number,
default: 45
},
backgroundColorMin: {
type: Number,
default: 180
},
backgroundColorMax: {
type: Number,
default: 240
},
colorMin: {
type: Number,
default: 50
},
colorMax: {
type: Number,
default: 160
},
lineColorMin: {
type: Number,
default: 40
},
lineColorMax: {
type: Number,
default: 180
},
dotColorMin: {
type: Number,
default: 0
},
dotColorMax: {
type: Number,
default: 255
},
contentWidth: {
type: Number,
default:136
},
contentHeight: {
type: Number,
default: 38
},
remote:{
type:Boolean,
default:false,
required:false
}
},
methods: {
// 生成一个随机数
randomNum (min, max) {
return Math.floor(Math.random() * (max - min) + min)
},
// 生成一个随机的颜色
randomColor (min, max) {
let r = this.randomNum(min, max)
let g = this.randomNum(min, max)
let b = this.randomNum(min, max)
return 'rgb(' + r + ',' + g + ',' + b + ')'
},
drawPic () {
this.randomCode().then(()=>{
let canvas = document.getElementById('gc-canvas')
let ctx = canvas.getContext('2d')
ctx.textBaseline = 'bottom'
// 绘制背景
ctx.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax)
ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
// 绘制文字
for (let i = 0; i < this.code.length; i++) {
this.drawText(ctx, this.code[i], i)
}
this.drawLine(ctx)
this.drawDot(ctx)
this.$emit("success",this.code)
})
},
drawText (ctx, txt, i) {
ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)
let fontSize = this.randomNum(this.fontSizeMin, this.fontSizeMax)
ctx.font = fontSize + 'px SimHei'
let padding = 10;
let offset = (this.contentWidth-40)/(this.code.length-1)
let x=padding;
if(i>0){
x = padding+(i*offset)
}
//let x = (i + 1) * (this.contentWidth / (this.code.length + 1))
let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
if(fontSize>40){
y=40
}
var deg = this.randomNum(-10,10)
// 修改坐标原点和旋转角度
ctx.translate(x, y)
ctx.rotate(deg * Math.PI / 180)
ctx.fillText(txt, 0, 0)
// 恢复坐标原点和旋转角度
ctx.rotate(-deg * Math.PI / 180)
ctx.translate(-x, -y)
},
drawLine (ctx) {
// 绘制干扰线
for (let i = 0; i <1; i++) {
ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)
ctx.beginPath()
ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
ctx.stroke()
}
},
drawDot (ctx) {
// 绘制干扰点
for (let i = 0; i < 100; i++) {
ctx.fillStyle = this.randomColor(0, 255)
ctx.beginPath()
ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
ctx.fill()
}
},
reloadPic(){
this.drawPic()
},
randomCode(){
return new Promise((resolve)=>{
if(this.remote==true){
getAction("/sys/getCheckCode").then(res=>{
console.log("aaaaa",res)
if(res.success){
this.checkKey = res.result.key
this.code = window.atob(res.result.code)
resolve();
}else{
this.$message.error("生成验证码错误,请联系系统管理员")
this.code = 'BUG'
resolve();
}
}).catch(()=>{
console.log("生成验证码连接服务器异常")
this.code = 'BUG'
resolve();
})
}else{
this.randomLocalCode();
resolve();
}
})
},
randomLocalCode(){
let random = ''
//去掉了I l i o O
let str = "QWERTYUPLKJHGFDSAZXCVBNMqwertyupkjhgfdsazxcvbnm1234567890"
for(let i = 0; i < this.length; i++) {
let index = Math.floor(Math.random()*57);
random += str[index];
}
this.code = random
},
getLoginParam(){
return {
checkCode:this.code,
checkKey:this.checkKey
}
}
},
mounted () {
this.drawPic()
},
data(){
return {
code:"",
checkKey:""
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -44,7 +44,6 @@ ...@@ -44,7 +44,6 @@
data(){ data(){
return { return {
uploadAction:window._CONFIG['domianURL']+"/sys/common/upload", uploadAction:window._CONFIG['domianURL']+"/sys/common/upload",
urlView:window._CONFIG['staticDomainURL'],
uploadLoading:false, uploadLoading:false,
picUrl:false, picUrl:false,
headers:{}, headers:{},
...@@ -103,7 +102,7 @@ ...@@ -103,7 +102,7 @@
let fileList = []; let fileList = [];
let arr = paths.split(",") let arr = paths.split(",")
for(var a=0;a<arr.length;a++){ for(var a=0;a<arr.length;a++){
let url = getFileAccessHttpUrl(arr[a],this.urlView,"http"); let url = getFileAccessHttpUrl(arr[a]);
fileList.push({ fileList.push({
uid: uidGenerator(), uid: uidGenerator(),
name: getFileName(arr[a]), name: getFileName(arr[a]),
...@@ -156,7 +155,7 @@ ...@@ -156,7 +155,7 @@
getAvatarView(){ getAvatarView(){
if(this.fileList.length>0){ if(this.fileList.length>0){
let url = this.fileList[0].url let url = this.fileList[0].url
return getFileAccessHttpUrl(url,this.urlView,"http") return getFileAccessHttpUrl(url)
} }
}, },
handlePathChange(){ handlePathChange(){
......
...@@ -32,7 +32,12 @@ ...@@ -32,7 +32,12 @@
handler:function(){ handler:function(){
this.initVal(); this.initVal();
} }
} },
// update-begin author:sunjianlei date:20200225 for:当 type 变化的时候重新计算值 ------
type() {
this.backValue({ target: { value: this.inputVal } })
},
// update-end author:sunjianlei date:20200225 for:当 type 变化的时候重新计算值 ------
}, },
model: { model: {
prop: 'value', prop: 'value',
......
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 :id="id" />
</template>
<script>
import 'codemirror/lib/codemirror.css'
import 'tui-editor/dist/tui-editor.css'
import 'tui-editor/dist/tui-editor-contents.css'
import Editor from 'tui-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: 'en_US'
}
},
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.getValue()) {
this.editor.setValue(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.setValue(this.value)
}
this.editor.on('change', () => {
this.$emit('change', this.editor.getValue())
})
},
destroyEditor() {
if (!this.editor) return
this.editor.off('change')
this.editor.remove()
},
setValue(value) {
this.editor.setValue(value)
},
getValue() {
return this.editor.getValue()
},
setHtml(value) {
this.editor.setHtml(value)
},
getHtml() {
return this.editor.getHtml()
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
<template> <template>
<a-modal <a-modal
ref="modal" ref="modal"
class="j-modal-box" :class="getClass(modalClass)"
:class="{'fullscreen':innerFullscreen,'no-title':isNoTitle,'no-footer':isNoFooter,}" :style="getStyle(modalStyle)"
:visible="visible" :visible="visible"
v-bind="_attrs" v-bind="_attrs"
v-on="$listeners" v-on="$listeners"
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
<script> <script>
import { getClass, getStyle } from '@/utils/props-util'
export default { export default {
name: 'JModal', name: 'JModal',
props: { props: {
...@@ -47,13 +49,18 @@ ...@@ -47,13 +49,18 @@
// 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符 // 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
fullscreen: { fullscreen: {
type: Boolean, type: Boolean,
default: true default: false
}, },
// 是否允许切换全屏(允许后右上角会出现一个按钮) // 是否允许切换全屏(允许后右上角会出现一个按钮)
switchFullscreen: { switchFullscreen: {
type: Boolean, type: Boolean,
default: false default: false
}, },
// 点击确定按钮的时候是否关闭弹窗
okClose: {
type: Boolean,
default: true
},
}, },
data() { data() {
return { return {
...@@ -73,6 +80,22 @@ ...@@ -73,6 +80,22 @@
} }
return attrs return attrs
}, },
modalClass() {
return {
'j-modal-box': true,
'fullscreen': this.innerFullscreen,
'no-title': this.isNoTitle,
'no-footer': this.isNoFooter,
}
},
modalStyle() {
let style = {}
// 如果全屏就将top设为 0
if (this.innerFullscreen) {
style['top'] = '0'
}
return style
},
isNoTitle() { isNoTitle() {
return !this.title && !this.allSlotsKeys.includes('title') return !this.title && !this.allSlotsKeys.includes('title')
}, },
...@@ -90,7 +113,7 @@ ...@@ -90,7 +113,7 @@
}, },
// 切换全屏的按钮图标 // 切换全屏的按钮图标
fullscreenButtonIcon() { fullscreenButtonIcon() {
return this.innerFullscreen ? 'fullscreen' : 'fullscreen-exit' return this.innerFullscreen ? 'fullscreen-exit' : 'fullscreen'
}, },
}, },
watch: { watch: {
...@@ -105,12 +128,21 @@ ...@@ -105,12 +128,21 @@
}, },
methods: { methods: {
getClass(clazz) {
return { ...getClass(this), ...clazz }
},
getStyle(style) {
return { ...getStyle(this), ...style }
},
close() { close() {
this.$emit('update:visible', false) this.$emit('update:visible', false)
}, },
handleOk() { handleOk() {
this.close() if (this.okClose) {
this.close()
}
}, },
handleCancel() { handleCancel() {
this.close() this.close()
...@@ -167,6 +199,7 @@ ...@@ -167,6 +199,7 @@
.right { .right {
width: 56px; width: 56px;
position: inherit;
.ant-modal-close { .ant-modal-close {
right: 56px; right: 56px;
...@@ -180,5 +213,13 @@ ...@@ -180,5 +213,13 @@
} }
} }
}
@media (max-width: 767px) {
.j-modal-box.fullscreen {
margin: 0;
max-width: 100vw;
}
} }
</style> </style>
\ No newline at end of file
<template>
<a-switch v-model="checkStatus" :disabled="disabled" @change="handleChange"/>
</template>
<script>
export default {
name: 'JSwitch',
props: {
value:{
type: String,
required: false
},
disabled:{
type: Boolean,
required: false,
default: false
},
options:{
type:Array,
required:false,
default:()=>['Y','N']
}
},
data () {
return {
checkStatus: false
}
},
watch: {
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{
this.checkStatus = false
}
}
}
}
},
methods: {
handleChange(checked){
let flag = checked===false?this.options[1]:this.options[0];
this.$emit('change', flag);
}
},
model: {
prop: 'value',
event: 'change'
}
}
</script>
...@@ -180,7 +180,11 @@ ...@@ -180,7 +180,11 @@
}, },
onChange(value){ onChange(value){
console.log(value) console.log(value)
this.$emit('change', value.value); if(!value){
this.$emit('change', '');
}else{
this.$emit('change', value.value);
}
this.treeValue = value this.treeValue = value
}, },
onSearch(value){ onSearch(value){
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<a-tree-select <a-tree-select
allowClear allowClear
labelInValue labelInValue
:getPopupContainer="(node) => node.parentNode"
style="width: 100%" style="width: 100%"
:disabled="disabled" :disabled="disabled"
:dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }" :dropdownStyle="{ maxHeight: '400px', overflow: 'auto' }"
......
<template>
<div>
<a-modal
title="文件上传"
:width="width"
:visible="visible"
@ok="ok"
cancelText="取消"
@cancel="close">
<!--style="top: 20px;"-->
<j-upload :file-type="fileType" :value="filePath" @change="handleChange" :disabled="disabled"></j-upload>
</a-modal>
</div>
</template>
<script>
import JUpload from '@/components/jeecg/JUpload'
import { getFileAccessHttpUrl } from '@/api/manage';
const getFileName=(path)=>{
if(path.lastIndexOf("\\")>=0){
let reg=new RegExp("\\\\","g");
path = path.replace(reg,"/");
}
return path.substring(path.lastIndexOf("/")+1);
}
export default {
name: 'JFilePop',
components: { JUpload },
props:{
title:{
type:String,
default:'',
required:false
},
position:{
type:String,
default:'right',
required:false
},
height:{
type:Number,
default:200,
required:false
},
width:{
type:Number,
default:520,
required:false
},
popContainer:{
type:String,
default:'',
required:false
},
disabled:{
type:Boolean,
default:false,
required:false
}
},
data(){
return {
visible:false,
filePath:'',
id:'',
fileType:'file'
}
},
methods:{
handleChange(value){
this.filePath = value;
},
show(id,value,flag){
this.id = id;
this.filePath = value;
this.visible=true
if(flag === 'img'){
this.fileType = 'image'
}else{
this.fileType = 'file'
}
},
ok(){
if(!this.filePath){
this.$message.error("未上传任何文件")
return false;
}
let arr = this.filePath.split(",")
let obj = {
name:getFileName(arr[0]),
url:getFileAccessHttpUrl(arr[0]),
path:this.filePath,
status: 'done',
id:this.id
}
this.$emit('ok',obj)
this.visible=false
},
close(){
this.visible=false
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
<template>
<a-popover trigger="contextmenu" v-model="visible" :placement="position">
<!--"(node) => node.parentNode.parentNode"-->
<div slot="title">
<span>{{ title }}</span>
<span style="float: right" title="关闭">
<a-icon type="close" @click="visible=false"/>
</span>
</div>
<a-input :value="inputContent" @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>
</div>
</a-popover>
</template>
<script>
export default {
name: 'JInputPop',
props:{
title:{
type:String,
default:'',
required:false
},
position:{
type:String,
default:'right',
required:false
},
height:{
type:Number,
default:200,
required:false
},
width:{
type:Number,
default:150,
required:false
},
value:{
type:String,
required:false
},
popContainer:{
type:String,
default:'',
required:false
}
},
data(){
return {
visible:false,
inputContent:''
}
},
watch:{
value:{
immediate:true,
handler:function(){
if(this.value && this.value.length>0){
this.inputContent = this.value;
}
}
},
},
model: {
prop: 'value',
event: 'change'
},
methods:{
handleInputChange(event){
this.inputContent = event.target.value
this.$emit('change',this.inputContent)
},
pop(){
this.visible=true
},
getPopupContainer(node){
if(!this.popContainer){
return node.parentNode
}else{
return document.getElementById(this.popContainer)
}
}
}
}
</script>
<style scoped>
</style>
\ No newline at end of file
...@@ -63,12 +63,14 @@ ...@@ -63,12 +63,14 @@
<script> <script>
import { getAction } from '@/api/manage' import { getAction } from '@/api/manage'
import Ellipsis from '@/components/Ellipsis'
import { JeecgListMixin } from '@/mixins/JeecgListMixin' import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import { cloneObject, pushIfNotExist } from '@/utils/util' import { cloneObject, pushIfNotExist } from '@/utils/util'
export default { export default {
name: 'JSelectBizComponentModal', name: 'JSelectBizComponentModal',
mixins: [JeecgListMixin], mixins: [JeecgListMixin],
components: { Ellipsis },
props: { props: {
value: { value: {
type: Array, type: Array,
...@@ -128,12 +130,15 @@ ...@@ -128,12 +130,15 @@
type: String, type: String,
default: 'id' default: 'id'
}, },
// 过长裁剪长度,设置为 -1 代表不裁剪
ellipsisLength: {
type: Number,
default: 12
},
}, },
data() { data() {
return { return {
innerValue: [], innerValue: [],
// 表头
innerColumns: this.columns,
// 已选择列表 // 已选择列表
selectedTable: { selectedTable: {
pagination: false, pagination: false,
...@@ -147,6 +152,7 @@ ...@@ -147,6 +152,7 @@
], ],
dataSource: [], dataSource: [],
}, },
renderEllipsis: (value) => (<ellipsis length={this.ellipsisLength}>{value}</ellipsis>),
url: { list: this.listUrl }, url: { list: this.listUrl },
/* 分页参数 */ /* 分页参数 */
ipagination: { ipagination: {
...@@ -164,6 +170,19 @@ ...@@ -164,6 +170,19 @@
dataSourceMap: {}, dataSourceMap: {},
} }
}, },
computed: {
// 表头
innerColumns() {
let columns = cloneObject(this.columns)
columns.forEach(column => {
// 给所有的列加上过长裁剪
if (this.ellipsisLength !== -1) {
column.customRender = (text) => this.renderEllipsis(text)
}
})
return columns
},
},
watch: { watch: {
value: { value: {
deep: true, deep: true,
......
...@@ -29,7 +29,7 @@ export default { ...@@ -29,7 +29,7 @@ export default {
| selectButtonText | String | | "选择" | 选择按钮的文字 | | selectButtonText | String | | "选择" | 选择按钮的文字 |
| queryParamText | String | | null | 查询条件显示文字,不传则使用 `name` | | queryParamText | String | | null | 查询条件显示文字,不传则使用 `name` |
| columns | Array | 是 | | 列配置项,与antd的table的配置完全一致。列的第一项会被配置成右侧已选择的列表上 | | columns | Array | 是 | | 列配置项,与antd的table的配置完全一致。列的第一项会被配置成右侧已选择的列表上 |
| columns[0].widthRight | Array | | null | 仅列的第一项可以应用此配置,表示右侧已选择列表的宽度,建议 `70%`,不传则应用`width` | | columns[0].widthRight | String | | null | 仅列的第一项可以应用此配置,表示右侧已选择列表的宽度,建议 `70%`,不传则应用`width` |
| placeholder | String | | "请选择" | 占位符 | | placeholder | String | | "请选择" | 占位符 |
| disabled | Boolean | | false | 是否禁用 | | disabled | Boolean | | false | 是否禁用 |
| multiple | Boolean | | false | 是否可多选 | | multiple | Boolean | | false | 是否可多选 |
......
...@@ -9,8 +9,9 @@ ...@@ -9,8 +9,9 @@
:options="selectOptions" :options="selectOptions"
allowClear allowClear
:disabled="disabled" :disabled="disabled"
:open="false" :open="selectOpen"
style="width: 100%;" style="width: 100%;"
@dropdownVisibleChange="handleDropdownVisibleChange"
@click.native="visible=(buttons?visible:true)" @click.native="visible=(buttons?visible:true)"
/> />
</slot> </slot>
...@@ -85,7 +86,8 @@ ...@@ -85,7 +86,8 @@
selectValue: [], selectValue: [],
selectOptions: [], selectOptions: [],
dataSourceMap: {}, dataSourceMap: {},
visible: false visible: false,
selectOpen: false,
} }
}, },
computed: { computed: {
...@@ -128,6 +130,13 @@ ...@@ -128,6 +130,13 @@
this.selectOptions = options this.selectOptions = options
this.dataSourceMap = dataSourceMap this.dataSourceMap = dataSourceMap
}, },
handleDropdownVisibleChange() {
// 解决antdv自己的bug —— open 设置为 false 了,点击后还是添加了 open 样式,导致点击事件失效
this.selectOpen = true
this.$nextTick(() => {
this.selectOpen = false
})
},
} }
} }
</script> </script>
...@@ -142,7 +151,7 @@ ...@@ -142,7 +151,7 @@
} }
.right { .right {
width: @width ; width: @width;
} }
.full { .full {
...@@ -150,7 +159,7 @@ ...@@ -150,7 +159,7 @@
} }
/deep/ .ant-select-search__field { /deep/ .ant-select-search__field {
display: none !important; display: none !important;
} }
} }
</style> </style>
\ No newline at end of file
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 --> <!-- 定义在这里的参数都是不可在外部覆盖的,防止出现问题 -->
<j-select-biz-component <j-select-biz-component
:value="value" :value="value"
:ellipsisLength="25"
:listUrl="url.list" :listUrl="url.list"
:columns="columns" :columns="columns"
v-on="$listeners" v-on="$listeners"
...@@ -20,15 +21,15 @@ ...@@ -20,15 +21,15 @@
return { return {
url: { list: '/sys/user/list' }, url: { list: '/sys/user/list' },
columns: [ columns: [
{ title: '姓名', align: 'center', width: '20%', widthRight: '70%', dataIndex: 'realname' }, { title: '姓名', align: 'center', width: '25%', widthRight: '70%', dataIndex: 'realname' },
{ title: '账号', align: 'center', width: '20%', dataIndex: 'username' }, { title: '账号', align: 'center', width: '25%', dataIndex: 'username' },
{ title: '电话', align: 'center', width: '23%', dataIndex: 'phone' }, { title: '电话', align: 'center', width: '20%', dataIndex: 'phone' },
{ title: '出生日期', align: 'center', width: '23%', dataIndex: 'birthday' } { title: '出生日期', align: 'center', width: '20%', dataIndex: 'birthday' }
], ],
// 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件 // 定义在这里的参数都是可以在外部传递覆盖的,可以更灵活的定制化使用的组件
default: { default: {
name: '用户', name: '用户',
width: 1000, width: 1200,
displayKey: 'realname', displayKey: 'realname',
returnKeys: ['id', 'username'], returnKeys: ['id', 'username'],
queryParamText: '账号', queryParamText: '账号',
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<a-input-search <a-input-search
v-model="userNames" v-model="userNames"
placeholder="请先选择用户" placeholder="请先选择用户"
disabled readOnly
unselectable="on"
@search="onSearchDepUser"> @search="onSearchDepUser">
<a-button slot="enterButton" :disabled="disabled">选择用户</a-button> <a-button slot="enterButton" :disabled="disabled">选择用户</a-button>
</a-input-search> </a-input-search>
......
...@@ -93,6 +93,8 @@ ...@@ -93,6 +93,8 @@
this.linkList.push(this.$route.fullPath) this.linkList.push(this.$route.fullPath)
this.activePage = this.$route.fullPath this.activePage = this.$route.fullPath
}, },
mounted() {
},
watch: { watch: {
'$route': function(newRoute) { '$route': function(newRoute) {
//console.log("新的路由",newRoute) //console.log("新的路由",newRoute)
...@@ -192,6 +194,7 @@ ...@@ -192,6 +194,7 @@
this.$message.warning('这是最后一页,不能再关闭了啦') this.$message.warning('这是最后一页,不能再关闭了啦')
return return
} }
console.log("this.pageList ",this.pageList );
this.pageList = this.pageList.filter(item => item.fullPath !== key) this.pageList = this.pageList.filter(item => item.fullPath !== key)
let index = this.linkList.indexOf(key) let index = this.linkList.indexOf(key)
this.linkList = this.linkList.filter(item => item !== key) this.linkList = this.linkList.filter(item => item !== key)
......
...@@ -43,7 +43,7 @@ export default { ...@@ -43,7 +43,7 @@ export default {
}, },
methods: { methods: {
closeMenu (e) { closeMenu (e) {
if (['menuitemicon', 'menuitem'].indexOf(e.target.getAttribute('role')) < 0) { if (this.visible === true && ['menuitemicon', 'menuitem'].indexOf(e.target.getAttribute('role')) < 0) {
this.$emit('update:visible', false) this.$emit('update:visible', false)
} }
}, },
......
...@@ -149,8 +149,11 @@ export default { ...@@ -149,8 +149,11 @@ export default {
this.selectedRows = [] this.selectedRows = []
}, },
onClearSelected() { onClearSelected() {
// 【TESTA-262】页面清空后还能才做所选行,增加 this.$emit('clearAll')
this.selectedRowKeys = [] this.selectedRowKeys = []
this.selectedRows = []
this.updateSelect([], []) this.updateSelect([], [])
this.$emit('clearAll')
}, },
renderMsg(h) { renderMsg(h) {
const _vm = this const _vm = this
......
...@@ -26,7 +26,7 @@ export default { ...@@ -26,7 +26,7 @@ export default {
console.log('this.$route.matched', this.$route.matched) console.log('this.$route.matched', this.$route.matched)
this.breadList = [] this.breadList = []
this.breadList.push({ name: 'dashboard', path: '/dashboard/', meta: { title: '首页' } }) this.breadList.push({ name: 'dashboard-analysis', path: '/dashboard/analysis', meta: { title: '首页' } })
this.name = this.$route.name this.name = this.$route.name
this.$route.matched.forEach((item) => { this.$route.matched.forEach((item) => {
......
...@@ -121,7 +121,7 @@ ...@@ -121,7 +121,7 @@
this.loadData(); this.loadData();
//this.timerFun(); //this.timerFun();
this.initWebSocket(); this.initWebSocket();
this.heartCheckFun(); // this.heartCheckFun();
}, },
destroyed: function () { // 离开页面生命周期函数 destroyed: function () { // 离开页面生命周期函数
this.websocketclose(); this.websocketclose();
...@@ -212,7 +212,7 @@ ...@@ -212,7 +212,7 @@
websocketOnopen: function () { websocketOnopen: function () {
console.log("WebSocket连接成功"); console.log("WebSocket连接成功");
//心跳检测重置 //心跳检测重置
this.heartCheck.reset().start(); //this.heartCheck.reset().start();
}, },
websocketOnerror: function (e) { websocketOnerror: function (e) {
console.log("WebSocket连接发生错误"); console.log("WebSocket连接发生错误");
...@@ -229,7 +229,7 @@ ...@@ -229,7 +229,7 @@
this.loadData(); this.loadData();
} }
//心跳检测重置 //心跳检测重置
this.heartCheck.reset().start(); //this.heartCheck.reset().start();
}, },
websocketOnclose: function (e) { websocketOnclose: function (e) {
console.log("connection closed (" + e.code + ")"); console.log("connection closed (" + e.code + ")");
......
<template> <template>
<a-modal <j-modal
class="announcementCustomModal" :title="title"
:width="modelStyle.width" :width="modelStyle.width"
:visible="visible" :visible="visible"
:bodyStyle ="bodyStyle" :bodyStyle ="bodyStyle"
:switchFullscreen="switchFullscreen"
@cancel="handleCancel" @cancel="handleCancel"
destroyOnClose> >
<template slot="title">
<a-button icon="fullscreen" class="custom-btn" @click="handleClickToggleFullScreen"/>
</template>
<template slot="footer"> <template slot="footer">
<a-button key="back" @click="handleCancel">关闭</a-button> <a-button key="back" @click="handleCancel">关闭</a-button>
<a-button v-if="record.openType==='url'&&record.readFlag!=='1'" type="primary" @click="toHandle">去处理</a-button> <a-button v-if="record.openType==='url'" type="primary" @click="toHandle">去处理</a-button>
</template> </template>
<a-card class="daily-article" :loading="loading"> <a-card class="daily-article" :loading="loading">
<a-card-meta <a-card-meta
...@@ -21,7 +19,7 @@ ...@@ -21,7 +19,7 @@
<a-divider /> <a-divider />
<span v-html="record.msgContent" class="article-content"></span> <span v-html="record.msgContent" class="article-content"></span>
</a-card> </a-card>
</a-modal> </j-modal>
</template> </template>
<script> <script>
...@@ -42,6 +40,7 @@ ...@@ -42,6 +40,7 @@
sm: { span: 16 }, sm: { span: 16 },
}, },
visible: false, visible: false,
switchFullscreen: true,
loading: false, loading: false,
bodyStyle:{ bodyStyle:{
padding: "0", padding: "0",
...@@ -79,7 +78,7 @@ ...@@ -79,7 +78,7 @@
this.modelStyle.fullScreen = mode this.modelStyle.fullScreen = mode
}, },
toHandle(){ toHandle(){
if(this.record.openType==='url'&&this.record.readFlag!== '1'){ if(this.record.openType==='url'){
this.visible = false; this.visible = false;
//链接跳转 //链接跳转
this.$router.push({path: this.record.openPage}) this.$router.push({path: this.record.openPage})
......
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
import DepartSelect from './DepartSelect' import DepartSelect from './DepartSelect'
import { mapActions, mapGetters,mapState } from 'vuex' import { mapActions, mapGetters,mapState } from 'vuex'
import { mixinDevice } from '@/utils/mixin.js' import { mixinDevice } from '@/utils/mixin.js'
import { getFileAccessHttpUrl } from "@/api/manage"
export default { export default {
name: "UserMenu", name: "UserMenu",
...@@ -157,8 +158,7 @@ ...@@ -157,8 +158,7 @@
...mapActions(["Logout"]), ...mapActions(["Logout"]),
...mapGetters(["nickname", "avatar","userInfo"]), ...mapGetters(["nickname", "avatar","userInfo"]),
getAvatar(){ getAvatar(){
console.log('url = '+ window._CONFIG['staticDomainURL']+"/"+this.avatar()) return getFileAccessHttpUrl(this.avatar())
return window._CONFIG['staticDomainURL']+"/"+this.avatar()
}, },
handleLogout() { handleLogout() {
const that = this const that = this
...@@ -229,13 +229,13 @@ ...@@ -229,13 +229,13 @@
color: inherit; color: inherit;
/deep/ .ant-select-selection { /deep/ .ant-select-selection {
background-color: inherit; background-color: inherit;
border: 0; border: 0;
border-bottom: 1px solid white; border-bottom: 1px solid white;
&__placeholder, &__field__placeholder { &__placeholder, &__field__placeholder {
color: inherit; color: inherit;
}
} }
}
} }
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ /* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/ /* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
......
...@@ -11,7 +11,7 @@ export const asyncRouterMap = [ ...@@ -11,7 +11,7 @@ export const asyncRouterMap = [
name: 'dashboard', name: 'dashboard',
component: TabLayout, component: TabLayout,
meta: { title: '首页' }, meta: { title: '首页' },
redirect: '/dashboard/workplace', redirect: '/dashboard/analysis',
children: [ children: [
// // dashboard // // dashboard
......
...@@ -14,13 +14,11 @@ import '@/permission' // permission control ...@@ -14,13 +14,11 @@ import '@/permission' // permission control
import '@/utils/filter' // base filter import '@/utils/filter' // base filter
import Print from 'vue-print-nb-jeecg' import Print from 'vue-print-nb-jeecg'
/*import '@babel/polyfill'*/ /*import '@babel/polyfill'*/
import VueApexCharts from 'vue-apexcharts'
import preview from 'vue-photo-preview' import preview from 'vue-photo-preview'
import 'vue-photo-preview/dist/skin.css' import 'vue-photo-preview/dist/skin.css'
require('@jeecg/antd-online-214') require('@jeecg/antd-online-beta220')
require('@jeecg/antd-online-214/dist/OnlineForm.css') require('@jeecg/antd-online-beta220/dist/OnlineForm.css')
import { import {
ACCESS_TOKEN, ACCESS_TOKEN,
...@@ -41,6 +39,8 @@ import JDictSelectTag from './components/dict/index.js' ...@@ -41,6 +39,8 @@ import JDictSelectTag from './components/dict/index.js'
import hasPermission from '@/utils/hasPermission' import hasPermission from '@/utils/hasPermission'
import vueBus from '@/utils/vueBus'; import vueBus from '@/utils/vueBus';
import JeecgComponents from '@/components/jeecg/index' import JeecgComponents from '@/components/jeecg/index'
import '@/assets/less/JAreaLinkage.less'
import VueAreaLinkage from 'vue-area-linkage'
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.use(Storage, config.storageOptions) Vue.use(Storage, config.storageOptions)
...@@ -50,11 +50,10 @@ Vue.use(Viser) ...@@ -50,11 +50,10 @@ Vue.use(Viser)
Vue.use(hasPermission) Vue.use(hasPermission)
Vue.use(JDictSelectTag) Vue.use(JDictSelectTag)
Vue.use(Print) Vue.use(Print)
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)
Vue.use(preview) Vue.use(preview)
Vue.use(vueBus); Vue.use(vueBus);
Vue.use(JeecgComponents); Vue.use(JeecgComponents);
Vue.use(VueAreaLinkage);
new Vue({ new Vue({
router, router,
......
...@@ -83,7 +83,16 @@ export const JEditableTableMixin = { ...@@ -83,7 +83,16 @@ export const JEditableTableMixin = {
requestSubTableData(url, params, tab, success) { requestSubTableData(url, params, tab, success) {
tab.loading = true tab.loading = true
getAction(url, params).then(res => { getAction(url, params).then(res => {
tab.dataSource = res.result || [] let { result } = res
let dataSource = []
if (result) {
if (Array.isArray(result)) {
dataSource = result
} else if (Array.isArray(result.records)) {
dataSource = result.records
}
}
tab.dataSource = dataSource
typeof success === 'function' ? success(res) : '' typeof success === 'function' ? success(res) : ''
}).finally(() => { }).finally(() => {
tab.loading = false tab.loading = false
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除 * data中url定义 list为查询列表 delete为删除单条记录 deleteBatch为批量删除
*/ */
import { filterObj } from '@/utils/util'; import { filterObj } from '@/utils/util';
import { deleteAction, getAction,downFile } from '@/api/manage' import { deleteAction, getAction,downFile,getFileAccessHttpUrl } from '@/api/manage'
import Vue from 'vue' import Vue from 'vue'
import { ACCESS_TOKEN } from "@/store/mutation-types" import { ACCESS_TOKEN } from "@/store/mutation-types"
...@@ -47,16 +47,18 @@ export const JeecgListMixin = { ...@@ -47,16 +47,18 @@ export const JeecgListMixin = {
/* 高级查询条件生效状态 */ /* 高级查询条件生效状态 */
superQueryFlag:false, superQueryFlag:false,
/* 高级查询条件 */ /* 高级查询条件 */
superQueryParams:"" superQueryParams: '',
/** 高级查询拼接方式 */
superQueryMatchType: 'and',
} }
}, },
created() { created() {
if(!this.disableMixinCreated){ if(!this.disableMixinCreated){
console.log(' -- mixin created -- ') console.log(' -- mixin created -- ')
this.loadData(); this.loadData();
//初始化字典配置 在自己页面定义 //初始化字典配置 在自己页面定义
this.initDictConfig(); this.initDictConfig();
} }
}, },
methods:{ methods:{
loadData(arg) { loadData(arg) {
...@@ -84,22 +86,24 @@ export const JeecgListMixin = { ...@@ -84,22 +86,24 @@ export const JeecgListMixin = {
initDictConfig(){ initDictConfig(){
console.log("--这是一个假的方法!") console.log("--这是一个假的方法!")
}, },
handleSuperQuery(arg) { handleSuperQuery(params, matchType) {
//高级查询方法 //高级查询方法
if(!arg){ if(!params){
this.superQueryParams='' this.superQueryParams=''
this.superQueryFlag = false this.superQueryFlag = false
}else{ }else{
this.superQueryFlag = true this.superQueryFlag = true
this.superQueryParams=JSON.stringify(arg) this.superQueryParams=JSON.stringify(params)
this.superQueryMatchType = matchType
} }
this.loadData() this.loadData(1)
}, },
getQueryParams() { getQueryParams() {
//获取查询条件 //获取查询条件
let sqp = {} let sqp = {}
if(this.superQueryParams){ if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams) sqp['superQueryParams']=encodeURI(this.superQueryParams)
sqp['superQueryMatchType'] = this.superQueryMatchType
} }
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters); var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
param.field = this.getQueryField(); param.field = this.getQueryField();
...@@ -206,6 +210,10 @@ export const JeecgListMixin = { ...@@ -206,6 +210,10 @@ export const JeecgListMixin = {
handleToggleSearch(){ handleToggleSearch(){
this.toggleSearchStatus = !this.toggleSearchStatus; this.toggleSearchStatus = !this.toggleSearchStatus;
}, },
// 给popup查询使用(查询区域不支持回填多个字段,限制只返回一个字段)
getPopupField(fields){
return fields.split(',')[0]
},
modalFormOk() { modalFormOk() {
// 新增/修改 成功时,重载列表 // 新增/修改 成功时,重载列表
this.loadData(); this.loadData();
...@@ -286,7 +294,7 @@ export const JeecgListMixin = { ...@@ -286,7 +294,7 @@ export const JeecgListMixin = {
if(text && text.indexOf(",")>0){ if(text && text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
return window._CONFIG['staticDomainURL']+"/"+text return getFileAccessHttpUrl(text)
}, },
/* 文件下载 */ /* 文件下载 */
uploadFile(text){ uploadFile(text){
...@@ -297,7 +305,8 @@ export const JeecgListMixin = { ...@@ -297,7 +305,8 @@ export const JeecgListMixin = {
if(text.indexOf(",")>0){ if(text.indexOf(",")>0){
text = text.substring(0,text.indexOf(",")) text = text.substring(0,text.indexOf(","))
} }
window.open(window._CONFIG['staticDomainURL']+ "/"+text); let url = getFileAccessHttpUrl(text)
window.open(url);
}, },
} }
......
export const HrefJump = {
data() {
return {
fieldHrefSlots: [],
hrefComponent: {
model: {
title: '',
width: '100%',
visible: false,
destroyOnClose: true,
style: {
top: 0,
left: 0,
height: '100%',
margin: 0,
padding: 0
},
bodyStyle: { padding: '8px', height: 'calc(100vh - 108px)', overflow: 'auto', overflowX: 'hidden' },
// 隐藏掉取消按钮
cancelButtonProps: { style: { display: 'none' } },
afterClose: () => {
// 恢复body的滚动
document.body.style.overflow = null
}
},
on: {
ok: () => this.hrefComponent.model.visible = false,
cancel: () => this.hrefComponent.model.visible = false
},
is: null,
params: {},
}
}
},
methods: {
//支持链接href跳转
handleClickFieldHref(field, record) {
let href = field.href
let urlPattern = /(ht|f)tp(s?)\:\/\/[0-9a-zA-Z]([-.\w]*[0-9a-zA-Z])*(:(0-9)*)*(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&amp;%\$#_]*)?/
let compPattern = /\.vue(\?.*)?$/
if (typeof href === 'string') {
href = href.trim().replace(/\${([^}]+)?}/g, (s1, s2) => record[s2])
if (urlPattern.test(href)) {
window.open(href, '_blank')
} else if (compPattern.test(href)) {
this.openHrefCompModal(href)
} else {
this.$router.push(href)
}
}
},
openHrefCompModal(href) {
// 解析 href 参数
let index = href.indexOf('?')
let path = href
if (index !== -1) {
path = href.substring(0, index)
let paramString = href.substring(index + 1, href.length)
let paramArray = paramString.split('&')
let params = {}
paramArray.forEach(paramObject => {
let paramItem = paramObject.split('=')
params[paramItem[0]] = paramItem[1]
})
this.hrefComponent.params = params
} else {
this.hrefComponent.params = {}
}
this.hrefComponent.model.visible = true
this.hrefComponent.model.title = '@/views/' + path
this.hrefComponent.is = () => import('@/views/' + (path.startsWith('/')?path.slice(1):path))
// 禁止body滚动,防止滚动穿透
setTimeout(() => {
document.body.style.overflow = 'hidden'
}, 300)
},
}
}
\ No newline at end of file
import { formatDate } from '@/utils/util'
import Area from '@/components/_util/Area'
const onlUtil = {
data(){
return {
mixin_pca:''
}
},
created(){
this.mixin_pca = new Area()
},
methods:{
simpleDateFormat(millisecond, format){
return formatDate(millisecond, format)
},
getPcaText(code){
return this.mixin_pca.getText(code);
},
getPcaCode(text){
return this.mixin_pca.getCode(text)
}
}
}
export { onlUtil }
\ No newline at end of file
...@@ -4,7 +4,7 @@ import store from './store' ...@@ -4,7 +4,7 @@ import store from './store'
import NProgress from 'nprogress' // progress bar import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style import 'nprogress/nprogress.css' // progress bar style
import notification from 'ant-design-vue/es/notification' import notification from 'ant-design-vue/es/notification'
import { ACCESS_TOKEN } from '@/store/mutation-types' import { ACCESS_TOKEN,INDEX_MAIN_PAGE_PATH } from '@/store/mutation-types'
import { generateIndexRouter } from "@/utils/util" import { generateIndexRouter } from "@/utils/util"
NProgress.configure({ showSpinner: false }) // NProgress Configuration NProgress.configure({ showSpinner: false }) // NProgress Configuration
...@@ -17,7 +17,7 @@ router.beforeEach((to, from, next) => { ...@@ -17,7 +17,7 @@ router.beforeEach((to, from, next) => {
if (Vue.ls.get(ACCESS_TOKEN)) { if (Vue.ls.get(ACCESS_TOKEN)) {
/* has token */ /* has token */
if (to.path === '/user/login') { if (to.path === '/user/login') {
next({ path: '/dashboard/workplace' }) next({ path: INDEX_MAIN_PAGE_PATH })
NProgress.done() NProgress.done()
} else { } else {
if (store.getters.permissionList.length === 0) { if (store.getters.permissionList.length === 0) {
......
import Vue from 'vue' import Vue from 'vue'
import { USER_INFO} from "@/store/mutation-types" import { USER_INFO, ENHANCE_PRE } from "@/store/mutation-types"
const getters = { const getters = {
device: state => state.app.device, device: state => state.app.device,
theme: state => state.app.theme, theme: state => state.app.theme,
...@@ -11,7 +11,12 @@ const getters = { ...@@ -11,7 +11,12 @@ const getters = {
welcome: state => state.user.welcome, welcome: state => state.user.welcome,
permissionList: state => state.user.permissionList, permissionList: state => state.user.permissionList,
userInfo: state => {state.user.info = Vue.ls.get(USER_INFO); return state.user.info}, userInfo: state => {state.user.info = Vue.ls.get(USER_INFO); return state.user.info},
addRouters: state => state.permission.addRouters addRouters: state => state.permission.addRouters,
enhanceJs:(state) => (code) => {
state.enhance.enhanceJs[code] = Vue.ls.get(ENHANCE_PRE+code);
return state.enhance.enhanceJs[code]
}
} }
export default getters export default getters
\ No newline at end of file
...@@ -4,6 +4,7 @@ import Vuex from 'vuex' ...@@ -4,6 +4,7 @@ import Vuex from 'vuex'
import app from './modules/app' import app from './modules/app'
import user from './modules/user' import user from './modules/user'
import permission from './modules/permission' import permission from './modules/permission'
import enhance from './modules/enhance'
import getters from './getters' import getters from './getters'
Vue.use(Vuex) Vue.use(Vuex)
...@@ -12,7 +13,8 @@ export default new Vuex.Store({ ...@@ -12,7 +13,8 @@ export default new Vuex.Store({
modules: { modules: {
app, app,
user, user,
permission permission,
enhance
}, },
state: { state: {
......
import Vue from 'vue'
const enhance = {
state: {
enhanceJs:{
}
},
mutations: {
ADD_TABLE_ENHANCE: (state, record) => {
if(!state.enhanceJs){
let obj = {}
let arr = []
arr.push({...record})
obj[record.code] = arr
state.enhanceJs = obj
}else{
if(!state.enhanceJs[record.code]){
let arr = []
arr.push({...record})
state.enhanceJs[record.code] = arr
}
state.enhanceJs[record.code].push({...record})
}
let arr = state.enhanceJs[record.code]
while(arr.length>16){
arr.shift()
}
Vue.ls.set('enhance_'+record['code'], arr)
}
},
actions: {
addEhanceRecord({ commit }, record) {
commit('ADD_TABLE_ENHANCE', record)
}
}
}
export default enhance
\ No newline at end of file
import Vue from 'vue' import Vue from 'vue'
import { login, logout, phoneLogin } from "@/api/login" import { login, logout, phoneLogin, thirdLogin } from "@/api/login"
import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types" import { ACCESS_TOKEN, USER_NAME,USER_INFO,USER_AUTH,SYS_BUTTON_AUTH,UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
import { welcome } from "@/utils/util" import { welcome } from "@/utils/util"
import { queryPermissionsByUser } from '@/api/api' import { queryPermissionsByUser } from '@/api/api'
import { getAction } from '@/api/manage' import { getAction } from '@/api/manage'
...@@ -71,6 +71,7 @@ const user = { ...@@ -71,6 +71,7 @@ const user = {
Vue.ls.set(ACCESS_TOKEN, result.token, 7 * 24 * 60 * 60 * 1000) Vue.ls.set(ACCESS_TOKEN, result.token, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(USER_NAME, userInfo.username, 7 * 24 * 60 * 60 * 1000) Vue.ls.set(USER_NAME, userInfo.username, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000) Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token) commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo) commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() }) commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
...@@ -94,6 +95,7 @@ const user = { ...@@ -94,6 +95,7 @@ const user = {
Vue.ls.set(ACCESS_TOKEN, result.token, 7 * 24 * 60 * 60 * 1000) Vue.ls.set(ACCESS_TOKEN, result.token, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(USER_NAME, userInfo.username, 7 * 24 * 60 * 60 * 1000) Vue.ls.set(USER_NAME, userInfo.username, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000) Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(UI_CACHE_DB_DICT_DATA, result.sysAllDictItems, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token) commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo) commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() }) commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
...@@ -151,10 +153,11 @@ const user = { ...@@ -151,10 +153,11 @@ const user = {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
commit('SET_PERMISSIONLIST', []) commit('SET_PERMISSIONLIST', [])
Vue.ls.remove(ACCESS_TOKEN) Vue.ls.remove(ACCESS_TOKEN)
Vue.ls.remove(UI_CACHE_DB_DICT_DATA)
//console.log('logoutToken: '+ logoutToken) //console.log('logoutToken: '+ logoutToken)
logout(logoutToken).then(() => { logout(logoutToken).then(() => {
//var sevice = "http://"+window.location.host+"/"; //let sevice = "http://"+window.location.host+"/";
//var serviceUrl = encodeURIComponent(sevice); //let serviceUrl = encodeURIComponent(sevice);
//window.location.href = window._CONFIG['casPrefixUrl']+"/logout?service="+serviceUrl; //window.location.href = window._CONFIG['casPrefixUrl']+"/logout?service="+serviceUrl;
resolve() resolve()
}).catch(() => { }).catch(() => {
...@@ -162,6 +165,29 @@ const user = { ...@@ -162,6 +165,29 @@ const user = {
}) })
}) })
}, },
// 第三方登录
ThirdLogin({ commit }, token) {
return new Promise((resolve, reject) => {
thirdLogin(token).then(response => {
if(response.code =='200'){
const result = response.result
const userInfo = result.userInfo
Vue.ls.set(ACCESS_TOKEN, result.token, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(USER_NAME, userInfo.username, 7 * 24 * 60 * 60 * 1000)
Vue.ls.set(USER_INFO, userInfo, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
commit('SET_INFO', userInfo)
commit('SET_NAME', { username: userInfo.username,realname: userInfo.realname, welcome: welcome() })
commit('SET_AVATAR', userInfo.avatar)
resolve(response)
}else{
reject(response)
}
}).catch(error => {
reject(error)
})
})
},
} }
} }
......
...@@ -14,6 +14,9 @@ export const USER_INFO = 'Login_Userinfo' ...@@ -14,6 +14,9 @@ export const USER_INFO = 'Login_Userinfo'
export const USER_AUTH = 'LOGIN_USER_BUTTON_AUTH' export const USER_AUTH = 'LOGIN_USER_BUTTON_AUTH'
export const SYS_BUTTON_AUTH = 'SYS_BUTTON_AUTH' export const SYS_BUTTON_AUTH = 'SYS_BUTTON_AUTH'
export const ENCRYPTED_STRING = 'ENCRYPTED_STRING' 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 CONTENT_WIDTH_TYPE = { export const CONTENT_WIDTH_TYPE = {
Fluid: 'Fluid', Fluid: 'Fluid',
......
...@@ -14,6 +14,7 @@ const FormTypes = { ...@@ -14,6 +14,7 @@ const FormTypes = {
sel_search:"sel_search", sel_search:"sel_search",
radio:'radio', radio:'radio',
checkbox_meta:"checkbox_meta", checkbox_meta:"checkbox_meta",
input_pop:'input_pop',
slot: 'slot', slot: 'slot',
hidden: 'hidden' hidden: 'hidden'
...@@ -77,18 +78,22 @@ export function validateFormAndTables(form, cases) { ...@@ -77,18 +78,22 @@ export function validateFormAndTables(form, cases) {
/** /**
* 验证并获取一个或多个表格的所有值 * 验证并获取一个或多个表格的所有值
* @param cases 接收一个数组,每项都是一个JEditableTable实例 * @param cases 接收一个数组,每项都是一个JEditableTable实例
* @param deleteTempId 是否删除临时ID,如果设为true,行编辑就不返回新增行的ID,ID需要后台生成
* @author sunjianlei * @author sunjianlei
*/ */
export function validateTables(cases) { export function validateTables(cases, deleteTempId) {
if (!(cases instanceof Array)) { if (!(cases instanceof Array)) {
throw `'validateTables'函数的'cases'参数需要的是一个数组,而传入的却是${typeof cases}` throw `'validateTables'函数的'cases'参数需要的是一个数组,而传入的却是${typeof cases}`
} }
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let tables = [] let tables = []
let index = 0; let index = 0;
if(!cases || cases.length==0){
resolve()
}
(function next() { (function next() {
let vm = cases[index] let vm = cases[index]
vm.getAll(true).then(all => { vm.getAll(true, deleteTempId).then(all => {
tables[index] = all tables[index] = all
// 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验 // 判断校验是否全部完成,完成返回成功,否则继续进行下一步校验
if (++index === cases.length) { if (++index === cases.length) {
......
...@@ -9,9 +9,10 @@ export function disabledAuthFilter(code,formData) { ...@@ -9,9 +9,10 @@ export function disabledAuthFilter(code,formData) {
} }
function nodeDisabledAuth(code,formData){ function nodeDisabledAuth(code,formData){
console.log("页面权限禁用--NODE--开始");
let permissionList = []; let permissionList = [];
try { try {
//console.log("页面权限禁用--NODE--开始",obj); console.log("页面权限禁用--NODE--开始",formData);
if (formData) { if (formData) {
let bpmList = formData.permissionList; let bpmList = formData.permissionList;
permissionList = bpmList.filter(item=>item.type=='2') permissionList = bpmList.filter(item=>item.type=='2')
...@@ -52,10 +53,10 @@ function nodeDisabledAuth(code,formData){ ...@@ -52,10 +53,10 @@ function nodeDisabledAuth(code,formData){
} }
function globalDisabledAuth(code){ function globalDisabledAuth(code){
//console.log("全局页面禁用权限--Global--开始"); console.log("全局页面禁用权限--Global--开始");
var permissionList = []; let permissionList = [];
var allPermissionList = []; let allPermissionList = [];
//let authList = Vue.ls.get(USER_AUTH); //let authList = Vue.ls.get(USER_AUTH);
let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]"); let authList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
...@@ -72,8 +73,8 @@ function globalDisabledAuth(code){ ...@@ -72,8 +73,8 @@ function globalDisabledAuth(code){
} }
} }
//设置全局配置是否有命中 //设置全局配置是否有命中
var gFlag = false;//禁用命中 let gFlag = false;//禁用命中
var invalidFlag = false;//无效命中 let invalidFlag = false;//无效命中
if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){ if(allPermissionList != null && allPermissionList != "" && allPermissionList != undefined && allPermissionList.length > 0){
for (let itemG of allPermissionList) { for (let itemG of allPermissionList) {
if(code === itemG.action){ if(code === itemG.action){
...@@ -116,7 +117,7 @@ function globalDisabledAuth(code){ ...@@ -116,7 +117,7 @@ function globalDisabledAuth(code){
export function colAuthFilter(columns,pre) { export function colAuthFilter(columns,pre) {
var authList = getNoAuthCols(pre); let authList = getNoAuthCols(pre);
const cols = columns.filter(item => { const cols = columns.filter(item => {
if (hasColoum(item,authList)) { if (hasColoum(item,authList)) {
return true return true
...@@ -126,6 +127,44 @@ export function colAuthFilter(columns,pre) { ...@@ -126,6 +127,44 @@ export function colAuthFilter(columns,pre) {
return cols return cols
} }
/**
* 【子表行编辑】实现两个功能:
* 1、隐藏JEditableTable无权限的字段
* 2、禁用JEditableTable无权限的字段
* @param columns
* @param pre
* @returns {*}
*/
export function colAuthFilterJEditableTable(columns,pre) {
let authList = getAllShowAndDisabledAuthCols(pre);
const cols = columns.filter(item => {
let oneAuth = authList.find(auth => {
return auth.action === pre + item.key;
});
if(!oneAuth){
return true
}
//代码严谨处理,防止一个授权标识,配置多次
if(oneAuth instanceof Array){
oneAuth = oneAuth[0]
}
//禁用逻辑
if (oneAuth.type == '2' && !oneAuth.isAuth) {
item["disabled"] = true
return true
}
//隐藏逻辑逻辑
if (oneAuth.type == '1' && !oneAuth.isAuth) {
return false
}
return true
})
return cols
}
function hasColoum(item,authList){ function hasColoum(item,authList){
if (authList.includes(item.dataIndex)) { if (authList.includes(item.dataIndex)) {
return false return false
...@@ -164,6 +203,32 @@ function getNoAuthCols(pre){ ...@@ -164,6 +203,32 @@ function getNoAuthCols(pre){
return cols; return cols;
} }
/**
* 额外增加方法【用于行编辑组件】
* date: 2020-04-05
* author: scott
* @param pre
* @returns {*[]}
*/
function getAllShowAndDisabledAuthCols(pre){
//用户拥有的权限
let userAuthList = JSON.parse(sessionStorage.getItem(USER_AUTH) || "[]");
//全部权限配置
let allAuthList = JSON.parse(sessionStorage.getItem(SYS_BUTTON_AUTH) || "[]");
let newAllAuthList = allAuthList.map(function (item, index) {
let hasAuthArray = userAuthList.filter(u => u.action===item.action );
if (hasAuthArray && hasAuthArray.length>0) {
item["isAuth"] = true
}
return item;
})
return newAllAuthList;
}
function startWith(str,pre) { function startWith(str,pre) {
if (pre == null || pre == "" || str==null|| str==""|| str.length == 0 || pre.length > str.length) if (pre == null || pre == "" || str==null|| str==""|| str.length == 0 || pre.length > str.length)
return false; return false;
......
import { getFileAccessHttpUrl } from '@/api/manage'
const getFileName=(path)=>{ const getFileName=(path)=>{
if(path.lastIndexOf("\\")>=0){ if(path.lastIndexOf("\\")>=0){
let reg=new RegExp("\\\\","g"); let reg=new RegExp("\\\\","g");
...@@ -15,7 +16,7 @@ const getFilePaths=(uploadFiles)=>{ ...@@ -15,7 +16,7 @@ const getFilePaths=(uploadFiles)=>{
if(!uploadFiles){ if(!uploadFiles){
return "" return ""
} }
for(var a=0;a<uploadFiles.length;a++){ for(let a=0;a<uploadFiles.length;a++){
arr.push(uploadFiles[a].response.message) arr.push(uploadFiles[a].response.message)
} }
if(arr && arr.length>0){ if(arr && arr.length>0){
...@@ -30,7 +31,7 @@ const getUploadFileList=(paths)=>{ ...@@ -30,7 +31,7 @@ const getUploadFileList=(paths)=>{
} }
let fileList = []; let fileList = [];
let arr = paths.split(",") let arr = paths.split(",")
for(var a=0;a<arr.length;a++){ for(let a=0;a<arr.length;a++){
if(!arr[a]){ if(!arr[a]){
continue continue
}else{ }else{
...@@ -38,7 +39,7 @@ const getUploadFileList=(paths)=>{ ...@@ -38,7 +39,7 @@ const getUploadFileList=(paths)=>{
uid:uidGenerator(), uid:uidGenerator(),
name:getFileName(arr[a]), name:getFileName(arr[a]),
status: 'done', status: 'done',
url: window._CONFIG['staticDomainURL']+"/"+arr[a], url: getFileAccessHttpUrl(arr[a]),
response:{ response:{
status:"history", status:"history",
message:arr[a] message:arr[a]
......
/*
*
* 这里填写用户自定义的表达式
* 可用在Online表单的默认值表达式中使用
* 需要外部使用的变量或方法一定要 export,否则无法识别
* 示例:
* export const name = '张三'; // const 是常量
* export let age = 17; // 看情况 export const 还是 let ,两者都可正常使用
* export function content(arg) { // export 方法,可传参数,使用时要加括号,值一定要return回去,可以返回Promise
* return 'content' + arg;
* }
* export const address = (arg) => content(arg) + ' | 北京市'; // export 箭头函数也可以
*
*/
/** 字段默认值官方示例:获取地址 */
export function demoFieldDefVal_getAddress(arg) {
if (!arg) {
arg = '朝阳区'
}
return `北京市 ${arg}`
}
\ No newline at end of file
...@@ -2,16 +2,16 @@ import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types" ...@@ -2,16 +2,16 @@ import { USER_AUTH,SYS_BUTTON_AUTH } from "@/store/mutation-types"
const hasPermission = { const hasPermission = {
install (Vue, options) { install (Vue, options) {
//console.log(options); console.log(options);
Vue.directive('has', { Vue.directive('has', {
inserted: (el, binding, vnode)=>{ inserted: (el, binding, vnode)=>{
//console.log("页面权限控制----"); console.log("页面权限控制----");
console.time() //console.time()
//节点权限处理,如果命中则不进行全局权限处理 //节点权限处理,如果命中则不进行全局权限处理
if(!filterNodePermission(el, binding, vnode)){ if(!filterNodePermission(el, binding, vnode)){
filterGlobalPermission(el, binding, vnode); filterGlobalPermission(el, binding, vnode);
} }
console.timeEnd() //计时结束并输出时长 //console.timeEnd() //计时结束并输出时长
} }
}); });
} }
......
/**
* 该文件截取自 "ant-design-vue/es/_util/props-util.js" 文件,并对其做出特殊修改
*/
function classNames() {
let classes = []
for (let i = 0; i < arguments.length; i++) {
let arg = arguments[i]
if (!arg) continue
let argType = typeof arg
if (argType === 'string' || argType === 'number') {
classes.push(arg)
} else if (Array.isArray(arg) && arg.length) {
let inner = classNames.apply(null, arg)
if (inner) {
classes.push(inner)
}
} else if (argType === 'object') {
for (let key in arg) {
if (arg.hasOwnProperty(key) && arg[key]) {
classes.push(key)
}
}
}
}
return classes.join(' ')
}
const camelizeRE = /-(\w)/g
function camelize(str) {
return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''))
}
function objectCamelize(obj) {
let res = {}
Object.keys(obj).forEach(k => (res[camelize(k)] = obj[k]))
return res
}
function parseStyleText(cssText = '', camel) {
const res = {}
const listDelimiter = /;(?![^(]*\))/g
const propertyDelimiter = /:(.+)/
cssText.split(listDelimiter).forEach(function (item) {
if (item) {
const tmp = item.split(propertyDelimiter)
if (tmp.length > 1) {
const k = camel ? camelize(tmp[0].trim()) : tmp[0].trim()
res[k] = tmp[1].trim()
}
}
})
return res
}
export function getClass(ele) {
let data = {}
if (ele.data) {
data = ele.data
} else if (ele.$vnode && ele.$vnode.data) {
data = ele.$vnode.data
}
const tempCls = data.class || {}
const staticClass = data.staticClass
let cls = {}
staticClass &&
staticClass.split(' ').forEach(c => {
cls[c.trim()] = true
})
if (typeof tempCls === 'string') {
tempCls.split(' ').forEach(c => {
cls[c.trim()] = true
})
} else if (Array.isArray(tempCls)) {
classNames(tempCls)
.split(' ')
.forEach(c => {
cls[c.trim()] = true
})
} else {
cls = { ...cls, ...tempCls }
}
return cls
}
export function getStyle(ele, camel) {
getClass(ele)
let data = {}
if (ele.data) {
data = ele.data
} else if (ele.$vnode && ele.$vnode.data) {
data = ele.$vnode.data
}
// update-begin-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
let style = data.style || {}
let staticStyle = data.staticStyle
staticStyle = staticStyle ? objectCamelize(data.staticStyle) : {}
// update-end-author:sunjianlei date:20200303 for: style 和 staticStyle 可以共存
if (typeof style === 'string') {
style = parseStyleText(style, camel)
} else if (camel && style) {
// 驼峰化
style = objectCamelize(style)
}
return { ...staticStyle, ...style }
}
...@@ -5,16 +5,18 @@ import { VueAxios } from './axios' ...@@ -5,16 +5,18 @@ import { VueAxios } from './axios'
import {Modal, notification} from 'ant-design-vue' import {Modal, notification} from 'ant-design-vue'
import { ACCESS_TOKEN } from "@/store/mutation-types" import { ACCESS_TOKEN } from "@/store/mutation-types"
//自动设置后台服务 baseURL (也可以手工指定写死项目名字) /**
let baseDomain = window._CONFIG['domianURL']; * 【指定 axios的 baseURL】
let baseProject = baseDomain.substring(baseDomain.lastIndexOf("/")); * 如果手工指定 baseURL: '/jeecg-boot'
console.log("baseDomain= ",baseDomain) * 则映射后端域名,通过 vue.config.js
console.log("baseProject= ",baseProject) * @type {*|string}
*/
let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
console.log("apiBaseUrl= ",apiBaseUrl)
// 创建 axios 实例 // 创建 axios 实例
const service = axios.create({ const service = axios.create({
//baseURL: '/jeecg-boot', //baseURL: '/jeecg-boot',
baseURL: baseProject, // api base_url baseURL: apiBaseUrl, // api base_url
timeout: 9000 // 请求超时时间 timeout: 9000 // 请求超时时间
}) })
......
import * as api from '@/api/api' import * as api from '@/api/api'
import { isURL } from '@/utils/validate' import { isURL } from '@/utils/validate'
import onlineCommons from '@jeecg/antd-online-beta220'
export function timeFix() { export function timeFix() {
const time = new Date() const time = new Date()
...@@ -33,7 +34,7 @@ export function filterObj(obj) { ...@@ -33,7 +34,7 @@ export function filterObj(obj) {
return; return;
} }
for ( var key in obj) { for ( let key in obj) {
if (obj.hasOwnProperty(key) if (obj.hasOwnProperty(key)
&& (obj[key] == null || obj[key] == undefined || obj[key] === '')) { && (obj[key] == null || obj[key] == undefined || obj[key] === '')) {
delete obj[key]; delete obj[key];
...@@ -49,7 +50,7 @@ export function filterObj(obj) { ...@@ -49,7 +50,7 @@ export function filterObj(obj) {
* @returns {*} * @returns {*}
*/ */
export function formatDate(value, fmt) { export function formatDate(value, fmt) {
var regPos = /^\d+(\.\d+)?$/; let regPos = /^\d+(\.\d+)?$/;
if(regPos.test(value)){ if(regPos.test(value)){
//如果是数字 //如果是数字
let getDate = new Date(value); let getDate = new Date(value);
...@@ -100,7 +101,7 @@ let indexRouter = [{ ...@@ -100,7 +101,7 @@ let indexRouter = [{
function generateChildRouters (data) { function generateChildRouters (data) {
const routers = []; const routers = [];
for (var item of data) { for (let item of data) {
let component = ""; let component = "";
if(item.component.indexOf("layouts")>=0){ if(item.component.indexOf("layouts")>=0){
component = "components/"+item.component; component = "components/"+item.component;
...@@ -114,11 +115,33 @@ function generateChildRouters (data) { ...@@ -114,11 +115,33 @@ function generateChildRouters (data) {
item.meta.url = URL; item.meta.url = URL;
} }
//online菜单路由加载逻辑
let componentPath
if(item.component=="modules/online/cgform/OnlCgformHeadList"){
componentPath = onlineCommons.OnlCgformHeadList
}else if(item.component=="modules/online/cgform/OnlCgformCopyList"){
componentPath = onlineCommons.OnlCgformCopyList
}else if(item.component=="modules/online/cgform/auto/OnlCgformAutoList"){
componentPath = onlineCommons.OnlCgformAutoList
}else if(item.component=="modules/online/cgform/auto/OnlCgformTreeList"){
componentPath = onlineCommons.OnlCgformTreeList
}else if(item.component=="modules/online/cgform/auto/erp/OnlCgformErpList"){
componentPath = onlineCommons.OnlCgformErpList
}else if(item.component=="modules/online/cgform/auto/innerTable/OnlCgformInnerTableList"){
componentPath = onlineCommons.OnlCgformInnerTableList
}else if(item.component=="modules/online/cgreport/OnlCgreportHeadList"){
componentPath = onlineCommons.OnlCgreportHeadList
}else if(item.component=="modules/online/cgreport/auto/OnlCgreportAutoList"){
componentPath = onlineCommons.OnlCgreportAutoList
}else{
componentPath = resolve => require(['@/' + component+'.vue'], resolve)
}
let menu = { let menu = {
path: item.path, path: item.path,
name: item.name, name: item.name,
redirect:item.redirect, redirect:item.redirect,
component: resolve => require(['@/' + component+'.vue'], resolve), component: componentPath,
hidden:item.hidden, hidden:item.hidden,
//component:()=> import(`@/views/${item.component}.vue`), //component:()=> import(`@/views/${item.component}.vue`),
meta: { meta: {
...@@ -414,4 +437,44 @@ export function alwaysResolve(promise) { ...@@ -414,4 +437,44 @@ export function alwaysResolve(promise) {
reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法') reject('alwaysResolve: 传入的参数不是一个Promise对象或返回Promise对象的方法')
} }
}) })
} }
\ No newline at end of file
/**
* 简单实现防抖方法
*
* 防抖(debounce)函数在第一次触发给定的函数时,不立即执行函数,而是给出一个期限值(delay),比如100ms。
* 如果100ms内再次执行函数,就重新开始计时,直到计时结束后再真正执行函数。
* 这样做的好处是如果短时间内大量触发同一事件,只会执行一次函数。
*
* @param fn 要防抖的函数
* @param delay 防抖的毫秒数
* @returns {Function}
*/
export function simpleDebounce(fn, delay = 100) {
let timer = null
return function () {
let args = arguments
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(null, args)
}, delay)
}
}
/**
* 不用正则的方式替换所有值
* @param text 被替换的字符串
* @param checker 替换前的内容
* @param replacer 替换后的内容
* @returns {String} 替换后的字符串
*/
export function replaceAll(text, checker, replacer) {
let lastText = text
text = text.replace(checker, replacer)
if (lastText !== text) {
return replaceAll(text, checker, replacer)
}
return text
}
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
import RouteView from "@/components/layouts/RouteView" import RouteView from "@/components/layouts/RouteView"
import { AppPage, ArticlePage, ProjectPage } from './page' import { AppPage, ArticlePage, ProjectPage } from './page'
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import { getFileAccessHttpUrl } from '@/api/manage';
export default { export default {
components: { components: {
...@@ -133,7 +134,7 @@ ...@@ -133,7 +134,7 @@
methods: { methods: {
...mapGetters(["nickname", "avatar"]), ...mapGetters(["nickname", "avatar"]),
getAvatar(){ getAvatar(){
return window._CONFIG['staticDomainURL']+"/"+this.avatar(); return getFileAccessHttpUrl(this.avatar());
}, },
getTeams() { getTeams() {
this.$http.get('/api/workplace/teams') this.$http.get('/api/workplace/teams')
......
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
import PageLayout from '@/components/page/PageLayout' import PageLayout from '@/components/page/PageLayout'
import HeadInfo from '@/components/tools/HeadInfo' import HeadInfo from '@/components/tools/HeadInfo'
import Radar from '@/components/chart/Radar' import Radar from '@/components/chart/Radar'
import { getRoleList, getServiceList } from "@/api/manage" import { getRoleList, getServiceList, getFileAccessHttpUrl } from "@/api/manage"
const DataSet = require('@antv/data-set') const DataSet = require('@antv/data-set')
...@@ -185,7 +185,7 @@ ...@@ -185,7 +185,7 @@
}, },
created() { created() {
this.user = this.userInfo this.user = this.userInfo
this.avatar = window._CONFIG['staticDomainURL'] +"/"+ this.userInfo.avatar this.avatar = getFileAccessHttpUrl(this.userInfo.avatar)
console.log('this.avatar :'+ this.avatar) console.log('this.avatar :'+ this.avatar)
getRoleList().then(res => { getRoleList().then(res => {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
<div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;"> <div style="float: left;width:104px;height:104px;margin-right: 10px;margin: 0 8px 8px 0;">
<div <div
style="width: 100%;height: 100%;position: relative;padding: 8px;border: 1px solid #d9d9d9;border-radius: 4px;"> style="width: 100%;height: 100%;position: relative;padding: 8px;border: 1px solid #d9d9d9;border-radius: 4px;">
<img style="width: 100%;" :src="fileDetail.imgUrl" :preview="dataSource[0].key"> <img style="width: 100%;" :src="fileDetail.imgUrl" :preview="dataSource[0].key">
</div> </div>
</div> </div>
</div> </div>
...@@ -65,37 +65,33 @@ ...@@ -65,37 +65,33 @@
}, },
data() { data() {
return { return {
description: '电子档补扫页面', description: '图片预览页面',
spinning:false, spinning:false,
//数据集 //数据集
dataSource: [{ dataSource: [{
key:0, key:0,
fileDetails:[ fileDetails:[
{ {
imgUrl:"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg" imgUrl:"https://static.jeecg.com/upload/test/3a4490d5d1cd495b826e528537a47cc1.jpg"
}, },
{ {
imgUrl:"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg" imgUrl:"https://static.jeecg.com/upload/test/8f22cd945be44388bacbf0b88cf86cfa.png"
},
{
imgUrl:"https://ss0.bdstatic.com/6Ox1bjeh1BF3odCf/it/u=3660968530,985748925&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=5e64af964be378c6c2a3b0acc65dfe24"
} }
] ]
},{ },{
key:1, key:1,
fileDetails:[ fileDetails:[
{ {
imgUrl:"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg" imgUrl:"https://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg"
}, },
{ {
imgUrl:"https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&fm=27&gp=0.jpg" imgUrl:"https://static.jeecg.com/upload/test/1_1588149743473.jpg"
} }
] ]
}, }
], ],
url: { url: {
}, }
} }
}, },
created() { created() {
......
...@@ -42,11 +42,11 @@ ...@@ -42,11 +42,11 @@
spinning: false, spinning: false,
//数据集 //数据集
dataSource: [ dataSource: [
{id:'000',sort: 0,filePath: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg'}, {id:'000',sort: 0,filePath: 'https://static.jeecg.com/upload/test/1_1588149743473.jpg'},
{id:'111',sort: 1,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg'}, {id:'111',sort: 1,filePath: 'https://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg'},
{id:'222',sort: 2,filePath: 'https://ss0.bdstatic.com/6Ox1bjeh1BF3odCf/it/u=3660968530,985748925&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=5e64af964be378c6c2a3b0acc65dfe24'}, {id:'222',sort: 2,filePath: 'https://static.jeecg.com/upload/test/u24454681402491956848fm27gp0_1588149712663.jpg'},
{id:'333',sort: 3,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg'}, {id:'333',sort: 3,filePath: 'https://static.jeecg.com/upload/test/8f22cd945be44388bacbf0b88cf86cfa.png'},
{id:'444',sort: 4,filePath: 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&fm=27&gp=0.jpg'} {id:'444',sort: 4,filePath: 'https://static.jeecg.com/upload/test/u8891206113801177793fm27gp0_1588149704459.jpg'}
], ],
oldDateSource:[], oldDateSource:[],
newDateSource:[], newDateSource:[],
......
...@@ -50,11 +50,11 @@ ...@@ -50,11 +50,11 @@
children: [{ children: [{
title: '1页', title: '1页',
key: '0-0-0', key: '0-0-0',
imgUrl:'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2735633715,2749454924&fm=27&gp=0.jpg' imgUrl:'https://static.jeecg.com/upload/test/1_1588149743473.jpg'
}, { }, {
title: '2页', title: '2页',
key: '0-0-1', key: '0-0-1',
imgUrl:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=3967239004,1951414302&fm=27&gp=0.jpg' imgUrl:'https://static.jeecg.com/upload/test/u27356337152749454924fm27gp0_1588149731821.jpg'
}] }]
},{ },{
title: '第二页', title: '第二页',
...@@ -62,11 +62,11 @@ ...@@ -62,11 +62,11 @@
children: [{ children: [{
title: '1页', title: '1页',
key: '0-1-0', key: '0-1-0',
imgUrl:'https://ss0.bdstatic.com/6Ox1bjeh1BF3odCf/it/u=3660968530,985748925&fm=191&app=48&size=h300&n=0&g=4n&f=JPEG?sec=1853310920&t=5e64af964be378c6c2a3b0acc65dfe24' imgUrl:'https://static.jeecg.com/upload/test/u24454681402491956848fm27gp0_1588149712663.jpg'
}, { }, {
title: '2页', title: '2页',
key: '0-1-1', key: '0-1-1',
imgUrl:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=889120611,3801177793&fm=27&gp=0.jpg' imgUrl:'https://static.jeecg.com/upload/test/u8891206113801177793fm27gp0_1588149704459.jpg'
}] }]
},{ },{
title: '第三页', title: '第三页',
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
children: [{ children: [{
title: '1页', title: '1页',
key: '0-2-0', key: '0-2-0',
imgUrl:'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=2445468140,2491956848&fm=27&gp=0.jpg' imgUrl:'https://static.jeecg.com/upload/test/1374962_1587621329085.jpg'
}] }]
}], }],
selectedKeys:[], selectedKeys:[],
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<a-tabs defaultActiveKey="1"> <a-tabs defaultActiveKey="1">
<a-tab-pane tab="response" key="1"> <a-tab-pane tab="response" key="1">
<textarea style="width:100%;font-size: 16px;font-weight:500" :rows="10" v-html="resultJson" readonly> <textarea style="width:100%;font-size: 16px;font-weight:500" :rows="10" v-html="resultJson" readOnly>
</textarea> </textarea>
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
......
...@@ -6,12 +6,12 @@ ...@@ -6,12 +6,12 @@
<a-form layout="inline" @keyup.enter.native="searchQuery"> <a-form layout="inline" @keyup.enter.native="searchQuery">
<a-row :gutter="24"> <a-row :gutter="24">
<a-col :md="6" :sm="8"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="用户名"> <a-form-item label="用户名">
<j-input placeholder="请输入名称模糊查询" v-model="queryParam.name"></j-input> <j-input placeholder="请输入名称模糊查询" v-model="queryParam.name"></j-input>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :md="6" :sm="8"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="年龄"> <a-form-item label="年龄">
<!-- <a-input placeholder="请输入名称查询" v-model="queryParam.age"></a-input>--> <!-- <a-input placeholder="请输入名称查询" v-model="queryParam.age"></a-input>-->
<a-input placeholder="最小年龄" type="ge" v-model="queryParam.age_begin" style="width:calc(50% - 15px);"></a-input> <a-input placeholder="最小年龄" type="ge" v-model="queryParam.age_begin" style="width:calc(50% - 15px);"></a-input>
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
</a-form-item> </a-form-item>
</a-col> </a-col>
<template v-if="toggleSearchStatus"> <template v-if="toggleSearchStatus">
<a-col :md="6" :sm="8"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="生日"> <a-form-item label="生日">
<a-range-picker v-model="queryParam.birthdayRange" <a-range-picker v-model="queryParam.birthdayRange"
format="YYYY-MM-DD" format="YYYY-MM-DD"
...@@ -28,56 +28,42 @@ ...@@ -28,56 +28,42 @@
@change="onBirthdayChange" /> @change="onBirthdayChange" />
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :md="6" :sm="8"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="性别"> <a-form-item label="性别">
<j-dict-select-tag v-model="queryParam.sex" placeholder="请选择性别" dictCode="sex"/> <j-dict-select-tag v-model="queryParam.sex" placeholder="请选择性别" dictCode="sex"/>
</a-form-item> </a-form-item>
</a-col> </a-col>
<a-col :md="6" :sm="8"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="选择用户"> <a-form-item label="选择用户">
<j-dict-select-tag v-model="queryParam.id" placeholder="请选择用户" dictCode="demo,name,id"/> <j-dict-select-tag v-model="queryParam.id" placeholder="请选择用户" dictCode="demo,name,id"/>
</a-form-item> </a-form-item>
</a-col> </a-col>
</template> </template>
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons"> <span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-col :md="6" :sm="24"> <a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button> <a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button> <a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</a-col> </a-col>
</span> </span>
<a-col :md="6" :sm="24">
<!-- <template v-if="superQueryFlag">
<a-tooltip title="已有高级查询条件生效!">
<button :disabled="false" class="ant-btn ant-btn-primary" @click="superQuery">
<a-icon type="appstore" theme="twoTone" spin="true"></a-icon>
<span>高级查询</span>
</button>
</a-tooltip>
</template>
<a-button v-else type="primary" @click="superQuery" icon="filter">高级查询</a-button>
-->
<!-- 高级查询区域 -->
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
<a @click="handleToggleSearch" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<a-icon :type="toggleSearchStatus ? 'up' : 'down'"/>
</a>
</a-col>
</a-row> </a-row>
</a-form> </a-form>
</div> </div>
<!-- 操作按钮区域 --> <!-- 操作按钮区域 -->
<div class="table-operator" style="margin-top: 5px"> <div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">新增</a-button> <a-button @click="handleAdd" type="primary" icon="plus">新增</a-button>
<a-button type="primary" icon="plus" @click="jump">创建单据</a-button> <a-button type="primary" icon="plus" @click="jump">创建单据</a-button>
<a-button type="primary" icon="plus" @click="onetomany">一对多</a-button> <a-button type="primary" icon="plus" @click="onetomany">一对多</a-button>
<a-button type="primary" icon="download" @click="handleExportXls('demo')">导出</a-button> <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-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel">
<a-button type="primary" icon="import">导入</a-button> <a-button type="primary" icon="import">导入</a-button>
</a-upload> </a-upload>
<!-- 高级查询区域 -->
<j-super-query :fieldList="fieldList" ref="superQueryModal" @handleSuperQuery="handleSuperQuery"></j-super-query>
<a-dropdown v-if="selectedRowKeys.length > 0"> <a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay"> <a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel"> <a-menu-item key="1" @click="batchDel">
...@@ -112,7 +98,7 @@ ...@@ -112,7 +98,7 @@
</a-row> </a-row>
</a-checkbox-group> </a-checkbox-group>
</template> </template>
<a><a-icon type="setting" />自定义列</a> <a><a-icon type="setting" />设置</a>
</a-popover> </a-popover>
</span> </span>
</div> </div>
...@@ -178,25 +164,27 @@ ...@@ -178,25 +164,27 @@
import JSuperQuery from '@/components/jeecg/JSuperQuery.vue'; import JSuperQuery from '@/components/jeecg/JSuperQuery.vue';
import JInput from '@/components/jeecg/JInput.vue'; import JInput from '@/components/jeecg/JInput.vue';
import JeecgDemoTabsModal from './modules/JeecgDemoTabsModal' import JeecgDemoTabsModal from './modules/JeecgDemoTabsModal'
import {initDictOptions, filterDictText} from '@/components/dict/JDictSelectUtil' import {initDictOptions, filterDictText,filterDictTextByCache} from '@/components/dict/JDictSelectUtil'
import { JeecgListMixin } from '@/mixins/JeecgListMixin' import { JeecgListMixin } from '@/mixins/JeecgListMixin'
import Vue from 'vue' import Vue from 'vue'
import { filterObj } from '@/utils/util'; import { filterObj } from '@/utils/util';
//高级查询modal需要参数 //高级查询modal需要参数
const superQueryFieldList=[{ const superQueryFieldList=[
type:"date", {
value:"birthday", type: "string",
text:"生日" value: "name",
},{ text: "用户名"
type:"string", }, {
value:"name", type: "int",
text:"用户名" value: "age",
},{ text: "年龄"
type:"int", }, {
value:"age", type: "date",
text:"年龄" value: "birthday",
}] text: "生日"
}
]
export default { export default {
name: "JeecgDemoList", name: "JeecgDemoList",
mixins:[JeecgListMixin], mixins:[JeecgListMixin],
...@@ -208,7 +196,7 @@ ...@@ -208,7 +196,7 @@
}, },
data() { data() {
return { return {
description: '用户管理页面', description: '单表示例列表',
//字典数组缓存 //字典数组缓存
sexDictOptions: [], sexDictOptions: [],
importExcelUrl:`${window._CONFIG['domianURL']}/test/jeecgDemo/importExcel`, importExcelUrl:`${window._CONFIG['domianURL']}/test/jeecgDemo/importExcel`,
...@@ -249,7 +237,7 @@ ...@@ -249,7 +237,7 @@
dataIndex: 'sex', dataIndex: 'sex',
customRender: (text) => { customRender: (text) => {
//字典值替换通用方法 //字典值替换通用方法
return filterDictText(this.sexDictOptions, text); return filterDictTextByCache('sex', text);
} }
}, },
{ {
...@@ -293,12 +281,11 @@ ...@@ -293,12 +281,11 @@
}, },
methods: { methods: {
getQueryParams(){ getQueryParams(){
console.log(this.queryParam.birthdayRange)
//高级查询器 //高级查询器
let sqp = {} let sqp = {}
if(this.superQueryParams){ if(this.superQueryParams){
sqp['superQueryParams']=encodeURI(this.superQueryParams) sqp['superQueryParams']=encodeURI(this.superQueryParams)
sqp['superQueryMatchType'] = this.superQueryMatchType
} }
var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters); var param = Object.assign(sqp, this.queryParam, this.isorter ,this.filters);
...@@ -380,38 +367,5 @@ ...@@ -380,38 +367,5 @@
} }
</script> </script>
<style scoped> <style scoped>
.ant-card-body .table-operator { @import '~@assets/less/common.less';
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
/** Button按钮间距 */
.ant-btn {
margin-left: 3px
}
</style> </style>
\ No newline at end of file
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</div> </div>
</template> </template>
<template v-else> <template v-else>
(暂无材料,点击右侧"选择文件"或"扫描上传"上传文件) (暂无材料,点击"选择文件"或"扫描上传"上传文件)
</template> </template>
</a-col> </a-col>
</a-row> </a-row>
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
<script> <script>
import { getAction } from '@/api/manage' import { getAction } from '@/api/manage'
export default { export default {
props: ['sex','name'],
data () { data () {
return { return {
formLayout: 'horizontal', formLayout: 'horizontal',
...@@ -63,11 +64,25 @@ ...@@ -63,11 +64,25 @@
}, },
}, },
created (){ created (){
console.log('============= online href common props ============= ');
console.log('props sex: ',this.sex);
console.log('props name: ',this.name);
getAction('/api/area').then((res) => { getAction('/api/area').then((res) => {
console.log("------------") console.log("------------")
console.log(res) console.log(res)
this.areaOptions = res; this.areaOptions = res;
}) })
} },
watch: {
$route: {
immediate: true,
handler() {
console.log('============= online href $route props ============= ');
let sex = this.$route.query.sex
console.log('$route sex: ', sex);
}
}
},
} }
</script> </script>
\ No newline at end of file
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
@selectRowChange="handleSelectRowChange"> @selectRowChange="handleSelectRowChange">
<template v-slot:action="props"> <template v-slot:action="props">
<a @click="handleDelete(props)">{{ props.text }}</a> <a @click="handleDelete(props)">删除</a>
</template> </template>
</j-editable-table> </j-editable-table>
...@@ -154,6 +154,8 @@ ...@@ -154,6 +154,8 @@
type: FormTypes.inputNumber, type: FormTypes.inputNumber,
defaultValue: 32, defaultValue: 32,
placeholder: '${title}', placeholder: '${title}',
// 是否是统计列,只有 inputNumber 才能设置统计列
statistics: true,
validateRules: [{ required: true, message: '请输入${title}' }] validateRules: [{ required: true, message: '请输入${title}' }]
}, },
{ {
...@@ -167,6 +169,15 @@ ...@@ -167,6 +169,15 @@
validateRules: [{ required: true, message: '请选择${title}' }] validateRules: [{ required: true, message: '请选择${title}' }]
}, },
{ {
title: '数字',
key: 'money',
width: '320px',
type: FormTypes.inputNumber,
defaultValue: '100.32',
placeholder: '请选择${title}',
validateRules: [{ required: true, message: '请选择${title}' }]
},
{
title: '可以为空', title: '可以为空',
key: 'isNull', key: 'isNull',
// width: '8%', // width: '8%',
...@@ -176,13 +187,22 @@ ...@@ -176,13 +187,22 @@
defaultChecked: false defaultChecked: false
}, },
{ {
type: FormTypes.popup,
key: 'popup',
title: 'JPopup',
width: '180px',
popupCode: 'demo',
field: 'name',
orgFields: 'name',
destFields: 'name'
},
{
title: '操作', title: '操作',
key: 'action', key: 'action',
// width: '8%', // width: '8%',
width: '100px', width: '100px',
type: FormTypes.slot, type: FormTypes.slot,
slotName: 'action', slotName: 'action',
defaultValue: '删除'
} }
], ],
......
...@@ -624,7 +624,7 @@ ...@@ -624,7 +624,7 @@
} }
}, },
callback (key) { callback (key) {
console.log(key) //console.log(key)
} }
} }
} }
......
...@@ -160,7 +160,6 @@ ...@@ -160,7 +160,6 @@
add: "/test/order/addCustomer", add: "/test/order/addCustomer",
edit: "/test/order/editCustomer", edit: "/test/order/editCustomer",
fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload", fileUpload: window._CONFIG['domianURL'] + "/sys/common/upload",
imgerver: window._CONFIG['staticDomainURL'],
getOrderCustomerList: "/test/order/listOrderCustomerByMainId", getOrderCustomerList: "/test/order/listOrderCustomerByMainId",
}, },
validatorRules: { validatorRules: {
...@@ -246,7 +245,11 @@ ...@@ -246,7 +245,11 @@
let formData = Object.assign(this.model, values); let formData = Object.assign(this.model, values);
console.log(formData); console.log(formData);
formData.orderId = this.orderId; formData.orderId = this.orderId;
formData.idcardPic = this.fileList; if(this.fileList != '') {
formData.idcardPic = this.fileList;
}else{
formData.idcardPic = '';
}
httpAction(httpurl, formData, method).then((res) => { httpAction(httpurl, formData, method).then((res) => {
if (res.success) { if (res.success) {
that.$message.success(res.message); that.$message.success(res.message);
...@@ -278,36 +281,6 @@ ...@@ -278,36 +281,6 @@
callback("您的身份证号码格式不正确!"); callback("您的身份证号码格式不正确!");
} }
}, },
handleChange(info) {
this.fileList = info.fileList;
if (info.file.status === 'uploading') {
return
}
if (info.file.status === 'done') {
var response = info.file.response;
if (!response.success) {
this.$message.warning(response.message);
}
}
},
handlePicCancel() {
this.previewVisible = false
this.previewImage=''
},
handlePicView(url){
this.previewImage = this.url.imgerver + "/" + url
this.previewVisible = true
},
handlePreview(file) {
this.previewImage = file.url || file.thumbUrl
this.previewVisible = true
},
getIdCardView(url) {
// let pics = this.model.idcardPic.split(",");
//let pics_len = pics.length;
// 显示上传的最后一个图片
return this.url.imgerver + "/" + url
}
} }
} }
</script> </script>
......
/**
* online 自定义按钮表达式处理类
*/
export default class ButtonExpHandler {
/**
* 构造器
* @param express
*/
constructor(express,record) {
this._express = express;
this._record = record;
}
get show() {
if(!this._express || this._express==''){
return true;
}
let arr = this._express.split('#');
//获取字段值
let fieldValue = this._record[arr[0]];
//获取表达式
let exp = arr[1].toLowerCase();
//判断表达式
if(exp === 'eq'){
return fieldValue == arr[2];
}else if(exp === 'ne'){
return !(fieldValue == arr[2]);
}else if(exp === 'empty'){
if(arr[2]==='true' || arr[2]===true){
return !fieldValue || fieldValue=='';
}else{
return fieldValue && fieldValue.length>0
}
}else if(exp === 'in'){
let arr2 = arr[2].split(',');
return arr2.indexOf(String(fieldValue))>=0;
}
return false;
}
}
\ No newline at end of file
<template>
<a-card :bordered="false" style="height: 100%">
<online-common-list
:ref="'onl_'+mainModel.currentTableName"
:code="code"
:model="mainModel"
@seleted="onSelected">
</online-common-list>
<a-tabs defaultActiveKey="0">
<a-tab-pane v-for="(item,index) in subList" :tab="item.description" :key="index+''" :forceRender="true" >
<online-common-list
:ref="item.currentTableName"
:code="item.code"
:model="item"
:main="selectedRow">
</online-common-list>
</a-tab-pane>
</a-tabs>
</a-card>
</template>
<script>
import { getAction } from '@/api/manage'
export default {
name: 'OnlCgformErpList',
components:{
},
data(){
return {
code:'',
url: {
getColumns: '/online/cgform/api/getErpColumns/',
},
mainModel:{},
subList:[],
mainId:'',
selectedRow:{}
}
},
watch: {
'$route'() {
// 刷新参数放到这里去触发,就可以刷新相同界面了
this.initColumnConfig()
}
},
created() {
this.initColumnConfig();
},
methods:{
getSubIndex(index){
return index+1 + ''
},
getSubRef(item){
let ref = item.currentTableName
console.log("ref string",ref)
return ref;
},
initColumnConfig(){
if(!this.$route.params.code){
return false
}
this.code = this.$route.params.code
getAction(`${this.url.getColumns}${this.code}`).then((res)=>{
console.log("erp表单配置",res)
if(res.success){
this.mainModel = res.result.main
this.subList = res.result.subList
this.$nextTick(()=>{
this.$refs['onl_'+this.mainModel.currentTableName].initListByModel();
if(this.subList && this.subList.length>0){
for(let item of this.subList){
this.$refs[item.currentTableName][0].initListByModel();
}
}
});
}
})
},
onSelected(row){
console.log("onSelected",row)
this.selectedRow = row;
}
}
}
</script>
<style>
.ant-card-body .table-operator{
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td{
padding-top:15px;
padding-bottom:15px;
}
.anty-row-operator button{margin: 0 5px}
.ant-btn-danger{background-color: #ffffff}
.anty-img-wrap{height:25px;position: relative;}
.anty-img-wrap > img{max-height:100%;}
.ant-modal-cust-warp{height: 100%}
.ant-modal-cust-warp .ant-modal-body{height:calc(100% - 110px) !important;overflow-y: auto}
.ant-modal-cust-warp .ant-modal-content{height:90% !important;overflow-y: hidden}
</style>
\ No newline at end of file
/**
* 同步列表,可以同步新增、修改、删除
* @author sunjianlei
* */
export async function syncAllTable(vm, table1) {
vm.$refs.editableTable.resetScrollTop()
let deleteIds = table1.$refs.editableTable.getDeleteIds()
let table1Value
await table1.$refs.editableTable.getValuesPromise(false).then((values) => {
table1Value = values
return vm.$refs.editableTable.getValuesPromise(false)
}).then((values) => {
table1Value.forEach(value => {
let flag = false
values.forEach((thisValue) => {
if (value.id === thisValue.id) {
// 判断是否修改了值
let dbFieldName = thisValue['dbFieldName']
let dbFieldTxt = thisValue['dbFieldTxt']
// return
if (value.dbFieldName !== dbFieldName
|| value.dbFieldTxt !== dbFieldTxt) {
// 修改了
vm.$refs.editableTable.setValues([{
rowKey: thisValue.id,
values: {
dbFieldName: value.dbFieldName,
dbFieldTxt: value.dbFieldTxt
}
}])
}
flag = true
} else {
// id不匹配则有可能是新增也有可能是删除了的
// 遍历传进来的 deleteIds 进行对比
deleteIds.forEach(delId => {
// 对比成功,则删除该条数据
if (delId === thisValue.id) {
vm.$refs.editableTable.removeRows(vm.$refs.editableTable.caseId + delId)
flag = true
}
})
}
})
// return
// 判断是否操作了该条数据,若没有操作则代表要执行新增操作
if (!flag) {
let record = Object.assign({}, value)
vm.columns.forEach(column => {
if (
column.dataIndex !== 'dbFieldName' &&
column.dataIndex !== 'dbFieldTxt'
) {
record[column.dataIndex] = column.defaultValue
}
})
vm.$refs.editableTable.push(record)
}
})
})
}
/**
* 将数据分类并Set进dataSource
* @author sunjianlei
**/
export function setDataSource(vm, queryData) {
let dataSource = []
// 遍历查询出来的数据
queryData.forEach(value => {
let data = { id: value['id'] }
vm.columns.forEach(column => {
let key = column.key
if (key) {
data[key] = value[key]
// 由于多选下拉框返回的是一个数组,所以需要改成 [1,2,3] 数组的形式,否则组件不识别
// if (key === 'indexField') {
// data[key] = value[key].split(',')
// }
}
})
dataSource.push(data)
})
vm.dataSource = dataSource
}
/** 获取主表的初始化数据 */
export function getMasterTableInitialData() {
return [
{
dbFieldName: 'id',
dbFieldTxt: '主键',
dbLength: 36,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '1',
dbIsNull: '0',
// table2
isShowForm: '0',
isShowList: '0',
isReadOnly: '1',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 1
},
{
dbFieldName: 'create_by',
dbFieldTxt: '创建人',
dbLength: 50,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 2
},
{
dbFieldName: 'create_time',
dbFieldTxt: '创建日期',
dbLength: 20,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'Date',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'datetime',
fieldLength: '120',
queryMode: 'single',
orderNum: 3
},
{
dbFieldName: 'update_by',
dbFieldTxt: '更新人',
dbLength: 50,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 4
},
{
dbFieldName: 'update_time',
dbFieldTxt: '更新日期',
dbLength: 20,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'Date',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'datetime',
fieldLength: '120',
queryMode: 'single',
orderNum: 5
},{
dbFieldName: 'sys_org_code',
dbFieldTxt: '所属部门',
dbLength: 64,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 6
}
// {
// dbFieldName: 'sys_org_code',
// dbFieldTxt: '所属部门',
// dbLength: 50,
// dbPointLength: 0,
// dbDefaultVal: '',
// dbType: 'string',
// dbIsKey: false,
// dbIsNull: true
// }, {
// dbFieldName: 'sys_company_code',
// dbFieldTxt: '所属公司',
// dbLength: 50,
// dbPointLength: 0,
// dbDefaultVal: '',
// dbType: 'string',
// dbIsKey: false,
// dbIsNull: true
// }, {
// dbFieldName: 'bpm_status',
// dbFieldTxt: '流程状态',
// dbLength: 32,
// dbPointLength: 0,
// dbDefaultVal: '',
// dbType: 'string',
// dbIsKey: false,
// dbIsNull: true
// }
]
}
/** 获取树的初始化数据 */
export function getTreeNeedFields() {
return [{
dbFieldName: 'pid',
dbFieldTxt: '父级节点',
dbLength: 32,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '1',
isShowList: '0',
fieldShowType: 'text',
fieldLength: '120',
queryMode: 'single',
orderNum: 7
},{
dbFieldName: 'has_child',
dbFieldTxt: '是否有子节点',
dbLength: 3,
dbPointLength: 0,
dbDefaultVal: '',
dbType: 'string',
dbIsKey: '0',
dbIsNull: '1',
// table2
isShowForm: '0',
isShowList: '0',
fieldShowType: 'list',
fieldLength: '120',
queryMode: 'single',
orderNum: 8,
// table3
dictField:"yn"
}]
}
\ No newline at end of file
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div class="table-page-search-wrapper">
<a-form layout="inline">
<a-row :gutter="24">
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="报表编码">
<a-input placeholder="请输入报表编码" v-model="queryParam.code"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<a-form-item label="报表名字">
<a-input placeholder="请输入报表名字" v-model="queryParam.name"></a-input>
</a-form-item>
</a-col>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left;overflow: hidden;" class="table-page-search-submitButtons">
<a-button type="primary" @click="searchQuery" icon="search">查询</a-button>
<a-button type="primary" @click="searchReset" icon="reload" style="margin-left: 8px">重置</a-button>
</span>
</a-col>
</a-row>
</a-form>
</div>
<!-- 操作按钮区域 -->
<div class="table-operator">
<a-button @click="handleAdd" type="primary" icon="plus">录入</a-button>
<a-dropdown v-if="selectedRowKeys.length > 0">
<a-menu slot="overlay">
<a-menu-item key="1" @click="batchDel">
<a-icon type="delete"/>
删除
</a-menu-item>
</a-menu>
<a-button style="margin-left: 8px"> 批量操作
<a-icon type="down"/>
</a-button>
</a-dropdown>
</div>
<!-- table区域-begin -->
<div>
<div class="ant-alert ant-alert-info" style="margin-bottom: 16px;">
<i class="anticon anticon-info-circle ant-alert-icon"></i>
已选择
<a style="font-weight: 600">
{{ selectedRowKeys.length }}
</a>
<a style="margin-left: 24px" @click="onClearSelected">清空</a>
</div>
<a-table
ref="table"
size="middle"
bordered
rowKey="id"
:columns="columns"
:dataSource="dataSource"
:pagination="ipagination"
:loading="loading"
:rowSelection="{selectedRowKeys: selectedRowKeys, onChange: onSelectChange}"
@change="handleTableChange">
<span slot="action" slot-scope="text, record">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical"/>
<a-dropdown>
<a class="ant-dropdown-link">更多 <a-icon type="down"/></a>
<a-menu slot="overlay">
<a-menu-item @click="popReportURL(record.id)">
配置地址
</a-menu-item>
<a-menu-item>
<a @click="goPageOnline(record.id)">功能测试</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>
<!-- table区域-end -->
<!-- 表单区域 -->
<onlCgreportHead-modal ref="modalForm" @ok="modalFormOk"></onlCgreportHead-modal>
<!-- 提示online报表链接 -->
<a-modal
title="报表访问链接"
:visible="visible"
@cancel="handleCancel">
<template slot="footer">
<a-button @click="handleCancel">关闭</a-button>
<a-button type="primary" class="copy-this-text" :data-clipboard-text="reportUrlText" @click="onCopyUrl">复制</a-button>
</template>
<p>{{ reportUrlText }}</p>
</a-modal>
</a-card>
</template>
<script>
import {JeecgListMixin} from '@/mixins/JeecgListMixin'
import Clipboard from 'clipboard'
import { getAction } from '@/api/manage'
export default {
name: 'OnlCgreportHeadList',
mixins: [JeecgListMixin],
components: {
Clipboard
},
data() {
return {
description: '在线报表配置管理页面',
visible:false,
reportUrlText:'',
// 表头
columns: [
{
title: '报表名称',
align: 'center',
dataIndex: 'name'
},
{
title: '编码',
align: 'center',
dataIndex: 'code'
},
{
title: '查询SQL',
align: 'center',
dataIndex: 'cgrSql'
},
{
title: '数据源',
align: 'center',
dataIndex: 'dbSource'
},
{
title: '创建时间',
align: 'center',
dataIndex: 'createTime'
},
{
title: '描述',
align: 'center',
dataIndex: 'content'
},
{
title: '操作',
dataIndex: 'action',
align: 'center',
scopedSlots: { customRender: 'action' }
}
],
url: {
list: '/online/cgreport/head/list',
delete: '/online/cgreport/head/delete',
deleteBatch: '/online/cgreport/head/deleteBatch',
getParamsInfo:'/online/cgreport/api/getParamsInfo/'
}
}
},
methods: {
initReportUrlText(id){
getAction(this.url.getParamsInfo+id).then((res) => {
let textUrl = ""
if (res.success) {
if(res.result && res.result.length>0){
for(let i of res.result){
textUrl+=i.paramName+"=${"+i.paramName+"}&"
}
}
} else {
this.$message.warning(res.message)
}
if(textUrl.length>0){
textUrl = textUrl.substring(0,textUrl.length-1)
this.reportUrlText = `/online/cgreport/${id}?${textUrl}`
}else{
this.reportUrlText = `/online/cgreport/${id}`
}
})
},
goPageOnline(id){
this.$router.push({path: '/online/cgreport/'+id})
},
popReportURL(id){
this.visible = true;
this.initReportUrlText(id)
},
handleCancel(){
this.visible = false
this.reportUrlText = '';
},
onCopyUrl(){
var clipboard = new Clipboard('.copy-this-text')
clipboard.on('success', () => {
clipboard.destroy()
this.$message.success('复制成功')
this.handleCancel()
})
clipboard.on('error', () => {
this.$message.error('该浏览器不支持自动复制')
clipboard.destroy()
})
}
}
}
</script>
<style lang="less" scoped>
.ant-card-body .table-operator {
margin-bottom: 18px;
}
.ant-table-tbody .ant-table-row td {
padding-top: 15px;
padding-bottom: 15px;
}
.anty-row-operator button {
margin: 0 5px
}
.ant-btn-danger {
background-color: #ffffff
}
.ant-modal-cust-warp {
height: 100%
}
.ant-modal-cust-warp .ant-modal-body {
height: calc(100% - 110px) !important;
overflow-y: auto
}
.ant-modal-cust-warp .ant-modal-content {
height: 90% !important;
overflow-y: hidden
}
</style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment